[Ovirt-devel] [PATCH server] Added the ability for NICs to be bonded for load balancing and failover.
Darryl L. Pierce
dpierce at redhat.com
Fri Sep 19 20:34:18 UTC 2008
You will need to perform a migration after applying this patch to get the new
tables.
Additionally, this patch includes a configuration controller for the server.
When the node requests its configuration, the controller generates on on the
fly based on details in the database
Signed-off-by: Darryl L. Pierce <dpierce at redhat.com>
---
src/app/controllers/managed_node_controller.rb | 67 +++++
src/app/controllers/nic_controller.rb | 1 +
src/app/models/bonding.rb | 46 +++
src/app/models/bonding_type.rb | 26 ++
src/app/models/boot_type.rb | 21 ++
src/app/models/host.rb | 9 +-
src/app/models/nic.rb | 3 +
src/config/environment.rb | 2 +
src/db/migrate/019_create_bonding_types.rb | 43 +++
src/db/migrate/020_create_bondings.rb | 47 +++
src/db/migrate/021_create_bondings_nics.rb | 40 +++
src/db/migrate/022_create_boot_types.rb | 56 ++++
src/dutils/active_record_env.rb | 1 +
src/host-browser/host-browser.rb | 14 +-
src/host-browser/test-host-browser-identify.rb | 283 ------------------
src/lib/managed_node_configuration.rb | 98 +++++--
src/test/fixtures/bonding_types.yml | 15 +
src/test/fixtures/bondings.yml | 10 +
src/test/fixtures/bondings_nics.yml | 7 +
src/test/fixtures/boot_types.yml | 11 +
src/test/fixtures/hosts.yml | 42 +++-
src/test/fixtures/nics.yml | 52 +++-
.../functional/managed_node_configuration_test.rb | 129 ++++++---
.../functional/managed_node_controller_test.rb | 63 ++++
src/test/functional/nic_controller_test.rb | 43 ---
src/test/unit/bonding_test.rb | 79 +++++
src/test/unit/bonding_type_test.rb | 34 +++
src/test/unit/boot_type_test.rb | 26 ++
.../unit/host_browser_awaken_test.rb} | 8 +-
src/test/unit/host_browser_identify_test.rb | 304 ++++++++++++++++++++
30 files changed, 1169 insertions(+), 411 deletions(-)
create mode 100644 src/app/controllers/managed_node_controller.rb
create mode 100644 src/app/models/bonding.rb
create mode 100644 src/app/models/bonding_type.rb
create mode 100644 src/app/models/boot_type.rb
create mode 100644 src/db/migrate/019_create_bonding_types.rb
create mode 100644 src/db/migrate/020_create_bondings.rb
create mode 100644 src/db/migrate/021_create_bondings_nics.rb
create mode 100644 src/db/migrate/022_create_boot_types.rb
delete mode 100755 src/host-browser/test-host-browser-identify.rb
create mode 100644 src/test/fixtures/bonding_types.yml
create mode 100644 src/test/fixtures/bondings.yml
create mode 100644 src/test/fixtures/bondings_nics.yml
create mode 100644 src/test/fixtures/boot_types.yml
create mode 100644 src/test/functional/managed_node_controller_test.rb
create mode 100644 src/test/unit/bonding_test.rb
create mode 100644 src/test/unit/bonding_type_test.rb
create mode 100644 src/test/unit/boot_type_test.rb
rename src/{host-browser/test-host-browser-awake.rb => test/unit/host_browser_awaken_test.rb} (93%)
mode change 100755 => 100644
create mode 100644 src/test/unit/host_browser_identify_test.rb
diff --git a/src/app/controllers/managed_node_controller.rb b/src/app/controllers/managed_node_controller.rb
new file mode 100644
index 0000000..1bf6169
--- /dev/null
+++ b/src/app/controllers/managed_node_controller.rb
@@ -0,0 +1,67 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
+# Street, Fifth Floor, Boston, MA 02110-1301, USA. A copy of the GNU General
+# Public License is also available at http://www.gnu.org/copyleft/gpl.html.
+
+# +ManagedNodeController+ provides methods for interacting over HTTP with a
+# managed node.
+#
+class ManagedNodeController < ApplicationController
+ before_filter :load_host, :only => :config
+ before_filter :load_macs, :only => :config
+
+ def is_logged_in
+ # this overrides the default which is to force the client to log in
+ end
+
+ # Generates a configuration file for the managed node.
+ #
+ def config
+ context = ManagedNodeConfiguration.generate(@host, @macs)
+
+ send_data("#{context}", :type => 'text', :disposition => 'inline')
+ end
+
+ def error
+ send_data("#{flash[:message]}", :type => 'text', :disposition => 'inline')
+ end
+
+ private
+
+ def load_host
+ @host = Host.find_by_hostname(params[:host])
+
+ unless @host
+ flash[:message] = 'Missing or invalid hostname specified.'
+ redirect_to :action => :error
+ end
+ end
+
+ def load_macs
+ @macs = Hash.new
+ mac_text = params[:macs]
+
+ mac_text.scan(/([^\,]+)\,?/).each do |line|
+ key, value = line.first.split("=")
+ @macs[key] = value
+ end
+
+ if @macs.empty?
+ flash[:message] = 'No MAC address mappings provided.'
+ redirect_to :action => :error
+ end
+ end
+end
diff --git a/src/app/controllers/nic_controller.rb b/src/app/controllers/nic_controller.rb
index 85d4315..b3473ac 100644
--- a/src/app/controllers/nic_controller.rb
+++ b/src/app/controllers/nic_controller.rb
@@ -46,6 +46,7 @@ class NicController < ApplicationController
end
private
+
#filter methods
def pre_new
flash[:notice] = 'Network Interfaces may not be edited via the web UI'
diff --git a/src/app/models/bonding.rb b/src/app/models/bonding.rb
new file mode 100644
index 0000000..941e2cd
--- /dev/null
+++ b/src/app/models/bonding.rb
@@ -0,0 +1,46 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+# A +Bonding+ represents a bonded interface on a node. It is associated with
+# one (though really should be at least two) +Nic+ instances.
+#
+# The +name+ is the human-readable name used in the oVirt server.
+#
+# The +interface_name+ defines the name by which the bonded interface is
+# addressed on the node.
+#
+# The +arp_ping_address+ and +arp_interval+ are the ip address and interval
+# settings used for those nodes that require them for monitoring a bonded
+# interface. They can be ignored if not used.
+#
+class Bonding < ActiveRecord::Base
+ validates_presence_of :name,
+ :message => 'A name is required.'
+
+ validates_presence_of :interface_name,
+ :message => 'An interface name is required.'
+
+ belongs_to :host
+ belongs_to :bonding_type
+
+ has_and_belongs_to_many :nics,
+ :join_table => 'bondings_nics',
+ :foreign_key => :bonding_id
+
+end
diff --git a/src/app/models/bonding_type.rb b/src/app/models/bonding_type.rb
new file mode 100644
index 0000000..e0d2193
--- /dev/null
+++ b/src/app/models/bonding_type.rb
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+# A +BondingType+ represents a mode in which two or more network interfaces
+# can be bound together.
+#
+class BondingType < ActiveRecord::Base
+ validates_presence_of :label
+ validates_presence_of :mode
+end
diff --git a/src/app/models/boot_type.rb b/src/app/models/boot_type.rb
new file mode 100644
index 0000000..8ffbe67
--- /dev/null
+++ b/src/app/models/boot_type.rb
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+class BootType < ActiveRecord::Base
+end
diff --git a/src/app/models/host.rb b/src/app/models/host.rb
index 3fc3abb..de5c5ee 100644
--- a/src/app/models/host.rb
+++ b/src/app/models/host.rb
@@ -21,15 +21,16 @@ require 'util/ovirt'
class Host < ActiveRecord::Base
belongs_to :hardware_pool
+ belongs_to :bonding_type
- has_many :cpus, :dependent => :destroy
- has_many :nics, :dependent => :destroy
- has_many :vms, :dependent => :nullify do
+ has_many :cpus, :dependent => :destroy
+ has_many :nics, :dependent => :destroy
+ has_many :bondings, :dependent => :destroy
+ has_many :vms, :dependent => :nullify
def consuming_resources
find(:all, :conditions=>{:state=>Vm::RUNNING_STATES})
end
- end
has_many :tasks, :class_name => "HostTask", :dependent => :destroy, :order => "id DESC" do
def queued
find(:all, :conditions=>{:state=>Task::STATE_QUEUED})
diff --git a/src/app/models/nic.rb b/src/app/models/nic.rb
index c1fc542..baf7095 100644
--- a/src/app/models/nic.rb
+++ b/src/app/models/nic.rb
@@ -19,4 +19,7 @@
class Nic < ActiveRecord::Base
belongs_to :host
+ belongs_to :boot_type
+
+ has_and_belongs_to_many :bonding, :join_table => 'bondings_nics'
end
diff --git a/src/config/environment.rb b/src/config/environment.rb
index ff6f6e8..3ec4379 100644
--- a/src/config/environment.rb
+++ b/src/config/environment.rb
@@ -80,3 +80,5 @@ end
require 'gettext/rails'
gem 'cobbler'
require 'cobbler'
+
+MANAGED_NODE_CONFIGURATION_DIR = '/var/www/html/ovirt-cfgdb'
diff --git a/src/db/migrate/019_create_bonding_types.rb b/src/db/migrate/019_create_bonding_types.rb
new file mode 100644
index 0000000..bf2972f
--- /dev/null
+++ b/src/db/migrate/019_create_bonding_types.rb
@@ -0,0 +1,43 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+class CreateBondingTypes < ActiveRecord::Migration
+ def self.up
+ create_table :bonding_types do |t|
+ t.string :label, :null => false, :limit => 20
+ t.integer :mode, :null => false
+ end
+
+ add_index :bonding_types, :label, :unique => true
+ add_index :bonding_types, :mode, :unique => true
+
+ # The order of the records is not related to the mode value.
+ # Instead, they are ordered this way to ensure they're presented
+ # in this particular order when loaded.
+ #
+ BondingType.create :label => 'Load Balancing', :mode => 2
+ BondingType.create :label => 'Failover', :mode => 1
+ BondingType.create :label => 'Broadcast', :mode => 3
+ BondingType.create :label => 'Link Aggregation', :mode => 4
+ end
+
+ def self.down
+ drop_table :bonding_types
+ end
+end
diff --git a/src/db/migrate/020_create_bondings.rb b/src/db/migrate/020_create_bondings.rb
new file mode 100644
index 0000000..e02adc3
--- /dev/null
+++ b/src/db/migrate/020_create_bondings.rb
@@ -0,0 +1,47 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+class CreateBondings < ActiveRecord::Migration
+ def self.up
+ create_table :bondings do |t|
+ t.string :name, :null => false, :limit => 50
+ t.string :interface_name, :null => false, :limit => 20
+ t.integer :bonding_type_id, :null => false
+ t.integer :host_id, :null => false
+ t.string :ip_addr, :null => true, :limit => 15
+ t.string :netmask, :null => true, :limit => 15
+ t.string :broadcast, :null => true, :limit => 15
+ t.string :arp_ping_address,:null => true
+ t.integer :arp_interval, :null => false, :default => 0
+
+ t.timestamps
+ end
+
+ add_index :bondings, [:interface_name, :host_id], :unique => true
+
+ execute 'alter table bondings add constraint fk_bonding_bonding_type
+ foreign key (bonding_type_id) references bonding_types(id)'
+ execute 'alter table bondings add constraint fk_bonding_host
+ foreign key (host_id) references hosts(id)'
+ end
+
+ def self.down
+ drop_table :bondings
+ end
+end
diff --git a/src/db/migrate/021_create_bondings_nics.rb b/src/db/migrate/021_create_bondings_nics.rb
new file mode 100644
index 0000000..1fe0789
--- /dev/null
+++ b/src/db/migrate/021_create_bondings_nics.rb
@@ -0,0 +1,40 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+class CreateBondingsNics < ActiveRecord::Migration
+ def self.up
+ create_table :bondings_nics do |t|
+ t.integer :bonding_id, :null => false
+ t.integer :nic_id, :null => false
+
+ t.timestamps
+ end
+
+ add_index :bondings_nics, [:bonding_id, :nic_id], :unique => true
+
+ execute 'alter table bondings_nics add constraint fk_bondings_nics_bonding
+ foreign key (bonding_id) references bondings(id)'
+ execute 'alter table bondings_nics add constraint fk_bondings_nics_nic
+ foreign key (nic_id) references nics(id)'
+ end
+
+ def self.down
+ drop_table :bondings_nics
+ end
+end
diff --git a/src/db/migrate/022_create_boot_types.rb b/src/db/migrate/022_create_boot_types.rb
new file mode 100644
index 0000000..e18d5c5
--- /dev/null
+++ b/src/db/migrate/022_create_boot_types.rb
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+class CreateBootTypes < ActiveRecord::Migration
+ def self.up
+ create_table :boot_types do |t|
+ t.string :label, :null => false, :limit => 25
+ t.string :proto, :null => false, :limit => 25
+
+ t.timestamps
+ end
+
+ add_index :boot_types, :label, :unique => true
+ add_index :boot_types, :proto, :unique => true
+
+ BootType.create(:label => 'Static IP', :proto => 'static')
+ BootType.create(:label => 'DHCP', :proto => 'dhcp')
+ BootType.create(:label => 'BOOTP', :proto => 'bootp')
+
+ add_column :nics, :boot_type_id, :integer, :null => true
+
+ execute 'alter table nics add constraint fk_nic_boot_type
+ foreign key (boot_type_id) references boot_types(id)'
+
+ boot_type = BootType.find_by_proto('static')
+
+ Nic.find(:all).each do |nic|
+ nic.boot_type_id = boot_type.id
+ nic.save!
+ end
+
+ change_column :nics, :boot_type_id, :integer, :null => false
+ end
+
+ def self.down
+ remove_column :nics, :boot_type_id
+
+ drop_table :boot_types
+ end
+end
diff --git a/src/dutils/active_record_env.rb b/src/dutils/active_record_env.rb
index c77f2d6..d0a005e 100644
--- a/src/dutils/active_record_env.rb
+++ b/src/dutils/active_record_env.rb
@@ -62,6 +62,7 @@ require 'models/directory_pool.rb'
require 'models/smart_pool.rb'
require 'models/host.rb'
require 'models/cpu.rb'
+require 'models/boot_type.rb'
require 'models/nic.rb'
require 'models/vm_resource_pool.rb'
diff --git a/src/host-browser/host-browser.rb b/src/host-browser/host-browser.rb
index f7a4a02..3adea03 100755
--- a/src/host-browser/host-browser.rb
+++ b/src/host-browser/host-browser.rb
@@ -297,16 +297,18 @@ class HostBrowser
end
# iterate over any nics left and create new records for them.
+ boot_type = BootType.find_by_proto('dhcp')
nic_info.collect do |nic|
puts "Creating a new nic..."
detail = Nic.new(
- 'mac' => nic['MAC'],
- 'bandwidth' => nic['BANDWIDTH'],
- 'usage_type' => 1,
- 'ip_addr' => nic['IP_ADDRESS'],
- 'netmask' => nic['NETMASK'],
- 'broadcast' => nic['BROADCAST'])
+ 'mac' => nic['MAC'],
+ 'bandwidth' => nic['BANDWIDTH'],
+ 'usage_type' => 1,
+ 'ip_addr' => nic['IP_ADDRESS'],
+ 'netmask' => nic['NETMASK'],
+ 'broadcast' => nic['BROADCAST'],
+ 'boot_type_id' => boot_type.id)
host.nics << detail
end
diff --git a/src/host-browser/test-host-browser-identify.rb b/src/host-browser/test-host-browser-identify.rb
deleted file mode 100755
index 7e672ce..0000000
--- a/src/host-browser/test-host-browser-identify.rb
+++ /dev/null
@@ -1,283 +0,0 @@
-#!/usr/bin/ruby -Wall
-#
-# Copyright (C) 2008 Red Hat, Inc.
-# Written by Darryl L. Pierce <dpierce at redhat.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-# MA 02110-1301, USA. A copy of the GNU General Public License is
-# also available at http://www.gnu.org/copyleft/gpl.html.
-
-require File.dirname(__FILE__) + '/../test/test_helper'
-require 'test/unit'
-require 'flexmock/test_unit'
-
-TESTING=true
-
-require 'host-browser'
-
-class TestHostBrowser < Test::Unit::TestCase
- def setup
- @session = flexmock('session')
- @session.should_receive(:peeraddr).at_least.once.returns { [nil,nil,nil,"192.168.2.255"] }
-
- @browser = HostBrowser.new(@session)
- @browser.logfile = './unit-test.log'
-
- # default host info
- @host_info = {}
- @host_info['UUID'] = 'node1'
- @host_info['IPADDR'] = '192.168.2.2'
- @host_info['HOSTNAME'] = 'prod.corp.com'
- @host_info['ARCH'] = 'x86_64'
- @host_info['MEMSIZE'] = '16384'
- @host_info['DISABLED'] = '0'
-
- @host_info['NUMCPUS'] = '2'
-
- @host_info['CPUINFO'] = Array.new
- @host_info['CPUINFO'][0] = {}
- @host_info['CPUINFO'][0]['CPUNUM'] = '0'
- @host_info['CPUINFO'][0]['CORENUM'] = '0'
- @host_info['CPUINFO'][0]['NUMCORES'] = '2'
- @host_info['CPUINFO'][0]['VENDOR'] = 'GenuineIntel'
- @host_info['CPUINFO'][0]['MODEL'] = '15'
- @host_info['CPUINFO'][0]['FAMILY'] = '6'
- @host_info['CPUINFO'][0]['CPUIDLVL'] = '10'
- @host_info['CPUINFO'][0]['SPEED'] = '3'
- @host_info['CPUINFO'][0]['CACHE'] = '4096 kb'
- @host_info['CPUINFO'][0]['FLAGS'] = 'fpu vme de pse tsc msr pae \
- mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx \
- fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs \
- bts pni monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr lahf_lm'
-
- @host_info['CPUINFO'][1] = {}
- @host_info['CPUINFO'][1]['CPUNUM'] = '1'
- @host_info['CPUINFO'][1]['CORENUM'] = '1'
- @host_info['CPUINFO'][1]['NUMCORES'] = '2'
- @host_info['CPUINFO'][1]['VENDOR'] = 'GenuineIntel'
- @host_info['CPUINFO'][1]['MODEL'] = '15'
- @host_info['CPUINFO'][1]['FAMILY'] = '6'
- @host_info['CPUINFO'][1]['CPUIDLVL'] = '10'
- @host_info['CPUINFO'][1]['SPEED'] = '3'
- @host_info['CPUINFO'][1]['CACHE'] = '4096 kb'
- @host_info['CPUINFO'][1]['FLAGS'] = 'fpu vme de pse tsc msr pae \
- mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx \
- fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs \
- bts pni monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr lahf_lm'
-
- @host_info['NICINFO'] = Array.new
- @host_info['NICINFO'][0] = {}
- @host_info['NICINFO'][0]['MAC'] = '00:11:22:33:44:55'
- @host_info['NICINFO'][0]['BANDWIDTH'] = '100'
-
- @host_info['NICINFO'][1] = {}
- @host_info['NICINFO'][1]['MAC'] = '00:77:11:77:19:65'
- @host_info['NICINFO'][1]['BANDWIDTH'] = '100'
- end
-
- # Ensures that the server is satisfied if the remote system is
- # making a wakeup call.
- #
- def test_get_mode_with_awaken_request
- @session.should_receive(:write).with("MODE?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "IDENTIFY\n" }
-
- result = @browser.get_mode()
-
- assert_equal "IDENTIFY", result, "method did not return the right value"
- end
-
- # Ensures that, if an info field is missing a key, the server raises
- # an exception.
- #
- def test_get_info_with_missing_key
- @session.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "=value1\n" }
-
- assert_raise(Exception) { @browser.get_remote_info }
- end
-
- # Ensures that, if an info field is missing a value, the server raises
- # an exception.
- #
- def test_get_info_with_missing_value
- @session.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key1=\n" }
-
- assert_raise(Exception) { @browser.get_remote_info }
- end
-
- # Ensures that, if the server gets a poorly formed ending statement, it
- # raises an exception.
- #
- def test_get_info_with_invalid_end
- @session.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key1=value1\n" }
- @session.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "ENDIFNO\n" }
-
- assert_raise(Exception) { @browser.get_remote_info }
- end
-
- # Ensures that a well-formed transaction works as expected.
- #
- def test_get_info
- @session.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key1=value1\n" }
- @session.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key2=value2\n" }
- @session.should_receive(:write).with("ACK key2\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "ENDINFO\n" }
-
- info = @browser.get_remote_info
-
- assert_equal 4,info.keys.size, "Should contain four keys"
- assert info.include?("IPADDR")
- assert info.include?("HOSTNAME")
- assert info.include?("key1")
- assert info.include?("key2")
- end
-
- # Ensures that the server is fine when no UUID is present.
- #
- def test_write_host_info_with_missing_uuid
- @host_info['UUID'] = nil
-
- assert_nothing_raised { @browser.write_host_info(@host_info) }
- end
-
- # Ensures that, if the hostname is missing, the server
- # raises an exception.
- #
- def test_write_host_info_with_missing_hostname
- @host_info['HOSTNAME'] = nil
-
- assert_raise(Exception) { @browser.write_host_info(@host_info) }
- end
-
- # Ensures that, if the architecture is missing, the server raises an
- # exception.
- #
- def test_write_host_info_with_missing_arch
- @host_info['ARCH'] = nil
-
- assert_raise(Exception) { @browser.write_host_info(@host_info) }
- end
-
- # Ensures that, if the memory size is missing, the server raises an
- # exception.
- #
- def test_write_host_info_info_with_missing_memsize
- @host_info['MEMSIZE'] = nil
-
- assert_raise(Exception) { @browser.write_host_info(@host_info) }
- end
-
- # Ensures that, if no cpu info was available, the server raises an
- # exception.
- #
- def test_write_host_info_with_missing_cpuinfo
- @host_info['CPUINFO'] = nil
-
- assert_raise(Exception) { @browser.write_host_info(@host_info) }
- end
-
- # Ensures that, if no NIC info was available, the server raises an
- # exception.
- #
- def test_write_host_info_with_missing_nicinfo
- @host_info['NICINFO'] = nil
-
- assert_raise(Exception) { @browser.write_host_info(@host_info) }
- end
-
- # Ensures the browser can properly parse the CPU details.
- #
- def test_parse_cpu_info
- @session.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "CPU\n" }
- @session.should_receive(:write).with("CPUINFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key1=value1\n" }
- @session.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key2=value2\n" }
- @session.should_receive(:write).with("ACK key2\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "ENDCPU\n" }
- @session.should_receive(:write).with("ACK CPU\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "ENDINFO\n" }
-
- info = @browser.get_remote_info
-
- assert_equal 3,info.keys.size, "Should contain four keys"
- assert info.include?("CPUINFO")
- end
-
- # Ensures the browser can properly parse the CPU details of two CPUs.
- #
- def test_parse_cpu_info_with_two_entries
- @session.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
-
- # CPU 0
- @session.should_receive(:readline).once().returns { "CPU\n" }
- @session.should_receive(:write).with("CPUINFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key1=value1\n" }
- @session.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key2=value2\n" }
- @session.should_receive(:write).with("ACK key2\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "ENDCPU\n" }
- @session.should_receive(:write).with("ACK CPU\n").once().returns { |request| request.length }
-
- # CPU 1
- @session.should_receive(:readline).once().returns { "CPU\n" }
- @session.should_receive(:write).with("CPUINFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key3=value3\n" }
- @session.should_receive(:write).with("ACK key3\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key4=value4\n" }
- @session.should_receive(:write).with("ACK key4\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "ENDCPU\n" }
- @session.should_receive(:write).with("ACK CPU\n").once().returns { |request| request.length }
-
- @session.should_receive(:readline).once().returns { "ENDINFO\n" }
-
- info = @browser.get_remote_info
-
- assert_equal 3,info.keys.size, "Should contain four keys"
- assert info.include?('CPUINFO')
- assert_equal 2, info['CPUINFO'].size, "Should contain details for two CPUs"
- assert_not_nil info['CPUINFO'][0]['key1']
- assert_not_nil info['CPUINFO'][0]['key2']
- assert_not_nil info['CPUINFO'][1]['key3']
- assert_not_nil info['CPUINFO'][1]['key4']
- end
-
- # Ensures the browser can properly parse the details for a NIC.
- #
- def test_parse_nic_info
- @session.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "NIC\n" }
- @session.should_receive(:write).with("NICINFO?\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key1=value1\n" }
- @session.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "key2=value2\n" }
- @session.should_receive(:write).with("ACK key2\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "ENDNIC\n" }
- @session.should_receive(:write).with("ACK NIC\n").once().returns { |request| request.length }
- @session.should_receive(:readline).once().returns { "ENDINFO\n" }
-
- info = @browser.get_remote_info
-
- assert_equal 3,info.keys.size, "Should contain four keys"
- assert info.include?("NICINFO")
- end
-
-end
diff --git a/src/lib/managed_node_configuration.rb b/src/lib/managed_node_configuration.rb
index 386eb05..4ade235 100644
--- a/src/lib/managed_node_configuration.rb
+++ b/src/lib/managed_node_configuration.rb
@@ -2,24 +2,23 @@
# Copyright (C) 2008 Red Hat, Inc.
# Written by Darryl L. Pierce <dpierce at redhat.com>.
#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; version 2 of the License.
#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-# MA 02110-1301, USA. A copy of the GNU General Public License is
-# also available at http://www.gnu.org/copyleft/gpl.html.
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
+# Street, Fifth Floor, Boston, MA 02110-1301, USA. A copy of the GNU General
+# Public License is also available at http://www.gnu.org/copyleft/gpl.html.
# +ManagedNodeConfiguration+ takes in the description for a managed node and,
-# from that, generates the configuration file that is consumed the next time
-# the managed node starts up.
+# from that, generates the configuration file that is consumed the next time the
+# managed node starts up.
#
require 'stringio'
@@ -30,18 +29,73 @@ class ManagedNodeConfiguration
def self.generate(host, macs)
result = StringIO.new
+ result.puts "#!/bin/bash"
+ result.puts "# THIS FILE IS GENERATED!"
+
+ # first process any bondings that're defined
+ unless host.bondings.empty?
+ result.puts "cat <<\EOF > /var/tmp/pre-config-script"
+ result.puts "#!/bin/bash"
+ result.puts "# THIS FILE IS GENERATED!"
+
+ host.bondings.each do |bonding|
+ result.puts "/sbin/modprobe bonding mode=#{bonding.bonding_type.mode}"
+ end
+
+ result.puts "EOF"
+ end
+
+ # now process the network interfaces and bondings
+ result.puts "cat <<\EOF > /var/tmp/node-augtool"
+
+ host.bondings.each do |bonding|
+ result.puts "rm #{NIC_ENTRY_PREFIX}/ifcfg-#{bonding.interface_name}"
+ result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{bonding.interface_name}/DEVICE #{bonding.interface_name}"
+ result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{bonding.interface_name}/IPADDR #{bonding.ip_addr}" if bonding.ip_addr
+ result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{bonding.interface_name}/ONBOOT yes"
+
+ bonding.nics.each do |nic|
+ process_nic result, nic, macs, bonding
+ end
+ end
+
host.nics.each do |nic|
- iface_name = macs[nic.mac]
-
- if iface_name
- result.puts "rm #{NIC_ENTRY_PREFIX}/ifcfg-#{iface_name}"
- result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{iface_name}/DEVICE #{iface_name}"
- result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{iface_name}/IPADDR #{nic.ip_addr}" if nic.ip_addr
- result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{iface_name}/BOOTPROTO dhcp" if nic.ip_addr == nil
- result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{iface_name}/BRIDGE #{nic.bridge}" if nic.bridge
+ # only process this nic if it doesn't have a bonding
+ if nic.bonding.empty?
+ process_nic result, nic, macs
end
end
+ result.puts "save"
+ result.puts "EOF"
+
result.string
end
+
+ private
+
+ def self.process_nic(result, nic, macs, bonding = nil)
+ iface_name = macs[nic.mac]
+
+ if iface_name
+ result.puts "rm #{NIC_ENTRY_PREFIX}/ifcfg-#{iface_name}"
+ result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{iface_name}/DEVICE #{iface_name}"
+
+ if bonding
+ result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{iface_name}/MASTER #{bonding.interface_name}"
+ result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{iface_name}/SLAVE yes"
+ else
+ result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{iface_name}/BOOTPROTO #{nic.boot_type.proto}"
+
+ if nic.boot_type.proto == 'static'
+ result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{iface_name}/IPADDR #{nic.ip_addr}"
+ result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{iface_name}/NETMASK #{nic.netmask}"
+ result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{iface_name}/BROADCAST #{nic.broadcast}"
+ end
+ end
+
+ result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{iface_name}/BRIDGE #{nic.bridge}" if nic.bridge
+ result.puts "set #{NIC_ENTRY_PREFIX}/ifcfg-#{iface_name}/ONBOOT yes"
+ end
+ end
end
diff --git a/src/test/fixtures/bonding_types.yml b/src/test/fixtures/bonding_types.yml
new file mode 100644
index 0000000..4bdeec5
--- /dev/null
+++ b/src/test/fixtures/bonding_types.yml
@@ -0,0 +1,15 @@
+load_balancing_bonding_type:
+ label: Load Balancing
+ mode: 2
+
+failover_bonding_type:
+ label: Failover
+ mode: 1
+
+broadcast_bonding_type:
+ label: Broadcast
+ mode: 3
+
+link_aggregation_bonding_type:
+ label: Link Aggregation
+ mode: 4
diff --git a/src/test/fixtures/bondings.yml b/src/test/fixtures/bondings.yml
new file mode 100644
index 0000000..c2a47b5
--- /dev/null
+++ b/src/test/fixtures/bondings.yml
@@ -0,0 +1,10 @@
+mailservers_managed_node_bonding:
+ name: Production Network
+ interface_name: bond0
+ bonding_type_id: <%= Fixtures.identify(:link_aggregation_bonding_type) %>
+ host_id: <%= Fixtures.identify(:mailservers_managed_node) %>
+ ip_addr: 172.31.0.15
+ netmask: 255.255.255.
+ broadcast: 172.31.0.255
+ arp_ping_address: 172.31.0.100
+ arp_interval: 0
diff --git a/src/test/fixtures/bondings_nics.yml b/src/test/fixtures/bondings_nics.yml
new file mode 100644
index 0000000..11a3d1a
--- /dev/null
+++ b/src/test/fixtures/bondings_nics.yml
@@ -0,0 +1,7 @@
+mailservers_managed_node_bonding_nic_1:
+ bonding_id: <%= Fixtures.identify(:mailservers_managed_node_bonding) %>
+ nic_id: <%= Fixtures.identify(:mailserver_nic_one) %>
+
+mailservers_managed_node_bonding_nic_2:
+ bonding_id: <%= Fixtures.identify(:mailservers_managed_node_bonding) %>
+ nic_id: <%= Fixtures.identify(:mailserver_nic_two) %>
diff --git a/src/test/fixtures/boot_types.yml b/src/test/fixtures/boot_types.yml
new file mode 100644
index 0000000..d3f31a2
--- /dev/null
+++ b/src/test/fixtures/boot_types.yml
@@ -0,0 +1,11 @@
+boot_type_static_ip:
+ label: Static IP
+ proto: static
+
+boot_type_dhcp:
+ label: DHCP
+ proto: dhcp
+
+boot_type_bootp:
+ label: BOOTP
+ proto: bootp
diff --git a/src/test/fixtures/hosts.yml b/src/test/fixtures/hosts.yml
index 44397da..5b8af15 100644
--- a/src/test/fixtures/hosts.yml
+++ b/src/test/fixtures/hosts.yml
@@ -1,4 +1,3 @@
-
one:
id: 1
uuid: '1148fdf8-961d-11dc-9387-001558c41534'
@@ -90,12 +89,39 @@ ten:
hypervisor_type: 'kvm'
hardware_pool_id: 1
state: "available"
+
mailservers_managed_node:
- id: 11
- uuid: '182a8596-961d-11dc-9387-001558c41534'
- hostname: 'mail.mynetwork.com'
- arch: 'i386'
- memory: 16384
- is_disabled: 0
- hypervisor_type: 'kvm'
+ uuid: '182a8596-961d-11dc-9387-001558c41534'
+ hostname: 'mail.mynetwork.com'
+ arch: 'i386'
+ memory: 16384
+ is_disabled: 0
+ hypervisor_type: 'kvm'
+ hardware_pool_id: <%= Fixtures.identify(:prodops_pool) %>
+
+fileserver_managed_node:
+ uuid: '928ad8172-9723-11dc-9387-001558c41534'
+ hostname: 'files.mynetwork.com'
+ arch: 'x86_64'
+ memory: 32768
+ is_disabled: 0
+ hypervisor_type: 'kvm'
+ hardware_pool_id: <%= Fixtures.identify(:prodops_pool) %>
+
+ldapserver_managed_node:
+ uuid: '919ae372-9156-11dc-9387-001558c41534'
+ hostname: 'ldap.mynetwork.com'
+ arch: 'i386'
+ memory: 16384
+ is_disabled: 0
+ hypervisor_type: 'kvm'
+ hardware_pool_id: <%= Fixtures.identify(:prodops_pool) %>
+
+buildserver_managed_node:
+ uuid: '6293acd9-2784-11dc-9387-001558c41534'
+ hostname: 'build.mynetwork.com'
+ arch: 'x86_64'
+ memory: 65536
+ is_disabled: 0
+ hypervisor_type: 'kvm'
hardware_pool_id: <%= Fixtures.identify(:prodops_pool) %>
diff --git a/src/test/fixtures/nics.yml b/src/test/fixtures/nics.yml
index 8726fb6..ccf71d2 100644
--- a/src/test/fixtures/nics.yml
+++ b/src/test/fixtures/nics.yml
@@ -5,6 +5,7 @@ one:
usage_type: '1'
bandwidth: 100
host_id: 10
+ boot_type_id: <%= Fixtures.identify(:boot_type_static_ip) %>
two:
id: 2
mac: 'AA:BB:CC:DD:EE:FF'
@@ -12,6 +13,7 @@ two:
usage_type: '2'
bandwidth: 1000
host_id: 10
+ boot_type_id: <%= Fixtures.identify(:boot_type_static_ip) %>
three:
id: 3
mac: '00:FF:11:EE:22:DD'
@@ -19,6 +21,7 @@ three:
usage_type: '1'
bandwidth: 10
host_id: 10
+ boot_type_id: <%= Fixtures.identify(:boot_type_static_ip) %>
four:
id: 4
mac: '00:FF:11:EE:22:DD'
@@ -26,11 +29,52 @@ four:
usage_type: '1'
bandwidth: 10
host_id: 10
+ boot_type_id: <%= Fixtures.identify(:boot_type_static_ip) %>
+
mailserver_nic_one:
- id: 5
- mac: '00:11:22:33:44:55'
+ mac: '00:11:22:33:44:55'
usage_type: '1'
- bandwidth: 100
- host_id: <%= Fixtures.identify(:mailservers_managed_node) %>
+ bandwidth: 100
+ ip_addr: '172.31.0.15'
+ host_id: <%= Fixtures.identify(:mailservers_managed_node) %>
+ boot_type_id: <%= Fixtures.identify(:boot_type_static_ip) %>
+mailserver_nic_two:
+ mac: '22:11:33:66:44:55'
+ usage_type: '1'
+ bandwidth: 100
+ host_id: <%= Fixtures.identify(:mailservers_managed_node) %>
+ boot_type_id: <%= Fixtures.identify(:boot_type_dhcp) %>
+fileserver_nic_one:
+ mac: '00:99:00:99:13:07'
+ usage_type: '1'
+ bandwidth: 100
+ host_id: <%= Fixtures.identify(:fileserver_managed_node) %>
+ boot_type_id: <%= Fixtures.identify(:boot_type_dhcp) %>
+
+ldapserver_nic_one:
+ mac: '00:03:02:00:09:06'
+ usage_type: '1'
+ bandwidth: 100
+ bridge: 'ovirtbr0'
+ ip_addr: '172.31.0.25'
+ host_id: <%= Fixtures.identify(:ldapserver_managed_node) %>
+ boot_type_id: <%= Fixtures.identify(:boot_type_static_ip) %>
+
+buildserver_nic_one:
+ mac: '07:17:19:65:03:38'
+ usage_type: '1'
+ bandwidth: 100
+ host_id: <%= Fixtures.identify(:buildserver_managed_node) %>
+ boot_type_id: <%= Fixtures.identify(:boot_type_dhcp) %>
+
+buildserver_nic_two:
+ mac: '07:17:19:65:03:39'
+ usage_type: '1'
+ bandwidth: 100
+ ip_addr: '172.31.0.31'
+ netmask: '255.255.255.0'
+ broadcast: '172.31.0.255'
+ host_id: <%= Fixtures.identify(:buildserver_managed_node) %>
+ boot_type_id: <%= Fixtures.identify(:boot_type_static_ip) %>
diff --git a/src/test/functional/managed_node_configuration_test.rb b/src/test/functional/managed_node_configuration_test.rb
index edb9092..b5a7ec5 100644
--- a/src/test/functional/managed_node_configuration_test.rb
+++ b/src/test/functional/managed_node_configuration_test.rb
@@ -24,24 +24,40 @@ require 'managed_node_configuration'
# Performs unit tests on the +ManagedNodeConfiguration+ class.
#
class ManagedNodeConfigurationTest < Test::Unit::TestCase
+ fixtures :bonding_types
+ fixtures :bondings
+ fixtures :bondings_nics
+ fixtures :boot_types
+ fixtures :hosts
+ fixtures :nics
+
def setup
- @host = Host.new
- @nic = Nic.new(:mac => '00:11:22:33:44:55')
- @host.nics << @nic
+ @host_with_dhcp_card = hosts(:fileserver_managed_node)
+ @host_with_ip_address = hosts(:ldapserver_managed_node)
+ @host_with_multiple_nics = hosts(:buildserver_managed_node)
+ @host_with_bondings = hosts(:mailservers_managed_node)
end
# Ensures that network interfaces uses DHCP when no IP address is specified.
#
def test_generate_with_no_ip_address
+ nic = @host_with_dhcp_card.nics.first
+
expected = <<-HERE
+#!/bin/bash
+# THIS FILE IS GENERATED!
+cat <<\EOF > /var/tmp/node-augtool
rm /files/etc/sysconfig/network-scripts/ifcfg-eth0
set /files/etc/sysconfig/network-scripts/ifcfg-eth0/DEVICE eth0
-set /files/etc/sysconfig/network-scripts/ifcfg-eth0/BOOTPROTO dhcp
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/BOOTPROTO #{nic.boot_type.proto}
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/ONBOOT yes
+save
+EOF
HERE
result = ManagedNodeConfiguration.generate(
- @host,
- {'00:11:22:33:44:55' => 'eth0'}
+ @host_with_dhcp_card,
+ {"#{nic.mac}" => 'eth0'}
)
assert_equal expected, result
@@ -49,75 +65,112 @@ set /files/etc/sysconfig/network-scripts/ifcfg-eth0/BOOTPROTO dhcp
# Ensures that network interfaces use the IP address when it's provided.
#
- def test_generate_with_ip_address
- @nic.ip_addr = '192.168.2.1'
+ def test_generate_with_ip_address_and_bridge
+ nic = @host_with_ip_address.nics.first
expected = <<-HERE
+#!/bin/bash
+# THIS FILE IS GENERATED!
+cat <<\EOF > /var/tmp/node-augtool
rm /files/etc/sysconfig/network-scripts/ifcfg-eth0
set /files/etc/sysconfig/network-scripts/ifcfg-eth0/DEVICE eth0
-set /files/etc/sysconfig/network-scripts/ifcfg-eth0/IPADDR 192.168.2.1
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/BOOTPROTO #{nic.boot_type.proto}
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/IPADDR #{nic.ip_addr}
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/NETMASK #{nic.netmask}
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/BROADCAST #{nic.broadcast}
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/BRIDGE ovirtbr0
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/ONBOOT yes
+save
+EOF
HERE
result = ManagedNodeConfiguration.generate(
- @host,
- {'00:11:22:33:44:55' => 'eth0'}
+ @host_with_ip_address,
+ {"#{nic.mac}" => 'eth0'}
)
assert_equal expected, result
end
- # Ensures the bridge is added to the configuration if one is defined.
+ # Ensures that more than one NIC is successfully processed.
#
- def test_generate_with_bridge
- @nic.bridge = 'ovirtbr0'
+ def test_generate_with_multiple_nics
+ nic1 = @host_with_multiple_nics.nics[0]
+ nic2 = @host_with_multiple_nics.nics[1]
expected = <<-HERE
+#!/bin/bash
+# THIS FILE IS GENERATED!
+cat <<\EOF > /var/tmp/node-augtool
rm /files/etc/sysconfig/network-scripts/ifcfg-eth0
set /files/etc/sysconfig/network-scripts/ifcfg-eth0/DEVICE eth0
-set /files/etc/sysconfig/network-scripts/ifcfg-eth0/BOOTPROTO dhcp
-set /files/etc/sysconfig/network-scripts/ifcfg-eth0/BRIDGE ovirtbr0
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/BOOTPROTO #{nic1.boot_type.proto}
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/IPADDR #{nic1.ip_addr}
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/NETMASK #{nic1.netmask}
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/BROADCAST #{nic1.broadcast}
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/ONBOOT yes
+rm /files/etc/sysconfig/network-scripts/ifcfg-eth1
+set /files/etc/sysconfig/network-scripts/ifcfg-eth1/DEVICE eth1
+set /files/etc/sysconfig/network-scripts/ifcfg-eth1/BOOTPROTO #{nic2.boot_type.proto}
+set /files/etc/sysconfig/network-scripts/ifcfg-eth1/ONBOOT yes
+save
+EOF
HERE
result = ManagedNodeConfiguration.generate(
- @host,
- {'00:11:22:33:44:55' => 'eth0'}
- )
+ @host_with_multiple_nics,
+ {
+ "#{nic1.mac}" => 'eth0',
+ "#{nic2.mac}" => 'eth1'
+ })
assert_equal expected, result
end
- # Ensures that more than one NIC is successfully processed.
+ # Ensures that the bonding portion is created if the host has a bonded
+ # interface defined.
#
- def test_generate_with_multiple_nics
- @host.nics << Nic.new(:mac => '11:22:33:44:55:66', :ip_addr => '172.31.0.15')
- @host.nics << Nic.new(:mac => '22:33:44:55:66:77', :ip_addr => '172.31.0.100')
- @host.nics << Nic.new(:mac => '33:44:55:66:77:88')
+ def test_generate_with_bonding
+ bonding = @host_with_bondings.bondings.first
+ nic1 = bonding.nics[0]
+ nic2 = bonding.nics[1]
expected = <<-HERE
+#!/bin/bash
+# THIS FILE IS GENERATED!
+cat <<\EOF > /var/tmp/pre-config-script
+#!/bin/bash
+# THIS FILE IS GENERATED!
+/sbin/modprobe bonding mode=#{bonding.bonding_type.mode}
+EOF
+cat <<\EOF > /var/tmp/node-augtool
+rm /files/etc/sysconfig/network-scripts/ifcfg-#{bonding.interface_name}
+set /files/etc/sysconfig/network-scripts/ifcfg-#{bonding.interface_name}/DEVICE #{bonding.interface_name}
+set /files/etc/sysconfig/network-scripts/ifcfg-#{bonding.interface_name}/IPADDR 172.31.0.15
+set /files/etc/sysconfig/network-scripts/ifcfg-#{bonding.interface_name}/ONBOOT yes
rm /files/etc/sysconfig/network-scripts/ifcfg-eth0
set /files/etc/sysconfig/network-scripts/ifcfg-eth0/DEVICE eth0
-set /files/etc/sysconfig/network-scripts/ifcfg-eth0/BOOTPROTO dhcp
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/MASTER #{bonding.interface_name}
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/SLAVE yes
+set /files/etc/sysconfig/network-scripts/ifcfg-eth0/ONBOOT yes
rm /files/etc/sysconfig/network-scripts/ifcfg-eth1
set /files/etc/sysconfig/network-scripts/ifcfg-eth1/DEVICE eth1
-set /files/etc/sysconfig/network-scripts/ifcfg-eth1/IPADDR 172.31.0.15
-rm /files/etc/sysconfig/network-scripts/ifcfg-eth2
-set /files/etc/sysconfig/network-scripts/ifcfg-eth2/DEVICE eth2
-set /files/etc/sysconfig/network-scripts/ifcfg-eth2/IPADDR 172.31.0.100
-rm /files/etc/sysconfig/network-scripts/ifcfg-eth3
-set /files/etc/sysconfig/network-scripts/ifcfg-eth3/DEVICE eth3
-set /files/etc/sysconfig/network-scripts/ifcfg-eth3/BOOTPROTO dhcp
- HERE
+set /files/etc/sysconfig/network-scripts/ifcfg-eth1/MASTER #{bonding.interface_name}
+set /files/etc/sysconfig/network-scripts/ifcfg-eth1/SLAVE yes
+set /files/etc/sysconfig/network-scripts/ifcfg-eth1/ONBOOT yes
+save
+EOF
+HERE
result = ManagedNodeConfiguration.generate(
- @host,
+ @host_with_bondings,
{
- '00:11:22:33:44:55' => 'eth0',
- '11:22:33:44:55:66' => 'eth1',
- '22:33:44:55:66:77' => 'eth2',
- '33:44:55:66:77:88' => 'eth3'
+ "#{nic1.mac}" => 'eth0',
+ "#{nic2.mac}" => 'eth1'
})
assert_equal expected, result
end
+
end
diff --git a/src/test/functional/managed_node_controller_test.rb b/src/test/functional/managed_node_controller_test.rb
new file mode 100644
index 0000000..fe76746
--- /dev/null
+++ b/src/test/functional/managed_node_controller_test.rb
@@ -0,0 +1,63 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+require File.dirname(__FILE__) + '/../test_helper'
+
+class ManagedNodeControllerTest < ActionController::TestCase
+ fixtures :bonding_types
+ fixtures :bondings
+ fixtures :bondings_nics
+ fixtures :hosts
+ fixtures :nics
+
+ # Ensures that the request fails if it's missing a hostname, or if the
+ # hostname is invalid.
+ #
+ def test_config_with_invalid_hostname
+ get :config
+
+ assert_redirected_to :action => :error
+
+ get :config, {:host => 'invalid.prod.com'}
+
+ assert_redirected_to :action => :error
+ end
+
+ # Ensures the request fails if no mac addresses are supplied.
+ #
+ def test_config_without_macs
+ get :config, {:host => hosts(:mailservers_managed_node).hostname}
+
+ assert_redirected_to :action => :error
+ end
+
+ # Ensures the request succeeds if it is well-formed.
+ #
+ def test_config
+ get :config,
+ {
+ :host => hosts(:mailservers_managed_node).hostname,
+ :macs => {nics(:mailserver_nic_one).mac, 'eth0'}
+ }
+
+ assert_response :success
+ assert @response.body.length, "Did not get a response"
+ end
+
+end
diff --git a/src/test/functional/nic_controller_test.rb b/src/test/functional/nic_controller_test.rb
index b183c0d..74a80f4 100644
--- a/src/test/functional/nic_controller_test.rb
+++ b/src/test/functional/nic_controller_test.rb
@@ -30,8 +30,6 @@ class NicControllerTest < Test::Unit::TestCase
@controller = NicController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
-
- @first_id = nics(:one).id
end
def test_show
@@ -51,45 +49,4 @@ class NicControllerTest < Test::Unit::TestCase
assert_redirected_to :controller => 'host', :action => 'show', :id => 1
end
-
- def test_create
- num_nics = Nic.count
-
- post :create, :nic => {}
-
- assert_response :redirect
- assert_redirected_to :controller => 'dashboard'
-
- assert_equal num_nics, Nic.count
- end
-
- def test_edit
- get :edit, :id => @first_id
-
- assert_response :redirect
- assert_redirected_to :action => 'show', :id => @first_id
-
- assert_not_nil assigns(:nic)
- assert assigns(:nic).valid?
- end
-
- def test_update
- post :update, :id => @first_id
- assert_response :redirect
- assert_redirected_to :action => 'show', :id => @first_id
- end
-
- def test_destroy
- assert_nothing_raised {
- Nic.find(@first_id)
- }
-
- post :destroy, :id => @first_id
- assert_response :redirect
- assert_redirected_to :action => 'show', :id => @first_id
-
- assert_nothing_raised {
- Nic.find(@first_id)
- }
- end
end
diff --git a/src/test/unit/bonding_test.rb b/src/test/unit/bonding_test.rb
new file mode 100644
index 0000000..4bdb079
--- /dev/null
+++ b/src/test/unit/bonding_test.rb
@@ -0,0 +1,79 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+require File.dirname(__FILE__) + '/../test_helper'
+
+class BondingTest < ActiveSupport::TestCase
+ fixtures :bondings
+ fixtures :bonding_types
+ fixtures :bondings_nics
+ fixtures :hosts
+ fixtures :nics
+
+ def setup
+ @bonding = Bonding.new(
+ :name => 'Bonding1',
+ :interface_name => 'bond0',
+ :type_id => bonding_types(:failover_bonding_type),
+ :host_id => hosts(:mailservers_managed_node))
+ end
+
+ # Ensures that the name is required.
+ #
+ def test_valid_fails_without_name
+ @bonding.name = ''
+
+ flunk 'Bondings having to have a name.' if @bonding.valid?
+ end
+
+ # Ensures that the interface name is required.
+ #
+ def test_valid_fails_without_interface_name
+ @bonding.interface_name = ''
+
+ flunk 'Bondings have to have an interface name.' if @bonding.valid?
+ end
+
+ # Ensures that the bonding type is required.
+ #
+ def test_valid_fails_without_type
+ @bonding.type_id = nil
+
+ flunk 'Bondings have to have a valid type.' if @bonding.valid?
+ end
+
+ # Ensures that a host is required
+ #
+ def test_valid_fails_without_host
+ @bonding.host_id = nil
+
+ flunk 'Bondings have to have a host.' if @bonding.valid?
+ end
+
+ # Ensure that retrieving a bonding returns its associated objects.
+ #
+ def test_find_all_for_host
+ result = Bonding.find_all_by_host_id(hosts(:mailservers_managed_node))
+
+ assert_equal 1, result.size, 'Did not find the right number of bondings.'
+ assert result[0].nics.empty? == false, 'Did not load any nics.'
+ assert_equal 2, result[0].nics.size, 'Did not load the right set of nics.'
+ end
+
+end
diff --git a/src/test/unit/bonding_type_test.rb b/src/test/unit/bonding_type_test.rb
new file mode 100644
index 0000000..5f2ccb2
--- /dev/null
+++ b/src/test/unit/bonding_type_test.rb
@@ -0,0 +1,34 @@
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+require File.dirname(__FILE__) + '/../test_helper'
+
+class BondingTypeTest < ActiveSupport::TestCase
+ def setup
+ @bonding_type = BondingType.new(:label => 'test', :mode => 999)
+ end
+
+ # Ensures that bonding types have a unique mode.
+ #
+ def test_modes_must_be_unique
+ @bonding_type.mode = BondingType.find(:first).mode
+
+ assert @bonding_type.save == false, 'A bonding type with a duplicate mode should not save.'
+ end
+end
diff --git a/src/test/unit/boot_type_test.rb b/src/test/unit/boot_type_test.rb
new file mode 100644
index 0000000..a30e258
--- /dev/null
+++ b/src/test/unit/boot_type_test.rb
@@ -0,0 +1,26 @@
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+require File.dirname(__FILE__) + '/../test_helper'
+
+class BootTypeTest < ActiveSupport::TestCase
+ # Replace this with your real tests.
+ def test_truth
+ assert true
+ end
+end
diff --git a/src/host-browser/test-host-browser-awake.rb b/src/test/unit/host_browser_awaken_test.rb
old mode 100755
new mode 100644
similarity index 93%
rename from src/host-browser/test-host-browser-awake.rb
rename to src/test/unit/host_browser_awaken_test.rb
index 02e9146..5340e01
--- a/src/host-browser/test-host-browser-awake.rb
+++ b/src/test/unit/host_browser_awaken_test.rb
@@ -18,7 +18,7 @@
# MA 02110-1301, USA. A copy of the GNU General Public License is
# also available at http://www.gnu.org/copyleft/gpl.html.
-require File.dirname(__FILE__) + '/../test/test_helper'
+require File.dirname(__FILE__) + '/../test_helper'
require 'test/unit'
require 'flexmock/test_unit'
@@ -26,8 +26,10 @@ TESTING=true
require 'host-browser'
-# +TestHostBrowserAwaken+
-class TestHostBrowserAwaken < Test::Unit::TestCase
+# +HostBrowserAwakenTest+ ensures that the host-browser daemon works correctly
+# during the identify phase of operation.
+#
+class HostBrowserAwakenTest < Test::Unit::TestCase
def setup
@session = flexmock('session')
diff --git a/src/test/unit/host_browser_identify_test.rb b/src/test/unit/host_browser_identify_test.rb
new file mode 100644
index 0000000..87c6f0b
--- /dev/null
+++ b/src/test/unit/host_browser_identify_test.rb
@@ -0,0 +1,304 @@
+#!/usr/bin/ruby -Wall
+#
+# Copyright (C) 2008 Red Hat, Inc.
+# Written by Darryl L. Pierce <dpierce at redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA. A copy of the GNU General Public License is
+# also available at http://www.gnu.org/copyleft/gpl.html.
+
+require File.dirname(__FILE__) + '/../test_helper'
+
+require 'test/unit'
+require 'flexmock/test_unit'
+require 'dutils'
+
+TESTING=true
+
+require 'host-browser'
+
+# +HostBrowserIdentifyTest+ tests the host-browser server to ensure that it
+# works correctly during the identify mode of operation.
+#
+class HostBrowserIdentifyTest < Test::Unit::TestCase
+ def setup
+ @connection = flexmock('connection')
+ @connection.should_receive(:peeraddr).at_least.once.returns { [nil,nil,nil,"192.168.2.255"] }
+
+ @browser = HostBrowser.new(@connection)
+ @browser.logfile = './unit-test.log'
+
+ # default host info
+ @host_info = {}
+ @host_info['UUID'] = 'node1'
+ @host_info['IPADDR'] = '192.168.2.2'
+ @host_info['HOSTNAME'] = 'prod.corp.com'
+ @host_info['ARCH'] = 'x86_64'
+ @host_info['MEMSIZE'] = '16384'
+ @host_info['DISABLED'] = '0'
+
+ @host_info['NUMCPUS'] = '2'
+
+ @host_info['CPUINFO'] = Array.new
+ @host_info['CPUINFO'][0] = {}
+ @host_info['CPUINFO'][0]['CPUNUM'] = '0'
+ @host_info['CPUINFO'][0]['CORENUM'] = '0'
+ @host_info['CPUINFO'][0]['NUMCORES'] = '2'
+ @host_info['CPUINFO'][0]['VENDOR'] = 'GenuineIntel'
+ @host_info['CPUINFO'][0]['MODEL'] = '15'
+ @host_info['CPUINFO'][0]['FAMILY'] = '6'
+ @host_info['CPUINFO'][0]['CPUIDLVL'] = '10'
+ @host_info['CPUINFO'][0]['SPEED'] = '3'
+ @host_info['CPUINFO'][0]['CACHE'] = '4096 kb'
+ @host_info['CPUINFO'][0]['FLAGS'] = 'fpu vme de pse tsc msr pae \
+ mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx \
+ fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs \
+ bts pni monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr lahf_lm'
+
+ @host_info['CPUINFO'][1] = {}
+ @host_info['CPUINFO'][1]['CPUNUM'] = '1'
+ @host_info['CPUINFO'][1]['CORENUM'] = '1'
+ @host_info['CPUINFO'][1]['NUMCORES'] = '2'
+ @host_info['CPUINFO'][1]['VENDOR'] = 'GenuineIntel'
+ @host_info['CPUINFO'][1]['MODEL'] = '15'
+ @host_info['CPUINFO'][1]['FAMILY'] = '6'
+ @host_info['CPUINFO'][1]['CPUIDLVL'] = '10'
+ @host_info['CPUINFO'][1]['SPEED'] = '3'
+ @host_info['CPUINFO'][1]['CACHE'] = '4096 kb'
+ @host_info['CPUINFO'][1]['FLAGS'] = 'fpu vme de pse tsc msr pae \
+ mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx \
+ fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs \
+ bts pni monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr lahf_lm'
+
+ @host_info['NICINFO'] = Array.new
+ @host_info['NICINFO'] << {
+ 'MAC' => '00:11:22:33:44:55',
+ 'BANDWIDTH' => '100',
+ 'IFACE_NAME' => 'eth0'}
+
+ @host_info['NICINFO'] << {
+ 'MAC' => '00:77:11:77:19:65',
+ 'BANDWIDTH' => '100',
+ 'IFACE_NAME' => 'eth01'}
+ end
+
+ # Ensures that the server is satisfied if the remote system is
+ # making a wakeup call.
+ #
+ def test_get_mode_with_awaken_request
+ @connection.should_receive(:write).with("MODE?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "IDENTIFY\n" }
+
+ result = @browser.get_mode()
+
+ assert_equal "IDENTIFY", result, "method did not return the right value"
+ end
+
+ # Ensures that, if an info field is missing a key, the server raises
+ # an exception.
+ #
+ def test_get_info_with_missing_key
+ @connection.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "=value1\n" }
+
+ assert_raise(Exception) { @browser.get_remote_info }
+ end
+
+ # Ensures that, if an info field is missing a value, the server raises
+ # an exception.
+ #
+ def test_get_info_with_missing_value
+ @connection.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key1=\n" }
+
+ assert_raise(Exception) { @browser.get_remote_info }
+ end
+
+ # Ensures that, if the server gets a poorly formed ending statement, it
+ # raises an exception.
+ #
+ def test_get_info_with_invalid_end
+ @connection.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key1=value1\n" }
+ @connection.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "ENDIFNO\n" }
+
+ assert_raise(Exception) { @browser.get_remote_info }
+ end
+
+ # Ensures that a well-formed transaction works as expected.
+ #
+ def test_get_info
+ @connection.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key1=value1\n" }
+ @connection.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key2=value2\n" }
+ @connection.should_receive(:write).with("ACK key2\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "ENDINFO\n" }
+
+ info = @browser.get_remote_info
+
+ assert_equal 4,info.keys.size, "Should contain four keys"
+ assert info.include?("IPADDR")
+ assert info.include?("HOSTNAME")
+ assert info.include?("key1")
+ assert info.include?("key2")
+ end
+
+ # Ensures that the server is fine when no UUID is present.
+ #
+ def test_write_host_info_with_missing_uuid
+ @host_info['UUID'] = nil
+
+ assert_nothing_raised { @browser.write_host_info(@host_info) }
+ end
+
+ # Ensures that, if the hostname is missing, the server
+ # raises an exception.
+ #
+ def test_write_host_info_with_missing_hostname
+ @host_info['HOSTNAME'] = nil
+
+ assert_raise(Exception) { @browser.write_host_info(@host_info) }
+ end
+
+ # Ensures that, if the architecture is missing, the server raises an
+ # exception.
+ #
+ def test_write_host_info_with_missing_arch
+ @host_info['ARCH'] = nil
+
+ assert_raise(Exception) { @browser.write_host_info(@host_info) }
+ end
+
+ # Ensures that, if the memory size is missing, the server raises an
+ # exception.
+ #
+ def test_write_host_info_info_with_missing_memsize
+ @host_info['MEMSIZE'] = nil
+
+ assert_raise(Exception) { @browser.write_host_info(@host_info) }
+ end
+
+ # Ensures that, if no cpu info was available, the server raises an
+ # exception.
+ #
+ def test_write_host_info_with_missing_cpuinfo
+ @host_info['CPUINFO'] = nil
+
+ assert_raise(Exception) { @browser.write_host_info(@host_info) }
+ end
+
+ # Ensures that, if no NIC info was available, the server raises an
+ # exception.
+ #
+ def test_write_host_info_with_missing_nicinfo
+ @host_info['NICINFO'] = nil
+
+ assert_raise(Exception) { @browser.write_host_info(@host_info) }
+ end
+
+ # Ensures that, if a NIC is present that was already submitted, it
+ # doesn't get re-entered.
+ #
+ def test_write_host_info_with_duplicate_nic
+ # Values taken from the nics.yml fixture
+ @host_info['NICINFO'] << {
+ 'MAC' => '00:11:22:33:44:55',
+ 'BANDWIDTH' => '100',
+ 'IFACE_NAME' => 'eth0'
+ }
+
+ assert_nothing_raised { @browser.write_host_info(@host_info) }
+ assert_equal 3, Host.find_by_hostname('prod.corp.com').nics.size, 'Expected three NICs.'
+ end
+
+ # Ensures the browser can properly parse the CPU details.
+ #
+ def test_parse_cpu_info
+ @connection.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "CPU\n" }
+ @connection.should_receive(:write).with("CPUINFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key1=value1\n" }
+ @connection.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key2=value2\n" }
+ @connection.should_receive(:write).with("ACK key2\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "ENDCPU\n" }
+ @connection.should_receive(:write).with("ACK CPU\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "ENDINFO\n" }
+
+ info = @browser.get_remote_info
+
+ assert_equal 3,info.keys.size, "Should contain four keys"
+ assert info.include?("CPUINFO")
+ end
+
+ # Ensures the browser can properly parse the CPU details of two CPUs.
+ #
+ def test_parse_cpu_info_with_two_entries
+ @connection.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
+
+ # CPU 0
+ @connection.should_receive(:readline).once().returns { "CPU\n" }
+ @connection.should_receive(:write).with("CPUINFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key1=value1\n" }
+ @connection.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key2=value2\n" }
+ @connection.should_receive(:write).with("ACK key2\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "ENDCPU\n" }
+ @connection.should_receive(:write).with("ACK CPU\n").once().returns { |request| request.length }
+
+ # CPU 1
+ @connection.should_receive(:readline).once().returns { "CPU\n" }
+ @connection.should_receive(:write).with("CPUINFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key3=value3\n" }
+ @connection.should_receive(:write).with("ACK key3\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key4=value4\n" }
+ @connection.should_receive(:write).with("ACK key4\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "ENDCPU\n" }
+ @connection.should_receive(:write).with("ACK CPU\n").once().returns { |request| request.length }
+
+ @connection.should_receive(:readline).once().returns { "ENDINFO\n" }
+
+ info = @browser.get_remote_info
+
+ assert_equal 3,info.keys.size, "Should contain four keys"
+ assert info.include?('CPUINFO')
+ assert_equal 2, info['CPUINFO'].size, "Should contain details for two CPUs"
+ assert_not_nil info['CPUINFO'][0]['key1']
+ assert_not_nil info['CPUINFO'][0]['key2']
+ assert_not_nil info['CPUINFO'][1]['key3']
+ assert_not_nil info['CPUINFO'][1]['key4']
+ end
+
+ # Ensures the browser can properly parse the details for a NIC.
+ #
+ def test_parse_nic_info
+ @connection.should_receive(:write).with("INFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "NIC\n" }
+ @connection.should_receive(:write).with("NICINFO?\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key1=value1\n" }
+ @connection.should_receive(:write).with("ACK key1\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "key2=value2\n" }
+ @connection.should_receive(:write).with("ACK key2\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "ENDNIC\n" }
+ @connection.should_receive(:write).with("ACK NIC\n").once().returns { |request| request.length }
+ @connection.should_receive(:readline).once().returns { "ENDINFO\n" }
+
+ info = @browser.get_remote_info
+
+ assert_equal 3,info.keys.size, "Should contain four keys"
+ assert info.include?("NICINFO")
+ end
+end
--
1.5.5.1
More information about the ovirt-devel
mailing list