[Ovirt-devel] [PATCH] Rewriting the identify-node piece into two managed node units

Darryl L. Pierce dpierce at redhat.com
Thu Jun 12 15:33:59 UTC 2008


Signed-off-by: Darryl L. Pierce <dpierce at redhat.com>
---
 ovirt-host-creator/common-post.ks                  |  347 ++++++++++++++------
 wui/src/host-browser/host-browser.rb               |  106 ++++---
 wui/src/host-browser/test-host-browser-awaken.rb   |   94 ++++++
 wui/src/host-browser/test-host-browser-identify.rb |  162 +++++++++
 wui/src/host-browser/test-host-browser.rb          |  204 ------------
 5 files changed, 556 insertions(+), 357 deletions(-)
 create mode 100755 wui/src/host-browser/test-host-browser-awaken.rb
 create mode 100755 wui/src/host-browser/test-host-browser-identify.rb
 delete mode 100755 wui/src/host-browser/test-host-browser.rb

diff --git a/ovirt-host-creator/common-post.ks b/ovirt-host-creator/common-post.ks
index 1cb1677..aaeb746 100644
--- a/ovirt-host-creator/common-post.ks
+++ b/ovirt-host-creator/common-post.ks
@@ -12,12 +12,15 @@ cat > /etc/sysconfig/iptables << \EOF
 COMMIT
 EOF
 
-echo "Writing ovirt-identify-node script"
-cat > /sbin/ovirt-identify-node << \EOF
+echo "Writing ovirt-awake script"
+cat > /sbin/ovirt-awake << \EOF
 #!/bin/bash
 #
+# ovirt-awake   Notifies the oVirt server that a managed node is
+#               starting up.
+#
 # Copyright (C) 2008 Red Hat, Inc.
-# Written by Chris Lalancette <clalance at redhat.com>
+# 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
@@ -34,109 +37,239 @@ cat > /sbin/ovirt-identify-node << \EOF
 # MA  02110-1301, USA.  A copy of the GNU General Public License is
 # also available at http://www.gnu.org/copyleft/gpl.html.
 
-ME=$(basename "$0")
-warn() { printf "$ME: $@\n" >&2; }
-try_h() { printf "Try \`$ME -h' for more information.\n" >&2; }
-die() { warn "$@"; try_h; exit 1; }
-
-usage() {
-    case $# in 1) warn "$1"; try_h; exit 1;; esac
-    cat <<EOF2
-Usage: $ME [-s server] [-p port]
-  -h: display this help and exit
-  -p: Port number the host-browser is listening on
-  -s: Hostname of the server to connect to
-EOF2
+# Source function library
+. /etc/init.d/ovirt-functions
+
+start () {
+    find-server identify tcp
+
+    connect-to-server
+
+    receive-text
+
+    if [ $REPLY == "HELLO?" ]; then
+        echo "Starting wakeup conversation."
+
+        send-text "HELLO!"
+
+        read 0<&3
+
+        if [ $REPLY == "MODE?" ]; then
+            send-text "AWAKEN"
+
+            receive-text
+
+            KEYTAB=`echo $REPLY | awk '{ print $2 }'`
+
+            if [ -n $KEYTAB ]; then
+                echo "Retrieving keytab: '$KEYTAB'"
+
+                wget $KEYTAB --output-file=$KEYTAB_FILE
+            else
+                echo "No keytab to retrieve"
+            fi
+        else
+            echo "Did not get a mode request."
+        fi
+    else
+        echo "Did not get a proper startup marker."
+    fi
+
+    echo "Disconnecting."
+
+    disconnect-from-server
 }
 
-send_key_value() {
-	echo "$1=$2" 1>&3
+case "$1" in
+    start)
+        KEYTAB_FILE=$2
+        SERVER=$3
+        PORT=$4
+        start
+        RETVAL=$?
+    ;;
+
+    *)
+        echo "Usage: $0 start"
+        RETVAL=2
+    ;;
+esac
+
+exit $RETVAL
+EOF
+chmod +x /sbin/ovirt-awake
+
+echo "Writing ovirt-identify script"
+cat > /sbin/ovirt-identify << \EOF
+#!/bin/bash
+#
+# ovirt-identify  Submits managed node details to the central server.
+#
+# 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.
+
+# Source function library
+. /etc/init.d/ovirt-functions
+
+start () {
+    find-server identify tcp
+
+    connect-to-server
+
+    receive-text
+
+    if [ $REPLY == "HELLO?" ]; then
+        echo "Starting wakeup conversation."
+
+        send-text "HELLO!"
+
+        read 0<&3
+
+        if [ $REPLY == "MODE?" ]; then
+            send-text "IDENTIFY"
+
+            receive-text
+
+            UUID=`hostname -f`
+            ARCH=`uname -i`
+            NUMCPUS=`getconf _NPROCESSORS_ONLN`
+            CPUSPEED=`grep "cpu MHz" /proc/cpuinfo | uniq | cut -d':' -f2 | sed -e 's/^[[:space:]]*\(.*\)$/\1/' -e 's/^\(.*\)[[:space:]]*$/\1/'`
+            MEMSIZE=$((`getconf _PHYS_PAGES` * `getconf PAGESIZE` / 1024 / 1024))
 
-	read 0<&3
-	test "$REPLY" != "ACK $1" && die "Failed acknowledge of key $1"
+            send-text "UUID=$UUID"
+            receive-text
+            send-text "ARCH=$ARCH"
+            receive-text
+            send-text "NUMCPUS=$NUMCPUS"
+            receive-text
+            send-text "CPUSPEED=$CPUSPEED"
+            receive-text
+            send-text "MEMSIZE=$MEMSIZE"
+            receive-text
+            send-text "ENDINFO"
+
+            receive-text
+
+            if [ $REPLY == "BYE" ]; then
+                echo "Success!"
+            else
+                echo "Error submitting node information..."
+            fi
+        else
+            echo "Did not get a mode request."
+        fi
+    else
+        echo "Did not get a proper startup marker."
+    fi
+
+    echo "Disconnecting."
+
+    disconnect-from-server
 }
 
-############# MAIN ##################
-
-# parse our options
-while getopts ":hs:p:" flag ; do
-	case "$flag" in
-	     	h)
-			usage ; exit 0
-			;;
-		s)
-			server=$OPTARG
-			;;
-		p)
-			port=$OPTARG
-			;;
-		?)
-			usage "Unknown flag $flag"
-			;;
-	esac
-done
+case "$1" in
+    start)
+        SERVER=$2
+        PORT=$3
+        PORT=$3
+        start
+        RETVAL=$?
+    ;;
+
+    *)
+        echo "Usage: $0 start"
+        RETVAL=2
+    ;;
+esac
 
-test $(( $# - $OPTIND )) -ge 0 && usage "Too many options"
-test -z "$server" && usage "Must specify -s"
-test -z "$port" && usage "Must specify -p"
-
-# gather our information
-all_ok=0
-uuid=$(hostname -f) &&
-  arch=$(uname -i) &&
-  memsize=$(( $(getconf _PHYS_PAGES) * $(getconf PAGESIZE) / 1024 / 1024 )) &&
-  numcpus=$(getconf _NPROCESSORS_ONLN) &&
-  speed=$(sed -n "/cpu MHz/{s/.*://p;q;}" /proc/cpuinfo | tr -dc 0-9.) &&
-  hostname=$(hostname -f) &&
-  hypervisor="QEMU" && all_ok=1
-
-test $all_ok = 1 || die "Information gathering failed...see above"
-
-# open our connection to the remote host
-eval 'exec 3<> /dev/tcp/$server/$port' 2>err
-test $? -ne 0 && die "Connection to $server:$port failed: $(cat err)"
-
-# say hello
-read 0<&3
-test "$REPLY" != "HELLO?" && die "Expected response HELLO?, received response $REPLY"
-echo "HELLO!" 1>&3
-
-# OK, start sending our information
-read 0<&3
-test "$REPLY" != "INFO?" && die "Expected response INFO?, received response $REPLY"
-
-send_key_value "UUID" "$uuid"
-send_key_value "ARCH" "$arch"
-send_key_value "MEMSIZE" "$memsize"
-send_key_value "NUMCPUS" "$numcpus"
-send_key_value "CPUSPEED" "$speed"
-send_key_value "HOSTNAME" "$hostname"
-send_key_value "HYPERVISOR_TYPE" "$hypervisor"
-
-echo "ENDINFO" 1>&3
-
-read 0<&3
-
-test "${REPLY:0:4}" != "KTAB" && die "Expected response KTAB <filename>, received response $REPLY"
-echo "${REPLY:5}"
+exit $RETVAL
 EOF
-chmod +x /sbin/ovirt-identify-node
+chmod +x /sbin/ovirt-identify
 
 echo "Writing ovirt-functions script"
 # common functions
 cat > /etc/init.d/ovirt-functions << \EOF
-# -*-Shell-script-*-
+# 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.
 
-find_srv() {
-        local dnsreply
+# Determines the hostname and port for the oVirt server.
+#
+find-server() {
+    if [ -z $SERVER ]; then
         dnsreply=$(dig +short -t srv _$1._$2.$(dnsdomainname))
         if [ $? -eq 0 ]; then
             set _ $dnsreply; shift
-            SRV_HOST=$4; SRV_PORT=$3
+            SERVER=$4; PORT=$3
         else
-            SRV_HOST=; SRV_PORT=
+            SERVER=; PORT=
         fi
+    fi
+
+    if [ -z $SERVER ]; then
+        echo "No server found..."
+        exit
+    fi
 }
+
+# Establishes a TCP connection to the server.
+#
+connect-to-server () {
+    echo "Connecting to $SERVER:$PORT"...
+
+    exec 3<> /dev/tcp/$SERVER/$PORT
+}
+
+# Disconnects form the server.
+#
+disconnect-from-server () {
+    <&3-
+}
+
+# Sends text to the remote server.
+#
+send-text () {
+    echo "Sending: \"$1\""
+    echo "$1" 1>&3
+}
+
+# Receives text from the remote server.
+#
+receive-text () {
+    read 0<&3
+
+    echo "Received: \"$REPLY\""
+}
+
 EOF
 
 echo "Writing ovirt-early init script"
@@ -168,7 +301,7 @@ configure_from_network() {
             if [ "$status" = "0" ]; then
                 hostname $HOSTNAME
                 # retrieve remote config
-                find_srv ovirt tcp
+                find-server ovirt tcp
                 printf .
                 if [ -n "$SRV_HOST" -a -n "$SRV_PORT" ]; then
                     curl -s "http://$SRV_HOST:$SRV_PORT/ovirt/cfgdb/$(hostname)" \
@@ -219,19 +352,27 @@ start() {
         # now LVM partitions
         LVMDEVS="$DEVICES `lvscan | awk '{print $2}' | tr -d \"'\"`"
 
-	SWAPDEVS="$LVMDEVS"
+    SWAPDEVS="$LVMDEVS"
         for dev in $BLOCKDEVS; do
             SWAPDEVS="$SWAPDEVS `fdisk -l $dev 2>/dev/null | tr '*' ' ' \
-	                         | awk '$5 ~ /82/ {print $1}'`"
+                             | awk '$5 ~ /82/ {print $1}'`"
         done
 
-	# now check if any of these partitions are swap, and activate if so
+    # now check if any of these partitions are swap, and activate if so
         for device in $SWAPDEVS; do
             sig=`dd if=$device bs=1 count=10 skip=$(( $PAGESIZE - 10 )) \
-	         2>/dev/null`
+             2>/dev/null`
             if [ "$sig" = "SWAPSPACE2" ]; then
                 swapon $device
             fi
+
+    # Notify the server we're awake and retrieve a keytab file
+    krb5_tab=/etc/libvirt/krb5.tab
+    if [ ! -s $krb5_tab ]; then
+        ovirt-awake start start $krb5_tab
+            || die "Failed to notify server the node is awake"
+    fi
+
         done
 }
 
@@ -283,7 +424,7 @@ die()
 start() {
     echo -n $"Starting ovirt: "
 
-    find_srv ipa tcp
+    find-server ipa tcp
     krb5_conf=/etc/krb5.conf
     if [ ! -s $krb5_conf ]; then
         rm -f $krb5_conf
@@ -294,17 +435,9 @@ start() {
     IPA_HOST=$SRV_HOST
     IPA_PORT=$SRV_PORT
 
-    find_srv identify tcp
-    krb5_tab=/etc/libvirt/krb5.tab
-    if [ ! -s $krb5_tab ]; then
-        keytab=$(ovirt-identify-node -s $SRV_HOST -p $SRV_PORT) \
-          || die "Failed to identify node"
-        # FIXME this is IPA specific, host-browser should return full URL
-        wget -q "http://$IPA_HOST:$IPA_PORT/config/$keytab" -O $krb5_tab \
-          || die "Failed to get $krb5_tab"
-    fi
+    ovirt-identify start
 
-    find_srv collectd tcp
+    find-server collectd tcp
     collectd_conf=/etc/collectd.conf
     if [ -f $collectd_conf.in -a $SRV_HOST -a $SRV_PORT ]; then
         sed -e "s/@COLLECTD_SERVER@/$SRV_HOST/" \
@@ -415,8 +548,8 @@ LoadPlugin disk
 </Plugin>
 
 <Plugin interface>
-	Interface "eth0"
-	IgnoreSelected false
+    Interface "eth0"
+    IgnoreSelected false
 </Plugin>
 
 EOF
diff --git a/wui/src/host-browser/host-browser.rb b/wui/src/host-browser/host-browser.rb
index e127ddb..3e242cf 100755
--- a/wui/src/host-browser/host-browser.rb
+++ b/wui/src/host-browser/host-browser.rb
@@ -1,5 +1,5 @@
 #!/usr/bin/ruby -Wall
-# 
+#
 # Copyright (C) 2008 Red Hat, Inc.
 # Written by Darryl L. Pierce <dpierce at redhat.com>
 #
@@ -41,7 +41,7 @@ class HostBrowser
     attr_accessor :logfile
     attr_accessor :keytab_dir
     attr_accessor :keytab_filename
-  
+
     def initialize(session)
         @session = session
         @log_prefix = "[#{session.peeraddr[3]}] "
@@ -51,19 +51,31 @@ class HostBrowser
     # Ensures the conversation starts properly.
     #
     def begin_conversation
-        puts "#{@log_prefix} Begin conversation"
+        puts "#{@log_prefix} Begin conversation" unless defined?(TESTING)
         @session.write("HELLO?\n")
 
         response = @session.readline.chomp
         raise Exception.new("received #{response}, expected HELLO!") unless response == "HELLO!"
     end
 
+    # Retrieves the mode request from the remote system.
+    #
+    def get_mode
+        puts "#{@log_prefix} Determining the runtime mode." unless defined?(TESTING)
+        @session.write("MODE?\n")
+        response = @session.readline.chomp
+        puts "#{@log_prefix} MODE=#{response}" unless defined?(TESTING)
+
+        response
+    end
+
     # Requests node information from the remote system.
     #
     def get_remote_info
-        puts "#{@log_prefix} Begin remote info collection"
+        puts "#{@log_prefix} Begin remote info collection" unless defined?(TESTING)
         result = {}
-        result['IPADDR'] = @session.peeraddr[3]
+        result['HOSTNAME'] = @session.peeraddr[2]
+        result['IPADDR']   = @session.peeraddr[3]
         @session.write("INFO?\n")
 
         loop do
@@ -75,9 +87,9 @@ class HostBrowser
 
             key, value = info.split("=")
 
-            puts "#{@log_prefix} ::Received - #{key}:#{value}"
+            puts "#{@log_prefix} ::Received - #{key}:#{value}" unless defined?(TESTING)
             result[key] = value
-        
+
             @session.write("ACK #{key}\n")
         end
 
@@ -94,13 +106,13 @@ class HostBrowser
         ensure_present(host_info,'ARCH')
         ensure_present(host_info,'MEMSIZE')
 
-        puts "Searching for existing host record..."
+        puts "Searching for existing host record..." unless defined?(TESTING)
         host = Host.find(:first, :conditions => ["uuid = ?", host_info['UUID']])
 
         if host == nil
             begin
-                puts "Creating a new record for #{host_info['HOSTNAME']}..."
-            
+                puts "Creating a new record for #{host_info['HOSTNAME']}..." unless defined?(TESTING)
+
                 Host.new(
                     "uuid"            => host_info['UUID'],
                     "hostname"        => host_info['HOSTNAME'],
@@ -115,7 +127,7 @@ class HostBrowser
                     # successfully connects to it via libvirt.
                     "state"           => "unavailable").save
             rescue Exception => error
-                puts "Error while creating record: #{error.message}"
+                puts "Error while creating record: #{error.message}" unless defined?(TESTING)
             end
         else
             host.uuid         = host_info['UUID']
@@ -125,45 +137,45 @@ class HostBrowser
             host.arch         = host_info['ARCH']
             host.memory_in_mb = host_info['MEMSIZE']
         end
-    
+
         return host
     end
 
-    # Ends the conversation, notifying the user of the key version number.
-    #
-    def end_conversation(ktab)
-        puts "#{@log_prefix} Ending conversation"
-
-        @session.write("KTAB #{ktab}\n")
-
-        response = @session.readline.chomp
-
-        raise Exception.new("ERROR! Malformed response : expected ACK, got #{response}") unless response == "ACK"
-
-        @session.write("BYE\n");
-    end
-  
     # Creates a keytab if one is needed, returning the filename.
     #
-    def create_keytab(host_info, krb5_arg = nil)
+    def create_keytab(hostname, ipaddress, krb5_arg = nil)
         krb5 = krb5_arg || Krb5.new
-  
+
         default_realm = krb5.get_default_realm
-        libvirt_princ = 'libvirt/' + host_info['HOSTNAME'] + '@' + default_realm
-        outfile = host_info['IPADDR'] + '-libvirt.tab'
+        libvirt_princ = 'libvirt/' + hostname + '@' + default_realm
+        outfile = ipaddress + '-libvirt.tab'
         @keytab_filename = @keytab_dir + outfile
 
         # TODO need a way to test this portion
         unless defined? TESTING || File.exists?(@keytab_filename)
             # TODO replace with Kr5Auth when it supports admin actions
-            puts "Writing keytab file: #{@keytab_filename}"
+            puts "Writing keytab file: #{@keytab_filename}" unless defined?(TESTING)
             kadmin_local('addprinc -randkey ' + libvirt_princ)
             kadmin_local('ktadd -k ' + @keytab_filename + ' ' + libvirt_princ)
 
             File.chmod(0644, at keytab_filename)
         end
 
-        return outfile
+        hostname = `hostname -f`.chomp
+
+        @session.write("KTAB http://#{hostname}/config/#{outfile}\n")
+
+        response = @session.readline.chomp
+
+        raise Exception.new("ERRINFO! No keytab acknowledgement") unless response == "ACK"
+    end
+
+    # Ends the conversation, notifying the user of the key version number.
+    #
+    def end_conversation
+        puts "#{@log_prefix} Ending conversation" unless defined?(TESTING)
+
+        @session.write("BYE\n");
     end
 
     private
@@ -185,35 +197,37 @@ def entry_point(server)
     while(session = server.accept)
         child = fork do
             remote = session.peeraddr[3]
-            
-            puts "Connected to #{remote}"
+
+            puts "Connected to #{remote}" unless defined?(TESTING)
 
             # This is needed because we just forked a new process
             # which now needs its own connection to the database.
             database_connect
-      
+
             begin
                 browser = HostBrowser.new(session)
 
                 browser.begin_conversation
-                host_info = browser.get_remote_info
-                browser.write_host_info(host_info)
-                keytab = browser.create_keytab(host_info)
-                browser.end_conversation(keytab)
+                case browser.get_mode
+                    when "AWAKEN": browser.create_keytab(remote,session.peeraddr[3])
+                    when "IDENTIFY": browser.write_host_info(browser.get_remote_info)
+                end
+
+                browser.end_conversation
             rescue Exception => error
                 session.write("ERROR #{error.message}\n")
-                puts "ERROR #{error.message}"
+                puts "ERROR #{error.message}" unless defined?(TESTING)
             end
-      
-            puts "Disconnected from #{remote}"
+
+            puts "Disconnected from #{remote}" unless defined?(TESTING)
         end
-    
-        Process.detach(child)        
-    end      
+
+        Process.detach(child)
+    end
 end
 
 unless defined?(TESTING)
-  
+
     # The main entry point.
     #
     unless ARGV[0] == "-n"
diff --git a/wui/src/host-browser/test-host-browser-awaken.rb b/wui/src/host-browser/test-host-browser-awaken.rb
new file mode 100755
index 0000000..a5ca2e7
--- /dev/null
+++ b/wui/src/host-browser/test-host-browser-awaken.rb
@@ -0,0 +1,94 @@
+#!/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'
+
+# +TestHostBrowserAwaken+
+class TestHostBrowserAwaken < Test::Unit::TestCase
+
+  def setup
+    @session = flexmock('session')
+    @session.should_receive(:peeraddr).at_least.once.returns { [nil,nil,nil,"192.168.2.255"] }
+
+    @krb5 = flexmock('krb5')
+
+    @browser = HostBrowser.new(@session)
+    @browser.logfile = './unit-test.log'
+    @browser.keytab_dir = '/var/temp/'
+  end
+
+  # Ensures that the server raises an exception when it receives an
+  # improper handshake response.
+  #
+  def test_begin_conversation_with_improper_response_to_greeting
+    @session.should_receive(:write).with("HELLO?\n").once().returns { |greeting| greeting.length }
+    @session.should_receive(:readline).once().returns { "SUP?" }
+
+    assert_raise(Exception) { @browser.begin_conversation }
+  end
+
+  # Ensures the server accepts a proper response from the remote system.
+  #
+  def test_begin_conversation
+    @session.should_receive(:write).with("HELLO?\n").once().returns { |greeting| greeting.length }
+    @session.should_receive(:readline).once().returns { "HELLO!\n" }
+
+    assert_nothing_raised(Exception) { @browser.begin_conversation }
+  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 { "AWAKEN\n" }
+
+    result = @browser.get_mode()
+
+    assert_equal "AWAKEN", result, "method did not return the right value"
+  end
+
+  # Ensures the host browser generates a keytab as expected.
+  #
+  def test_create_keytab
+    @krb5.should_receive(:get_default_realm).once().returns { "ovirt-test-realm" }
+    servername = `hostname -f`.chomp
+    @session.should_receive(:write).with("KTAB http://#{servername}/config/127.0.0.1-libvirt.tab\n").once().returns { |request| request.length }
+    @session.should_receive(:readline).once().returns { "ACK\n" }
+
+    assert_nothing_raised(Exception) { @browser.create_keytab('localhost','127.0.0.1', at krb5) }
+  end
+
+  # Ensures that, if a keytab is present and a key version number available,
+  # the server ends the conversation by returning the key version number.
+  #
+  def test_end_conversation
+    @session.should_receive(:write).with("BYE\n").once().returns { |request| request.length }
+
+    assert_nothing_raised(Exception) { @browser.end_conversation }
+  end
+
+end
diff --git a/wui/src/host-browser/test-host-browser-identify.rb b/wui/src/host-browser/test-host-browser-identify.rb
new file mode 100755
index 0000000..a70884d
--- /dev/null
+++ b/wui/src/host-browser/test-host-browser-identify.rb
@@ -0,0 +1,162 @@
+#!/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'] = 'node1.ovirt.redhat.com'
+    @host_info['NUMCPUS']  = '3'
+    @host_info['CPUSPEED'] = '3'
+    @host_info['ARCH']     = 'x86_64'
+    @host_info['MEMSIZE']  = '16384'
+    @host_info['DISABLED'] = '0'
+  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 two keys"
+    assert info.include?("IPADDR")
+    assert info.include?("HOSTNAME")
+    assert info.include?("key1")
+    assert info.include?("key2")
+  end
+
+  # Ensures that, if no UUID is present, the server raises an exception.
+  #
+  def test_write_host_info_with_missing_uuid
+    @host_info['UUID'] = nil
+
+    assert_raise(Exception) { @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 number of CPUs is missing, the server raises an exception.
+  #
+  def test_write_host_info_with_missing_numcpus
+    @host_info['NUMCPUS'] = nil
+
+    assert_raise(Exception) { @browser.write_host_info(@host_info) }
+  end
+
+  # Ensures that, if the CPU speed is missing, the server raises an exception.
+  #
+  def test_write_host_info_with_missing_cpuspeed
+    @host_info['CPUSPEED'] = 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
+
+end
diff --git a/wui/src/host-browser/test-host-browser.rb b/wui/src/host-browser/test-host-browser.rb
deleted file mode 100755
index 6f4c660..0000000
--- a/wui/src/host-browser/test-host-browser.rb
+++ /dev/null
@@ -1,204 +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"] }
-
-    @krb5 = flexmock('krb5')
-
-    @browser = HostBrowser.new(@session)
-    @browser.logfile = './unit-test.log'
-    @browser.keytab_dir = '/var/temp/'
-
-    # default host info
-    @host_info = {}
-    @host_info['UUID']     = 'node1'
-    @host_info['IPADDR']   = '192.168.2.2'
-    @host_info['HOSTNAME'] = 'node1.ovirt.redhat.com'
-    @host_info['NUMCPUS']  = '3'
-    @host_info['CPUSPEED'] = '3'
-    @host_info['ARCH']     = 'x86_64'
-    @host_info['MEMSIZE']  = '16384'
-    @host_info['DISABLED'] = '0'
-  end
-
-  # Ensures that the server raises an exception when it receives an
-  # improper handshake response.
-  #
-  def test_begin_conversation_with_improper_response_to_greeting
-    @session.should_receive(:write).with("HELLO?\n").once().returns { |greeting| greeting.length }
-    @session.should_receive(:readline).once().returns { "SUP?" }
-
-    assert_raise(Exception) { @browser.begin_conversation }
-  end
-
-  # Ensures the server accepts a proper response from the remote system.
-  #
-  def test_begin_conversation
-    @session.should_receive(:write).with("HELLO?\n").once().returns { |greeting| greeting.length }
-    @session.should_receive(:readline).once().returns { "HELLO!\n" }
-
-    assert_nothing_raised(Exception) { @browser.begin_conversation }
-  end
-
-  # Ensures that the server raises an exception when it receives
-  # poorly formed data while exchanging system information.
-  #
-  def test_get_info_with_bad_handshake
-    @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 { "farkledina\n" }
-
-    assert_raise(Exception) { @browser.get_remote_info }
-  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 3,info.keys.size, "Should contain two keys"
-    assert info.include?("IPADDR")
-    assert info.include?("key1")
-    assert info.include?("key2")
-  end
-
-  # Ensures the host browser generates a keytab as expected.
-  #
-  def test_create_keytab
-    @krb5.should_receive(:get_default_realm).once().returns { "ovirt-test-realm" }
-
-    result = @browser.create_keytab(@host_info, at krb5)
-
-    assert_equal @browser.keytab_filename, result, "Should have returned the keytab filename"
-  end
-
-  # Ensures that, if no UUID is present, the server raises an exception.
-  #
-  def test_write_host_info_with_missing_uuid
-    @host_info['UUID'] = nil
-
-    assert_raise(Exception) { @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 number of CPUs is missing, the server raises an exception.
-  #
-  def test_write_host_info_with_missing_numcpus
-    @host_info['NUMCPUS'] = nil
-
-    assert_raise(Exception) { @browser.write_host_info(@host_info) }
-  end
-
-  # Ensures that, if the CPU speed is missing, the server raises an exception.
-  #
-  def test_write_host_info_with_missing_cpuspeed
-    @host_info['CPUSPEED'] = 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 a keytab is present and a key version number available,
-  # the server ends the conversation by returning the key version number.
-  #
-  def test_end_conversation
-    @session.should_receive(:write).with("KTAB 12345\n").once().returns { |request| request.length }
-    @session.should_receive(:readline).once().returns { "ACK\n" }
-    @session.should_receive(:write).with("BYE\n").once().returns { |request| request.length }
-
-    assert_nothing_raised(Exception) { @browser.end_conversation(12345) }
-  end
-
-end
-- 
1.5.4.1




More information about the ovirt-devel mailing list