[KVM-AUTOTEST PATCH 1/3] KVM test: kvm_utils.py: add utility function which locates program files

2010-07-04 Thread Michael Goldish
find_command() is similar to os_dep.command(), but instead of searching $PATH,
it searches a few hard coded locations.  The problem with searching
$PATH is that different users may have different $PATHs.  For example, autotest
can be executed by a non-root user, or using sudo, and in some OSes this will
result in /sbin not being included in $PATH.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_utils.py |9 +
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index 0372565..a57a334 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -322,6 +322,15 @@ def env_unregister_vm(env, name):
 
 # Utility functions for dealing with external processes
 
+def find_command(cmd):
+for dir in [/usr/local/sbin, /usr/local/bin,
+/usr/sbin, /usr/bin, /sbin, /bin]:
+file = os.path.join(dir, cmd)
+if os.path.exists(file):
+return file
+raise ValueError('Missing command: %s' % cmd)
+
+
 def pid_exists(pid):
 
 Return True if a given PID exists.
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 2/3] KVM test: use kvm_utils.find_command() where appropriate

2010-07-04 Thread Michael Goldish
Instead of hardcoding binary paths, use kvm_utils.find_command().
This should make the KVM test a little more distro independent.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_preprocessing.py |4 ++--
 client/tests/kvm/kvm_utils.py |7 ---
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/client/tests/kvm/kvm_preprocessing.py 
b/client/tests/kvm/kvm_preprocessing.py
index ee279bd..2f6994a 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -208,8 +208,8 @@ def preprocess(test, params, env):
 env[tcpdump].close()
 del env[tcpdump]
 if tcpdump not in env and params.get(run_tcpdump, yes) == yes:
-command = /usr/sbin/tcpdump -npvi any 'dst port 68'
-logging.debug(Starting tcpdump (%s)..., command)
+cmd = %s -npvi any 'dst port 68' % kvm_utils.find_command(tcpdump)
+logging.debug(Starting tcpdump (%s)..., cmd)
 env[tcpdump] = kvm_subprocess.kvm_tail(
 command=command,
 output_func=_update_address_cache,
diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index a57a334..4183f1c 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -250,19 +250,20 @@ def verify_ip_address_ownership(ip, macs, timeout=10.0):
 regex = re.compile(r\b%s\b.*\b(%s)\b % (ip, mac_regex), re.IGNORECASE)
 
 # Check the ARP cache
-o = commands.getoutput(/sbin/arp -n)
+o = commands.getoutput(%s -n % find_command(arp))
 if regex.search(o):
 return True
 
 # Get the name of the bridge device for arping
-o = commands.getoutput(/sbin/ip route get %s % ip)
+o = commands.getoutput(%s route get %s % (find_command(ip), ip))
 dev = re.findall(dev\s+\S+, o, re.IGNORECASE)
 if not dev:
 return False
 dev = dev[0].split()[-1]
 
 # Send an ARP request
-o = commands.getoutput(/sbin/arping -f -c 3 -I %s %s % (dev, ip))
+o = commands.getoutput(%s -f -c 3 -I %s %s %
+   (find_command(arping), dev, ip))
 return bool(regex.search(o))
 
 
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 3/3] KVM test: kvm_subprocess: allow garbage collection of kvm_tail instances

2010-07-04 Thread Michael Goldish
Tail threads refer to kvm_tail objects, preventing them from being garbage-
collected.

1) Before a tail thread exits, remove the reference to the thread from the
   kvm_tail object.
2) Add a function kill_tail_threads() which asks all tail threads to terminate
   and waits for them to do so.
3) Use kill_tail_threads() instead of VM.kill_tail_thread() (which was there
   for a different reason) in kvm_preprocessing.py.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_preprocessing.py |5 +-
 client/tests/kvm/kvm_subprocess.py|  121 ++---
 client/tests/kvm/kvm_vm.py|8 --
 3 files changed, 69 insertions(+), 65 deletions(-)

diff --git a/client/tests/kvm/kvm_preprocessing.py 
b/client/tests/kvm/kvm_preprocessing.py
index 2f6994a..123928e 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -344,9 +344,8 @@ def postprocess(test, params, env):
 else:
 vm.destroy(gracefully=False)
 
-# Kill the tailing threads of all VMs
-for vm in kvm_utils.env_get_all_vms(env):
-vm.kill_tail_thread()
+# Kill all kvm_subprocess tail threads
+kvm_subprocess.kill_tail_threads()
 
 # Terminate tcpdump if no VMs are alive
 living_vms = [vm for vm in kvm_utils.env_get_all_vms(env) if vm.is_alive()]
diff --git a/client/tests/kvm/kvm_subprocess.py 
b/client/tests/kvm/kvm_subprocess.py
index 93a8429..f815069 100755
--- a/client/tests/kvm/kvm_subprocess.py
+++ b/client/tests/kvm/kvm_subprocess.py
@@ -548,6 +548,21 @@ class kvm_spawn:
 self.send(str + self.linesep)
 
 
+_thread_kill_requested = False
+
+def kill_tail_threads():
+
+Kill all kvm_tail threads.
+
+After calling this function no new threads should be started.
+
+global _thread_kill_requested
+_thread_kill_requested = True
+for t in threading.enumerate():
+if hasattr(t, name) and t.name.startswith(tail_thread):
+t.join(10)
+
+
 class kvm_tail(kvm_spawn):
 
 This class runs a child process in the background and sends its output in
@@ -608,7 +623,6 @@ class kvm_tail(kvm_spawn):
 
 # Start the thread in the background
 self.tail_thread = None
-self.__thread_kill_requested = False
 if termination_func or output_func:
 self._start_thread()
 
@@ -675,15 +689,6 @@ class kvm_tail(kvm_spawn):
 self.output_prefix = output_prefix
 
 
-def kill_tail_thread(self):
-
-Stop the tailing thread which calls output_func() and
-termination_func().
-
-self.__thread_kill_requested = True
-self._join_thread()
-
-
 def _tail(self):
 def print_line(text):
 # Pre-pend prefix and remove trailing whitespace
@@ -695,60 +700,68 @@ class kvm_tail(kvm_spawn):
 except TypeError:
 pass
 
-fd = self._get_fd(tail)
-buffer = 
-while True:
-if self.__thread_kill_requested:
+try:
+fd = self._get_fd(tail)
+buffer = 
+while True:
+global _thread_kill_requested
+if _thread_kill_requested:
+return
+try:
+# See if there's any data to read from the pipe
+r, w, x = select.select([fd], [], [], 0.05)
+except:
+break
+if fd in r:
+# Some data is available; read it
+new_data = os.read(fd, 1024)
+if not new_data:
+break
+buffer += new_data
+# Send the output to output_func line by line
+# (except for the last line)
+if self.output_func:
+lines = buffer.split(\n)
+for line in lines[:-1]:
+print_line(line)
+# Leave only the last line
+last_newline_index = buffer.rfind(\n)
+buffer = buffer[last_newline_index+1:]
+else:
+# No output is available right now; flush the buffer
+if buffer:
+print_line(buffer)
+buffer = 
+# The process terminated; print any remaining output
+if buffer:
+print_line(buffer)
+# Get the exit status, print it and send it to termination_func
+status = self.get_status()
+if status is None:
 return
+print_line((Process terminated with status %s) % status)
 try:
-# See if there's any data to read from the pipe
-r, w, x = select.select([fd], [], [], 0.05)
-except:
-break
-if fd in r

Re: [KVM-AUTOTEST PATCH] KVM test: Windows unattended_install: don't start the telnet service at startup

2010-06-29 Thread Michael Goldish
On 06/29/2010 04:33 AM, Chen Cao wrote:
 On Mon, Jun 28, 2010 at 05:54:18PM +0300, Michael Goldish wrote:
 The telnet service isn't used by kvm-autotest (AFAIK) and may interfere with
 rss.exe (port 23).

 
 Michael,
 
 I think it is better to leave the port 23 (and also 22) alone, people
 may want to use both telnet (e.g. telnet is integrited into some
 testing tools and/or some other reasons) and rss.exe.
 and rss.exe could use other port and we can configure the port NR
 through the config file of kvm-autotest to use it.
 
 
 Regards,
 
 Cao, Chen
 2010/06/29

OK, I'll try using ports 1022 and 1023 instead.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH v3] [RFC] KVM test: add python client for rss file transfer services

2010-06-29 Thread Michael Goldish
See details in docstrings in rss_file_transfer.py.
See protocol details in rss.cpp.

Changes from v2:
- Raise FileTransferNotFoundError if no files/dirs are transferred (due to
  a bad path or wildcard pattern)
- Make all connection related errors in the base class raise
  FileTransferConnectError

Changes from v1:
- Use glob() instead of iglob() (Python 2.4 doesn't like iglob())
- Change a few comments

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/rss_file_transfer.py |  436 +
 1 files changed, 436 insertions(+), 0 deletions(-)
 create mode 100755 client/tests/kvm/rss_file_transfer.py

diff --git a/client/tests/kvm/rss_file_transfer.py 
b/client/tests/kvm/rss_file_transfer.py
new file mode 100755
index 000..d60aa5e
--- /dev/null
+++ b/client/tests/kvm/rss_file_transfer.py
@@ -0,0 +1,436 @@
+#!/usr/bin/python
+
+Client for file transfer services offered by RSS (Remote Shell Server).
+
+...@author: Michael Goldish (mgold...@redhat.com)
+...@copyright: 2008-2010 Red Hat Inc.
+
+
+import socket, struct, time, sys, os, glob
+
+# Globals
+BUFSIZE = 65536
+
+# Protocol message constants
+RSS_MAGIC   = 0x525353
+RSS_OK  = 1
+RSS_ERROR   = 2
+RSS_UPLOAD  = 3
+RSS_DOWNLOAD= 4
+RSS_SET_PATH= 5
+RSS_CREATE_FILE = 6
+RSS_CREATE_DIR  = 7
+RSS_LEAVE_DIR   = 8
+RSS_DONE= 9
+
+# See rss.cpp for protocol details.
+
+
+class FileTransferError(Exception):
+pass
+
+
+class FileTransferConnectError(FileTransferError):
+pass
+
+
+class FileTransferTimeoutError(FileTransferError):
+pass
+
+
+class FileTransferProtocolError(FileTransferError):
+pass
+
+
+class FileTransferSendError(FileTransferError):
+pass
+
+
+class FileTransferServerError(FileTransferError):
+pass
+
+
+class FileTransferNotFoundError(FileTransferError):
+pass
+
+
+class FileTransferClient(object):
+
+Connect to a RSS (remote shell server) and transfer files.
+
+
+def __init__(self, address, port, timeout=10):
+
+Connect to a server.
+
+@param address: The server's address
+@param port: The server's port
+@param timeout: Time duration to wait for connection to succeed
+@raise FileTransferConnectError: Raised if the connection fails
+@raise FileTransferProtocolError: Raised if an incorrect magic number
+is received
+
+self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+self._socket.settimeout(timeout)
+try:
+self._socket.connect((address, port))
+except socket.error:
+raise FileTransferConnectError(Could not connect to server)
+try:
+if self._receive_msg(timeout) != RSS_MAGIC:
+raise FileTransferConnectError(Received wrong magic number)
+except FileTransferTimeoutError:
+raise FileTransferConnectError(Timeout expired while trying to 
+   connect to server)
+
+
+def __del__(self):
+self.close()
+
+
+def close(self):
+
+Close the connection.
+
+self._socket.close()
+
+
+def _send(self, str):
+try:
+self._socket.sendall(str)
+except socket.error:
+raise FileTransferSendError(Could not send data to server)
+
+
+def _receive(self, size, timeout=10):
+s = 
+end_time = time.time() + timeout
+while size:
+try:
+self._socket.settimeout(max(0, end_time - time.time()))
+data = self._socket.recv(min(BUFSIZE, size))
+except socket.timeout:
+raise FileTransferTimeoutError(Timeout expired while 
+   receiving data from server)
+except socket.error:
+raise FileTransferProtocolError(Error receiving data from 
+server)
+if not data:
+raise FileTransferProtocolError(Connection closed 
+unexpectedly)
+s += data
+size -= len(data)
+return s
+
+
+def _send_packet(self, str):
+self._send(struct.pack(=Q, len(str)))
+self._send(str)
+
+
+def _receive_packet(self, timeout=10):
+size = struct.unpack(=Q, self._receive(8))[0]
+return self._receive(size, timeout)
+
+
+def _send_packet_from_file(self, filename, timeout=30):
+self._send(struct.pack(=Q, os.path.getsize(filename)))
+f = open(filename, rb)
+try:
+end_time = time.time() + timeout
+while time.time()  end_time:
+data = f.read(BUFSIZE)
+if not data:
+break
+self._send(data)
+else:
+raise FileTransferTimeoutError

[KVM-AUTOTEST PATCH v3] [RFC] KVM test: rss.cpp: add file transfer support

2010-06-29 Thread Michael Goldish
Enable RSS to send/receive files and directory trees (recursively).

See protocol details in rss.cpp.

Changes from v2:
- Use ports 10022 and 10023 by default instead of 22 and 23.

Changes from v1:
- Expand environment variables (e.g. %WinDir%) in all paths.
- Change text box limit to 16384 chars.
- When text box is full, clear 3/4 of old text instead of 1/2 (looks prettier).
- Use const char * instead of char * where appropriate.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/deps/rss.cpp | 1448 -
 1 files changed, 989 insertions(+), 459 deletions(-)

diff --git a/client/tests/kvm/deps/rss.cpp b/client/tests/kvm/deps/rss.cpp
index 66d9a5b..b95a45d 100644
--- a/client/tests/kvm/deps/rss.cpp
+++ b/client/tests/kvm/deps/rss.cpp
@@ -1,459 +1,989 @@
-// Simple remote shell server
-// Author: Michael Goldish mgold...@redhat.com
-// Much of the code here was adapted from Microsoft code samples.
-
-// Usage: rss.exe [port]
-// If no port is specified the default is 22.
-
-#define _WIN32_WINNT 0x0500
-
-#include windows.h
-#include winsock2.h
-#include stdio.h
-
-#pragma comment(lib, ws2_32.lib)
-
-int port = 22;
-
-HWND hMainWindow = NULL;
-HWND hTextBox = NULL;
-
-struct client_info {
-SOCKET socket;
-sockaddr_in addr;
-int pid;
-HWND hwnd;
-HANDLE hJob;
-HANDLE hChildOutputRead;
-HANDLE hThreadChildToSocket;
-};
-
-void ExitOnError(char *message, BOOL winsock = 0)
-{
-LPVOID system_message;
-char buffer[512];
-
-int error_code;
-if (winsock)
-error_code = WSAGetLastError();
-else
-error_code = GetLastError();
-
-WSACleanup();
-
-FormatMessage(
-FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
-NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-(LPTSTR)system_message, 0, NULL);
-
-sprintf(buffer,
-%s!\n
-Error code = %d\n
-Error message = %s,
-message, error_code, (char *)system_message);
-
-MessageBox(hMainWindow, buffer, Error, MB_OK | MB_ICONERROR);
-
-LocalFree(system_message);
-ExitProcess(1);
-}
-
-void AppendMessage(char *message)
-{
-int length = GetWindowTextLength(hTextBox);
-SendMessage(hTextBox, EM_SETSEL, (WPARAM)length, (LPARAM)length);
-SendMessage(hTextBox, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)message);
-}
-
-void FormatStringForPrinting(char *dst, char *src, int size)
-{
-int j = 0;
-
-for (int i = 0; i  size  src[i]; i++) {
-if (src[i] == '\n') {
-dst[j++] = '\\';
-dst[j++] = 'n';
-} else if (src[i] == '\r') {
-dst[j++] = '\\';
-dst[j++] = 'r';
-} else if (src[i] == '\t') {
-dst[j++] = '\\';
-dst[j++] = 't';
-} else if (src[i] == '\\') {
-dst[j++] = '\\';
-dst[j++] = '\\';
-} else dst[j++] = src[i];
-}
-dst[j] = 0;
-}
-
-char* GetClientIPAddress(client_info *ci)
-{
-char *address = inet_ntoa(ci-addr.sin_addr);
-if (address)
-return address;
-else
-return unknown;
-}
-
-DWORD WINAPI ChildToSocket(LPVOID client_info_ptr)
-{
-char buffer[1024], message[1024];
-client_info ci;
-DWORD bytes_read;
-int bytes_sent;
-
-memcpy(ci, client_info_ptr, sizeof(ci));
-
-while (1) {
-// Read data from the child's STDOUT/STDERR pipes
-if (!ReadFile(ci.hChildOutputRead,
-  buffer, sizeof(buffer),
-  bytes_read, NULL) || !bytes_read) {
-if (GetLastError() == ERROR_BROKEN_PIPE)
-break; // Pipe done -- normal exit path
-else
-ExitOnError(ReadFile failed); // Something bad happened
-}
-// Send data to the client
-bytes_sent = send(ci.socket, buffer, bytes_read, 0);
-/*
-// Make sure all the data was sent
-if (bytes_sent != bytes_read) {
-sprintf(message,
-ChildToSocket: bytes read (%d) != bytes sent (%d),
-bytes_read, bytes_sent);
-ExitOnError(message, 1);
-}
-*/
-}
-
-AppendMessage(Child exited\r\n);
-shutdown(ci.socket, SD_BOTH);
-
-return 0;
-}
-
-DWORD WINAPI SocketToChild(LPVOID client_info_ptr)
-{
-char buffer[256], formatted_buffer[768];
-char message[1024], client_info_str[256];
-client_info ci;
-DWORD bytes_written;
-int bytes_received;
-
-memcpy(ci, client_info_ptr, sizeof(ci));
-
-sprintf(client_info_str, address %s, port %d,
-GetClientIPAddress(ci), ci.addr.sin_port);
-
-sprintf(message, New client connected (%s)\r\n, client_info_str);
-AppendMessage(message);
-
-while (1) {
-// Receive data from the socket
-ZeroMemory(buffer, sizeof(buffer));
-bytes_received = recv(ci.socket, buffer, sizeof(buffer), 0

[KVM-AUTOTEST PATCH v2] KVM test: enable file transfers for Windows guests

2010-06-29 Thread Michael Goldish
This will only work with the most recent rss.exe.

Usage examples:

vm.copy_files_from(r'C:\foobar\*', test.debugdir, timeout=30)
vm.copy_files_from(r'%SystemRoot%\memory.dmp', '/tmp/', timeout=60)
vm.copy_files_to('/usr/local', r'C:\Windows', timeout=600)

Changes from v1:
- Use ports 10022 and 10023 instead of 22 and 23.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_vm.py |   20 +++-
 client/tests/kvm/tests_base.cfg.sample |   10 ++
 2 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 46b0aa3..7cc2ffa 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -6,7 +6,7 @@ Utility classes and functions to handle Virtual Machine 
creation using qemu.
 
 
 import time, socket, os, logging, fcntl, re, commands, glob
-import kvm_utils, kvm_subprocess, kvm_monitor
+import kvm_utils, kvm_subprocess, kvm_monitor, rss_file_transfer
 from autotest_lib.client.common_lib import error
 from autotest_lib.client.bin import utils
 
@@ -954,17 +954,22 @@ class VM:
 client = self.params.get(file_transfer_client)
 address = self.get_address(nic_index)
 port = self.get_port(int(self.params.get(file_transfer_port)))
-log_filename = (scp-%s-%s.log %
-(self.name, kvm_utils.generate_random_string(4)))
 
 if not address or not port:
 logging.debug(IP address or port unavailable)
 return None
 
 if client == scp:
+log_filename = (scp-%s-%s.log %
+(self.name, kvm_utils.generate_random_string(4)))
 return kvm_utils.scp_to_remote(address, port, username, password,
local_path, remote_path,
log_filename, timeout)
+elif client == rss:
+c = rss_file_transfer.FileUploadClient(address, port)
+c.upload(local_path, remote_path, timeout)
+c.close()
+return True
 
 
 def copy_files_from(self, remote_path, local_path, nic_index=0, 
timeout=600):
@@ -982,17 +987,22 @@ class VM:
 client = self.params.get(file_transfer_client)
 address = self.get_address(nic_index)
 port = self.get_port(int(self.params.get(file_transfer_port)))
-log_filename = (scp-%s-%s.log %
-(self.name, kvm_utils.generate_random_string(4)))
 
 if not address or not port:
 logging.debug(IP address or port unavailable)
 return None
 
 if client == scp:
+log_filename = (scp-%s-%s.log %
+(self.name, kvm_utils.generate_random_string(4)))
 return kvm_utils.scp_from_remote(address, port, username, password,
  remote_path, local_path,
  log_filename, timeout)
+elif client == rss:
+c = rss_file_transfer.FileDownloadClient(address, port)
+c.download(remote_path, local_path, timeout)
+c.close()
+return True
 
 
 def serial_login(self, timeout=10):
diff --git a/client/tests/kvm/tests_base.cfg.sample 
b/client/tests/kvm/tests_base.cfg.sample
index 2c78cfc..c90415a 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -996,10 +996,12 @@ variants:
 password = 123456
 shell_linesep = \r\n
 shell_client = nc
-shell_port = 22
-# File transfers are currently unsupported
-# file_transfer_client = scp
-# file_transfer_port = 22
+shell_port = 10022
+file_transfer_client = rss
+file_transfer_port = 10023
+redirs +=  file_transfer
+guest_port_remote_shell = 10022
+guest_port_file_transfer = 10023
 
 # This ISO will be used for all tests except install:
 cdrom = windows/winutils.iso
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH] KVM test: setuprss.bat: use 'netsh advfirewall' to disable firewall

2010-06-29 Thread Michael Goldish
In addition to 'netsh firewall ...' use 'netsh advfirewall ...' which seems to
be the preferred way of changing firewall settings in Win7.
('netsh firewall ...' results in the firewall being disabled only for one type
of network (e.g. public networks) but not for the other (home networks).)

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/deps/setuprss.bat |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/client/tests/kvm/deps/setuprss.bat 
b/client/tests/kvm/deps/setuprss.bat
index 82d620d..1adff0f 100644
--- a/client/tests/kvm/deps/setuprss.bat
+++ b/client/tests/kvm/deps/setuprss.bat
@@ -5,6 +5,7 @@ copy %rsspath% C:\rss.exe
 net user Administrator /active:yes
 net user Administrator 1q2w3eP
 netsh firewall set opmode disable
+netsh advfirewall set allprofiles state off
 powercfg /G OFF /OPTION RESUMEPASSWORD
 
 reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v Remote Shell 
Server /d C:\rss.exe 22 /t REG_SZ /f
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH] KVM test: setuprss.bat: let rss.exe use its default ports

2010-06-29 Thread Michael Goldish
Don't tell rss.exe to use port 22.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/deps/setuprss.bat |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/client/tests/kvm/deps/setuprss.bat 
b/client/tests/kvm/deps/setuprss.bat
index 1adff0f..97298cd 100644
--- a/client/tests/kvm/deps/setuprss.bat
+++ b/client/tests/kvm/deps/setuprss.bat
@@ -8,7 +8,7 @@ netsh firewall set opmode disable
 netsh advfirewall set allprofiles state off
 powercfg /G OFF /OPTION RESUMEPASSWORD
 
-reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v Remote Shell 
Server /d C:\rss.exe 22 /t REG_SZ /f
+reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v Remote Shell 
Server /d C:\rss.exe /t REG_SZ /f
 reg add HKLM\Software\Microsoft\Windows NT\CurrentVersion\winlogon /v 
AutoAdminLogon /d 1 /t REG_SZ /f
 reg add HKLM\Software\Microsoft\Windows NT\CurrentVersion\winlogon /v 
DefaultUserName /d Administrator /t REG_SZ /f
 reg add HKLM\Software\Microsoft\Windows NT\CurrentVersion\winlogon /v 
DefaultPassword /d 1q2w3eP /t REG_SZ /f
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH] KVM test: kvm.py: add exception class name to failure message

2010-06-29 Thread Michael Goldish
This will result in more informative messages, e.g.:

Test failed: FileTransferConnectError: Could not connect to server

instead of

Test failed: Could not connect to server

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm.py |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/client/tests/kvm/kvm.py b/client/tests/kvm/kvm.py
index 0799cff..9da4c33 100644
--- a/client/tests/kvm/kvm.py
+++ b/client/tests/kvm/kvm.py
@@ -75,7 +75,8 @@ class kvm(test.test):
 test_passed = True
 
 except Exception, e:
-logging.error(Test failed: %s, e)
+logging.error(Test failed: %s: %s,
+  e.__class__.__name__, e)
 try:
 kvm_preprocessing.postprocess_on_error(
 self, params, env)
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Autotest] [PATCH 1/2] KVM Test: Update cmd() help function in kvm_monitor.py to support parameters.

2010-06-28 Thread Michael Goldish
On 06/28/2010 10:45 AM, Feng Yang wrote:
 This function allow user send qmp command with parameters.
 e.g.  balloon value=1073741824
 Also log command to debug. 
 
 Signed-off-by: Feng Yang fy...@redhat.com
 ---
  client/tests/kvm/kvm_monitor.py |   32 
  1 files changed, 24 insertions(+), 8 deletions(-)
 
 diff --git a/client/tests/kvm/kvm_monitor.py b/client/tests/kvm/kvm_monitor.py
 index 8440835..af9ff21 100644
 --- a/client/tests/kvm/kvm_monitor.py
 +++ b/client/tests/kvm/kvm_monitor.py
 @@ -188,6 +188,7 @@ class HumanMonitor(Monitor):
  
  try:
  try:
 +logging.debug(Send command: %s % command)
  self._socket.sendall(command + \n)
  except socket.error:
  raise MonitorSendError(Could not send monitor command '%s' 
 %
 @@ -258,9 +259,8 @@ class HumanMonitor(Monitor):
  
  def cmd(self, command, timeout=20):
  
 -Send a simple command with no parameters and return its output.
 -Should only be used for commands that take no parameters and are
 -implemented under the same name for both the human and QMP monitors.
 +Send a simple command with/without parameters and return its output.
 +Implemented under the same name for both the human and QMP monitors.
  
  @param command: Command to send
  @param timeout: Time duration to wait for (qemu) prompt after command
 @@ -486,6 +486,7 @@ class QMPMonitor(Monitor):
  try:
  cmdobj = self._build_cmd(cmd, args, id)
  try:
 +logging.debug(Send command: %s % cmdobj)
  self._socket.sendall(json.dumps(cmdobj) + \n)
  except socket.error:
  raise MonitorSendError(Could not send QMP command '%s' % 
 cmd)
 @@ -601,11 +602,13 @@ class QMPMonitor(Monitor):
  # Note: all of the following functions raise exceptions in a similar 
 manner
  # to cmd() and _get_command_output().
  
 -def cmd(self, command, timeout=20):
 +def cmd(self, cmdline, timeout=20):
  
 -Send a simple command with no parameters and return its output.
 -Should only be used for commands that take no parameters and are
 -implemented under the same name for both the human and QMP monitors.
 +Send a simple command with/without parameters and return its output.
 +Implemented under the same name for both the human and QMP monitors.
 +Command with parameters should in following format e.g.:
 +'memsave val=0 size=10240 filename=memsave'
 +Command without parameter: 'memsave'
  
  @param command: Command to send
  @param timeout: Time duration to wait for response
 @@ -614,7 +617,20 @@ class QMPMonitor(Monitor):
  @raise MonitorSendError: Raised if the command cannot be sent
  @raise MonitorProtocolError: Raised if no response is received
  
 -return self._get_command_output(command, timeout=timeout)
 +cmdargs = cmdline.split()
 +command = cmdargs[0]
 +args = {}
 +for arg in cmdargs[1:]:
 +opt = arg.split('=')
 +try:
 +try:
 +value = int(opt[1])
 +except ValueError:
 +value = opt[1]
 +args[opt[0]] = value
 +except:
 +  logging.debug(Fail to create args, please check command)
 +return self._get_command_output(command, args, timeout=timeout)
  
  
  def quit(self):

Why not add a wrapper for the command you're interested in?
If we do it your way, a test that uses cmd() with parameters will have
to handle the human case and the QMP case separately.  For example, if a
human monitor is used the test will have to use

  vm.monitor.cmd(screendump scr.ppm)

and if QMP is used the test will have to use

  vm.monitor.cmd(screendump filename=scr.ppm).

but if we use a wrapper,

  vm.monitor.screendump(scr.ppm)

will work in both cases.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH] KVM test: Windows unattended_install: don't start the telnet service at startup

2010-06-28 Thread Michael Goldish
The telnet service isn't used by kvm-autotest (AFAIK) and may interfere with
rss.exe (port 23).

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/unattended/win2003-32.sif |   10 +++-
 client/tests/kvm/unattended/win2003-64.sif |   10 +++-
 .../kvm/unattended/win2008-32-autounattend.xml |   18 ++-
 .../kvm/unattended/win2008-64-autounattend.xml |   18 ++-
 .../kvm/unattended/win2008-r2-autounattend.xml |   18 ++-
 .../tests/kvm/unattended/win7-32-autounattend.xml  |   22 ---
 .../tests/kvm/unattended/win7-64-autounattend.xml  |   22 ---
 .../kvm/unattended/winvista-32-autounattend.xml|   18 ++-
 .../kvm/unattended/winvista-64-autounattend.xml|   18 ++-
 9 files changed, 33 insertions(+), 121 deletions(-)

diff --git a/client/tests/kvm/unattended/win2003-32.sif 
b/client/tests/kvm/unattended/win2003-32.sif
index f58b0b0..d1e8495 100644
--- a/client/tests/kvm/unattended/win2003-32.sif
+++ b/client/tests/kvm/unattended/win2003-32.sif
@@ -56,9 +56,7 @@
 YResolution=768
 
 [GuiRunOnce]
-Command0=cmd /c sc config TlntSvr start= auto
-Command1=cmd /c netsh firewall set opmode disable
-Command2=cmd /c net start telnet
-Command3=cmd /c E:\setuprss.bat
-Command4=cmd /c netsh interface ip set address local dhcp
-Command5=cmd /c ping 10.0.2.2 -n 20  A:\finish.exe
+Command0=cmd /c netsh firewall set opmode disable
+Command1=cmd /c E:\setuprss.bat
+Command2=cmd /c netsh interface ip set address local dhcp
+Command3=cmd /c ping 10.0.2.2 -n 20  A:\finish.exe
diff --git a/client/tests/kvm/unattended/win2003-64.sif 
b/client/tests/kvm/unattended/win2003-64.sif
index f58b0b0..d1e8495 100644
--- a/client/tests/kvm/unattended/win2003-64.sif
+++ b/client/tests/kvm/unattended/win2003-64.sif
@@ -56,9 +56,7 @@
 YResolution=768
 
 [GuiRunOnce]
-Command0=cmd /c sc config TlntSvr start= auto
-Command1=cmd /c netsh firewall set opmode disable
-Command2=cmd /c net start telnet
-Command3=cmd /c E:\setuprss.bat
-Command4=cmd /c netsh interface ip set address local dhcp
-Command5=cmd /c ping 10.0.2.2 -n 20  A:\finish.exe
+Command0=cmd /c netsh firewall set opmode disable
+Command1=cmd /c E:\setuprss.bat
+Command2=cmd /c netsh interface ip set address local dhcp
+Command3=cmd /c ping 10.0.2.2 -n 20  A:\finish.exe
diff --git a/client/tests/kvm/unattended/win2008-32-autounattend.xml 
b/client/tests/kvm/unattended/win2008-32-autounattend.xml
index 44a9fc4..74f99b1 100644
--- a/client/tests/kvm/unattended/win2008-32-autounattend.xml
+++ b/client/tests/kvm/unattended/win2008-32-autounattend.xml
@@ -116,30 +116,18 @@
FirstLogonCommands
SynchronousCommand wcm:action=add
Order1/Order
-   CommandLine%WINDIR%\System32\cmd /c 
start /w pkgmgr /iu:TelnetServer/CommandLine
-   /SynchronousCommand
-   SynchronousCommand wcm:action=add
-   Order2/Order
-   CommandLine%WINDIR%\System32\cmd /c 
sc config TlntSvr start= auto/CommandLine
-   /SynchronousCommand
-   SynchronousCommand wcm:action=add
-   Order3/Order
CommandLine%WINDIR%\System32\cmd /c 
netsh firewall set opmode disable/CommandLine
/SynchronousCommand
SynchronousCommand wcm:action=add
-   Order4/Order
-   CommandLine%WINDIR%\System32\cmd /c 
net start telnet/CommandLine
-   /SynchronousCommand
-   SynchronousCommand wcm:action=add
-   Order5/Order
+   Order2/Order
CommandLine%WINDIR%\System32\cmd /c 
E:\setuprss.bat/CommandLine
/SynchronousCommand
SynchronousCommand wcm:action=add
-   Order6/Order
+   Order3/Order
CommandLine%WINDIR%\System32\cmd /c 
netsh interface ip set address Local Area Connection dhcp/CommandLine
/SynchronousCommand
SynchronousCommand wcm:action=add
-   Order7/Order
+   Order4/Order
CommandLine%WINDIR%\System32\cmd /c 
ping 10.0.2.2 -n 20 #38;#38; A:\finish.exe/CommandLine

[KVM-AUTOTEST PATCH v2] [RFC] KVM test: rss.cpp: add file transfer support

2010-06-27 Thread Michael Goldish
Enable RSS to send/receive files and directory trees (recursively).

See protocol details in rss.cpp.

Changes from v1:
- Expand environment variables (e.g. %WinDir%) in all paths.
- Change text box limit to 16384 chars.
- When text box is full, clear 3/4 of old text instead of 1/2 (looks prettier).
- Use const char * instead of char * where appropriate.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/deps/rss.cpp | 1448 -
 1 files changed, 989 insertions(+), 459 deletions(-)

diff --git a/client/tests/kvm/deps/rss.cpp b/client/tests/kvm/deps/rss.cpp
index 66d9a5b..b6eca68 100644
--- a/client/tests/kvm/deps/rss.cpp
+++ b/client/tests/kvm/deps/rss.cpp
@@ -1,459 +1,989 @@
-// Simple remote shell server
-// Author: Michael Goldish mgold...@redhat.com
-// Much of the code here was adapted from Microsoft code samples.
-
-// Usage: rss.exe [port]
-// If no port is specified the default is 22.
-
-#define _WIN32_WINNT 0x0500
-
-#include windows.h
-#include winsock2.h
-#include stdio.h
-
-#pragma comment(lib, ws2_32.lib)
-
-int port = 22;
-
-HWND hMainWindow = NULL;
-HWND hTextBox = NULL;
-
-struct client_info {
-SOCKET socket;
-sockaddr_in addr;
-int pid;
-HWND hwnd;
-HANDLE hJob;
-HANDLE hChildOutputRead;
-HANDLE hThreadChildToSocket;
-};
-
-void ExitOnError(char *message, BOOL winsock = 0)
-{
-LPVOID system_message;
-char buffer[512];
-
-int error_code;
-if (winsock)
-error_code = WSAGetLastError();
-else
-error_code = GetLastError();
-
-WSACleanup();
-
-FormatMessage(
-FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
-NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-(LPTSTR)system_message, 0, NULL);
-
-sprintf(buffer,
-%s!\n
-Error code = %d\n
-Error message = %s,
-message, error_code, (char *)system_message);
-
-MessageBox(hMainWindow, buffer, Error, MB_OK | MB_ICONERROR);
-
-LocalFree(system_message);
-ExitProcess(1);
-}
-
-void AppendMessage(char *message)
-{
-int length = GetWindowTextLength(hTextBox);
-SendMessage(hTextBox, EM_SETSEL, (WPARAM)length, (LPARAM)length);
-SendMessage(hTextBox, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)message);
-}
-
-void FormatStringForPrinting(char *dst, char *src, int size)
-{
-int j = 0;
-
-for (int i = 0; i  size  src[i]; i++) {
-if (src[i] == '\n') {
-dst[j++] = '\\';
-dst[j++] = 'n';
-} else if (src[i] == '\r') {
-dst[j++] = '\\';
-dst[j++] = 'r';
-} else if (src[i] == '\t') {
-dst[j++] = '\\';
-dst[j++] = 't';
-} else if (src[i] == '\\') {
-dst[j++] = '\\';
-dst[j++] = '\\';
-} else dst[j++] = src[i];
-}
-dst[j] = 0;
-}
-
-char* GetClientIPAddress(client_info *ci)
-{
-char *address = inet_ntoa(ci-addr.sin_addr);
-if (address)
-return address;
-else
-return unknown;
-}
-
-DWORD WINAPI ChildToSocket(LPVOID client_info_ptr)
-{
-char buffer[1024], message[1024];
-client_info ci;
-DWORD bytes_read;
-int bytes_sent;
-
-memcpy(ci, client_info_ptr, sizeof(ci));
-
-while (1) {
-// Read data from the child's STDOUT/STDERR pipes
-if (!ReadFile(ci.hChildOutputRead,
-  buffer, sizeof(buffer),
-  bytes_read, NULL) || !bytes_read) {
-if (GetLastError() == ERROR_BROKEN_PIPE)
-break; // Pipe done -- normal exit path
-else
-ExitOnError(ReadFile failed); // Something bad happened
-}
-// Send data to the client
-bytes_sent = send(ci.socket, buffer, bytes_read, 0);
-/*
-// Make sure all the data was sent
-if (bytes_sent != bytes_read) {
-sprintf(message,
-ChildToSocket: bytes read (%d) != bytes sent (%d),
-bytes_read, bytes_sent);
-ExitOnError(message, 1);
-}
-*/
-}
-
-AppendMessage(Child exited\r\n);
-shutdown(ci.socket, SD_BOTH);
-
-return 0;
-}
-
-DWORD WINAPI SocketToChild(LPVOID client_info_ptr)
-{
-char buffer[256], formatted_buffer[768];
-char message[1024], client_info_str[256];
-client_info ci;
-DWORD bytes_written;
-int bytes_received;
-
-memcpy(ci, client_info_ptr, sizeof(ci));
-
-sprintf(client_info_str, address %s, port %d,
-GetClientIPAddress(ci), ci.addr.sin_port);
-
-sprintf(message, New client connected (%s)\r\n, client_info_str);
-AppendMessage(message);
-
-while (1) {
-// Receive data from the socket
-ZeroMemory(buffer, sizeof(buffer));
-bytes_received = recv(ci.socket, buffer, sizeof(buffer), 0);
-if (bytes_received = 0)
-break;
-// Report the data received

[KVM-AUTOTEST PATCH v2] [RFC] KVM test: add python client for rss file transfer services

2010-06-27 Thread Michael Goldish
See details in docstrings in rss_file_transfer.py.
See protocol details in rss.cpp.

Changes from v1:
- Use glob() instead of iglob() (Python 2.4 doesn't like iglob())
- Change a few comments

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/rss_file_transfer.py |  412 +
 1 files changed, 412 insertions(+), 0 deletions(-)
 create mode 100755 client/tests/kvm/rss_file_transfer.py

diff --git a/client/tests/kvm/rss_file_transfer.py 
b/client/tests/kvm/rss_file_transfer.py
new file mode 100755
index 000..f866a81
--- /dev/null
+++ b/client/tests/kvm/rss_file_transfer.py
@@ -0,0 +1,412 @@
+#!/usr/bin/python
+
+Client for file transfer services offered by RSS (Remote Shell Server).
+
+...@author: Michael Goldish (mgold...@redhat.com)
+...@copyright: 2008-2010 Red Hat Inc.
+
+
+import socket, struct, time, sys, os, glob
+
+# Globals
+BUFSIZE = 65536
+
+# Protocol message constants
+RSS_MAGIC   = 0x525353
+RSS_OK  = 1
+RSS_ERROR   = 2
+RSS_UPLOAD  = 3
+RSS_DOWNLOAD= 4
+RSS_SET_PATH= 5
+RSS_CREATE_FILE = 6
+RSS_CREATE_DIR  = 7
+RSS_LEAVE_DIR   = 8
+RSS_DONE= 9
+
+# See rss.cpp for protocol details.
+
+
+class FileTransferError(Exception):
+pass
+
+
+class FileTransferConnectError(FileTransferError):
+pass
+
+
+class FileTransferTimeoutError(FileTransferError):
+pass
+
+
+class FileTransferProtocolError(FileTransferError):
+pass
+
+
+class FileTransferSendError(FileTransferError):
+pass
+
+
+class FileTransferServerError(FileTransferError):
+pass
+
+
+class FileTransferClient(object):
+
+Connect to a RSS (remote shell server) and transfer files.
+
+
+def __init__(self, address, port, timeout=10):
+
+Connect to a server.
+
+@param address: The server's address
+@param port: The server's port
+@param timeout: Time duration to wait for connection to succeed
+@raise FileTransferConnectError: Raised if the connection fails
+@raise FileTransferProtocolError: Raised if an incorrect magic number
+is received
+
+self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+self._socket.settimeout(timeout)
+try:
+self._socket.connect((address, port))
+except socket.error:
+raise FileTransferConnectError(Could not connect to server)
+if self._receive_msg(timeout) != RSS_MAGIC:
+raise FileTransferProtocolError(Received wrong magic number)
+
+
+def __del__(self):
+self.close()
+
+
+def close(self):
+
+Close the connection.
+
+self._socket.close()
+
+
+def _send(self, str):
+try:
+self._socket.sendall(str)
+except socket.error:
+raise FileTransferSendError(Could not send data to server)
+
+
+def _receive(self, size, timeout=10):
+s = 
+end_time = time.time() + timeout
+while size:
+try:
+self._socket.settimeout(max(0, end_time - time.time()))
+data = self._socket.recv(min(BUFSIZE, size))
+except socket.timeout:
+raise FileTransferTimeoutError(Timeout expired while 
+   receiving data from server)
+except socket.error:
+raise FileTransferProtocolError(Error receiving data from 
+server)
+if not data:
+raise FileTransferProtocolError(Connection closed 
+unexpectedly)
+s += data
+size -= len(data)
+return s
+
+
+def _send_packet(self, str):
+self._send(struct.pack(=Q, len(str)))
+self._send(str)
+
+
+def _receive_packet(self, timeout=10):
+size = struct.unpack(=Q, self._receive(8))[0]
+return self._receive(size, timeout)
+
+
+def _send_packet_from_file(self, filename, timeout=30):
+self._send(struct.pack(=Q, os.path.getsize(filename)))
+f = open(filename, rb)
+try:
+end_time = time.time() + timeout
+while time.time()  end_time:
+data = f.read(BUFSIZE)
+if not data:
+break
+self._send(data)
+else:
+raise FileTransferTimeoutError(Timeout expired while sending 
+   file %s % filename)
+finally:
+f.close()
+
+
+def _receive_packet_into_file(self, filename, timeout=30):
+size = struct.unpack(=Q, self._receive(8))[0]
+f = open(filename, wb)
+try:
+end_time = time.time() + timeout
+while size:
+try:
+self._socket.settimeout(max(0, end_time - time.time

[KVM-AUTOTEST PATCH] KVM test: kvm_vm.py: remove serial console file when VM is destroyed

2010-06-27 Thread Michael Goldish
Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_vm.py |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index c5234c8..46b0aa3 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -717,7 +717,8 @@ class VM:
 self.process.close()
 if self.serial_console:
 self.serial_console.close()
-for f in ([self.get_testlog_filename()] +
+for f in ([self.get_testlog_filename(),
+   self.get_serial_console_filename()] +
   self.get_monitor_filenames()):
 try:
 os.unlink(f)
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH] KVM test: enable file transfers for Windows guests

2010-06-27 Thread Michael Goldish
This will only work with the most recent rss.exe.

Usage examples:

vm.copy_files_from(r'C:\foobar\*', test.debugdir, timeout=30)
vm.copy_files_from(r'%SystemRoot%\memory.dmp', '/tmp/', timeout=60)
vm.copy_files_to('/usr/local', r'C:\Windows', timeout=600)

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_vm.py |   20 +++-
 client/tests/kvm/tests_base.cfg.sample |7 ---
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 46b0aa3..7cc2ffa 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -6,7 +6,7 @@ Utility classes and functions to handle Virtual Machine 
creation using qemu.
 
 
 import time, socket, os, logging, fcntl, re, commands, glob
-import kvm_utils, kvm_subprocess, kvm_monitor
+import kvm_utils, kvm_subprocess, kvm_monitor, rss_file_transfer
 from autotest_lib.client.common_lib import error
 from autotest_lib.client.bin import utils
 
@@ -954,17 +954,22 @@ class VM:
 client = self.params.get(file_transfer_client)
 address = self.get_address(nic_index)
 port = self.get_port(int(self.params.get(file_transfer_port)))
-log_filename = (scp-%s-%s.log %
-(self.name, kvm_utils.generate_random_string(4)))
 
 if not address or not port:
 logging.debug(IP address or port unavailable)
 return None
 
 if client == scp:
+log_filename = (scp-%s-%s.log %
+(self.name, kvm_utils.generate_random_string(4)))
 return kvm_utils.scp_to_remote(address, port, username, password,
local_path, remote_path,
log_filename, timeout)
+elif client == rss:
+c = rss_file_transfer.FileUploadClient(address, port)
+c.upload(local_path, remote_path, timeout)
+c.close()
+return True
 
 
 def copy_files_from(self, remote_path, local_path, nic_index=0, 
timeout=600):
@@ -982,17 +987,22 @@ class VM:
 client = self.params.get(file_transfer_client)
 address = self.get_address(nic_index)
 port = self.get_port(int(self.params.get(file_transfer_port)))
-log_filename = (scp-%s-%s.log %
-(self.name, kvm_utils.generate_random_string(4)))
 
 if not address or not port:
 logging.debug(IP address or port unavailable)
 return None
 
 if client == scp:
+log_filename = (scp-%s-%s.log %
+(self.name, kvm_utils.generate_random_string(4)))
 return kvm_utils.scp_from_remote(address, port, username, password,
  remote_path, local_path,
  log_filename, timeout)
+elif client == rss:
+c = rss_file_transfer.FileDownloadClient(address, port)
+c.download(remote_path, local_path, timeout)
+c.close()
+return True
 
 
 def serial_login(self, timeout=10):
diff --git a/client/tests/kvm/tests_base.cfg.sample 
b/client/tests/kvm/tests_base.cfg.sample
index 2c78cfc..94e2d6f 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -997,9 +997,10 @@ variants:
 shell_linesep = \r\n
 shell_client = nc
 shell_port = 22
-# File transfers are currently unsupported
-# file_transfer_client = scp
-# file_transfer_port = 22
+file_transfer_client = rss
+file_transfer_port = 23
+redirs +=  file_transfer
+guest_port_file_transfer = 23
 
 # This ISO will be used for all tests except install:
 cdrom = windows/winutils.iso
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 5/5] KVM test: Make it possible to run VMs without NICs

2010-06-25 Thread Michael Goldish
On 06/25/2010 02:33 AM, Lucas Meneghel Rodrigues wrote:
 For unittesting, for example, is interesting that we
 run the VM with the bare mininum number of parameters.
 This fix allows that.
 
 Signed-off-by: Lucas Meneghel Rodrigues l...@redhat.com
 ---
  client/tests/kvm/kvm_vm.py |5 +++--
  1 files changed, 3 insertions(+), 2 deletions(-)
 
 diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
 index 7b1fc05..3c01fa0 100755
 --- a/client/tests/kvm/kvm_vm.py
 +++ b/client/tests/kvm/kvm_vm.py
 @@ -118,8 +118,9 @@ class VM:
  self.root_dir = root_dir
  self.address_cache = address_cache
  self.netdev_id = []
 -for nic in params.get(nics).split():
 -self.netdev_id.append(kvm_utils.generate_random_id())
 +if params.get(nics):
 +for nic in params.get(nics).split():

That's exactly what kvm_utils.get_sub_dict_names() does.  It may be a
long name for something so simple but it's used everywhere in kvm-autotest.

 +self.netdev_id.append(kvm_utils.generate_random_id())

I think the 3 lines above belong in VM.create(), not VM.__init__(),
because VM params are routinely changed in calls to VM.create().  If the
code stays in __init__() the changed params will not affect
self.netdev_id.  A good place for it would be near the code that handles
-redir.

  
  # Find a unique identifier for this VM
  while True:
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH] [RFC] KVM test: rss.cpp: add file transfer support

2010-06-24 Thread Michael Goldish
Enable RSS to send/receive files and directory trees (recursively).

See protocol details in rss.cpp.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/deps/rss.cpp | 1429 -
 1 files changed, 970 insertions(+), 459 deletions(-)

diff --git a/client/tests/kvm/deps/rss.cpp b/client/tests/kvm/deps/rss.cpp
index 66d9a5b..b2f6049 100644
--- a/client/tests/kvm/deps/rss.cpp
+++ b/client/tests/kvm/deps/rss.cpp
@@ -1,459 +1,970 @@
-// Simple remote shell server
-// Author: Michael Goldish mgold...@redhat.com
-// Much of the code here was adapted from Microsoft code samples.
-
-// Usage: rss.exe [port]
-// If no port is specified the default is 22.
-
-#define _WIN32_WINNT 0x0500
-
-#include windows.h
-#include winsock2.h
-#include stdio.h
-
-#pragma comment(lib, ws2_32.lib)
-
-int port = 22;
-
-HWND hMainWindow = NULL;
-HWND hTextBox = NULL;
-
-struct client_info {
-SOCKET socket;
-sockaddr_in addr;
-int pid;
-HWND hwnd;
-HANDLE hJob;
-HANDLE hChildOutputRead;
-HANDLE hThreadChildToSocket;
-};
-
-void ExitOnError(char *message, BOOL winsock = 0)
-{
-LPVOID system_message;
-char buffer[512];
-
-int error_code;
-if (winsock)
-error_code = WSAGetLastError();
-else
-error_code = GetLastError();
-
-WSACleanup();
-
-FormatMessage(
-FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
-NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-(LPTSTR)system_message, 0, NULL);
-
-sprintf(buffer,
-%s!\n
-Error code = %d\n
-Error message = %s,
-message, error_code, (char *)system_message);
-
-MessageBox(hMainWindow, buffer, Error, MB_OK | MB_ICONERROR);
-
-LocalFree(system_message);
-ExitProcess(1);
-}
-
-void AppendMessage(char *message)
-{
-int length = GetWindowTextLength(hTextBox);
-SendMessage(hTextBox, EM_SETSEL, (WPARAM)length, (LPARAM)length);
-SendMessage(hTextBox, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)message);
-}
-
-void FormatStringForPrinting(char *dst, char *src, int size)
-{
-int j = 0;
-
-for (int i = 0; i  size  src[i]; i++) {
-if (src[i] == '\n') {
-dst[j++] = '\\';
-dst[j++] = 'n';
-} else if (src[i] == '\r') {
-dst[j++] = '\\';
-dst[j++] = 'r';
-} else if (src[i] == '\t') {
-dst[j++] = '\\';
-dst[j++] = 't';
-} else if (src[i] == '\\') {
-dst[j++] = '\\';
-dst[j++] = '\\';
-} else dst[j++] = src[i];
-}
-dst[j] = 0;
-}
-
-char* GetClientIPAddress(client_info *ci)
-{
-char *address = inet_ntoa(ci-addr.sin_addr);
-if (address)
-return address;
-else
-return unknown;
-}
-
-DWORD WINAPI ChildToSocket(LPVOID client_info_ptr)
-{
-char buffer[1024], message[1024];
-client_info ci;
-DWORD bytes_read;
-int bytes_sent;
-
-memcpy(ci, client_info_ptr, sizeof(ci));
-
-while (1) {
-// Read data from the child's STDOUT/STDERR pipes
-if (!ReadFile(ci.hChildOutputRead,
-  buffer, sizeof(buffer),
-  bytes_read, NULL) || !bytes_read) {
-if (GetLastError() == ERROR_BROKEN_PIPE)
-break; // Pipe done -- normal exit path
-else
-ExitOnError(ReadFile failed); // Something bad happened
-}
-// Send data to the client
-bytes_sent = send(ci.socket, buffer, bytes_read, 0);
-/*
-// Make sure all the data was sent
-if (bytes_sent != bytes_read) {
-sprintf(message,
-ChildToSocket: bytes read (%d) != bytes sent (%d),
-bytes_read, bytes_sent);
-ExitOnError(message, 1);
-}
-*/
-}
-
-AppendMessage(Child exited\r\n);
-shutdown(ci.socket, SD_BOTH);
-
-return 0;
-}
-
-DWORD WINAPI SocketToChild(LPVOID client_info_ptr)
-{
-char buffer[256], formatted_buffer[768];
-char message[1024], client_info_str[256];
-client_info ci;
-DWORD bytes_written;
-int bytes_received;
-
-memcpy(ci, client_info_ptr, sizeof(ci));
-
-sprintf(client_info_str, address %s, port %d,
-GetClientIPAddress(ci), ci.addr.sin_port);
-
-sprintf(message, New client connected (%s)\r\n, client_info_str);
-AppendMessage(message);
-
-while (1) {
-// Receive data from the socket
-ZeroMemory(buffer, sizeof(buffer));
-bytes_received = recv(ci.socket, buffer, sizeof(buffer), 0);
-if (bytes_received = 0)
-break;
-// Report the data received
-FormatStringForPrinting(formatted_buffer, buffer, sizeof(buffer));
-sprintf(message, Client (%s) entered text: \%s\\r\n,
-client_info_str, formatted_buffer);
-AppendMessage(message);
-// Send the data as a series

[KVM-AUTOTEST PATCH] [RFC] KVM test: add python client for rss file transfer services

2010-06-24 Thread Michael Goldish
For usage details see docstrings in rss_file_transfer.py.
For protocol details see deps/rss.cpp.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/rss_file_transfer.py |  412 +
 1 files changed, 412 insertions(+), 0 deletions(-)
 create mode 100644 client/tests/kvm/rss_file_transfer.py

diff --git a/client/tests/kvm/rss_file_transfer.py 
b/client/tests/kvm/rss_file_transfer.py
new file mode 100644
index 000..3d35df7
--- /dev/null
+++ b/client/tests/kvm/rss_file_transfer.py
@@ -0,0 +1,412 @@
+#!/usr/bin/python
+
+Client for file transfer services offered by RSS (Remote Shell Server).
+
+...@author: Michael Goldish (mgold...@redhat.com)
+...@copyright: 2008-2010 Red Hat Inc.
+
+
+import socket, struct, time, sys, os, glob
+
+# Globals
+BUFSIZE = 65536
+
+# Protocol message constants
+RSS_MAGIC   = 0x525353
+RSS_OK  = 1
+RSS_ERROR   = 2
+RSS_UPLOAD  = 3
+RSS_DOWNLOAD= 4
+RSS_SET_PATH= 5
+RSS_CREATE_FILE = 6
+RSS_CREATE_DIR  = 7
+RSS_LEAVE_DIR   = 8
+RSS_DONE= 9
+
+# See rss.cpp for protocol details.
+
+
+class FileTransferError(Exception):
+pass
+
+
+class FileTransferConnectError(FileTransferError):
+pass
+
+
+class FileTransferTimeoutError(FileTransferError):
+pass
+
+
+class FileTransferProtocolError(FileTransferError):
+pass
+
+
+class FileTransferSendError(FileTransferError):
+pass
+
+
+class FileTransferServerError(FileTransferError):
+pass
+
+
+class FileTransferClient(object):
+
+Connect to a RSS (remote shell server) and transfer files.
+
+
+def __init__(self, address, port, timeout=10):
+
+Connect to a server.
+
+@param address: The server's address
+@param port: The server's port
+@param timeout: Time duration to wait for connection to succeed
+@raise FileTransferConnectError: Raised if the connection fails
+@raise FileTransferProtocolError: Raised if an incorrect magic number
+is received
+
+self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+self._socket.settimeout(timeout)
+try:
+self._socket.connect((address, port))
+except socket.error:
+raise FileTransferConnectError(Could not connect to server)
+if self._receive_msg(timeout) != RSS_MAGIC:
+raise FileTransferProtocolError(Received wrong magic number)
+
+
+def __del__(self):
+self.close()
+
+
+def close(self):
+
+Close the connection.
+
+self._socket.close()
+
+
+def _send(self, str):
+try:
+self._socket.sendall(str)
+except socket.error:
+raise FileTransferSendError(Could not send data to server)
+
+
+def _receive(self, size, timeout=10):
+s = 
+end_time = time.time() + timeout
+while size:
+try:
+self._socket.settimeout(max(0, end_time - time.time()))
+data = self._socket.recv(min(BUFSIZE, size))
+except socket.timeout:
+raise FileTransferTimeoutError(Timeout expired while 
+   receiving data from server)
+except socket.error:
+raise FileTransferProtocolError(Error receiving data from 
+server)
+if not data:
+raise FileTransferProtocolError(Connection closed 
+unexpectedly)
+s += data
+size -= len(data)
+return s
+
+
+def _send_packet(self, str):
+self._send(struct.pack(=Q, len(str)))
+self._send(str)
+
+
+def _receive_packet(self, timeout=10):
+size = struct.unpack(=Q, self._receive(8))[0]
+return self._receive(size, timeout)
+
+
+def _send_packet_from_file(self, filename, timeout=30):
+self._send(struct.pack(=Q, os.path.getsize(filename)))
+f = open(filename, rb)
+try:
+end_time = time.time() + timeout
+while time.time()  end_time:
+data = f.read(BUFSIZE)
+if not data:
+break
+self._send(data)
+else:
+raise FileTransferTimeoutError(Timeout expired while sending 
+   file %s % filename)
+finally:
+f.close()
+
+
+def _receive_packet_into_file(self, filename, timeout=30):
+size = struct.unpack(=Q, self._receive(8))[0]
+f = open(filename, wb)
+try:
+end_time = time.time() + timeout
+while size:
+try:
+self._socket.settimeout(max(0, end_time - time.time()))
+data = self._socket.recv(min(BUFSIZE, size))
+except

Re: [KVM-AUTOTEST PATCH] [RFC] KVM test: rss.cpp: add file transfer support

2010-06-24 Thread Michael Goldish
On 06/24/2010 02:25 PM, Yaniv Kaul wrote:
  On 6/24/2010 2:03 PM, Michael Goldish wrote:
 Enable RSS to send/receive files and directory trees (recursively).
 
 Are you slowly developing a competitor to STAF
 (http://staf.sourceforge.net/) ?

I think STAF offers much more stuff.  However, rss is well suited to
freshly-installed guests (no setup whatsoever) and offers an interactive
command shell, which is useful for our tests.

 And re. the file transfer protocol, why not use TFTP, instead of
 creating your own protocol?
 Y.

Can TFTP send/receive directory trees recursively?
Also, I got the impression that TFTP isn't as trivial as it sounds, but
I might be wrong.  If it can do what we need, maybe it's a good idea to
give it a try.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] KVM Test: Fix invalid literal bug in ioquit

2010-06-21 Thread Michael Goldish
On 06/21/2010 01:07 PM, Feng Yang wrote:
 Sometime check_cmd could not finish in setting time.
 Then o=, so int(o) will cause ValueError:
 invalid literal for int() with base 10: ''
 So change to check return status.
 
 Signed-off-by: Feng Yang fy...@redhat.com
 ---
  client/tests/kvm/tests/ioquit.py   |6 +++---
  client/tests/kvm/tests_base.cfg.sample |2 +-
  2 files changed, 4 insertions(+), 4 deletions(-)
 
 diff --git a/client/tests/kvm/tests/ioquit.py 
 b/client/tests/kvm/tests/ioquit.py
 index 389a867..8126139 100644
 --- a/client/tests/kvm/tests/ioquit.py
 +++ b/client/tests/kvm/tests/ioquit.py
 @@ -23,13 +23,13 @@ def run_ioquit(test, params, env):
  (s, o) = session.get_command_status_output(bg_cmd, timeout=60)
  check_cmd = params.get(check_cmd)
  (s, o) = session2.get_command_status_output(check_cmd, timeout=60)
 -if int(o) = 0:
 +if s:
  raise error.TestError(Fail to add IO workload for Guest OS)

Please use 'if s != 0' because in case of a timeout s is None.

  logging.info(Sleep for a while)
  time.sleep(random.randrange(30,100))
 -(s, o) = session2.get_command_status_output(check_cmd, timeout=300)
 -if int(o) = 0:
 +(s, o) = session2.get_command_status_output(check_cmd, timeout=60)
 +if s:

Same here.

  logging.info(IO workload finished before the VM was killed)
  logging.info(Kill the virtual machine)
  vm.process.close()
 diff --git a/client/tests/kvm/tests_base.cfg.sample 
 b/client/tests/kvm/tests_base.cfg.sample
 index ce88235..0fd5543 100644
 --- a/client/tests/kvm/tests_base.cfg.sample
 +++ b/client/tests/kvm/tests_base.cfg.sample
 @@ -411,7 +411,7 @@ variants:
  - ioquit:
  type = ioquit
  background_cmd = for i in 1 2 3 4; do (nohup dd if=/dev/urandom 
 of=/tmp/file bs=102400 count=1000 ) done
 -check_cmd = ps -a |grep dd |wc -l
 +check_cmd = ps -a |grep dd
  login_timeout = 360
  
  - qemu_img:

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH] KVM test: kvm_preprocessing.py: test for vm.is_alive() instead of vm.is_dead()

2010-06-21 Thread Michael Goldish
vm.is_alive() verifies that the monitor is responsive, which is required for
taking screendumps.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_preprocessing.py |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/client/tests/kvm/kvm_preprocessing.py 
b/client/tests/kvm/kvm_preprocessing.py
index 1ed4ec2..ee279bd 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -406,7 +406,7 @@ def _take_screendumps(test, params, env):
 
 while True:
 for vm in kvm_utils.env_get_all_vms(env):
-if vm.is_dead():
+if not vm.is_alive():
 continue
 try:
 vm.monitor.screendump(temp_filename)
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH] KVM test: concentrate image and cdrom filename prefixes in tests.cfg.sample

2010-06-21 Thread Michael Goldish
Don't prefix image_name and cdrom at the end of tests_base.cfg.sample.
Instead, do it all in tests.cfg.sample, to make it clearer to users editing
the file.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/tests.cfg.sample  |   10 --
 client/tests/kvm/tests_base.cfg.sample |2 --
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/client/tests/kvm/tests.cfg.sample 
b/client/tests/kvm/tests.cfg.sample
index a55a320..b303686 100644
--- a/client/tests/kvm/tests.cfg.sample
+++ b/client/tests/kvm/tests.cfg.sample
@@ -4,19 +4,17 @@
 include tests_base.cfg
 include cdkeys.cfg
 
-# Modify/comment the following lines if you wish to modify
-# the paths of the image files, ISO files, step files or qemu binaries.
+# Modify/comment the following lines if you wish to modify the paths of the
+# image files, ISO files or qemu binaries.
 #
 # As for the defaults:
 # * qemu and qemu-img are expected to be found under /usr/bin/qemu-kvm and
 #   /usr/bin/qemu-img respectively.
 # * All image files are expected under /tmp/kvm_autotest_root/images/
 # * All iso files are expected under /tmp/kvm_autotest_root/isos/
-# * All step files are expected under /tmp/kvm_autotest_root/steps/
 qemu_img_binary = /usr/bin/qemu-img
-image_name.* ?= /tmp/kvm_autotest_root/
-cdrom.* ?= /tmp/kvm_autotest_root/
-steps ?= /tmp/kvm_autotest_root/
+image_name.* ?= /tmp/kvm_autotest_root/images/
+cdrom.* ?= /tmp/kvm_autotest_root/isos/
 
 # Here are the test sets variants. The variant 'qemu_kvm_windows_quick' is
 # fully commented, the following ones have comments only on noteworthy points
diff --git a/client/tests/kvm/tests_base.cfg.sample 
b/client/tests/kvm/tests_base.cfg.sample
index ec61a5e..2c78cfc 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -1447,6 +1447,4 @@ variants:
 devices_requested = 7
 
 
-image_name.* ?= images/
-cdrom.* ?= isos/
 steps ?= steps/
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH] KVM test: scan_results.py: fix handling of empty result list

2010-06-21 Thread Michael Goldish
If there are no test results, max() tries to operate on an empty sequence
and throws an exception.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/scan_results.py |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/client/tests/kvm/scan_results.py b/client/tests/kvm/scan_results.py
index f7073e4..a339a85 100755
--- a/client/tests/kvm/scan_results.py
+++ b/client/tests/kvm/scan_results.py
@@ -74,7 +74,7 @@ def main(resfiles):
 continue
 results = parse_results(text)
 result_lists.append((resfile, results))
-name_width = max(name_width, max(len(r[0]) for r in results))
+name_width = max([name_width] + [len(r[0]) for r in results])
 
 print_result((Test, Status, Seconds, Info), name_width)
 print_result((, --, ---, ), name_width)
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 01/18] KVM test: kvm_preprocessing.py: allow modifying VM params without restarting

2010-06-17 Thread Michael Goldish
Currently a VM's params are changed before the test only if it's restarted.
This patch allows VM params to be changed when it isn't restarted.  This is
useful for params that can have an effect without a restart, such as
main_monitor: monitors can be switched between tests without restarting, so
that one test talks to the human monitor and the next test talks to the QMP
monitor of the same VM.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_preprocessing.py |9 +++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/client/tests/kvm/kvm_preprocessing.py 
b/client/tests/kvm/kvm_preprocessing.py
index ee3e9b2..17f3a29 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -79,8 +79,13 @@ def preprocess_vm(test, params, env, name):
   restarting it...)
 start_vm = True
 
-if start_vm and not vm.create(name, params, test.bindir, for_migration):
-raise error.TestError(Could not start VM)
+if start_vm:
+# Start the VM (or restart it if it's already up)
+if not vm.create(name, params, test.bindir, for_migration):
+raise error.TestError(Could not start VM)
+else:
+# Don't start the VM, just update its params
+vm.params = params
 
 scrdump_filename = os.path.join(test.debugdir, pre_%s.ppm % name)
 try:
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 02/18] KVM test: kvm.py: suppress exceptions during postprocessing if the test fails

2010-06-17 Thread Michael Goldish
We don't want an exception during postprocessing to mask the exception that
caused the failure.

Also, move abort-on-error handling from kvm_preprocessing.py to kvm.py, and
modify some debug messages.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm.py   |  100 +---
 client/tests/kvm/kvm_preprocessing.py |   14 -
 2 files changed, 65 insertions(+), 49 deletions(-)

diff --git a/client/tests/kvm/kvm.py b/client/tests/kvm/kvm.py
index c6e146d..bab1e6f 100644
--- a/client/tests/kvm/kvm.py
+++ b/client/tests/kvm/kvm.py
@@ -32,49 +32,79 @@ class kvm(test.test):
 self.write_test_keyval({key: params[key]})
 
 # Open the environment file
+logging.info(Unpickling env. You may see some harmless error 
+ messages.)
 env_filename = os.path.join(self.bindir, params.get(env, env))
 env = kvm_utils.load_env(env_filename, {})
-logging.debug(Contents of environment: %s, str(env))
+logging.debug(Contents of environment: %s, env)
+
+test_passed = False
 
 try:
 try:
-# Get the test routine corresponding to the specified test type
-t_type = params.get(type)
-# Verify if we have the correspondent source file for it
-subtest_dir = os.path.join(self.bindir, tests)
-module_path = os.path.join(subtest_dir, %s.py % t_type)
-if not os.path.isfile(module_path):
-raise error.TestError(No %s.py test file found % t_type)
-# Load the test module
-f, p, d = imp.find_module(t_type, [subtest_dir])
-test_module = imp.load_module(t_type, f, p, d)
-f.close()
-
-# Preprocess
 try:
-kvm_preprocessing.preprocess(self, params, env)
-finally:
-kvm_utils.dump_env(env, env_filename)
-# Run the test function
-run_func = getattr(test_module, run_%s % t_type)
-try:
-run_func(self, params, env)
-finally:
-kvm_utils.dump_env(env, env_filename)
+# Get the test routine corresponding to the specified
+# test type
+t_type = params.get(type)
+# Verify if we have the correspondent source file for it
+subtest_dir = os.path.join(self.bindir, tests)
+module_path = os.path.join(subtest_dir, %s.py % t_type)
+if not os.path.isfile(module_path):
+raise error.TestError(No %s.py test file found %
+  t_type)
+# Load the test module
+f, p, d = imp.find_module(t_type, [subtest_dir])
+test_module = imp.load_module(t_type, f, p, d)
+f.close()
 
-except Exception, e:
-logging.error(Test failed: %s, e)
-logging.debug(Postprocessing on error...)
+# Preprocess
+try:
+kvm_preprocessing.preprocess(self, params, env)
+finally:
+kvm_utils.dump_env(env, env_filename)
+# Run the test function
+run_func = getattr(test_module, run_%s % t_type)
+try:
+run_func(self, params, env)
+finally:
+kvm_utils.dump_env(env, env_filename)
+test_passed = True
+
+except Exception, e:
+logging.error(Test failed: %s, e)
+try:
+kvm_preprocessing.postprocess_on_error(
+self, params, env)
+finally:
+kvm_utils.dump_env(env, env_filename)
+raise
+
+finally:
+# Postprocess
 try:
-kvm_preprocessing.postprocess_on_error(self, params, env)
+try:
+kvm_preprocessing.postprocess(self, params, env)
+except Exception, e:
+if test_passed:
+raise
+logging.error(Exception raised during 
+  postprocessing: %s, e)
 finally:
 kvm_utils.dump_env(env, env_filename)
-raise
+logging.debug(Contents of environment: %s, env)
 
-finally:
-# Postprocess
-try:
-kvm_preprocessing.postprocess(self, params, env)
-finally:
-kvm_utils.dump_env(env, env_filename

[KVM-AUTOTEST PATCH 03/18] KVM test: kvm_monitor.py: add convenience method get_event()

2010-06-17 Thread Michael Goldish
get_event() looks for and returns a single event matching the given name,
or None if none is found.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_monitor.py |   12 
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/client/tests/kvm/kvm_monitor.py b/client/tests/kvm/kvm_monitor.py
index 12cf773..c2c6261 100644
--- a/client/tests/kvm/kvm_monitor.py
+++ b/client/tests/kvm/kvm_monitor.py
@@ -566,6 +566,18 @@ class QMPMonitor(Monitor):
 self._lock.release()
 
 
+def get_event(self, name):
+
+Look for an event with the given name in the list of events.
+
+@param name: The name of the event to look for (e.g. 'RESET')
+@return: An event object or None if none is found
+
+for e in self.get_events():
+if e.get(event) == name:
+return e
+
+
 def clear_events(self):
 
 Clear the list of asynchronous events.
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 07/18] KVM test: kvm_preprocessing.py: simplify pre/post_command error handling

2010-06-17 Thread Michael Goldish
Currently the error message appears twice: both in a logging.warn() statement
and in an exception.  Also the error.TestError raised adds unnecessary text to
the exception message, which is informative enough as it is.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_preprocessing.py |   10 --
 1 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/client/tests/kvm/kvm_preprocessing.py 
b/client/tests/kvm/kvm_preprocessing.py
index 84ad7c5..1ed4ec2 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -162,12 +162,10 @@ def process_command(test, params, env, command, 
command_timeout,
 try:
 utils.system(cd %s; %s % (test.bindir, command))
 except error.CmdError, e:
-logging.warn(Custom processing command '%s' failed, output is: %s,
- command, str(e))
-if not command_noncritical:
-raise error.TestError(Custom processing command failed: %s %
-  str(e))
-
+if command_noncritical:
+logging.warn(e)
+else:
+raise
 
 def process(test, params, env, image_func, vm_func):
 
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 09/18] KVM test: kvm_utils.py: add a primitive logging mechanism for kvm_subprocess

2010-06-17 Thread Michael Goldish
Add log_line() which logs a single line to a given file.  The file's path is
given relative to a certain base dir.
Add set_log_dir() which sets the base dir.

This is useful for logging the output of kvm_subprocess.  kvm_subprocess can
take a callback function, which it calls with each line of output it gets from
the running subprocess.  Redirecting kvm_subprocess's output to the regular log
files is done by passing it logging.debug or logging.info.  However, in order
to log to other files, we'd have to pass kvm_subprocess a custom logger method,
e.g. our_custom_logger.debug.  Unfortunately, such methods (called
instancemethods) cannot be pickled, and kvm_subprocess relies on pickling.
This patch offers an easy yet somewhat dirty solution to the problem.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_utils.py |   37 +
 1 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index 1399892..8569ac3 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -732,6 +732,43 @@ def find_free_ports(start_port, end_port, count):
 return ports
 
 
+# An easy way to log lines to files when the logging system can't be used
+
+_open_log_files = {}
+_log_file_dir = /tmp
+
+
+def log_line(filename, line):
+
+Write a line to a file.  '\n' is appended to the line.
+
+@param filename: Path of file to write to, either absolute or relative to
+the dir set by set_log_file_dir().
+@param line: Line to write.
+
+global _open_log_files, _log_file_dir
+if filename not in _open_log_files:
+path = get_path(_log_file_dir, filename)
+try:
+os.makedirs(os.path.dirname(path))
+except OSError:
+pass
+_open_log_files[filename] = open(path, w)
+timestr = time.strftime(%Y-%m-%d %H:%M:%S)
+_open_log_files[filename].write(%s: %s\n % (timestr, line))
+_open_log_files[filename].flush()
+
+
+def set_log_file_dir(dir):
+
+Set the base directory for log files created by log_line().
+
+@param dir: Directory for log files.
+
+global _log_file_dir
+_log_file_dir = dir
+
+
 # The following are miscellaneous utility functions.
 
 def get_path(base_path, user_path):
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 11/18] KVM test: restructure remote_login() and remote_scp()

2010-06-17 Thread Michael Goldish
- Add _remote_login() and _remote_scp() which, instead of taking a command
  line, take an existing session and operate on it.  This is useful for logging
  into existing always-open sessions, such as serial console sessions.

- Merge ssh/telnet/netcat into remote_login().

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_utils.py |  208 +++--
 client/tests/kvm/kvm_vm.py|   11 +--
 2 files changed, 100 insertions(+), 119 deletions(-)

diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index 8569ac3..468e7a8 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -451,142 +451,183 @@ def check_kvm_source_dir(source_dir):
 # The following are functions used for SSH, SCP and Telnet communication with
 # guests.
 
-def remote_login(command, password, prompt, linesep=\n, timeout=10):
+def _remote_login(session, password, prompt, timeout=10):
 
-Log into a remote host (guest) using SSH or Telnet. Run the given command
-using kvm_spawn and provide answers to the questions asked. If timeout
-expires while waiting for output from the child (e.g. a password prompt
-or a shell prompt) -- fail.
+Log into a remote host (guest) using SSH or Telnet.  Wait for questions
+and provide answers.  If timeout expires while waiting for output from the
+child (e.g. a password prompt or a shell prompt) -- fail.
 
 @brief: Log into a remote host (guest) using SSH or Telnet.
 
-@param command: The command to execute (e.g. ssh r...@localhost)
+@param session: A kvm_expect or kvm_shell_session instance to operate on
 @param password: The password to send in reply to a password prompt
 @param prompt: The shell prompt that indicates a successful login
-@param linesep: The line separator to send instead of \\n
-(sometimes \\r\\n is required)
 @param timeout: The maximal time duration (in seconds) to wait for each
 step of the login procedure (i.e. the Are you sure prompt, the
 password prompt, the shell prompt, etc)
 
-@return Return the kvm_spawn object on success and None on failure.
+@return: True on success and False otherwise.
 
-sub = kvm_subprocess.kvm_shell_session(command,
-   linesep=linesep,
-   prompt=prompt)
-
 password_prompt_count = 0
 
-logging.debug(Trying to login with command '%s' % command)
-
 while True:
-(match, text) = sub.read_until_last_line_matches(
+(match, text) = session.read_until_last_line_matches(
 [r[Aa]re you sure, r[Pp]assword:\s*$, r^\s*[Ll]ogin:\s*$,
  r[Cc]onnection.*closed, r[Cc]onnection.*refused,
  r[Pp]lease wait, prompt],
  timeout=timeout, internal_timeout=0.5)
 if match == 0:  # Are you sure you want to continue connecting
 logging.debug(Got 'Are you sure...'; sending 'yes')
-sub.sendline(yes)
+session.sendline(yes)
 continue
 elif match == 1:  # password:
 if password_prompt_count == 0:
 logging.debug(Got password prompt; sending '%s' % password)
-sub.sendline(password)
+session.sendline(password)
 password_prompt_count += 1
 continue
 else:
 logging.debug(Got password prompt again)
-sub.close()
-return None
+return False
 elif match == 2:  # login:
 logging.debug(Got unexpected login prompt)
-sub.close()
-return None
+return False
 elif match == 3:  # Connection closed
 logging.debug(Got 'Connection closed')
-sub.close()
-return None
+return False
 elif match == 4:  # Connection refused
 logging.debug(Got 'Connection refused')
-sub.close()
-return None
+return False
 elif match == 5:  # Please wait
 logging.debug(Got 'Please wait')
 timeout = 30
 continue
 elif match == 6:  # prompt
 logging.debug(Got shell prompt -- logged in)
-return sub
+return session
 else:  # match == None
 logging.debug(Timeout elapsed or process terminated)
-sub.close()
-return None
+return False
 
 
-def remote_scp(command, password, transfer_timeout=600, login_timeout=10):
+def _remote_scp(session, password, transfer_timeout=600, login_timeout=10):
 
-Run the given command using kvm_spawn and provide answers to the questions
-asked. If transfer_timeout expires while waiting for the transfer to
-complete, fail. If login_timeout expires while waiting for output from

[KVM-AUTOTEST PATCH 05/18] KVM test: check for RESET QMP events in the system_reset test

2010-06-17 Thread Michael Goldish
If the VM has QMP monitors and no such events are found, fail.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_test_utils.py |   14 +-
 1 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/client/tests/kvm/kvm_test_utils.py 
b/client/tests/kvm/kvm_test_utils.py
index 9fdea87..7358589 100644
--- a/client/tests/kvm/kvm_test_utils.py
+++ b/client/tests/kvm/kvm_test_utils.py
@@ -80,14 +80,26 @@ def reboot(vm, session, method=shell, 
sleep_before_reset=10, nic_index=0,
 if method == shell:
 # Send a reboot command to the guest's shell
 session.sendline(vm.get_params().get(reboot_command))
-logging.info(Reboot command sent. Waiting for guest to go down)
+logging.info(Reboot command sent. Waiting for guest to go down...)
 elif method == system_reset:
 # Sleep for a while before sending the command
 time.sleep(sleep_before_reset)
+# Clear the event list of all QMP monitors
+monitors = [m for m in vm.monitors if m.protocol == qmp]
+for m in monitors:
+m.clear_events()
 # Send a system_reset monitor command
 vm.monitor.cmd(system_reset)
 logging.info(Monitor command system_reset sent. Waiting for guest to 
  go down...)
+# Look for RESET QMP events
+time.sleep(1)
+for m in monitors:
+if not m.get_event(RESET):
+raise error.TestFail(RESET QMP event not received after 
+ system_reset (monitor '%s') % m.name)
+else:
+logging.info(RESET QMP event received)
 else:
 logging.error(Unknown reboot method: %s, method)
 
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 10/18] KVM test: add the auto_close option to all kvm_subprocess classes

2010-06-17 Thread Michael Goldish
Allow all kvm_subprocess classes (kvm_spawn, kvm_tail, kvm_expect,
kvm_shell_session) to close automatically if auto_close is given and True.
By default auto_close if False for all classes except kvm_shell_session,
for which it is True by default.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_subprocess.py |   50 +---
 1 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/client/tests/kvm/kvm_subprocess.py 
b/client/tests/kvm/kvm_subprocess.py
index 2d70146..73edc5d 100755
--- a/client/tests/kvm/kvm_subprocess.py
+++ b/client/tests/kvm/kvm_subprocess.py
@@ -285,7 +285,8 @@ class kvm_spawn:
 resumes _tail() if needed.
 
 
-def __init__(self, command=None, id=None, echo=False, linesep=\n):
+def __init__(self, command=None, id=None, auto_close=False, echo=False,
+ linesep=\n):
 
 Initialize the class and run command as a child process.
 
@@ -293,6 +294,8 @@ class kvm_spawn:
 server.
 @param id: ID of an already running server, if accessing a running
 server, or None if starting a new one.
+@param auto_close: If True, close() the instance automatically when its
+reference count drops to zero (default False).
 @param echo: Boolean indicating whether echo should be initially
 enabled for the pseudo terminal running the subprocess.  This
 parameter has an effect only when starting a new server.
@@ -316,6 +319,7 @@ class kvm_spawn:
   self.id)
 
 # Remember some attributes
+self.auto_close = auto_close
 self.echo = echo
 self.linesep = linesep
 
@@ -378,7 +382,12 @@ class kvm_spawn:
 def __getinitargs__(self):
 # Save some information when pickling -- will be passed to the
 # constructor upon unpickling
-return (None, self.id, self.echo, self.linesep)
+return (None, self.id, self.auto_close, self.echo, self.linesep)
+
+
+def __del__(self):
+if self.auto_close:
+self.close()
 
 
 def _add_reader(self, reader):
@@ -554,10 +563,9 @@ class kvm_tail(kvm_spawn):
 When this class is unpickled, it automatically resumes reporting output.
 
 
-def __init__(self, command=None, id=None, echo=False, linesep=\n,
- termination_func=None, termination_params=(),
- output_func=None, output_params=(),
- output_prefix=):
+def __init__(self, command=None, id=None, auto_close=False, echo=False,
+ linesep=\n, termination_func=None, termination_params=(),
+ output_func=None, output_params=(), output_prefix=):
 
 Initialize the class and run command as a child process.
 
@@ -565,6 +573,8 @@ class kvm_tail(kvm_spawn):
 server.
 @param id: ID of an already running server, if accessing a running
 server, or None if starting a new one.
+@param auto_close: If True, close() the instance automatically when its
+reference count drops to zero (default False).
 @param echo: Boolean indicating whether echo should be initially
 enabled for the pseudo terminal running the subprocess.  This
 parameter has an effect only when starting a new server.
@@ -587,7 +597,7 @@ class kvm_tail(kvm_spawn):
 self._add_close_hook(kvm_tail._join_thread)
 
 # Init the superclass
-kvm_spawn.__init__(self, command, id, echo, linesep)
+kvm_spawn.__init__(self, command, id, auto_close, echo, linesep)
 
 # Remember some attributes
 self.termination_func = termination_func
@@ -751,10 +761,9 @@ class kvm_expect(kvm_tail):
 It also provides all of kvm_tail's functionality.
 
 
-def __init__(self, command=None, id=None, echo=False, linesep=\n,
- termination_func=None, termination_params=(),
- output_func=None, output_params=(),
- output_prefix=):
+def __init__(self, command=None, id=None, auto_close=False, echo=False,
+ linesep=\n, termination_func=None, termination_params=(),
+ output_func=None, output_params=(), output_prefix=):
 
 Initialize the class and run command as a child process.
 
@@ -762,6 +771,8 @@ class kvm_expect(kvm_tail):
 server.
 @param id: ID of an already running server, if accessing a running
 server, or None if starting a new one.
+@param auto_close: If True, close() the instance automatically when its
+reference count drops to zero (default False).
 @param echo: Boolean indicating whether echo should be initially
 enabled for the pseudo terminal running the subprocess.  This
 parameter has an effect only

[KVM-AUTOTEST PATCH 12/18] KVM test: send username in remote_login()

2010-06-17 Thread Michael Goldish
In order to let the serial console work, we must let the
remote_login() send the username when met the username prompt. This
patch fails the progress if if it met the username prompt twice.

Signed-off-by: Jason Wang jasow...@redhat.com
Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_utils.py |   16 
 1 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index 468e7a8..6750d15 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -451,7 +451,7 @@ def check_kvm_source_dir(source_dir):
 # The following are functions used for SSH, SCP and Telnet communication with
 # guests.
 
-def _remote_login(session, password, prompt, timeout=10):
+def _remote_login(session, username, password, prompt, timeout=10):
 
 Log into a remote host (guest) using SSH or Telnet.  Wait for questions
 and provide answers.  If timeout expires while waiting for output from the
@@ -460,6 +460,7 @@ def _remote_login(session, password, prompt, timeout=10):
 @brief: Log into a remote host (guest) using SSH or Telnet.
 
 @param session: A kvm_expect or kvm_shell_session instance to operate on
+@param username: The username to send in reply to a login prompt
 @param password: The password to send in reply to a password prompt
 @param prompt: The shell prompt that indicates a successful login
 @param timeout: The maximal time duration (in seconds) to wait for each
@@ -469,6 +470,7 @@ def _remote_login(session, password, prompt, timeout=10):
 @return: True on success and False otherwise.
 
 password_prompt_count = 0
+login_prompt_count = 0
 
 while True:
 (match, text) = session.read_until_last_line_matches(
@@ -490,8 +492,14 @@ def _remote_login(session, password, prompt, timeout=10):
 logging.debug(Got password prompt again)
 return False
 elif match == 2:  # login:
-logging.debug(Got unexpected login prompt)
-return False
+if login_prompt_count == 0:
+logging.debug(Got username prompt; sending '%s' % username)
+session.sendline(username)
+login_prompt_count += 1
+continue
+else:
+logging.debug(Got username prompt again)
+return False
 elif match == 3:  # Connection closed
 logging.debug(Got 'Connection closed')
 return False
@@ -596,7 +604,7 @@ def remote_login(client, host, port, username, password, 
prompt, linesep=\n,
 logging.debug(Trying to login with command '%s' % cmd)
 session = kvm_subprocess.kvm_shell_session(cmd, linesep=linesep,
prompt=prompt)
-if _remote_login(session, password, prompt, timeout):
+if _remote_login(session, username, password, prompt, timeout):
 return session
 else:
 session.close()
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 14/18] KVM test: kvm_vm.py: redirect the serial console to a unix socket

2010-06-17 Thread Michael Goldish
Based on Jason Wang's patch.

Signed-off-by: Jason Wang jasow...@redhat.com
Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_vm.py |   13 +
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index c82226d..5012d66 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -203,6 +203,9 @@ class VM:
 def add_qmp_monitor(help, filename):
 return  -qmp unix:'%s',server,nowait % filename
 
+def add_serial(help, filename):
+return  -serial unix:'%s',server,nowait % filename
+
 def add_mem(help, mem):
 return  -m %s % mem
 
@@ -313,6 +316,9 @@ class VM:
 else:
 qemu_cmd += add_human_monitor(help, monitor_filename)
 
+# Add serial console redirection
+qemu_cmd += add_serial(help, self.get_serial_console_filename())
+
 for image_name in kvm_utils.get_sub_dict_names(params, images):
 image_params = kvm_utils.get_sub_dict(params, image_name)
 if image_params.get(boot_drive) == no:
@@ -772,6 +778,13 @@ class VM:
 kvm_utils.get_sub_dict_names(self.params, monitors)]
 
 
+def get_serial_console_filename(self):
+
+Return the serial console filename.
+
+return /tmp/serial-%s % self.instance
+
+
 def get_testlog_filename(self):
 
 Return the testlog filename.
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 17/18] KVM test: kvm_subprocess.py: don't sanitize text before passing it to callbacks

2010-06-17 Thread Michael Goldish
Converting the text to utf-8 seems to cause trouble when converting back (e.g.
when writing to files).  The logging system seems to be fine with unsanitized
text, so let's not sanitize it.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_subprocess.py |6 ++
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/client/tests/kvm/kvm_subprocess.py 
b/client/tests/kvm/kvm_subprocess.py
index 73edc5d..93a8429 100755
--- a/client/tests/kvm/kvm_subprocess.py
+++ b/client/tests/kvm/kvm_subprocess.py
@@ -688,9 +688,7 @@ class kvm_tail(kvm_spawn):
 def print_line(text):
 # Pre-pend prefix and remove trailing whitespace
 text = self.output_prefix + text.rstrip()
-# Sanitize text
-text = text.decode(utf-8, replace)
-# Pass it to output_func
+# Pass text to output_func
 try:
 params = self.output_params + (text,)
 self.output_func(*params)
@@ -888,7 +886,7 @@ class kvm_expect(kvm_tail):
 if str.endswith(\n):
 str = str[:-1]
 for line in str.split(\n):
-print_func(line.decode(utf-8, replace))
+print_func(line)
 data += newdata
 
 done = False
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 18/18] KVM test: log output of all shell sessions and SCP transfers

2010-06-17 Thread Michael Goldish
Use kvm_utils.log_line() to log the output of all shell sessions and SCP
transfers.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_utils.py |   33 ++---
 client/tests/kvm/kvm_vm.py|   15 ---
 2 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index 074fa2c..409804a 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -572,7 +572,7 @@ def _remote_scp(session, password, transfer_timeout=600, 
login_timeout=10):
 
 
 def remote_login(client, host, port, username, password, prompt, linesep=\n,
- timeout=10):
+ log_filename=None, timeout=10):
 
 Log into a remote host (guest) using SSH/Telnet/Netcat.
 
@@ -584,6 +584,7 @@ def remote_login(client, host, port, username, password, 
prompt, linesep=\n,
 @param prompt: Shell prompt (regular expression)
 @param linesep: The line separator to use when sending lines
 (e.g. '\\n' or '\\r\\n')
+@param log_filename: If specified, log all output to this file
 @param timeout: The maximal time duration (in seconds) to wait for
 each step of the login procedure (i.e. the Are you sure prompt
 or the password prompt)
@@ -601,16 +602,21 @@ def remote_login(client, host, port, username, password, 
prompt, linesep=\n,
 else:
 logging.error(Unknown remote shell client: %s % client)
 return
+
 logging.debug(Trying to login with command '%s' % cmd)
 session = kvm_subprocess.kvm_shell_session(cmd, linesep=linesep,
prompt=prompt)
 if _remote_login(session, username, password, prompt, timeout):
+if log_filename:
+session.set_output_func(log_line)
+session.set_output_params((log_filename,))
 return session
 else:
 session.close()
 
 
-def remote_scp(command, password, transfer_timeout=600, login_timeout=10):
+def remote_scp(command, password, log_filename=None, transfer_timeout=600,
+   login_timeout=10):
 
 Transfer file(s) to a remote host (guest) using SCP.
 
@@ -619,6 +625,7 @@ def remote_scp(command, password, transfer_timeout=600, 
login_timeout=10):
 @param command: The command to execute
 (e.g. scp -r foobar r...@localhost:/tmp/).
 @param password: The password to send in reply to a password prompt.
+@param log_filename: If specified, log all output to this file
 @param transfer_timeout: The time duration (in seconds) to wait for the
 transfer to complete.
 @param login_timeout: The maximal time duration (in seconds) to wait for
@@ -629,7 +636,17 @@ def remote_scp(command, password, transfer_timeout=600, 
login_timeout=10):
 
 logging.debug(Trying to SCP with command '%s', timeout %ss,
   command, transfer_timeout)
-session = kvm_subprocess.kvm_expect(command)
+
+if log_filename:
+output_func = log_line
+output_params = (log_filename,)
+else:
+output_func = None
+output_params = ()
+
+session = kvm_subprocess.kvm_expect(command,
+output_func=output_func,
+output_params=output_params)
 try:
 return _remote_scp(session, password, transfer_timeout, login_timeout)
 finally:
@@ -637,7 +654,7 @@ def remote_scp(command, password, transfer_timeout=600, 
login_timeout=10):
 
 
 def scp_to_remote(host, port, username, password, local_path, remote_path,
-  timeout=600):
+  log_filename=None, timeout=600):
 
 Copy files to a remote host (guest).
 
@@ -646,6 +663,7 @@ def scp_to_remote(host, port, username, password, 
local_path, remote_path,
 @param password: Password (if required)
 @param local_path: Path on the local machine where we are copying from
 @param remote_path: Path on the remote machine where we are copying to
+@param log_filename: If specified, log all output to this file
 @param timeout: The time duration (in seconds) to wait for the transfer
 to complete.
 
@@ -654,11 +672,11 @@ def scp_to_remote(host, port, username, password, 
local_path, remote_path,
 command = (scp -v -o UserKnownHostsFile=/dev/null 
-o PreferredAuthentications=password -r -P %s %s %...@%s:%s %
(port, local_path, username, host, remote_path))
-return remote_scp(command, password, timeout)
+return remote_scp(command, password, log_filename, timeout)
 
 
 def scp_from_remote(host, port, username, password, remote_path, local_path,
-timeout=600):
+log_filename=None, timeout=600):
 
 Copy files from a remote host (guest).
 
@@ -667,6 +685,7 @@ def scp_from_remote(host, port, username, password, 
remote_path, local_path

Re: [Autotest] [KVM-AUTOTEST PATCH 13/14] KVM test: kvm_monitor.py: add QMP interface

2010-06-14 Thread Michael Goldish
On 06/14/2010 05:39 AM, Amos Kong wrote:
 On Sun, Jun 13, 2010 at 05:33:44PM +0300, Michael Goldish wrote:
 An initial QMP client implementation.
 Should be fully functional and supports asynchronous events.
 However, most tests must be modified to support it, because it returns output
 in a different format from the human monitor (the human monitor returns 
 strings
 and the QMP one returns dicts or lists).

 To enable QMP, set main_monitor to a monitor whose monitor_type is qmp.

 For example (a single QMP monitor):

 monitors = monitor1
 monitor_type_monitor1 = qmp
 main_monitor = monitor1

 Another example (multiple monitors, both human and QMP):

 monitors = MyMonitor SomeOtherMonitor YetAnotherMonitor   # defines 3 
 monitors
 monitor_type = human# default for all monitors
 monitor_type_SomeOtherMonitor = qmp # applies only to 
 SomeOtherMonitor
 monitor_type_YetAnotherMonitor = qmp# applies only to 
 YetAnotherMonitor
 main_monitor = SomeOtherMonitor # the main monitor is a QMP one, 
 so
 # the test will use QMP

 Note:
 Monitor methods now raise exceptions such as MonitorLockError and 
 QMPCmdError.
 If this turns out to be a bad idea, it shouldn't be hard to revert to the old
 convention of returning a (status, output) tuple.

 Signed-off-by: Michael Goldish mgold...@redhat.com
 ---
  client/tests/kvm/kvm_monitor.py |  275 
 +++
  client/tests/kvm/kvm_vm.py  |6 +-
  2 files changed, 279 insertions(+), 2 deletions(-)

 diff --git a/client/tests/kvm/kvm_monitor.py 
 b/client/tests/kvm/kvm_monitor.py
 index c5cf9c3..76a1a83 100644
 --- a/client/tests/kvm/kvm_monitor.py
 +++ b/client/tests/kvm/kvm_monitor.py
 @@ -6,6 +6,11 @@ Interfaces to the QEMU monitor.
  
  import socket, time, threading, logging
  import kvm_utils
 +try:
 +import json
 +except ImportError:
 +logging.warning(Could not import json module. 
 +QMP monitor functionality disabled.)
  
  
  class MonitorError(Exception):
 @@ -28,6 +33,10 @@ class MonitorProtocolError(MonitorError):
  pass
  
  
 +class QMPCmdError(MonitorError):
 +pass
 +
 +
  class Monitor:
  
  Common code for monitor classes.
 @@ -114,6 +123,8 @@ class HumanMonitor(Monitor):
  suppress_exceptions is False
  @raise MonitorProtocolError: Raised if the initial (qemu) prompt 
 isn't
  found and suppress_exceptions is False
 +@note: Other exceptions may be raised.  See _get_command_output's
 +docstring.
  
  try:
  Monitor.__init__(self, filename)
 @@ -354,3 +365,267 @@ class HumanMonitor(Monitor):
  @return: The command's output
  
  return self._get_command_output(mouse_button %d % state)
 +
 +
 +class QMPMonitor(Monitor):
 +
 +Wraps QMP monitor commands.
 +
 +
 +def __init__(self, filename, suppress_exceptions=False):
 +
 +Connect to the monitor socket and issue the qmp_capabilities command
 +
 +@param filename: Monitor socket filename
 +@raise MonitorConnectError: Raised if the connection fails and
 +suppress_exceptions is False
 +@note: Other exceptions may be raised if the qmp_capabilities 
 command
 +fails.  See _get_command_output's docstring.
 +
 +try:
 +Monitor.__init__(self, filename)
 +
 +self.protocol = qmp
 +self.events = []
 +
 +# Issue qmp_capabilities
 +self._get_command_output(qmp_capabilities)
 +
 +except MonitorError, e:
 +if suppress_exceptions:
 +logging.warn(e)
 +else:
 +raise
 +
 +
 +# Private methods
 +
 +def _build_cmd(self, cmd, args=None):
 +obj = {execute: cmd}
 +if args:
 +obj[arguments] = args
 +return obj
 +
 +
 +def _read_objects(self, timeout=5):
 +
 +Read lines from monitor and try to decode them.
 +Stop when all available lines have been successfully decoded, or 
 when
 +timeout expires.  If any decoded objects are asynchronous events, 
 store
 +them in self.events.  Return all decoded objects.
 +
 +@param timeout: Time to wait for all lines to decode successfully
 +@return: A list of objects
 +
 +s = 
 +objs = []
 +end_time = time.time() + timeout
 +while time.time()  end_time:
 +s += self._recvall()
 +for line in s.splitlines():
 +if not line:
 +continue
 +try:
 +obj = json.loads(line)
 +except:
 +# Found an incomplete or broken line -- keep reading
 +break
 +objs += [obj]
 +else

[KVM-AUTOTEST PATCH v2 1/3] KVM test: add kvm_monitor.py, an interface to QEMU monitors

2010-06-14 Thread Michael Goldish
This module should replace vm.send_monitor_cmd().  Instead of connecting to the
monitor each time a command is issued, this module maintains a continuous
connection to the monitor.  It disconnects when a test terminates and
reconnects as soon as the next test begins (upon unpickling).

It currently contains only an interface to the human monitor.  A QMP interface
will be introduced in a future patch.

Changes from v1:
- Add name parameter to __init__()
- Remove help() method
- Rename help attribute to _help_str to indicate private use
- Rename lock to _lock
- Rename socket to _socket

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_monitor.py |  354 +++
 1 files changed, 354 insertions(+), 0 deletions(-)
 create mode 100644 client/tests/kvm/kvm_monitor.py

diff --git a/client/tests/kvm/kvm_monitor.py b/client/tests/kvm/kvm_monitor.py
new file mode 100644
index 000..27045a4
--- /dev/null
+++ b/client/tests/kvm/kvm_monitor.py
@@ -0,0 +1,354 @@
+
+Interfaces to the QEMU monitor.
+
+...@copyright: 2008-2010 Red Hat Inc.
+
+
+import socket, time, threading, logging
+import kvm_utils
+
+
+class MonitorError(Exception):
+pass
+
+
+class MonitorConnectError(MonitorError):
+pass
+
+
+class MonitorSendError(MonitorError):
+pass
+
+
+class MonitorLockError(MonitorError):
+pass
+
+
+class MonitorProtocolError(MonitorError):
+pass
+
+
+class Monitor:
+
+Common code for monitor classes.
+
+
+def __init__(self, name, filename):
+
+Initialize the instance.
+
+@param name: Monitor identifier (a string)
+@param filename: Monitor socket filename
+@raise MonitorConnectError: Raised if the connection fails
+
+self.name = name
+self.filename = filename
+self._lock = threading.RLock()
+self._socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+self._socket.setblocking(False)
+
+try:
+self._socket.connect(filename)
+except socket.error:
+raise MonitorConnectError(Could not connect to monitor socket)
+
+
+def __del__(self):
+# Automatically close the connection when the instance is garbage
+# collected
+try:
+self._socket.shutdown(socket.SHUT_RDWR)
+except socket.error:
+pass
+self._socket.close()
+
+
+# The following two functions are defined to make sure the state is set
+# exclusively by the constructor call as specified in __getinitargs__().
+
+def __getstate__(self):
+pass
+
+
+def __setstate__(self, state):
+pass
+
+
+def __getinitargs__(self):
+# Save some information when pickling -- will be passed to the
+# constructor upon unpickling
+return self.name, self.filename, True
+
+
+def _acquire_lock(self, timeout=20):
+end_time = time.time() + timeout
+while time.time()  end_time:
+if self._lock.acquire(False):
+return True
+time.sleep(0.05)
+return False
+
+
+def _recvall(self):
+s = 
+while True:
+try:
+data = self._socket.recv(1024)
+except socket.error:
+break
+if not data:
+break
+s += data
+return s
+
+
+class HumanMonitor(Monitor):
+
+Wraps human monitor commands.
+
+
+def __init__(self, name, filename, suppress_exceptions=False):
+
+Connect to the monitor socket and find the (qemu) prompt.
+
+@param name: Monitor identifier (a string)
+@param filename: Monitor socket filename
+@raise MonitorConnectError: Raised if the connection fails and
+suppress_exceptions is False
+@raise MonitorProtocolError: Raised if the initial (qemu) prompt isn't
+found and suppress_exceptions is False
+@note: Other exceptions may be raised.  See _get_command_output's
+docstring.
+
+try:
+Monitor.__init__(self, name, filename)
+
+self.protocol = human
+
+# Find the initial (qemu) prompt
+s, o = self._read_up_to_qemu_prompt(20)
+if not s:
+raise MonitorProtocolError(Could not find (qemu) prompt 
+   after connecting to monitor. 
+   Output so far: %r % o)
+
+# Save the output of 'help' for future use
+self._help_str = self._get_command_output(help)
+
+except MonitorError, e:
+if suppress_exceptions:
+logging.warn(e)
+else:
+raise
+
+
+# Private methods
+
+def _read_up_to_qemu_prompt(self, timeout=20):
+o = 
+end_time = time.time() + timeout
+while time.time()  end_time:
+try

[KVM-AUTOTEST PATCH v2 2/3] KVM test: use new monitor interface

2010-06-14 Thread Michael Goldish
- Add new monitor definition syntax that allows definition of multiple monitors.
  Monitors are now defined like other objects in the config file:

  monitors = MyMonitor SomeOtherMonitor YetAnotherMonitor   # defines 3 
monitors
  monitor_type = human# default for all monitors
  monitor_type_SomeOtherMonitor = qmp # applies only to SomeOtherMonitor
  monitor_type_YetAnotherMonitor = qmp# applies only to 
YetAnotherMonitor
  main_monitor = MyMonitor# defines the main monitor to use
  # in the test

- Use the new syntax in tests_base.cfg.sample.

- Establish monitor connections using kvm_monitor in VM.create().
  Store all monitors in self.monitors.  Store main monitor in self.monitor.

- Replace calls to send_monitor_cmd() with appropriate calls to methods of
  self.monitor (the main monitor).

- For now, ignore the parameter screendump_verbose because currently monitor
  commands are always silent (when successful).

Changes from v1:
- Turn VM.monitor into a property

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_preprocessing.py  |   33 ++--
 client/tests/kvm/kvm_test_utils.py |   35 +--
 client/tests/kvm/kvm_vm.py |  236 +---
 client/tests/kvm/tests/balloon_check.py|   12 +-
 client/tests/kvm/tests/boot_savevm.py  |   41 ++--
 client/tests/kvm/tests/ksm_overcommit.py   |8 +-
 client/tests/kvm/tests/pci_hotplug.py  |   13 +-
 client/tests/kvm/tests/physical_resources_check.py |   40 ++--
 client/tests/kvm/tests/shutdown.py |2 +-
 client/tests/kvm/tests/stepmaker.py|   44 ++--
 client/tests/kvm/tests/steps.py|   12 +-
 client/tests/kvm/tests_base.cfg.sample |7 +-
 12 files changed, 241 insertions(+), 242 deletions(-)

diff --git a/client/tests/kvm/kvm_preprocessing.py 
b/client/tests/kvm/kvm_preprocessing.py
index 76c8268..ee3e9b2 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -1,7 +1,7 @@
 import sys, os, time, commands, re, logging, signal, glob, threading, shutil
 from autotest_lib.client.bin import test, utils
 from autotest_lib.client.common_lib import error
-import kvm_vm, kvm_utils, kvm_subprocess, ppm_utils
+import kvm_vm, kvm_utils, kvm_subprocess, kvm_monitor, ppm_utils
 try:
 import PIL.Image
 except ImportError:
@@ -83,7 +83,11 @@ def preprocess_vm(test, params, env, name):
 raise error.TestError(Could not start VM)
 
 scrdump_filename = os.path.join(test.debugdir, pre_%s.ppm % name)
-vm.send_monitor_cmd(screendump %s % scrdump_filename)
+try:
+if vm.monitor:
+vm.monitor.screendump(scrdump_filename)
+except kvm_monitor.MonitorError, e:
+logging.warn(e)
 
 
 def postprocess_image(test, params):
@@ -117,7 +121,11 @@ def postprocess_vm(test, params, env, name):
 return
 
 scrdump_filename = os.path.join(test.debugdir, post_%s.ppm % name)
-vm.send_monitor_cmd(screendump %s % scrdump_filename)
+try:
+if vm.monitor:
+vm.monitor.screendump(scrdump_filename)
+except kvm_monitor.MonitorError, e:
+logging.warn(e)
 
 if params.get(kill_vm) == yes:
 kill_vm_timeout = float(params.get(kill_vm_timeout, 0))
@@ -356,8 +364,9 @@ def postprocess(test, params, env):
 for vm in kvm_utils.env_get_all_vms(env):
 if not vm.is_dead():
 logging.info(VM '%s' is alive., vm.name)
-logging.info(The monitor unix socket of '%s' is: %s,
- vm.name, vm.monitor_file_name)
+for m in vm.monitors:
+logging.info('%s' has a %s monitor unix socket at: %s,
+ vm.name, m.protocol, m.filename)
 logging.info(The command line used to start '%s' was:\n%s,
  vm.name, vm.make_qemu_command())
 raise error.JobError(Abort requested (%s) % exc_string)
@@ -403,10 +412,6 @@ def _take_screendumps(test, params, env):
  kvm_utils.generate_random_string(6))
 delay = float(params.get(screendump_delay, 5))
 quality = int(params.get(screendump_quality, 30))
-if params.get(screendump_verbose) == 'yes':
-screendump_verbose = True
-else:
-screendump_verbose = False
 
 cache = {}
 
@@ -414,11 +419,11 @@ def _take_screendumps(test, params, env):
 for vm in kvm_utils.env_get_all_vms(env):
 if vm.is_dead():
 continue
-if screendump_verbose:
-vm.send_monitor_cmd(screendump %s % temp_filename)
-else:
-vm.send_monitor_cmd(screendump %s % temp_filename,
-verbose=False)
+try

[KVM-AUTOTEST PATCH v2 3/3] KVM test: kvm_monitor.py: add QMP interface

2010-06-14 Thread Michael Goldish
An initial QMP client implementation.
Should be fully functional and supports asynchronous events.
However, most tests must be modified to support it, because it returns output
in a different format from the human monitor (the human monitor returns strings
and the QMP one returns dicts or lists).

To enable QMP, set main_monitor to a monitor whose monitor_type is qmp.

For example (a single QMP monitor):

monitors = monitor1
monitor_type_monitor1 = qmp
main_monitor = monitor1

Another example (multiple monitors, both human and QMP):

monitors = MyMonitor SomeOtherMonitor YetAnotherMonitor   # defines 3 
monitors
monitor_type = human# default for all monitors
monitor_type_SomeOtherMonitor = qmp # applies only to SomeOtherMonitor
monitor_type_YetAnotherMonitor = qmp# applies only to YetAnotherMonitor
main_monitor = SomeOtherMonitor # the main monitor is a QMP one, so
# the test will use QMP

Note:
Monitor methods now raise exceptions such as MonitorLockError and QMPCmdError.
If this turns out to be a bad idea, it shouldn't be hard to revert to the old
convention of returning a (status, output) tuple.

Changes from v1:
- Upon connection make sure the QMP greeting is received (otherwise raise an
  exception)
- Upon connection make sure the json module is available
- Rename the events attribute to _events to indicate private use
- Use _lock instead of lock
- Use _socket instead of socket

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_monitor.py |  305 +++
 client/tests/kvm/kvm_vm.py  |8 +-
 2 files changed, 310 insertions(+), 3 deletions(-)

diff --git a/client/tests/kvm/kvm_monitor.py b/client/tests/kvm/kvm_monitor.py
index 27045a4..12cf773 100644
--- a/client/tests/kvm/kvm_monitor.py
+++ b/client/tests/kvm/kvm_monitor.py
@@ -6,6 +6,11 @@ Interfaces to the QEMU monitor.
 
 import socket, time, threading, logging
 import kvm_utils
+try:
+import json
+except ImportError:
+logging.warning(Could not import json module. 
+QMP monitor functionality disabled.)
 
 
 class MonitorError(Exception):
@@ -28,6 +33,14 @@ class MonitorProtocolError(MonitorError):
 pass
 
 
+class MonitorNotSupportedError(MonitorError):
+pass
+
+
+class QMPCmdError(MonitorError):
+pass
+
+
 class Monitor:
 
 Common code for monitor classes.
@@ -352,3 +365,295 @@ class HumanMonitor(Monitor):
 @return: The command's output
 
 return self._get_command_output(mouse_button %d % state)
+
+
+class QMPMonitor(Monitor):
+
+Wraps QMP monitor commands.
+
+
+def __init__(self, name, filename, suppress_exceptions=False):
+
+Connect to the monitor socket, read the greeting message and issue the
+qmp_capabilities command.  Also make sure the json module is available.
+
+@param name: Monitor identifier (a string)
+@param filename: Monitor socket filename
+@raise MonitorConnectError: Raised if the connection fails and
+suppress_exceptions is False
+@raise MonitorProtocolError: Raised if the no QMP greeting message is
+received and suppress_exceptions is False
+@raise MonitorNotSupportedError: Raised if json isn't available and
+suppress_exceptions is False
+@note: Other exceptions may be raised if the qmp_capabilities command
+fails.  See _get_command_output's docstring.
+
+try:
+Monitor.__init__(self, name, filename)
+
+self.protocol = qmp
+self._greeting = None
+self._events = []
+
+# Make sure json is available
+try:
+json
+except NameError:
+raise MonitorNotSupportedError(QMP requires the json module 
+   (Python 2.6 and up))
+
+# Read greeting message
+end_time = time.time() + 20
+while time.time()  end_time:
+for obj in self._read_objects():
+if QMP in obj:
+self._greeting = obj[QMP]
+break
+if self._greeting:
+break
+time.sleep(0.1)
+else:
+raise MonitorProtocolError(No QMP greeting message received)
+
+# Issue qmp_capabilities
+self._get_command_output(qmp_capabilities)
+
+except MonitorError, e:
+if suppress_exceptions:
+logging.warn(e)
+else:
+raise
+
+
+# Private methods
+
+def _build_cmd(self, cmd, args=None):
+obj = {execute: cmd}
+if args:
+obj[arguments] = args
+return obj
+
+
+def _read_objects(self, timeout=5):
+
+Read

[KVM-AUTOTEST PATCH 01/14] KVM test: tests_base.cfg.sample: remove inline comments

2010-06-13 Thread Michael Goldish
Inline comments are not supported (yet?) and break the parsing of
tests_base.cfg.sample.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/tests_base.cfg.sample |   12 
 1 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/client/tests/kvm/tests_base.cfg.sample 
b/client/tests/kvm/tests_base.cfg.sample
index ab8922b..84a903b 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -86,22 +86,26 @@ variants:
 initrd = initrd.img
 nic_mode = tap
 variants:
-- cdrom: # install guest from cdrom 
+# Install guest from cdrom 
+- cdrom:
 medium = cdrom
 nic_mode = user
 redirs +=  unattended_install
 kernel =
 initrd = 
-- url: # install guest from http/ftp url
+# Install guest from http/ftp url
+- url:
 medium = url
 extra_params +=  --append ks=floppy
 url = REPLACE_THIS_WITH_TREE_URL
-- nfs: # install guest from nfs nfs_server:nfs_dir
+# Install guest from nfs nfs_server:nfs_dir
+- nfs:
 medium = nfs
 extra_params +=  --append ks=floppy
 nfs_server = REPLACE_THIS_WITH_NFS_SERVER
 nfs_dir = REPLACE_THIS_WITH_NFS_DIRECTORY
-- remote_ks: # install guest with a remote kickstart
+# Install guest with a remote kickstart
+- remote_ks:
 medium = url
 extra_params +=  --append ks=REPLACE_THIS_WITH_URL_OF_KS
 url = REPLACE_THIS_WITH_TREE_URL
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 02/14] KVM test: tests_base.cfg.sample: style modifications

2010-06-13 Thread Michael Goldish
Try to exclude tests as soon as possible.
(Also remove broken linux_s3 exception at the same time.)

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/tests_base.cfg.sample |   22 ++
 1 files changed, 6 insertions(+), 16 deletions(-)

diff --git a/client/tests/kvm/tests_base.cfg.sample 
b/client/tests/kvm/tests_base.cfg.sample
index 84a903b..b302557 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -982,7 +982,7 @@ variants:
 
 # Windows section
 - @Windows:
-no autotest linux_s3 vlan_tag
+no autotest linux_s3 vlan_tag ioquit 
unattended_install.(url|nfs|remote_ks)
 shutdown_command = shutdown /s /f /t 0
 reboot_command = shutdown /r /f /t 0
 status_test_command = echo %errorlevel%
@@ -1368,13 +1368,6 @@ variants:
 md5sum = 9fae22f2666369968a76ef59e9a81ced
 
 
-linux_s3
-only Linux
-
-unattended_install.url|unattended_install.nfs|unattended_install.remote_ks:
-only Linux
-
-
 variants:
 - @up:
 no autotest.npb autotest.tsc
@@ -1414,17 +1407,20 @@ virtio|virtio_blk|e1000|balloon_check:
 variants:
 - @qcow2:
 image_format = qcow2
-post_command =  python scripts/check_image.py;
-remove_image = no
+post_command +=  python scripts/check_image.py;
 post_command_timeout = 600
 post_command_noncritical = yes
+ioquit:
+post_command_noncritical = no
 - vmdk:
+no ioquit
 only Fedora Ubuntu Windows
 only smp2
 only rtl8139
 only acpi
 image_format = vmdk
 - raw:
+no ioquit
 only Fedora Ubuntu Windows
 only smp2
 only rtl8139
@@ -1439,12 +1435,6 @@ variants:
 extra_params +=  -mem-path /mnt/kvm_hugepage
 
 
-ioquit:
-post_command_noncritical = no
-only qcow2
-only Linux
-
-
 variants:
 - @no_pci_assignable:
 pci_assignable = no
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 03/14] KVM test: kvm_utils.py: warn about exceptions raised during unpickling of env

2010-06-13 Thread Michael Goldish
Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_utils.py |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index 0da7015..82ecb77 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -35,7 +35,8 @@ def load_env(filename, default={}):
 return obj
 # Almost any exception can be raised during unpickling, so let's catch
 # them all
-except:
+except Exception, e:
+logging.warn(e)
 return default
 
 
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 07/14] KVM test: kvm_vm.py: correct add_smp() mistake in make_qemu_command()

2010-06-13 Thread Michael Goldish
add_smp() is defined but not used.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_vm.py |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index f65d967..039fbff 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -350,7 +350,7 @@ class VM:
 
 smp = params.get(smp)
 if smp:
-qemu_cmd +=  -smp %s % smp
+qemu_cmd += add_smp(help, smp)
 
 iso = params.get(cdrom)
 if iso:
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 04/14] KVM test: kvm_utils.py: remove unnecessary imports

2010-06-13 Thread Michael Goldish
Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_utils.py |3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index 82ecb77..0ea5a8a 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -4,8 +4,7 @@ KVM test utility functions.
 @copyright: 2008-2009 Red Hat Inc.
 
 
-import thread, subprocess, time, string, random, socket, os, signal
-import select, re, logging, commands, cPickle, pty
+import time, string, random, socket, os, signal, re, logging, commands, cPickle
 from autotest_lib.client.bin import utils
 from autotest_lib.client.common_lib import error, logging_config
 import kvm_subprocess
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 09/14] KVM test: remove reference to _screendump_thread at postprocessing

2010-06-13 Thread Michael Goldish
_screendump_thread contains a reference to 'env' which prevents VMs from being
garbage collected.  This makes a difference for multi-iteration tests where
several tests run consecutively in the same process.  Removing the reference
to _screendump_thread also removes a reference to VMs, thus allowing them to be
garbage collected.  This is mainly important for the new monitor classes.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_preprocessing.py |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/client/tests/kvm/kvm_preprocessing.py 
b/client/tests/kvm/kvm_preprocessing.py
index 318bf3f..76c8268 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -285,6 +285,8 @@ def postprocess(test, params, env):
 logging.debug(Terminating screendump thread...)
 _screendump_thread_termination_event.set()
 _screendump_thread.join(10)
+_screendump_thread = None
+_screendump_thread_termination_event = None
 
 # Warn about corrupt PPM files
 for f in glob.glob(os.path.join(test.debugdir, *.ppm)):
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 12/14] KVM test: use new monitor interface

2010-06-13 Thread Michael Goldish
- Add new monitor definition syntax that allows definition of multiple monitors.
  Monitors are now defined like other objects in the config file:

  monitors = MyMonitor SomeOtherMonitor YetAnotherMonitor   # defines 3 
monitors
  monitor_type = human# default for all monitors
  monitor_type_SomeOtherMonitor = qmp # applies only to SomeOtherMonitor
  monitor_type_YetAnotherMonitor = qmp# applies only to 
YetAnotherMonitor
  main_monitor = MyMonitor# defines the main monitor to use
  # in the test

- Use the new syntax in tests_base.cfg.sample.

- Establish monitor connections using kvm_monitor in VM.create().
  Store all monitors in self.monitors.  Store main monitor in self.monitor.

- Replace calls to send_monitor_cmd() with appropriate calls to methods of
  self.monitor (the main monitor).

- For now, ignore the parameter screendump_verbose because currently monitor
  commands are always silent (when successful).

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_preprocessing.py  |   33 ++--
 client/tests/kvm/kvm_test_utils.py |   35 +--
 client/tests/kvm/kvm_vm.py |  226 +---
 client/tests/kvm/tests/balloon_check.py|   12 +-
 client/tests/kvm/tests/boot_savevm.py  |   41 ++--
 client/tests/kvm/tests/ksm_overcommit.py   |8 +-
 client/tests/kvm/tests/pci_hotplug.py  |   13 +-
 client/tests/kvm/tests/physical_resources_check.py |   40 ++--
 client/tests/kvm/tests/shutdown.py |2 +-
 client/tests/kvm/tests/stepmaker.py|   44 ++--
 client/tests/kvm/tests/steps.py|   12 +-
 client/tests/kvm/tests_base.cfg.sample |7 +-
 12 files changed, 232 insertions(+), 241 deletions(-)

diff --git a/client/tests/kvm/kvm_preprocessing.py 
b/client/tests/kvm/kvm_preprocessing.py
index 76c8268..ee3e9b2 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -1,7 +1,7 @@
 import sys, os, time, commands, re, logging, signal, glob, threading, shutil
 from autotest_lib.client.bin import test, utils
 from autotest_lib.client.common_lib import error
-import kvm_vm, kvm_utils, kvm_subprocess, ppm_utils
+import kvm_vm, kvm_utils, kvm_subprocess, kvm_monitor, ppm_utils
 try:
 import PIL.Image
 except ImportError:
@@ -83,7 +83,11 @@ def preprocess_vm(test, params, env, name):
 raise error.TestError(Could not start VM)
 
 scrdump_filename = os.path.join(test.debugdir, pre_%s.ppm % name)
-vm.send_monitor_cmd(screendump %s % scrdump_filename)
+try:
+if vm.monitor:
+vm.monitor.screendump(scrdump_filename)
+except kvm_monitor.MonitorError, e:
+logging.warn(e)
 
 
 def postprocess_image(test, params):
@@ -117,7 +121,11 @@ def postprocess_vm(test, params, env, name):
 return
 
 scrdump_filename = os.path.join(test.debugdir, post_%s.ppm % name)
-vm.send_monitor_cmd(screendump %s % scrdump_filename)
+try:
+if vm.monitor:
+vm.monitor.screendump(scrdump_filename)
+except kvm_monitor.MonitorError, e:
+logging.warn(e)
 
 if params.get(kill_vm) == yes:
 kill_vm_timeout = float(params.get(kill_vm_timeout, 0))
@@ -356,8 +364,9 @@ def postprocess(test, params, env):
 for vm in kvm_utils.env_get_all_vms(env):
 if not vm.is_dead():
 logging.info(VM '%s' is alive., vm.name)
-logging.info(The monitor unix socket of '%s' is: %s,
- vm.name, vm.monitor_file_name)
+for m in vm.monitors:
+logging.info('%s' has a %s monitor unix socket at: %s,
+ vm.name, m.protocol, m.filename)
 logging.info(The command line used to start '%s' was:\n%s,
  vm.name, vm.make_qemu_command())
 raise error.JobError(Abort requested (%s) % exc_string)
@@ -403,10 +412,6 @@ def _take_screendumps(test, params, env):
  kvm_utils.generate_random_string(6))
 delay = float(params.get(screendump_delay, 5))
 quality = int(params.get(screendump_quality, 30))
-if params.get(screendump_verbose) == 'yes':
-screendump_verbose = True
-else:
-screendump_verbose = False
 
 cache = {}
 
@@ -414,11 +419,11 @@ def _take_screendumps(test, params, env):
 for vm in kvm_utils.env_get_all_vms(env):
 if vm.is_dead():
 continue
-if screendump_verbose:
-vm.send_monitor_cmd(screendump %s % temp_filename)
-else:
-vm.send_monitor_cmd(screendump %s % temp_filename,
-verbose=False)
+try:
+vm.monitor.screendump(temp_filename

[KVM-AUTOTEST PATCH 14/14] KVM test: migration: support QMP

2010-06-13 Thread Michael Goldish
If the value returned from a monitor method call is a string, treat it as
human monitor output.  Otherwise treat it as QMP output.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_test_utils.py |   15 ---
 1 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/client/tests/kvm/kvm_test_utils.py 
b/client/tests/kvm/kvm_test_utils.py
index c3b6b8a..9fdea87 100644
--- a/client/tests/kvm/kvm_test_utils.py
+++ b/client/tests/kvm/kvm_test_utils.py
@@ -120,15 +120,24 @@ def migrate(vm, env=None):
 # Helper functions
 def mig_finished():
 o = vm.monitor.info(migrate)
-return status: active not in o
+if isinstance(o, str):
+return status: active not in o
+else:
+return o.get(status) != active
 
 def mig_succeeded():
 o = vm.monitor.info(migrate)
-return status: completed in o
+if isinstance(o, str):
+return status: completed in o
+else:
+return o.get(status) == completed
 
 def mig_failed():
 o = vm.monitor.info(migrate)
-return status: failed in o
+if isinstance(o, str):
+return status: failed in o
+else:
+return o.get(status) == failed
 
 # Clone the source VM and ask the clone to wait for incoming migration
 dest_vm = vm.clone()
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 13/14] KVM test: kvm_monitor.py: add QMP interface

2010-06-13 Thread Michael Goldish
An initial QMP client implementation.
Should be fully functional and supports asynchronous events.
However, most tests must be modified to support it, because it returns output
in a different format from the human monitor (the human monitor returns strings
and the QMP one returns dicts or lists).

To enable QMP, set main_monitor to a monitor whose monitor_type is qmp.

For example (a single QMP monitor):

monitors = monitor1
monitor_type_monitor1 = qmp
main_monitor = monitor1

Another example (multiple monitors, both human and QMP):

monitors = MyMonitor SomeOtherMonitor YetAnotherMonitor   # defines 3 
monitors
monitor_type = human# default for all monitors
monitor_type_SomeOtherMonitor = qmp # applies only to SomeOtherMonitor
monitor_type_YetAnotherMonitor = qmp# applies only to YetAnotherMonitor
main_monitor = SomeOtherMonitor # the main monitor is a QMP one, so
# the test will use QMP

Note:
Monitor methods now raise exceptions such as MonitorLockError and QMPCmdError.
If this turns out to be a bad idea, it shouldn't be hard to revert to the old
convention of returning a (status, output) tuple.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_monitor.py |  275 +++
 client/tests/kvm/kvm_vm.py  |6 +-
 2 files changed, 279 insertions(+), 2 deletions(-)

diff --git a/client/tests/kvm/kvm_monitor.py b/client/tests/kvm/kvm_monitor.py
index c5cf9c3..76a1a83 100644
--- a/client/tests/kvm/kvm_monitor.py
+++ b/client/tests/kvm/kvm_monitor.py
@@ -6,6 +6,11 @@ Interfaces to the QEMU monitor.
 
 import socket, time, threading, logging
 import kvm_utils
+try:
+import json
+except ImportError:
+logging.warning(Could not import json module. 
+QMP monitor functionality disabled.)
 
 
 class MonitorError(Exception):
@@ -28,6 +33,10 @@ class MonitorProtocolError(MonitorError):
 pass
 
 
+class QMPCmdError(MonitorError):
+pass
+
+
 class Monitor:
 
 Common code for monitor classes.
@@ -114,6 +123,8 @@ class HumanMonitor(Monitor):
 suppress_exceptions is False
 @raise MonitorProtocolError: Raised if the initial (qemu) prompt isn't
 found and suppress_exceptions is False
+@note: Other exceptions may be raised.  See _get_command_output's
+docstring.
 
 try:
 Monitor.__init__(self, filename)
@@ -354,3 +365,267 @@ class HumanMonitor(Monitor):
 @return: The command's output
 
 return self._get_command_output(mouse_button %d % state)
+
+
+class QMPMonitor(Monitor):
+
+Wraps QMP monitor commands.
+
+
+def __init__(self, filename, suppress_exceptions=False):
+
+Connect to the monitor socket and issue the qmp_capabilities command
+
+@param filename: Monitor socket filename
+@raise MonitorConnectError: Raised if the connection fails and
+suppress_exceptions is False
+@note: Other exceptions may be raised if the qmp_capabilities command
+fails.  See _get_command_output's docstring.
+
+try:
+Monitor.__init__(self, filename)
+
+self.protocol = qmp
+self.events = []
+
+# Issue qmp_capabilities
+self._get_command_output(qmp_capabilities)
+
+except MonitorError, e:
+if suppress_exceptions:
+logging.warn(e)
+else:
+raise
+
+
+# Private methods
+
+def _build_cmd(self, cmd, args=None):
+obj = {execute: cmd}
+if args:
+obj[arguments] = args
+return obj
+
+
+def _read_objects(self, timeout=5):
+
+Read lines from monitor and try to decode them.
+Stop when all available lines have been successfully decoded, or when
+timeout expires.  If any decoded objects are asynchronous events, store
+them in self.events.  Return all decoded objects.
+
+@param timeout: Time to wait for all lines to decode successfully
+@return: A list of objects
+
+s = 
+objs = []
+end_time = time.time() + timeout
+while time.time()  end_time:
+s += self._recvall()
+for line in s.splitlines():
+if not line:
+continue
+try:
+obj = json.loads(line)
+except:
+# Found an incomplete or broken line -- keep reading
+break
+objs += [obj]
+else:
+# All lines are OK -- stop reading
+break
+time.sleep(0.1)
+# Keep track of asynchronous events
+self.events += [obj for obj in objs if event in obj]
+return objs
+
+
+def _send_command(self

[KVM-AUTOTEST PATCH 11/14] KVM test: add kvm_monitor.py, an interface to QEMU monitors

2010-06-13 Thread Michael Goldish
This module should replace vm.send_monitor_cmd().  Instead of connecting to the
monitor each time a command is issued, this module maintains a continuous
connection to the monitor.  It disconnects when a test terminates and
reconnects as soon as the next test begins (upon unpickling).

It currently contains only an interface to the human monitor.  A QMP interface
will be introduced in a future patch.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_monitor.py |  356 +++
 1 files changed, 356 insertions(+), 0 deletions(-)
 create mode 100644 client/tests/kvm/kvm_monitor.py

diff --git a/client/tests/kvm/kvm_monitor.py b/client/tests/kvm/kvm_monitor.py
new file mode 100644
index 000..c5cf9c3
--- /dev/null
+++ b/client/tests/kvm/kvm_monitor.py
@@ -0,0 +1,356 @@
+
+Interfaces to the QEMU monitor.
+
+...@copyright: 2008-2010 Red Hat Inc.
+
+
+import socket, time, threading, logging
+import kvm_utils
+
+
+class MonitorError(Exception):
+pass
+
+
+class MonitorConnectError(MonitorError):
+pass
+
+
+class MonitorSendError(MonitorError):
+pass
+
+
+class MonitorLockError(MonitorError):
+pass
+
+
+class MonitorProtocolError(MonitorError):
+pass
+
+
+class Monitor:
+
+Common code for monitor classes.
+
+
+def __init__(self, filename):
+
+Initialize the instance.
+
+@param filename: Monitor socket filename.
+@raise MonitorConnectError: Raised if the connection fails
+
+self.filename = filename
+self.lock = threading.RLock()
+self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+self.socket.setblocking(False)
+
+try:
+self.socket.connect(filename)
+except socket.error:
+raise MonitorConnectError(Could not connect to monitor socket)
+
+
+def __del__(self):
+# Automatically close the connection when the instance is garbage
+# collected
+try:
+self.socket.shutdown(socket.SHUT_RDWR)
+except socket.error:
+pass
+self.socket.close()
+
+
+# The following two functions are defined to make sure the state is set
+# exclusively by the constructor call as specified in __getinitargs__().
+
+def __getstate__(self):
+pass
+
+
+def __setstate__(self, state):
+pass
+
+
+def __getinitargs__(self):
+# Save some information when pickling -- will be passed to the
+# constructor upon unpickling
+return self.filename, True
+
+
+def _acquire_lock(self, timeout=20):
+end_time = time.time() + timeout
+while time.time()  end_time:
+if self.lock.acquire(False):
+return True
+time.sleep(0.05)
+return False
+
+
+def _recvall(self):
+s = 
+while True:
+try:
+data = self.socket.recv(1024)
+except socket.error:
+break
+if not data:
+break
+s += data
+return s
+
+
+class HumanMonitor(Monitor):
+
+Wraps human monitor commands.
+
+
+def __init__(self, filename, suppress_exceptions=False):
+
+Connect to the monitor socket and find the (qemu) prompt.
+
+@param filename: Monitor socket filename
+@raise MonitorConnectError: Raised if the connection fails and
+suppress_exceptions is False
+@raise MonitorProtocolError: Raised if the initial (qemu) prompt isn't
+found and suppress_exceptions is False
+
+try:
+Monitor.__init__(self, filename)
+
+self.protocol = human
+
+# Find the initial (qemu) prompt
+s, o = self._read_up_to_qemu_prompt(20)
+if not s:
+raise MonitorProtocolError(Could not find (qemu) prompt 
+   after connecting to monitor. 
+   Output so far: %r % o)
+
+# Save the output of 'help' for future use
+self.help = self._get_command_output(help)
+
+except MonitorError, e:
+if suppress_exceptions:
+logging.warn(e)
+else:
+raise
+
+
+# Private methods
+
+def _read_up_to_qemu_prompt(self, timeout=20):
+o = 
+end_time = time.time() + timeout
+while time.time()  end_time:
+try:
+data = self.socket.recv(1024)
+if not data:
+break
+o += data
+if o.splitlines()[-1].split()[-1] == (qemu):
+return True, \n.join(o.splitlines()[:-1])
+except (socket.error, IndexError):
+time.sleep(0.01)
+return False, \n.join(o.splitlines())
+
+
+def _send_command(self, command):
+
+Send a command

[KVM-AUTOTEST PATCH 08/14] KVM test: kvm_vm.py: use shell quoting in make_qemu_command() where appropriate

2010-06-13 Thread Michael Goldish
Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_vm.py |   36 ++--
 1 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 039fbff..e40abb4 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -204,7 +204,7 @@ class VM:
 return  -name '%s' % name
 
 def add_unix_socket_monitor(help, filename):
-return  -monitor unix:%s,server,nowait % filename
+return  -monitor unix:'%s',server,nowait % filename
 
 def add_mem(help, mem):
 return  -m %s % mem
@@ -214,18 +214,18 @@ class VM:
 
 def add_cdrom(help, filename, index=2):
 if has_option(help, drive):
-return  -drive file=%s,index=%d,media=cdrom % (filename,
- index)
+return  -drive file='%s',index=%d,media=cdrom % (filename,
+   index)
 else:
-return  -cdrom %s % filename
+return  -cdrom '%s' % filename
 
 def add_drive(help, filename, format=None, cache=None, werror=None,
   serial=None, snapshot=False, boot=False):
-cmd =  -drive file=%s % filename
+cmd =  -drive file='%s' % filename
 if format: cmd += ,if=%s % format
 if cache: cmd += ,cache=%s % cache
 if werror: cmd += ,werror=%s % werror
-if serial: cmd += ,serial=%s % serial
+if serial: cmd += ,serial='%s' % serial
 if snapshot: cmd += ,snapshot=on
 if boot: cmd += ,boot=on
 return cmd
@@ -233,23 +233,23 @@ class VM:
 def add_nic(help, vlan, model=None, mac=None):
 cmd =  -net nic,vlan=%d % vlan
 if model: cmd += ,model=%s % model
-if mac: cmd += ,macaddr=%s % mac
+if mac: cmd += ,macaddr='%s' % mac
 return cmd
 
 def add_net(help, vlan, mode, ifname=None, script=None,
 downscript=None):
 cmd =  -net %s,vlan=%d % (mode, vlan)
 if mode == tap:
-if ifname: cmd += ,ifname=%s % ifname
-if script: cmd += ,script=%s % script
-cmd += ,downscript=%s % (downscript or no)
+if ifname: cmd += ,ifname='%s' % ifname
+if script: cmd += ,script='%s' % script
+cmd += ,downscript='%s' % (downscript or no)
 return cmd
 
 def add_floppy(help, filename):
-return  -fda %s % filename
+return  -fda '%s' % filename
 
 def add_tftp(help, filename):
-return  -tftp %s % filename
+return  -tftp '%s' % filename
 
 def add_tcp_redir(help, host_port, guest_port):
 return  -redir tcp:%s::%s % (host_port, guest_port)
@@ -267,22 +267,22 @@ class VM:
 return  -nographic
 
 def add_uuid(help, uuid):
-return  -uuid %s % uuid
+return  -uuid '%s' % uuid
 
 def add_pcidevice(help, host):
-return  -pcidevice host=%s % host
+return  -pcidevice host='%s' % host
 
 def add_initrd(help, filename):
-return  -initrd %s % filename
+return  -initrd '%s' % filename
 
 def add_kernel(help, filename):
-return  -kernel %s % filename
+return  -kernel '%s' % filename
 
 def add_kernel_cmdline(help, cmdline):
-return  -append %s % cmdline
+return  -append '%s' % cmdline
 
 def add_testdev(help, filename):
-return ( -chardev file,id=testlog,path=%s
+return ( -chardev file,id=testlog,path='%s'
  -device testdev,chardev=testlog % filename)
 
 # End of command line option wrappers
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [KVM-AUTOTEST PATCH v2 1/4] KVM test: support -kernel and -append command line options

2010-06-09 Thread Michael Goldish
On 06/09/2010 03:03 PM, Avi Kivity wrote:
 On 06/09/2010 12:50 AM, Michael Goldish wrote:
 Signed-off-by: Michael Goldishmgold...@redhat.com
 ---
   client/tests/kvm/kvm_vm.py |   15 +++
   1 files changed, 15 insertions(+), 0 deletions(-)

 diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
 index 94bacdf..f3c05f3 100755
 --- a/client/tests/kvm/kvm_vm.py
 +++ b/client/tests/kvm/kvm_vm.py
 @@ -268,6 +268,12 @@ class VM:
   def add_pcidevice(help, host):
   return  -pcidevice host=%s % host

 +def add_kernel(help, filename):
 +return  -kernel %s % filename
 +
 +def add_kernel_cmdline(help, cmdline):
 +return  -append %s % cmdline
 +

 
 Shell quoting is a good idea here.  Everywhere else too, in fact, but
 -append is very likely to contain spaces.
 

Thanks.  I'll fix that for all parameters in a new patch.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH v2 1/4] KVM test: support -kernel and -append command line options

2010-06-08 Thread Michael Goldish
Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_vm.py |   15 +++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 94bacdf..f3c05f3 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -268,6 +268,12 @@ class VM:
 def add_pcidevice(help, host):
 return  -pcidevice host=%s % host
 
+def add_kernel(help, filename):
+return  -kernel %s % filename
+
+def add_kernel_cmdline(help, cmdline):
+return  -append %s % cmdline
+
 # End of command line option wrappers
 
 if name is None: name = self.name
@@ -360,6 +366,15 @@ class VM:
 tftp = kvm_utils.get_path(root_dir, tftp)
 qemu_cmd += add_tftp(help, tftp)
 
+kernel = params.get(kernel)
+if kernel:
+kernel = kvm_utils.get_path(root_dir, kernel)
+qemu_cmd += add_kernel(help, kernel)
+
+kernel_cmdline = params.get(kernel_cmdline)
+if kernel_cmdline:
+qemu_cmd += add_kernel_cmdline(help, kernel_cmdline)
+
 for redir_name in kvm_utils.get_sub_dict_names(params, redirs):
 redir_params = kvm_utils.get_sub_dict(params, redir_name)
 guest_port = int(redir_params.get(guest_port))
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH v2 2/4] KVM test: add boolean 'testdev' VM parameter for RHEL-6 style unit tests

2010-06-08 Thread Michael Goldish
Should be set to yes to enable testdev.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_vm.py |   28 
 1 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index f3c05f3..af45a81 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -118,12 +118,16 @@ class VM:
 
 # Find available monitor filename
 while True:
-# The monitor filename should be unique
+# A unique identifier for this VM
 self.instance = (time.strftime(%Y%m%d-%H%M%S-) +
  kvm_utils.generate_random_string(4))
-self.monitor_file_name = os.path.join(/tmp,
-  monitor- + self.instance)
-if not os.path.exists(self.monitor_file_name):
+# Monitor
+self.monitor_file_name = /tmp/monitor- + self.instance
+# Test log for unit tests
+self.testlog_file_name = /tmp/testlog- + self.instance
+# Verify uniqueness
+if True not in map(os.path.exists, [self.monitor_file_name,
+self.testlog_file_name]):
 break
 
 
@@ -274,6 +278,10 @@ class VM:
 def add_kernel_cmdline(help, cmdline):
 return  -append %s % cmdline
 
+def add_testdev(help, filename):
+return ( -chardev file,id=testlog,path=%s
+ -device testdev,chardev=testlog % filename)
+
 # End of command line option wrappers
 
 if name is None: name = self.name
@@ -393,6 +401,9 @@ class VM:
 elif params.get(uuid):
 qemu_cmd += add_uuid(help, params.get(uuid))
 
+if params.get(testdev) == yes:
+qemu_cmd += add_testdev(help, self.testlog_file_name)
+
 # If the PCI assignment step went OK, add each one of the PCI assigned
 # devices to the qemu command line.
 if self.pci_assignable:
@@ -728,10 +739,11 @@ class VM:
 self.pci_assignable.release_devs()
 if self.process:
 self.process.close()
-try:
-os.unlink(self.monitor_file_name)
-except OSError:
-pass
+for f in [self.monitor_file_name, self.testlog_file_name]:
+try:
+os.unlink(f)
+except OSError:
+pass
 
 
 def is_alive(self):
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH v2 3/4] KVM test: add wrapper for RHEL-6 style unittests

2010-06-08 Thread Michael Goldish
Based on Naphtali Sprei's patches.

Changes from v1:
- Determine success/failure by exit status instead of output
- Restructure loop so that vm.is_dead() is called less often
- Copy test log to debugdir/unittest.log
- Change parameters passed to wait_for()

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/tests/unittest.py |   65 
 1 files changed, 65 insertions(+), 0 deletions(-)
 create mode 100644 client/tests/kvm/tests/unittest.py

diff --git a/client/tests/kvm/tests/unittest.py 
b/client/tests/kvm/tests/unittest.py
new file mode 100644
index 000..4570096
--- /dev/null
+++ b/client/tests/kvm/tests/unittest.py
@@ -0,0 +1,65 @@
+import logging, time, os, shutil
+from autotest_lib.client.common_lib import error
+import kvm_subprocess, kvm_test_utils, kvm_utils
+
+
+def run_unittest(test, params, env):
+
+KVM RHEL-6 style unit test:
+1) Resume a stopped VM
+2) Wait for VM to terminate
+3) Make sure qemu's exit status is 0
+
+@param test: kvm test object
+@param params: Dictionary with the test parameters
+@param env: Dictionary with test environment
+
+# Get VM
+vm = kvm_test_utils.get_living_vm(env, params.get(main_vm))
+# Resume VM if stopped
+vm.send_monitor_cmd(cont)
+
+timeout = float(params.get(unittest_timeout, 60))
+
+try:
+if params.get(log_output) == yes:
+# Log test output
+f = open(vm.testlog_file_name)
+logging.info( Test output )
+try:
+end_time = time.time() + timeout
+while time.time()  end_time:
+line = f.readline()
+if line:
+logging.info(line.rstrip())
+elif vm.is_dead():
+break
+else:
+time.sleep(1)
+else:
+raise error.TestFail(Timeout elapsed (%ss) % timeout)
+# Make sure everything has been read and logged
+while True:
+line = f.readline()
+if line:
+logging.info(line.rstrip())
+else:
+break
+finally:
+logging.info( End of test output )
+f.close()
+else:
+# Just wait for the VM to terminate
+logging.info(Waiting for VM to terminate...)
+if not kvm_utils.wait_for(vm.is_dead, timeout):
+raise error.TestFail(Timeout elapsed (%ss) % timeout)
+finally:
+# Copy test log to debugdir/unittest.log
+testlog_path = os.path.join(test.debugdir, unittest.log)
+shutil.copy(vm.testlog_file_name, testlog_path)
+
+# Check qemu's exit status
+status = vm.process.get_status()
+if status != 0:
+raise error.TestFail(qemu exited with status %s (see unittest 
+ output at %s) % (status, testlog_path))
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH v2 4/4] KVM test: add sample RHEL-6 style unittest config file

2010-06-08 Thread Michael Goldish
Based on Naphtali Sprei's patches.

Changes from v1:
- Remove reference_output parameter

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/unittests.cfg.sample |   83 +
 1 files changed, 83 insertions(+), 0 deletions(-)
 create mode 100644 client/tests/kvm/unittests.cfg.sample

diff --git a/client/tests/kvm/unittests.cfg.sample 
b/client/tests/kvm/unittests.cfg.sample
new file mode 100644
index 000..f3b7fcd
--- /dev/null
+++ b/client/tests/kvm/unittests.cfg.sample
@@ -0,0 +1,83 @@
+# Copy this file to tests_base.cfg and edit it.
+#
+# Define the objects we'll be using
+vms = vm1
+
+# Choose the main VM
+main_vm = vm1
+
+# Some preprocessor/postprocessor params
+start_vm = yes
+kill_vm = yes
+kill_vm_gracefully = no
+
+# Screendump specific stuff
+convert_ppm_files_to_png_on_error = yes
+#keep_ppm_files = yes
+#keep_ppm_files_on_error = yes
+take_regular_screendumps = yes
+keep_screendumps_on_error = yes
+screendump_delay = 5
+screendump_quality = 30
+screendump_temp_dir = /dev/shm
+
+# Some default VM params
+qemu_binary = qemu
+qemu_img_binary = qemu-img
+smp = 1
+mem = 512
+display = vnc
+
+# Default scheduler params
+used_cpus = 1
+used_mem = 512
+
+# NIC parameters
+run_tcpdump = no
+
+# Misc
+run_kvm_stat = yes
+
+
+# Tests
+variants:
+# (This variant is defined only in order make all test names begin with 
'unittest.')
+- unittest:
+type = unittest
+unittest_timeout = 600
+log_output = yes
+testdev = yes
+extra_params +=  -S
+
+# All kernels are expected under unittests/
+kernel = unittests/
+
+variants:
+- access:
+kernel += access.flat
+- apic:
+kernel += apic.flat
+- emulator:
+kernel += emulator.flat
+- hypercall:
+kernel += hypercall.flat
+- memtest1:
+kernel += memtest1.flat
+- msr:
+kernel += msr.flat
+- port80:
+kernel += port80.flat
+- realmode:
+kernel += realmode.flat
+- sieve:
+kernel += sieve.flat
+- simple:
+kernel += simple.flat
+- smptest:
+kernel += smptest.flat
+- stringio:
+kernel += stringio.flat
+- tsc:
+kernel += tsc.flat
+- vmexit:
+kernel += vmexit.flat
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH] KVM test: kvm_vm.py: don't require pci_assignable to be defined

2010-06-06 Thread Michael Goldish
Currently to disable PCI device assignment pci_assignable must be explicitly
set to no.  This patch allows it to remain undefined (and adds a warning
message and a comment).

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_vm.py |   47 +--
 1 files changed, 23 insertions(+), 24 deletions(-)

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index af45a81..78cbb16 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -502,49 +502,48 @@ class VM:
 self.uuid = f.read().strip()
 f.close()
 
-if not params.get(pci_assignable) == no:
-pa_type = params.get(pci_assignable)
+# Assign a PCI assignable device
+self.pci_assignable = None
+pa_type = params.get(pci_assignable)
+if pa_type in [vf, pf, mixed]:
 pa_devices_requested = params.get(devices_requested)
 
 # Virtual Functions (VF) assignable devices
 if pa_type == vf:
-pa_driver = params.get(driver)
-pa_driver_option = params.get(driver_option)
-self.pci_assignable = kvm_utils.PciAssignable(type=pa_type,
-driver=pa_driver,
-driver_option=pa_driver_option,
-devices_requested=pa_devices_requested)
+self.pci_assignable = kvm_utils.PciAssignable(
+type=pa_type,
+driver=params.get(driver),
+driver_option=params.get(driver_option),
+devices_requested=pa_devices_requested)
 # Physical NIC (PF) assignable devices
 elif pa_type == pf:
-pa_device_names = params.get(device_names)
-self.pci_assignable = kvm_utils.PciAssignable(type=pa_type,
- names=pa_device_names,
- 
devices_requested=pa_devices_requested)
+self.pci_assignable = kvm_utils.PciAssignable(
+type=pa_type,
+names=params.get(device_names),
+devices_requested=pa_devices_requested)
 # Working with both VF and PF
 elif pa_type == mixed:
-pa_device_names = params.get(device_names)
-pa_driver = params.get(driver)
-pa_driver_option = params.get(driver_option)
-self.pci_assignable = kvm_utils.PciAssignable(type=pa_type,
-driver=pa_driver,
-driver_option=pa_driver_option,
-names=pa_device_names,
-devices_requested=pa_devices_requested)
+self.pci_assignable = kvm_utils.PciAssignable(
+type=pa_type,
+driver=params.get(driver),
+driver_option=params.get(driver_option),
+names=params.get(device_names),
+devices_requested=pa_devices_requested)
 
 self.pa_pci_ids = self.pci_assignable.request_devs()
 
 if self.pa_pci_ids:
-logging.debug(Successfuly assigned devices: %s %
+logging.debug(Successfuly assigned devices: %s,
   self.pa_pci_ids)
 else:
 logging.error(No PCI assignable devices were assigned 
   and 'pci_assignable' is defined to %s 
-  on your config file. Aborting VM creation. 
%
+  on your config file. Aborting VM creation.,
   pa_type)
 return False
 
-else:
-self.pci_assignable = None
+elif pa_type and pa_type != no:
+logging.warn(Unsupported pci_assignable type: %s, pa_type)
 
 # Make qemu command
 qemu_command = self.make_qemu_command()
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 1/4] KVM test: support -kernel and -append command line options

2010-06-03 Thread Michael Goldish
Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_vm.py |   15 +++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 94bacdf..f3c05f3 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -268,6 +268,12 @@ class VM:
 def add_pcidevice(help, host):
 return  -pcidevice host=%s % host
 
+def add_kernel(help, filename):
+return  -kernel %s % filename
+
+def add_kernel_cmdline(help, cmdline):
+return  -append %s % cmdline
+
 # End of command line option wrappers
 
 if name is None: name = self.name
@@ -360,6 +366,15 @@ class VM:
 tftp = kvm_utils.get_path(root_dir, tftp)
 qemu_cmd += add_tftp(help, tftp)
 
+kernel = params.get(kernel)
+if kernel:
+kernel = kvm_utils.get_path(root_dir, kernel)
+qemu_cmd += add_kernel(help, kernel)
+
+kernel_cmdline = params.get(kernel_cmdline)
+if kernel_cmdline:
+qemu_cmd += add_kernel_cmdline(help, kernel_cmdline)
+
 for redir_name in kvm_utils.get_sub_dict_names(params, redirs):
 redir_params = kvm_utils.get_sub_dict(params, redir_name)
 guest_port = int(redir_params.get(guest_port))
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 2/4] KVM test: add boolean 'testdev' VM parameter for RHEL-6 style unit tests

2010-06-03 Thread Michael Goldish
Should be set to yes to enable testdev.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_vm.py |   28 
 1 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index f3c05f3..af45a81 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -118,12 +118,16 @@ class VM:
 
 # Find available monitor filename
 while True:
-# The monitor filename should be unique
+# A unique identifier for this VM
 self.instance = (time.strftime(%Y%m%d-%H%M%S-) +
  kvm_utils.generate_random_string(4))
-self.monitor_file_name = os.path.join(/tmp,
-  monitor- + self.instance)
-if not os.path.exists(self.monitor_file_name):
+# Monitor
+self.monitor_file_name = /tmp/monitor- + self.instance
+# Test log for unit tests
+self.testlog_file_name = /tmp/testlog- + self.instance
+# Verify uniqueness
+if True not in map(os.path.exists, [self.monitor_file_name,
+self.testlog_file_name]):
 break
 
 
@@ -274,6 +278,10 @@ class VM:
 def add_kernel_cmdline(help, cmdline):
 return  -append %s % cmdline
 
+def add_testdev(help, filename):
+return ( -chardev file,id=testlog,path=%s
+ -device testdev,chardev=testlog % filename)
+
 # End of command line option wrappers
 
 if name is None: name = self.name
@@ -393,6 +401,9 @@ class VM:
 elif params.get(uuid):
 qemu_cmd += add_uuid(help, params.get(uuid))
 
+if params.get(testdev) == yes:
+qemu_cmd += add_testdev(help, self.testlog_file_name)
+
 # If the PCI assignment step went OK, add each one of the PCI assigned
 # devices to the qemu command line.
 if self.pci_assignable:
@@ -728,10 +739,11 @@ class VM:
 self.pci_assignable.release_devs()
 if self.process:
 self.process.close()
-try:
-os.unlink(self.monitor_file_name)
-except OSError:
-pass
+for f in [self.monitor_file_name, self.testlog_file_name]:
+try:
+os.unlink(f)
+except OSError:
+pass
 
 
 def is_alive(self):
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 3/4] KVM test: add wrapper for RHEL-6 style unittests

2010-06-03 Thread Michael Goldish
Based on Naphtali Sprei's patches.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/tests/unittest.py |   66 
 1 files changed, 66 insertions(+), 0 deletions(-)
 create mode 100644 client/tests/kvm/tests/unittest.py

diff --git a/client/tests/kvm/tests/unittest.py 
b/client/tests/kvm/tests/unittest.py
new file mode 100644
index 000..c073d04
--- /dev/null
+++ b/client/tests/kvm/tests/unittest.py
@@ -0,0 +1,66 @@
+import logging, time, select, os, difflib
+from autotest_lib.client.common_lib import error
+import kvm_subprocess, kvm_test_utils, kvm_utils
+
+
+def run_unittest(test, params, env):
+
+KVM RHEL-6 style unit test:
+1) Resume a stopped VM
+2) Wait for VM to terminate
+3) Compare output with reference output
+
+@param test: kvm test object
+@param params: Dictionary with the test parameters
+@param env: Dictionary with test environment.
+
+# Get params
+ref_output_filename = params.get(reference_output)
+if not ref_output_filename:
+raise error.TestError(reference_output not specified)
+ref_output_filename = kvm_utils.get_path(test.bindir, ref_output_filename)
+if not os.path.exists(ref_output_filename):
+raise error.TestError(Reference file not found: %s %
+  ref_output_filename)
+timeout = float(params.get(unittest_timeout, 60))
+
+# Get VM
+vm = kvm_test_utils.get_living_vm(env, params.get(main_vm))
+# Resume VM if stopped
+vm.send_monitor_cmd(cont)
+
+if params.get(log_output) == yes:
+# Log test output
+f = open(vm.testlog_file_name)
+logging.info( Test output )
+try:
+end_time = time.time() + timeout
+while time.time()  end_time:
+dead = vm.is_dead()
+line = f.readline()
+if line:
+logging.info(line.rstrip())
+elif dead:
+break
+else:
+time.sleep(1)
+else:
+raise error.TestFail(Timeout elapsed (%ss) % timeout)
+finally:
+logging.info( End of test output )
+f.close()
+else:
+# Just wait for the VM to terminate
+logging.info(Waiting for VM to terminate...)
+if not kvm_utils.wait_for(vm.is_dead, 0, 1, timeout):
+raise error.TestFail(Timeout elapsed (%ss) % timeout)
+
+# Compare output with reference_output
+logging.info(Comparing test output with reference output)
+test_output = open(vm.testlog_file_name, U).readlines()
+ref_output = open(ref_output_filename, U).readlines()
+if test_output != ref_output:
+logging.error(Difference between reference output and test output:)
+for line in difflib.unified_diff(ref_output, test_output):
+logging.error(line.rstrip())
+raise error.TestFail(Test output differs from reference output)
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 4/4] KVM test: add sample RHEL-6 style unittest config file

2010-06-03 Thread Michael Goldish
Based on Naphtali Sprei's patches.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/unittests.cfg.sample |   98 +
 1 files changed, 98 insertions(+), 0 deletions(-)
 create mode 100644 client/tests/kvm/unittests.cfg.sample

diff --git a/client/tests/kvm/unittests.cfg.sample 
b/client/tests/kvm/unittests.cfg.sample
new file mode 100644
index 000..f214337
--- /dev/null
+++ b/client/tests/kvm/unittests.cfg.sample
@@ -0,0 +1,98 @@
+# Copy this file to tests_base.cfg and edit it.
+#
+# Define the objects we'll be using
+vms = vm1
+
+# Choose the main VM
+main_vm = vm1
+
+# Some preprocessor/postprocessor params
+start_vm = yes
+kill_vm = yes
+kill_vm_gracefully = no
+
+# Screendump specific stuff
+convert_ppm_files_to_png_on_error = yes
+#keep_ppm_files = yes
+#keep_ppm_files_on_error = yes
+take_regular_screendumps = yes
+keep_screendumps_on_error = yes
+screendump_delay = 5
+screendump_quality = 30
+screendump_temp_dir = /dev/shm
+
+# Some default VM params
+qemu_binary = qemu
+qemu_img_binary = qemu-img
+smp = 1
+mem = 512
+display = vnc
+
+# Default scheduler params
+used_cpus = 1
+used_mem = 512
+
+# NIC parameters
+run_tcpdump = no
+
+# Misc
+run_kvm_stat = yes
+
+
+# Tests
+variants:
+# (This variant is defined only in order make all test names begin with 
'unittest.')
+- unittest:
+type = unittest
+unittest_timeout = 600
+log_output = yes
+testdev = yes
+extra_params +=  -S
+
+# All kernels and reference output files are expected under unittests/
+kernel = unittests/
+reference_output = unittests/
+
+variants:
+- access:
+kernel += access.flat
+reference_output += access.log.ref
+- apic:
+kernel += apic.flat
+reference_output += apic.log.ref
+- emulator:
+kernel += emulator.flat
+reference_output += emulator.log.ref
+- hypercall:
+kernel += hypercall.flat
+reference_output += hypercall.log.ref
+- memtest1:
+kernel += memtest1.flat
+reference_output += memtest1.log.ref
+- msr:
+kernel += msr.flat
+reference_output += msr.log.ref
+- port80:
+kernel += port80.flat
+reference_output += port80.log.ref
+- realmode:
+kernel += realmode.flat
+reference_output += realmode.log.ref
+- sieve:
+kernel += sieve.flat
+reference_output += sieve.log.ref
+- simple:
+kernel += simple.flat
+reference_output += simple.log.ref
+- smptest:
+kernel += smptest.flat
+reference_output += smptest.log.ref
+- stringio:
+kernel += stringio.flat
+reference_output += stringio.log.ref
+- tsc:
+kernel += tsc.flat
+reference_output += tsc.log.ref
+- vmexit:
+kernel += vmexit.flat
+reference_output += vmexit.log.ref
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Autotest] [v3 PATCH] KVM test: Add a helper to search the panic in the log

2010-05-26 Thread Michael Goldish
On 05/24/2010 10:38 AM, Jason Wang wrote:
 Michael Goldish wrote:
 On 05/19/2010 12:13 PM, Jason Wang wrote:
   
 This checker serves as the post_command to find the panic information
 in the file which contains the content of guest serial console.

 Changes from v2:
 - Put all things into __main__
 - Fix some typos

 Signed-off-by: Jason Wang jasow...@redhat.com
 ---
  client/tests/kvm/scripts/check_serial.py |   24 
  client/tests/kvm/tests_base.cfg.sample   |7 +--
  2 files changed, 29 insertions(+), 2 deletions(-)
  create mode 100644 client/tests/kvm/scripts/check_serial.py

 diff --git a/client/tests/kvm/scripts/check_serial.py 
 b/client/tests/kvm/scripts/check_serial.py
 new file mode 100644
 index 000..6432c27
 --- /dev/null
 +++ b/client/tests/kvm/scripts/check_serial.py
 @@ -0,0 +1,24 @@
 +import os, sys, glob, re
 +
 +
 +class SerialCheckerError(Exception):
 +
 +Simple wrapper for the builtin Exception class.
 +
 +pass
 +
 +
 +if __name__ == __main__:
 +client_dir =  os.environ['AUTODIR']
 +pattern = os.environ['KVM_TEST_search_pattern']
 +shortname = os.environ['KVM_TEST_shortname']
 +debugdir = os.path.join(client_dir, results/default/kvm.%s/debug 
 +% shortname)
 +serial_files = glob.glob(os.path.join(debugdir, 'serial*'))
 +
 +fail = [ f for f in serial_files if
 + re.findall(pattern, file(f).read(), re.I) ]
 +if fail:
 +print %s is found in %s % (pattern, fail)
 +raise SerialCheckerError(Error found during the check, please  
 + check the log)
 diff --git a/client/tests/kvm/tests_base.cfg.sample 
 b/client/tests/kvm/tests_base.cfg.sample
 index e85bb4a..c4e522a 100644
 --- a/client/tests/kvm/tests_base.cfg.sample
 +++ b/client/tests/kvm/tests_base.cfg.sample
 @@ -52,6 +52,10 @@ address_index = 0
  # Misc
  profilers = kvm_stat
  
 +# pattern to search in guest serial console
 +search_pattern = panic
 +post_command = python scripts/check_serial.py
 +post_command_noncritical = no
  
  # Tests
  variants:
 @@ -1324,10 +1328,9 @@ virtio|virtio_blk|e1000|balloon_check:
  variants:
  - @qcow2:
  image_format = qcow2
 -post_command =  python scripts/check_image.py;
 +post_command +=   python scripts/check_image.py
 

 If post_command is empty before executing this line, it'll end up being
   python scripts/... and bash doesn't like that AFAIK.  I think this
 line should be:

 post_command +=  python scripts/check_image.py;

 So if post_command is empty, it becomes  python ...; which is OK, and
 if it isn't empty, it becomes previous command; python ...; (assuming
 the previous command ended with ';').

   
 What I want is to fail the case when panic was found, so how about use
 = like:
 post_command = python scripts/check_image.py;

In that case I think it's best to use

post_command +=  python scripts/check_image.py;

because when commands are separated by ';', the returned exit status is
that of the last command (at least according to my little check).
However, check_image.py must be the last command in the series, so no
other commands should be appended to post_command after it.  If
additional commands are needed they should be pre-pended using =.

The current way of defining post_command is a little limited.  If we
find out that we need to create complex combinations of commands, some
of which are critical and some of which are not, we may want to start
defining commands like we define VMs:

post_commands = cmd1
command_cmd1 = ls
command_critical_cmd1 = no
command_timeout_cmd1 = 10

...

post_commands +=  check_image
command_check_image = python scripts/check_image.py
command_critical_check_image = yes
command_timeout_check_image = 60

This offers a lot of flexibility but is also uglier.

  remove_image = no
  post_command_timeout = 600
 -post_command_noncritical = yes
  - vmdk:
  only Fedora Ubuntu Windows
  only smp2

 ___
 Autotest mailing list
 autot...@test.kernel.org
 http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
 

 --
 To unsubscribe from this list: send the line unsubscribe kvm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
   
 
 --
 To unsubscribe from this list: send the line unsubscribe kvm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Autotest][PATCH] KVM Test: Extend migration test to test unix, exec and migrate_cancel

2010-05-26 Thread Michael Goldish
On 05/26/2010 07:41 AM, Feng Yang wrote:
 Update migrate() in kvm_test_utils.py to support unix, exec protocol
 and migration cancel test.
 Add four migration sub test. There are tcp, unix, exec and mig_cancel.
 migrate_cancel only work in tcp protocol.
 
 Signed-off-by: Feng Yang fy...@redhat.com
 ---
  client/tests/kvm/kvm_test_utils.py |   96 +--
  client/tests/kvm/tests/migration.py|7 ++-
  client/tests/kvm/tests_base.cfg.sample |   11 
  3 files changed, 94 insertions(+), 20 deletions(-)
 
 diff --git a/client/tests/kvm/kvm_test_utils.py 
 b/client/tests/kvm/kvm_test_utils.py
 index 24e2bf5..a3d6217 100644
 --- a/client/tests/kvm/kvm_test_utils.py
 +++ b/client/tests/kvm/kvm_test_utils.py
 @@ -108,13 +108,17 @@ def reboot(vm, session, method=shell, 
 sleep_before_reset=10, nic_index=0,
  return session
  
  
 -def migrate(vm, env=None):
 +def migrate(vm, env=None, mig_timeout=3600, mig_protocol=tcp,
 +mig_cancel=False):
  
  Migrate a VM locally and re-register it in the environment.
  
  @param vm: The VM to migrate.
  @param env: The environment dictionary.  If omitted, the migrated VM will
  not be registered.
 +@param mig_timeout: timeout value for migration.
 +@param mig_protocol: migration protocol
 +@param mig_cancel: Test migrate_cancel or not when protocol is tcp.
  @return: The post-migration VM.
  
  # Helper functions
 @@ -126,6 +130,10 @@ def migrate(vm, env=None):
  s, o = vm.send_monitor_cmd(info migrate)
  return s == 0 and Migration status: completed in o
  
 +def mig_canceled():
 +s, o = vm.send_monitor_cmd(info migrate)
 +return s == 0 and Migration status: cancelled in o
 +
  def mig_failed():
  s, o = vm.send_monitor_cmd(info migrate)
  return s == 0 and Migration status: failed in o
 @@ -135,29 +143,73 @@ def migrate(vm, env=None):
  if not info migrate in o:
  raise error.TestError(Migration is not supported)
  
 -# Clone the source VM and ask the clone to wait for incoming migration
 -dest_vm = vm.clone()
 -if not dest_vm.create(for_migration=True):
 -raise error.TestError(Could not create dest VM)
 -
 -try:
 +if mig_protocol == tcp:
 +migration_port = kvm_utils.find_free_port(5200, 6000)
 +mig_extra_params =  -incoming tcp:0:%d % migration_port
  # Define the migration command
 -cmd = migrate -d tcp:localhost:%d % dest_vm.migration_port
 -logging.debug(Migrating with command: %s % cmd)
 -
 -# Migrate
 -s, o = vm.send_monitor_cmd(cmd)
 -if s:
 -logging.error(Migration command failed (command: %r, output: 
 %r)
 -  % (cmd, o))
 -raise error.TestFail(Migration command failed)
 -
 -# Wait for migration to finish
 -if not kvm_utils.wait_for(mig_finished, 90, 2, 2,
 +mig_cmd = migrate -d tcp:localhost:%d % migration_port
 +if mig_protocol == unix:
 +file = os.path.join(/tmp/, mig_protocol +
 + time.strftime(%Y%m%d-%H%M%S))
 +mig_extra_params =  -incoming unix:%s % file
 +mig_cmd = migrate unix:%s % file
 +
 +if mig_protocol == exec:
 +file = os.path.join(/tmp/, mig_protocol +
 + time.strftime(%Y%m%d-%H%M%S))
 +mig_extra_params =  -incoming \exec: gzip -c -d %s\ % file
 +mig_cmd = migrate \exec:gzip -c  %s\ % file
 +
 +vm.send_monitor_cmd(stop)
 +vm.send_monitor_cmd(mig_cmd, timeout=mig_timeout)
 +if not kvm_utils.wait_for(mig_finished, mig_timeout, 2, 2,
Waiting for migration to finish...):
  raise error.TestFail(Timeout elapsed while waiting for 
 migration 
   to finish)
  
 +# Clone the source VM and ask the clone to wait for incoming migration
 +params = vm.params
 +if params.has_key(extra_params):
 +params[extra_params] += mig_extra_params
 +else:
 +params[extra_params] = mig_extra_params

This looks like a good patch.  I'd like to point out some things though:

1. It is preferable not to add migration params to extra_params.  If we
do that, the preprocessor of the next test will look at the qemu command
(which contains extra_params) to decide if the VM should be restarted,
and the VM will be restarted even when it shouldn't.  If the parameters
of the VM of the next test are exactly identical to those of the current
test, except for migration parameters, then there's no need to restart
the VM.  Including migration parameters in extra_params will cause the
VM to be restarted anyway.

To clarify, an example: let's say there's a migration test with a VM:
image_name = img
mem = 512
smp = 2

and then a reboot test with an identical VM:
image_name = img
mem = 512
smp = 2

There's no 

Re: [Autotest] [PATCH] KVM Test: Make remote_scp() more robust.

2010-05-20 Thread Michael Goldish
On 05/19/2010 05:14 AM, Feng Yang wrote:
 
 - Michael Goldish mgold...@redhat.com wrote:
 
 From: Michael Goldish mgold...@redhat.com
 To: Feng Yang fy...@redhat.com
 Cc: autot...@test.kernel.org, kvm@vger.kernel.org
 Sent: Monday, May 17, 2010 11:05:37 PM GMT +08:00 Beijing / Chongqing / Hong 
 Kong / Urumqi
 Subject: Re: [Autotest] [PATCH] KVM Test: Make remote_scp() more robust.

 On 05/07/2010 01:26 PM, Feng Yang wrote:
 1. In remote_scp(), if SCP connetion stalled for some reason,
 following
 code will be ran.
 else:  # match == None

 logging.debug(Timeout elapsed or process terminated)
 status = sub.get_status()
 sub.close()
 return status == 0
 At this moment, kvm_subprocess server is still running which means
 lock_server_running_filename is still locked. But sub.get_status()
 tries to lock it again.  If kvm_subprocess server keeps running,
 a deadlock will happen. This patch will fix this issue by enable

 Agreed.  It's a mistake (my mistake) to call get_status() on a
 process
 that's still running and isn't expected to terminate soon.  I think
 even
 the docstring of get_status() says that it blocks, so that's expected
 behavior.
 However, there's a simple solution to that, and I don't see why an
 additional timeout is necessary.

 timeout parameter. Update default value for timeout to 600, it
 should
 be enough.

 2. Add -v in scp command to catch more infomation. Also add Exit
 status
 and stalled match prompt in remote_scp().
 Signed-off-by: Feng Yang fy...@redhat.com
 ---
  client/tests/kvm/kvm_utils.py |   36
 
  client/tests/kvm/kvm_vm.py|4 ++--
  2 files changed, 30 insertions(+), 10 deletions(-)

 diff --git a/client/tests/kvm/kvm_utils.py
 b/client/tests/kvm/kvm_utils.py
 index 25f3c8c..3db4dec 100644
 --- a/client/tests/kvm/kvm_utils.py
 +++ b/client/tests/kvm/kvm_utils.py
 @@ -524,7 +524,7 @@ def remote_login(command, password, prompt,
 linesep=\n, timeout=10):
  return None
  
  
 -def remote_scp(command, password, timeout=300, login_timeout=10):
 +def remote_scp(command, password, timeout=600, login_timeout=10):
  
  Run the given command using kvm_spawn and provide answers to
 the questions
  asked. If timeout expires while waiting for the transfer to
 complete ,
 @@ -548,12 +548,18 @@ def remote_scp(command, password, timeout=300,
 login_timeout=10):
  
  password_prompt_count = 0
  _timeout = login_timeout
 +end_time = time.time() + timeout
 +logging.debug(Trying to SCP...)
  
 -logging.debug(Trying to login...)
  
  while True:
 +if end_time = time.time():
 +logging.debug(transfer timeout!)
 +sub.close()
 +return False
  (match, text) = sub.read_until_last_line_matches(
 -[r[Aa]re you sure, r[Pp]assword:\s*$, rlost
 connection],
 +[r[Aa]re you sure, r[Pp]assword:\s*$, rlost
 connection,
 + rExit status, rstalled],
  timeout=_timeout, internal_timeout=0.5)
  if match == 0:  # Are you sure you want to continue
 connecting
  logging.debug(Got 'Are you sure...'; sending 'yes')
 @@ -574,15 +580,29 @@ def remote_scp(command, password, timeout=300,
 login_timeout=10):
  logging.debug(Got 'lost connection')
  sub.close()
  return False
 +elif match == 3: # Exit status

 This check for Exit status is redundant.  When the process
 terminates,
 read_until_last_line_matches() will return None and get_status() will
 return the exit status.
 Here check for Exit status, we can get not only the exit status,but also 
 some useful debug information when exit status is not 0.
 Because we have enable '-v' in scp command.
 
 but read_until_last_line_matches() only return exit status.

You get the same information from read_until_last_line_matches().  It
returns (match, text).  If match is None, and sub.get_status() != 0,
then something bad happened, and then we can print text.


 +sub.close()
 +if Exit status 0 in text:
 +logging.debug(SCP command completed
 successfully)
 +return True
 +else:
 +logging.debug(SCP command fail with exit status
 %s % text)
 +return False
 +elif match == 4: # stalled
 +logging.debug(SCP connection stalled for some
 reason)
 +continue
 +
  else:  # match == None
 -logging.debug(Timeout elapsed or process terminated)
 +if sub.is_alive():
 +continue
 +logging.debug(Process terminated for some reason)
  status = sub.get_status()
  sub.close()
  return status == 0

 To avoid a deadlock, we can simply check if the process is still
 alive
 before calling get_status(), i.e.

 else:  # match == None
 if sub.is_alive

Re: [KVM-AUTOTEST PATCH] KVM test: use command line option wrapper functions

2010-05-20 Thread Michael Goldish
On 05/19/2010 11:25 AM, Feng Yang wrote:
 Hi, Michael
 
 Thanks for your patch.
 We plan add netdev parameter support in make_qemu_command.  Since you are 
 working on this part. Could you add netdev support in your patch? hopeful 
 netdev can be default supported in make_qemu_command if qemu support it. 
 Thanks very much!

Sure, I'll look into it.

 I think the point of this patch is good and we need this kinds of patch.
 But I think we need not add so many new function.  Especially some function 
 only directly return the string and do nothing more.
 This will increase the function call consumption.
 
 
 - Michael Goldish mgold...@redhat.com wrote:
 
 From: Michael Goldish mgold...@redhat.com
 To: autot...@test.kernel.org, kvm@vger.kernel.org
 Cc: Michael Goldish mgold...@redhat.com
 Sent: Monday, May 17, 2010 9:29:35 PM GMT +08:00 Beijing / Chongqing / Hong 
 Kong / Urumqi
 Subject: [KVM-AUTOTEST PATCH] KVM test: use command line option wrapper 
 functions

 In order to support multiple versions of qemu which use different
 command line
 options or syntaxes, wrap all command line options in small helper
 functions,
 which append text to the command line according to the output of 'qemu
 -help'.

 Signed-off-by: Michael Goldish mgold...@redhat.com
 ---
  client/tests/kvm/kvm_vm.py |  198
 ++--
  1 files changed, 135 insertions(+), 63 deletions(-)

 diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
 index 047505a..94bacdf 100755
 --- a/client/tests/kvm/kvm_vm.py
 +++ b/client/tests/kvm/kvm_vm.py
 @@ -186,12 +186,100 @@ class VM:
 nic_model -- string to pass as 'model' parameter for
 this
 NIC (e.g. e1000)
  
 -if name is None:
 -name = self.name
 -if params is None:
 -params = self.params
 -if root_dir is None:
 -root_dir = self.root_dir
 +# Helper function for command line option wrappers
 +def has_option(help, option):
 +return bool(re.search(r^-%s(\s|$) % option, help,
 re.MULTILINE))
 +
 +# Wrappers for all supported qemu command line parameters.
 +# This is meant to allow support for multiple qemu versions.
 +# Each of these functions receives the output of 'qemu -help'
 as a
 +# parameter, and should add the requested command line
 option
 +# accordingly.
 +
 +def add_name(help, name):
 +return  -name '%s' % name
 
 I think we need not add so many new function.  Especially some function only 
 directly return the string and do nothing more.
 This will increase the function call consumption.
 
 +
 +def add_unix_socket_monitor(help, filename):
 +return  -monitor unix:%s,server,nowait % filename
 Same as above
 +
 +def add_mem(help, mem):
 +return  -m %s % mem
 Same as above
 +
 +def add_smp(help, smp):
 +return  -smp %s % smp
 Same as above.

All these helper functions are meant to be extended and modified in the
future.  They're only there to minimize future effort involved in adding
support for new command line syntaxes.
Right now add_smp() just returns  -smp %s, but in the future we may
have to support different syntaxes for -smp, and then add_smp() will
consult the output of 'qemu -help' and return the proper string.
What do you mean by function call consumption?  I don't think these
functions cause a measurable slowdown, and make_qemu_command() is called
very few times, so this really isn't a concern IMO.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Autotest] [v3 PATCH] KVM test: Add a helper to search the panic in the log

2010-05-20 Thread Michael Goldish
On 05/19/2010 12:13 PM, Jason Wang wrote:
 This checker serves as the post_command to find the panic information
 in the file which contains the content of guest serial console.
 
 Changes from v2:
 - Put all things into __main__
 - Fix some typos
 
 Signed-off-by: Jason Wang jasow...@redhat.com
 ---
  client/tests/kvm/scripts/check_serial.py |   24 
  client/tests/kvm/tests_base.cfg.sample   |7 +--
  2 files changed, 29 insertions(+), 2 deletions(-)
  create mode 100644 client/tests/kvm/scripts/check_serial.py
 
 diff --git a/client/tests/kvm/scripts/check_serial.py 
 b/client/tests/kvm/scripts/check_serial.py
 new file mode 100644
 index 000..6432c27
 --- /dev/null
 +++ b/client/tests/kvm/scripts/check_serial.py
 @@ -0,0 +1,24 @@
 +import os, sys, glob, re
 +
 +
 +class SerialCheckerError(Exception):
 +
 +Simple wrapper for the builtin Exception class.
 +
 +pass
 +
 +
 +if __name__ == __main__:
 +client_dir =  os.environ['AUTODIR']
 +pattern = os.environ['KVM_TEST_search_pattern']
 +shortname = os.environ['KVM_TEST_shortname']
 +debugdir = os.path.join(client_dir, results/default/kvm.%s/debug 
 +% shortname)
 +serial_files = glob.glob(os.path.join(debugdir, 'serial*'))
 +
 +fail = [ f for f in serial_files if
 + re.findall(pattern, file(f).read(), re.I) ]
 +if fail:
 +print %s is found in %s % (pattern, fail)
 +raise SerialCheckerError(Error found during the check, please  
 + check the log)
 diff --git a/client/tests/kvm/tests_base.cfg.sample 
 b/client/tests/kvm/tests_base.cfg.sample
 index e85bb4a..c4e522a 100644
 --- a/client/tests/kvm/tests_base.cfg.sample
 +++ b/client/tests/kvm/tests_base.cfg.sample
 @@ -52,6 +52,10 @@ address_index = 0
  # Misc
  profilers = kvm_stat
  
 +# pattern to search in guest serial console
 +search_pattern = panic
 +post_command = python scripts/check_serial.py
 +post_command_noncritical = no
  
  # Tests
  variants:
 @@ -1324,10 +1328,9 @@ virtio|virtio_blk|e1000|balloon_check:
  variants:
  - @qcow2:
  image_format = qcow2
 -post_command =  python scripts/check_image.py;
 +post_command +=   python scripts/check_image.py

If post_command is empty before executing this line, it'll end up being
  python scripts/... and bash doesn't like that AFAIK.  I think this
line should be:

post_command +=  python scripts/check_image.py;

So if post_command is empty, it becomes  python ...; which is OK, and
if it isn't empty, it becomes previous command; python ...; (assuming
the previous command ended with ';').

  remove_image = no
  post_command_timeout = 600
 -post_command_noncritical = yes
  - vmdk:
  only Fedora Ubuntu Windows
  only smp2
 
 ___
 Autotest mailing list
 autot...@test.kernel.org
 http://test.kernel.org/cgi-bin/mailman/listinfo/autotest

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH] KVM test: formatting improvements to scan_results.py

2010-05-17 Thread Michael Goldish
Print results clearly even if test names are very long.
Also, for consistency, use the same quote character everywhere.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/scan_results.py |   49 ++---
 1 files changed, 29 insertions(+), 20 deletions(-)

diff --git a/client/tests/kvm/scan_results.py b/client/tests/kvm/scan_results.py
index f7bafa9..f7073e4 100755
--- a/client/tests/kvm/scan_results.py
+++ b/client/tests/kvm/scan_results.py
@@ -24,19 +24,19 @@ def parse_results(text):
 # Found a START line -- get start time
 if (line.startswith(START) and len(parts) = 5 and
 parts[3].startswith(timestamp)):
-start_time = float(parts[3].split('=')[1])
+start_time = float(parts[3].split(=)[1])
 start_time_list.append(start_time)
 info_list.append()
 
 # Found an END line -- get end time, name and status
 elif (line.startswith(END) and len(parts) = 5 and
   parts[3].startswith(timestamp)):
-end_time = float(parts[3].split('=')[1])
+end_time = float(parts[3].split(=)[1])
 start_time = start_time_list.pop()
 info = info_list.pop()
 test_name = parts[2]
 test_status = parts[0].split()[1]
-# Remove 'kvm.' prefix
+# Remove kvm. prefix
 if test_name.startswith(kvm.):
 test_name = test_name.split(kvm.)[1]
 result_list.append((test_name, test_status,
@@ -50,39 +50,48 @@ def parse_results(text):
 return result_list
 
 
-def print_result(result):
-Nicely print a single Autotest result.
+def print_result(result, name_width):
+
+Nicely print a single Autotest result.
 
-result -- a 4-tuple
+@param result: a 4-tuple
+@param name_width: test name maximum width
 
 if result:
-print '%-48s\t\t%s\t%s\t%s' % tuple(map(str, result))
+format = %%-%ds%%-10s %%-8s %%s % name_width
+print format % result
 
 
 def main(resfiles):
-print_result(('Test', 'Status', 'Seconds', 'Info'))
-print_result(('', '--', '---', ''))
+result_lists = []
+name_width = 40
 
 for resfile in resfiles:
-print '(Result file: %s)' % resfile
 try:
-f = file(resfile)
-text = f.read()
-f.close()
+text = open(resfile).read()
 except IOError:
-print 'Bad result file: %s' % resfile
-return
+print Bad result file: %s % resfile
+continue
 results = parse_results(text)
-map(print_result, results)
+result_lists.append((resfile, results))
+name_width = max(name_width, max(len(r[0]) for r in results))
+
+print_result((Test, Status, Seconds, Info), name_width)
+print_result((, --, ---, ), name_width)
+
+for resfile, results in result_lists:
+print (Result file: %s) % resfile
+for r in results:
+print_result(r, name_width)
 
 
-if __name__ == '__main__':
+if __name__ == __main__:
 import sys, os, glob
 
-resfiles = glob.glob('../../results/default/status*')
+resfiles = glob.glob(../../results/default/status*)
 if len(sys.argv)  1:
-if sys.argv[1] == '-h' or sys.argv[1] == '--help':
-print 'Usage: %s [result files]' % sys.argv[0]
+if sys.argv[1] == -h or sys.argv[1] == --help:
+print Usage: %s [result files] % sys.argv[0]
 sys.exit(0)
 resfiles = sys.argv[1:]
 main(resfiles)
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH] KVM test: use command line option wrapper functions

2010-05-17 Thread Michael Goldish
In order to support multiple versions of qemu which use different command line
options or syntaxes, wrap all command line options in small helper functions,
which append text to the command line according to the output of 'qemu -help'.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_vm.py |  198 ++--
 1 files changed, 135 insertions(+), 63 deletions(-)

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 047505a..94bacdf 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -186,12 +186,100 @@ class VM:
nic_model -- string to pass as 'model' parameter for this
NIC (e.g. e1000)
 
-if name is None:
-name = self.name
-if params is None:
-params = self.params
-if root_dir is None:
-root_dir = self.root_dir
+# Helper function for command line option wrappers
+def has_option(help, option):
+return bool(re.search(r^-%s(\s|$) % option, help, re.MULTILINE))
+
+# Wrappers for all supported qemu command line parameters.
+# This is meant to allow support for multiple qemu versions.
+# Each of these functions receives the output of 'qemu -help' as a
+# parameter, and should add the requested command line option
+# accordingly.
+
+def add_name(help, name):
+return  -name '%s' % name
+
+def add_unix_socket_monitor(help, filename):
+return  -monitor unix:%s,server,nowait % filename
+
+def add_mem(help, mem):
+return  -m %s % mem
+
+def add_smp(help, smp):
+return  -smp %s % smp
+
+def add_cdrom(help, filename, index=2):
+if has_option(help, drive):
+return  -drive file=%s,index=%d,media=cdrom % (filename,
+ index)
+else:
+return  -cdrom %s % filename
+
+def add_drive(help, filename, format=None, cache=None, werror=None,
+  serial=None, snapshot=False, boot=False):
+cmd =  -drive file=%s % filename
+if format: cmd += ,if=%s % format
+if cache: cmd += ,cache=%s % cache
+if werror: cmd += ,werror=%s % werror
+if serial: cmd += ,serial=%s % serial
+if snapshot: cmd += ,snapshot=on
+if boot: cmd += ,boot=on
+return cmd
+
+def add_nic(help, vlan, model=None, mac=None):
+cmd =  -net nic,vlan=%d % vlan
+if model: cmd += ,model=%s % model
+if mac: cmd += ,macaddr=%s % mac
+return cmd
+
+def add_net(help, vlan, mode, ifname=None, script=None,
+downscript=None):
+cmd =  -net %s,vlan=%d % (mode, vlan)
+if mode == tap:
+if ifname: cmd += ,ifname=%s % ifname
+if script: cmd += ,script=%s % script
+cmd += ,downscript=%s % (downscript or no)
+return cmd
+
+def add_floppy(help, filename):
+return  -fda %s % filename
+
+def add_tftp(help, filename):
+return  -tftp %s % filename
+
+def add_tcp_redir(help, host_port, guest_port):
+return  -redir tcp:%s::%s % (host_port, guest_port)
+
+def add_vnc(help, vnc_port):
+return  -vnc :%d % (vnc_port - 5900)
+
+def add_sdl(help):
+if has_option(help, sdl):
+return  -sdl
+else:
+return 
+
+def add_nographic(help):
+return  -nographic
+
+def add_uuid(help, uuid):
+return  -uuid %s % uuid
+
+def add_pcidevice(help, host):
+return  -pcidevice host=%s % host
+
+# End of command line option wrappers
+
+if name is None: name = self.name
+if params is None: params = self.params
+if root_dir is None: root_dir = self.root_dir
+
+qemu_binary = kvm_utils.get_path(root_dir, params.get(qemu_binary,
+  qemu))
+# Get the output of 'qemu -help' (log a message in case this call never
+# returns or causes some other kind of trouble)
+logging.debug(Getting output of 'qemu -help')
+help = commands.getoutput(%s -help % qemu_binary)
 
 # Start constructing the qemu command
 qemu_cmd = 
@@ -199,65 +287,49 @@ class VM:
 if params.get(x11_display):
 qemu_cmd += DISPLAY=%s  % params.get(x11_display)
 # Add the qemu binary
-qemu_cmd += kvm_utils.get_path(root_dir, params.get(qemu_binary,
-qemu))
+qemu_cmd += qemu_binary
 # Add the VM's name
-qemu_cmd +=  -name '%s' % name
+qemu_cmd

[KVM-AUTOTEST PATCH] KVM test: make use of tcpdump optional

2010-05-17 Thread Michael Goldish
To disable tcpdump, set 'run_tcpdump = no' in a config file.
If 'run_tcpdump' isn't set at all, it defaults to 'yes'.

(Currently TAP mode cannot be used without tcpdump.)

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_preprocessing.py  |2 +-
 client/tests/kvm/tests_base.cfg.sample |1 +
 2 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/client/tests/kvm/kvm_preprocessing.py 
b/client/tests/kvm/kvm_preprocessing.py
index 50db65c..e11207a 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -196,7 +196,7 @@ def preprocess(test, params, env):
 if tcpdump in env and not env[tcpdump].is_alive():
 env[tcpdump].close()
 del env[tcpdump]
-if tcpdump not in env:
+if tcpdump not in env and params.get(run_tcpdump, yes) == yes:
 command = /usr/sbin/tcpdump -npvi any 'dst port 68'
 logging.debug(Starting tcpdump (%s)..., command)
 env[tcpdump] = kvm_subprocess.kvm_tail(
diff --git a/client/tests/kvm/tests_base.cfg.sample 
b/client/tests/kvm/tests_base.cfg.sample
index c9dfd0b..1276267 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -46,6 +46,7 @@ nic_mode = user
 #nic_mode = tap
 nic_script = scripts/qemu-ifup
 address_index = 0
+run_tcpdump = yes
 
 # Misc
 run_kvm_stat = yes
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Autotest] [KVM-AUTOTEST PATCH] KVM test: make use of tcpdump optional

2010-05-17 Thread Michael Goldish
On 05/17/2010 04:35 PM, Lucas Meneghel Rodrigues wrote:
 On Mon, 2010-05-17 at 16:29 +0300, Michael Goldish wrote:
 To disable tcpdump, set 'run_tcpdump = no' in a config file.
 If 'run_tcpdump' isn't set at all, it defaults to 'yes'.

 (Currently TAP mode cannot be used without tcpdump.)
 
 Maybe we can just tie tcpdump execution to tap mode - if running on tap
 mode, enable tcpdump, else, disable it. I'd rather prefer this
 approach. 

Checking for nic_mode == 'tap' is incorrect IMO, because nic_mode is a
VM parameter, not a global parameter.
There can be several VMs, some with nic_mode == 'user' and some with
nic_mode == 'tap', e.g.

nic_mode = user # default value for all VMs
nic_mode_vm2 = tap  # specific to vm2 (overrides nic_mode)

so if we went by nic_mode, we wouldn't run tcpdump, which is required by
vm2.

Also, a test is free to start its own VMs.  Consider this (somewhat
unlikely) scenario: nic_mode=user, so vm1 uses user mode, and the test
clones it, changes the clone's mode to tap, and starts the clone.  If we
went by nic_mode, we wouldn't start tcpdump even though the clone needs it.

 Signed-off-by: Michael Goldish mgold...@redhat.com
 ---
  client/tests/kvm/kvm_preprocessing.py  |2 +-
  client/tests/kvm/tests_base.cfg.sample |1 +
  2 files changed, 2 insertions(+), 1 deletions(-)

 diff --git a/client/tests/kvm/kvm_preprocessing.py 
 b/client/tests/kvm/kvm_preprocessing.py
 index 50db65c..e11207a 100644
 --- a/client/tests/kvm/kvm_preprocessing.py
 +++ b/client/tests/kvm/kvm_preprocessing.py
 @@ -196,7 +196,7 @@ def preprocess(test, params, env):
  if tcpdump in env and not env[tcpdump].is_alive():
  env[tcpdump].close()
  del env[tcpdump]
 -if tcpdump not in env:
 +if tcpdump not in env and params.get(run_tcpdump, yes) == yes:
  command = /usr/sbin/tcpdump -npvi any 'dst port 68'
  logging.debug(Starting tcpdump (%s)..., command)
  env[tcpdump] = kvm_subprocess.kvm_tail(
 diff --git a/client/tests/kvm/tests_base.cfg.sample 
 b/client/tests/kvm/tests_base.cfg.sample
 index c9dfd0b..1276267 100644
 --- a/client/tests/kvm/tests_base.cfg.sample
 +++ b/client/tests/kvm/tests_base.cfg.sample
 @@ -46,6 +46,7 @@ nic_mode = user
  #nic_mode = tap
  nic_script = scripts/qemu-ifup
  address_index = 0
 +run_tcpdump = yes
  
  # Misc
  run_kvm_stat = yes
 
 
 --
 To unsubscribe from this list: send the line unsubscribe kvm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Autotest] [PATCH] KVM Test: Make remote_scp() more robust.

2010-05-17 Thread Michael Goldish
On 05/07/2010 01:26 PM, Feng Yang wrote:
 1. In remote_scp(), if SCP connetion stalled for some reason, following
 code will be ran.
 else:  # match == None
 
 logging.debug(Timeout elapsed or process terminated)
 status = sub.get_status()
 sub.close()
 return status == 0
 At this moment, kvm_subprocess server is still running which means
 lock_server_running_filename is still locked. But sub.get_status()
 tries to lock it again.  If kvm_subprocess server keeps running,
 a deadlock will happen. This patch will fix this issue by enable

Agreed.  It's a mistake (my mistake) to call get_status() on a process
that's still running and isn't expected to terminate soon.  I think even
the docstring of get_status() says that it blocks, so that's expected
behavior.
However, there's a simple solution to that, and I don't see why an
additional timeout is necessary.

 timeout parameter. Update default value for timeout to 600, it should
 be enough.
 
 2. Add -v in scp command to catch more infomation. Also add Exit status
 and stalled match prompt in remote_scp().
 Signed-off-by: Feng Yang fy...@redhat.com
 ---
  client/tests/kvm/kvm_utils.py |   36 
  client/tests/kvm/kvm_vm.py|4 ++--
  2 files changed, 30 insertions(+), 10 deletions(-)
 
 diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
 index 25f3c8c..3db4dec 100644
 --- a/client/tests/kvm/kvm_utils.py
 +++ b/client/tests/kvm/kvm_utils.py
 @@ -524,7 +524,7 @@ def remote_login(command, password, prompt, linesep=\n, 
 timeout=10):
  return None
  
  
 -def remote_scp(command, password, timeout=300, login_timeout=10):
 +def remote_scp(command, password, timeout=600, login_timeout=10):
  
  Run the given command using kvm_spawn and provide answers to the 
 questions
  asked. If timeout expires while waiting for the transfer to complete ,
 @@ -548,12 +548,18 @@ def remote_scp(command, password, timeout=300, 
 login_timeout=10):
  
  password_prompt_count = 0
  _timeout = login_timeout
 +end_time = time.time() + timeout
 +logging.debug(Trying to SCP...)
  
 -logging.debug(Trying to login...)
  
  while True:
 +if end_time = time.time():
 +logging.debug(transfer timeout!)
 +sub.close()
 +return False
  (match, text) = sub.read_until_last_line_matches(
 -[r[Aa]re you sure, r[Pp]assword:\s*$, rlost 
 connection],
 +[r[Aa]re you sure, r[Pp]assword:\s*$, rlost connection,
 + rExit status, rstalled],
  timeout=_timeout, internal_timeout=0.5)
  if match == 0:  # Are you sure you want to continue connecting
  logging.debug(Got 'Are you sure...'; sending 'yes')
 @@ -574,15 +580,29 @@ def remote_scp(command, password, timeout=300, 
 login_timeout=10):
  logging.debug(Got 'lost connection')
  sub.close()
  return False
 +elif match == 3: # Exit status

This check for Exit status is redundant.  When the process terminates,
read_until_last_line_matches() will return None and get_status() will
return the exit status.

 +sub.close()
 +if Exit status 0 in text:
 +logging.debug(SCP command completed successfully)
 +return True
 +else:
 +logging.debug(SCP command fail with exit status %s % text)
 +return False
 +elif match == 4: # stalled
 +logging.debug(SCP connection stalled for some reason)
 +continue
 +
  else:  # match == None
 -logging.debug(Timeout elapsed or process terminated)
 +if sub.is_alive():
 +continue
 +logging.debug(Process terminated for some reason)
  status = sub.get_status()
  sub.close()
  return status == 0

To avoid a deadlock, we can simply check if the process is still alive
before calling get_status(), i.e.

else:  # match == None
if sub.is_alive():
logging.debug(Timeout elapsed)
sub.close()
return False
else:
status = sub.get_status()
sub.close()
logging.debug(Process exited with status %d, status)
return status == 0

This looks like the simplest solution to me.

  
  
  def scp_to_remote(host, port, username, password, local_path, remote_path,
 -  timeout=300):
 +  timeout=600):
  
  Copy files to a remote host (guest).
  
 @@ -596,14 +616,14 @@ def scp_to_remote(host, port, username, password, 
 local_path, remote_path,
  
  @return: True on success and False on failure.
  
 -command = (scp -o UserKnownHostsFile=/dev/null 
 +command = (scp -v -o UserKnownHostsFile=/dev/null 
 -o PreferredAuthentications=password -r -P %s %s %...@%s:%s 
 %
 

Re: [PATCH v2 10/10] KVM test: Add a helper to search the panic in the log

2010-05-12 Thread Michael Goldish
On 05/11/2010 12:04 PM, Jason Wang wrote:
 This checker serves as the post_command to find the panic information
 in the file which contains the content of guest serial console.
 
 Signed-off-by: Jason Wang jasow...@redhat.com
 ---
  client/tests/kvm/scripts/check_serial.py |   41 
 ++
  client/tests/kvm/tests_base.cfg.sample   |7 -
  2 files changed, 46 insertions(+), 2 deletions(-)
  create mode 100644 client/tests/kvm/scripts/check_serial.py
 
 diff --git a/client/tests/kvm/scripts/check_serial.py 
 b/client/tests/kvm/scripts/check_serial.py
 new file mode 100644
 index 000..969bbe3
 --- /dev/null
 +++ b/client/tests/kvm/scripts/check_serial.py
 @@ -0,0 +1,41 @@
 +import os, sys, glob, re
 +
 +
 +class SerialCheckerError(Exception):
 +
 +Simple wrapper for the builtin Exception class.
 +
 +pass
 +
 +
 +class SerialChecker(object):
 +
 +Serach the panic or other keywords in the guest serial.
 +
 +def __init__(self):
 +
 +Gets params from environment variables and sets class attributes.
 +
 +client_dir =  os.environ['AUTODIR']
 +self.pattern = os.environ['KVM_TEST_search_pattern']
 +self.shortname = os.environ['KVM_TEST_shortname']
 +self.debugdir = os.path.join(client_dir, 
 results/default/kvm.%s/debug \

I think the final backslash is unnecessary.

 + % self.shortname)
 +self.serial_files = glob.glob(os.path.join(self.debugdir, 'serial*'))
 +
 +
 +def check(self):
 +
 +Check whether the pattern were found in the serial files
 +
 +fail = [ f for f in self.serial_files if
 + re.findall(self.pattern, file(f).read(), re.I) ]
 +if fail:
 +print %s is found in %s % (self.pattern, fail)
 +raise SerialCheckerError(Error found during the check, Please \

Same here.

 +  check the log)
 +
 +
 +if __name__ == __main__:
 +checker = SerialChecker()
 +checker.check()

I wonder why we need a class.  Why not just put all the code here?

 diff --git a/client/tests/kvm/tests_base.cfg.sample 
 b/client/tests/kvm/tests_base.cfg.sample
 index 3c0933e..3ac8f0d 100644
 --- a/client/tests/kvm/tests_base.cfg.sample
 +++ b/client/tests/kvm/tests_base.cfg.sample
 @@ -52,6 +52,10 @@ address_index = 0
  # Misc
  profilers = kvm_stat
  
 +# pattern serach in guest serial console
 +serach_pattern = panic
 +post_command = python scripts/check_serial.py
 +post_command_noncritical = no
  
  # Tests
  variants:
 @@ -1314,10 +1318,9 @@ virtio|virtio_blk|e1000|balloon_check:
  variants:
  - @qcow2:
  image_format = qcow2
 -post_command =  python scripts/check_image.py;
 +post_command =  python scripts/check_image.py; python 
 scripts/check_serial.py
^
This should be +=, because post_command may have been previously
assigned some value.

  remove_image = no
  post_command_timeout = 600
 -post_command_noncritical = yes
  - vmdk:
  only Fedora Ubuntu Windows
  only smp2
 
 --
 To unsubscribe from this list: send the line unsubscribe kvm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Autotest] [PATCH 7/9] KVM test: Introduce the local_login()

2010-05-05 Thread Michael Goldish
On 04/29/2010 02:44 AM, Amos Kong wrote:
 On Wed, Apr 28, 2010 at 03:01:40PM +0300, Michael Goldish wrote:
 On 04/26/2010 01:04 PM, Jason Wang wrote:
 This patch introduces a new method which is used to log into the guest
 through the guest serial console. The serial_mode must be set to
 session in order to make use of this patch.

 In what cases would we want to use this feature?  The serial console is
 not supported by all guests and I'm not sure it supports multiple
 concurrent sessions (does it?), so it's probably not possible to use it
 reliably as a replacement for the regular remote shell servers, or even
 as an alternative variant.
 
 We could not get system log by ssh session when network doesn't work(haven't
 launched, down, unstable, ...) Using serial console can get more useful info.
 Control guest by ssh in some network related testcases isn't credible. It 
 should
 be independent.

Can you provide a usage example?  Which test is going to use this and
how?  Do you think it should be used in existing tests or in new tests only?

  
 
 Signed-off-by: Jason Wang jasow...@redhat.com
 ---
  client/tests/kvm/kvm_vm.py |   25 +
  1 files changed, 25 insertions(+), 0 deletions(-)

 diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
 index 0cdf925..a22893b 100755
 --- a/client/tests/kvm/kvm_vm.py
 +++ b/client/tests/kvm/kvm_vm.py
 @@ -814,7 +814,32 @@ class VM:
  command, ))
  return session
  
 +def local_login(self, timeout=240):
 +
 +Log into the guest via serial console
 +If timeout expires while waiting for output from the guest (e.g. a
 +password prompt or a shell prompt) -- fail.
 +
 +
 +serial_mode = self.params.get(serial_mode)
 +username = self.params.get(username, )
 +password = self.params.get(password, )
 +prompt = self.params.get(shell_prompt, [\#\$])
 +linesep = eval('%s' % self.params.get(shell_linesep, r\n))
  
 +if serial_mode != session:
 +logging.debug(serial_mode is not session)
 +return None
 +else:
 +command = nc -U %s  % self.serial_file_name
 +assist = self.params.get(prompt_assist)
 +session = kvm_utils.remote_login(command, password, prompt, 
 linesep,
 + timeout, , username)
  ^
 You probably meant to pass the prompt assist string to remote_login()
 but instead you're passing .

 +if session:
 +
 session.set_status_test_command(self.params.get(status_test_
 +command, 
 ))
 +return session
 +
  def copy_files_to(self, local_path, remote_path, nic_index=0, 
 timeout=300):
  
  Transfer files to the guest.

 --
 To unsubscribe from this list: send the line unsubscribe kvm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html

 ___
 Autotest mailing list
 autot...@test.kernel.org
 http://test.kernel.org/cgi-bin/mailman/listinfo/autotest

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/9] KVM test: Make the login re suitable for serial console

2010-04-28 Thread Michael Goldish
On 04/26/2010 01:03 PM, Jason Wang wrote:
 Current matching re ^\s*[Ll]ogin:\s*$ is not suitable for the serial
 console, so change it to [Ll]ogin:.
 
 Signed-off-by: Jason Wang jasow...@redhat.com
 ---
  client/tests/kvm/kvm_utils.py |2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)
 
 diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
 index 1ea0852..bb42314 100644
 --- a/client/tests/kvm/kvm_utils.py
 +++ b/client/tests/kvm/kvm_utils.py
 @@ -488,7 +488,7 @@ def remote_login(command, password, prompt, linesep=\n, 
 timeout=10,
  
  while True:
  (match, text) = sub.read_until_last_line_matches(
 -[r[Aa]re you sure, r[Pp]assword:\s*$, 
 r^\s*[Ll]ogin:\s*$,
 +[r[Aa]re you sure, r[Pp]assword:\s*$, r[Ll]ogin:,

This RE will also match

Last login: Wed Apr 28 14:07:28 2010 from localhost.localdomain

so we should probably settle for [Ll]ogin:\s*$.

   r[Cc]onnection.*closed, r[Cc]onnection.*refused,
   r[Pp]lease wait, prompt],
   timeout=timeout, internal_timeout=0.5)
 
 --
 To unsubscribe from this list: send the line unsubscribe kvm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/9] KVM test: Introduce the prompt assist

2010-04-28 Thread Michael Goldish
On 04/26/2010 01:03 PM, Jason Wang wrote:
 Sometimes we need to send an assist string to a session in order to
 get the prompt especially when re-connecting to an already logged
 serial session. This patch send the assist string before doing the
 pattern matching of remote_login.

Can you give an example of a prompt assist string, and a typical usage
example?  What guests require prompt assist strings?

 Signed-off-by: Jason Wang jasow...@redhat.com
 ---
  client/tests/kvm/kvm_utils.py |9 +++--
  1 files changed, 7 insertions(+), 2 deletions(-)
 
 diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
 index 25f3c8c..9adbaee 100644
 --- a/client/tests/kvm/kvm_utils.py
 +++ b/client/tests/kvm/kvm_utils.py
 @@ -451,7 +451,8 @@ def check_kvm_source_dir(source_dir):
  # The following are functions used for SSH, SCP and Telnet communication with
  # guests.
  
 -def remote_login(command, password, prompt, linesep=\n, timeout=10):
 +def remote_login(command, password, prompt, linesep=\n, timeout=10,
 + prompt_assist = None):
 ^ ^
These spaces do not conform with PEP 8.

  
  Log into a remote host (guest) using SSH or Telnet. Run the given command
  using kvm_spawn and provide answers to the questions asked. If timeout
 @@ -468,7 +469,8 @@ def remote_login(command, password, prompt, linesep=\n, 
 timeout=10):
  @param timeout: The maximal time duration (in seconds) to wait for each
  step of the login procedure (i.e. the Are you sure prompt, the
  password prompt, the shell prompt, etc)
 -
 +@prarm prompt_assist: An assistant string sent before the pattern

Typo^

 +matching in order to get the prompt for some kinds of 
 shell_client.
  @return Return the kvm_spawn object on success and None on failure.
  
  sub = kvm_subprocess.kvm_shell_session(command,
 @@ -479,6 +481,9 @@ def remote_login(command, password, prompt, linesep=\n, 
 timeout=10):
  
  logging.debug(Trying to login with command '%s' % command)
  
 +if prompt_assist is not None:
 +sub.sendline(prompt_assist)
 +
  while True:
  (match, text) = sub.read_until_last_line_matches(
  [r[Aa]re you sure, r[Pp]assword:\s*$, 
 r^\s*[Ll]ogin:\s*$,
 
 --
 To unsubscribe from this list: send the line unsubscribe kvm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/9] KVM test: Add the ability to send the username in remote_login()

2010-04-28 Thread Michael Goldish
On 04/26/2010 01:03 PM, Jason Wang wrote:
 In order to let the serial console work, we must let the
 remote_login() send the username when needed.
 
 Signed-off-by: Jason Wang jasow...@redhat.com
 ---
  client/tests/kvm/kvm_utils.py |   14 ++
  1 files changed, 10 insertions(+), 4 deletions(-)
 
 diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
 index 9adbaee..1ea0852 100644
 --- a/client/tests/kvm/kvm_utils.py
 +++ b/client/tests/kvm/kvm_utils.py
 @@ -452,7 +452,7 @@ def check_kvm_source_dir(source_dir):
  # guests.
  
  def remote_login(command, password, prompt, linesep=\n, timeout=10,
 - prompt_assist = None):
 + prompt_assist = None, username = None):
 ^ ^  ^ ^
Same here: PEP 8 says no spaces around keyword arguments or default
values, and pretty much all of the KVM test code conforms with PEP 8, so
let's be consistent.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Autotest] [PATCH 8/9] KVM test: Create the background threads before calling process()

2010-04-28 Thread Michael Goldish
On 04/26/2010 01:04 PM, Jason Wang wrote:
 If the screendump and scrialdump threads are created after the
 process(), we may lose the progress tracking of guest shutting
 down. So this patch creates them before calling process() in preprocess.
 
 Signed-off-by: Jason Wang jasow...@redhat.com
 ---
  client/tests/kvm/kvm_preprocessing.py |5 ++---
  1 files changed, 2 insertions(+), 3 deletions(-)
 
 diff --git a/client/tests/kvm/kvm_preprocessing.py 
 b/client/tests/kvm/kvm_preprocessing.py
 index 50d0e35..73e835a 100644
 --- a/client/tests/kvm/kvm_preprocessing.py
 +++ b/client/tests/kvm/kvm_preprocessing.py
 @@ -257,9 +257,6 @@ def preprocess(test, params, env):
  int(params.get(pre_command_timeout, 600)),
  params.get(pre_command_noncritical) == yes)
  
 -# Preprocess all VMs and images
 -process(test, params, env, preprocess_image, preprocess_vm)
 -
  # Start the screendump thread
  if params.get(take_regular_screendumps) == yes:
  logging.debug(Starting screendump thread)
 @@ -278,6 +275,8 @@ def preprocess(test, params, env):
args=(test, params, env))
  _serialdump_thread.start()
  
 +# Preprocess all VMs and images
 +process(test, params, env, preprocess_image, preprocess_vm)
  
  
  def postprocess(test, params, env):

The initial shutdown procedure is carried out automatically by the
preprocessor in order to prepare the VMs for the current test, and is
not part of the test.  During the procedure VMs from a previous test are
shut down and/or restarted.  I think it'll be confusing (or at least
irrelevant) for the user to see a Fedora guest shutting down at the
beginning of a Windows test.  Also, it will be inconsistent with the
pre_*.ppm screendumps which are taken after the new VMs are started.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 7/9] KVM test: Introduce the local_login()

2010-04-28 Thread Michael Goldish
On 04/26/2010 01:04 PM, Jason Wang wrote:
 This patch introduces a new method which is used to log into the guest
 through the guest serial console. The serial_mode must be set to
 session in order to make use of this patch.

In what cases would we want to use this feature?  The serial console is
not supported by all guests and I'm not sure it supports multiple
concurrent sessions (does it?), so it's probably not possible to use it
reliably as a replacement for the regular remote shell servers, or even
as an alternative variant.

 Signed-off-by: Jason Wang jasow...@redhat.com
 ---
  client/tests/kvm/kvm_vm.py |   25 +
  1 files changed, 25 insertions(+), 0 deletions(-)
 
 diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
 index 0cdf925..a22893b 100755
 --- a/client/tests/kvm/kvm_vm.py
 +++ b/client/tests/kvm/kvm_vm.py
 @@ -814,7 +814,32 @@ class VM:
  command, ))
  return session
  
 +def local_login(self, timeout=240):
 +
 +Log into the guest via serial console
 +If timeout expires while waiting for output from the guest (e.g. a
 +password prompt or a shell prompt) -- fail.
 +
 +
 +serial_mode = self.params.get(serial_mode)
 +username = self.params.get(username, )
 +password = self.params.get(password, )
 +prompt = self.params.get(shell_prompt, [\#\$])
 +linesep = eval('%s' % self.params.get(shell_linesep, r\n))
  
 +if serial_mode != session:
 +logging.debug(serial_mode is not session)
 +return None
 +else:
 +command = nc -U %s  % self.serial_file_name
 +assist = self.params.get(prompt_assist)
 +session = kvm_utils.remote_login(command, password, prompt, 
 linesep,
 + timeout, , username)
 ^
You probably meant to pass the prompt assist string to remote_login()
but instead you're passing .

 +if session:
 +
 session.set_status_test_command(self.params.get(status_test_
 +command, 
 ))
 +return session
 +
  def copy_files_to(self, local_path, remote_path, nic_index=0, 
 timeout=300):
  
  Transfer files to the guest.
 
 --
 To unsubscribe from this list: send the line unsubscribe kvm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] [RFC] KVM test: Create a remote session cleaning thread

2010-04-21 Thread Michael Goldish
On 04/17/2010 01:23 AM, Lucas Meneghel Rodrigues wrote:
 In some occasions even though a VM has terminated,
 some remote shell sessions will take a long time
 before giving up on the host. This situation is
 happening frequently on subtests such as autotest:
 The VM shuts down, but the session will be alive
 for a long time after the VM died.

How long?

See comments below.

 So let's keep track of all sessions stablished to
 a VM object, and create a remote session cleaning
 thread, very much similar to the screendumps thread
 recently introduced. This thread would go over all
 dead VMs in the environment, and kill any remote
 sessions associated to them that might still be alive.
 
 This way we can save some good time in tests where
 the VM was terminated due to some weird reason.
 
 Signed-off-by: Lucas Meneghel Rodrigues l...@redhat.com
 ---
  client/tests/kvm/kvm_preprocessing.py |   33 
 -
  client/tests/kvm/kvm_vm.py|7 +++
  2 files changed, 39 insertions(+), 1 deletions(-)
 
 diff --git a/client/tests/kvm/kvm_preprocessing.py 
 b/client/tests/kvm/kvm_preprocessing.py
 index 50db65c..707565d 100644
 --- a/client/tests/kvm/kvm_preprocessing.py
 +++ b/client/tests/kvm/kvm_preprocessing.py
 @@ -13,7 +13,8 @@ except ImportError:
  
  _screendump_thread = None
  _screendump_thread_termination_event = None
 -
 +_session_cleaning_thread = None
 +_session_cleaning_thread_termination_event = None
  
  def preprocess_image(test, params):
  
 @@ -267,6 +268,14 @@ def preprocess(test, params, env):
args=(test, params, env))
  _screendump_thread.start()
  
 +# Start the session cleaning thread
 +logging.debug(Starting remote session cleaning thread)
 +global _session_cleaning_thread, 
 _session_cleaning_thread_termination_event
 +_session_cleaning_thread_termination_event = threading.Event()
 +_session_cleaning_thread = 
 threading.Thread(target=_clean_remote_sessions,
 +  args=(test, params, env))
 +_session_cleaning_thread.start()
 +
  
  def postprocess(test, params, env):
  
 @@ -442,3 +451,25 @@ def _take_screendumps(test, params, env):
  if _screendump_thread_termination_event.isSet():
  break
  _screendump_thread_termination_event.wait(delay)
 +
 +
 +def _clean_remote_sessions(test, params, env):
 +
 +Some remote shell servers such as SSH can be very slow on giving up of a
 +connection, which is fair. However, if the VM is known to be dead, we
 +can speed up this process reaping the remote sessions stablished to it.
 +
 +@param test: KVM test object.
 +@param params: Dictionary with test parameters.
 +@param env: KVM test environment.
 +
 +global _session_cleaning_termination_event
 +delay = float(params.get(session_cleaning_delay, 30))
 +while True:
 +for vm in kvm_utils.env_get_all_vms(env):
 +if vm.is_dead():
 +for session in vm.get_remote_session_list():
 +session.close()
 +if _session_cleaning_thread_termination_event.isSet():
 +break
 +_session_cleaning_thread_termination_event.wait(delay)
 diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
 index 047505a..82ef3cf 100755
 --- a/client/tests/kvm/kvm_vm.py
 +++ b/client/tests/kvm/kvm_vm.py
 @@ -115,6 +115,7 @@ class VM:
  self.root_dir = root_dir
  self.address_cache = address_cache
  self.pci_assignable = None
 +self.remote_session_list = []
  
  # Find available monitor filename
  while True:
 @@ -749,6 +750,10 @@ class VM:
  return self.process.get_pid()
  
  
 +def get_remote_session_list(self):
 +return self.remote_session_list
 +
 +
  def get_shared_meminfo(self):
  
  Returns the VM's shared memory information.
 @@ -802,6 +807,8 @@ class VM:
  if session:
  session.set_status_test_command(self.params.get(status_test_
  command, ))
 +self.remote_session_list.append(session)
 +
  return session
  
  

The problem with this approach is that storing the remote sessions in
the VM object can have weird side effects:
- The VM object is pickled at the end of the test, and unpickled at the
beginning of the next test.  The stored sessions will also be unpickled.
 I'm not sure if that's bad but we should check it out.
- Currently sessions are terminated automatically as soon as they're not
needed.  Keeping them in the VM object will delay their termination
(though I don't think they'll make it to the next test alive).
I'm still not sure these are actual problems -- I'd like to test it to
be sure.

Minor issues:
- You need to set() the termination event and join() the thread at
postprocessing, otherwise it's pointless to 

Re: [PATCH] KVM test: Silence screendump thread by default

2010-04-20 Thread Michael Goldish
On 04/16/2010 09:12 PM, Lucas Meneghel Rodrigues wrote:
 The VM screendump thread recently introduced generates
 a lot of output on debug logs. Such output is not needed
 most of the time (we are interested to see if a screenshot
 production attempt failed though) and distracts the user
 from other more important info.
 
 So let's add an additional parameter on send_monitor_cmd
 that specifies if we actually want the monitor command logged,
 defaulting it to True so the rest of the callers won't have
 any change on their behavior. The screendump thread will
 call send_monitor_cmd with verbose=False unless in the
 configuration file one sets screendump_verbose=yes (defaults
 to no on the sample confifg file).
 
 Signed-off-by: Lucas Meneghel Rodrigues l...@redhat.com
 ---
  client/tests/kvm/kvm_preprocessing.py  |   10 +-
  client/tests/kvm/kvm_vm.py |7 +--
  client/tests/kvm/tests_base.cfg.sample |1 +
  3 files changed, 15 insertions(+), 3 deletions(-)
 
 diff --git a/client/tests/kvm/kvm_preprocessing.py 
 b/client/tests/kvm/kvm_preprocessing.py
 index 50db65c..4b9290c 100644
 --- a/client/tests/kvm/kvm_preprocessing.py
 +++ b/client/tests/kvm/kvm_preprocessing.py
 @@ -401,6 +401,10 @@ def _take_screendumps(test, params, env):
   kvm_utils.generate_random_string(6))
  delay = float(params.get(screendump_delay, 5))
  quality = int(params.get(screendump_quality, 30))
 +if params.get(screendump_verbose) == 'yes':
 +screendump_verbose = True
 +else:
 +screendump_verbose = False

Why not:

screendump_verbose = params.get(screendump_verbose) == yes

  cache = {}
  
 @@ -408,7 +412,11 @@ def _take_screendumps(test, params, env):
  for vm in kvm_utils.env_get_all_vms(env):
  if vm.is_dead():
  continue
 -vm.send_monitor_cmd(screendump %s % temp_filename)
 +if screendump_verbose:
 +vm.send_monitor_cmd(screendump %s % temp_filename)
 +else:
 +vm.send_monitor_cmd(screendump %s % temp_filename,
 +verbose=False)

Also, why not:

vm.send_monitor_cmd(screendump %s % temp_filename,
verbose=screendump_verbose)

  if not os.path.exists(temp_filename):
  logging.warn(VM '%s' failed to produce a screendump, 
 vm.name)
  continue
 diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
 index 047505a..244355e 100755
 --- a/client/tests/kvm/kvm_vm.py
 +++ b/client/tests/kvm/kvm_vm.py
 @@ -498,7 +498,7 @@ class VM:
  lockfile.close()
  
  
 -def send_monitor_cmd(self, command, block=True, timeout=20.0):
 +def send_monitor_cmd(self, command, block=True, timeout=20.0, 
 verbose=True):
  
  Send command to the QEMU monitor.
  
 @@ -541,8 +541,11 @@ class VM:
  time.sleep(0.01)
  return (False, o)
  
 +# In certain conditions printing this debug output might be too much
 +# Just print it if verbose is enabled (True by default)
 +if verbose:
 +logging.debug(Sending monitor command: %s % command)
  # Connect to monitor
 -logging.debug(Sending monitor command: %s % command)
  try:
  s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  s.setblocking(False)
 diff --git a/client/tests/kvm/tests_base.cfg.sample 
 b/client/tests/kvm/tests_base.cfg.sample
 index 4baa1dc..e74c7cb 100644
 --- a/client/tests/kvm/tests_base.cfg.sample
 +++ b/client/tests/kvm/tests_base.cfg.sample
 @@ -23,6 +23,7 @@ keep_screendumps_on_error = yes
  screendump_delay = 5
  screendump_quality = 30
  screendump_temp_dir = /dev/shm
 +screendump_verbose = no
  
  # Some default VM params
  qemu_binary = qemu

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: kvm autotest, how to disable address cache

2010-04-15 Thread Michael Goldish
On 04/08/2010 11:53 PM, Ryan Harper wrote:
 Is there any way to disable this?  I'm running a guest on -net user
 networking, no interaction with the host network, yet, during the test,
 I get tons of:
 
 15:50:48 DEBUG| (address cache) Adding cache entry: 00:1a:64:39:04:91 --- 
 10.0.253.16
 15:50:49 DEBUG| (address cache) Adding cache entry: e4:1f:13:2c:e5:04 --- 
 10.0.253.132
 
 many times for the same mapping.  If I'm not using tap networking on a
 public bridge, what's this address cache doing for me? And, how the heck
 do turn this off?
 
 

Currently that's not configurable.  It's there under the assumption that
it doesn't annoy anyone too much.  Now that I know you're annoyed by it
I'll send a patch to make it optional.  If you can't wait, feel free to
comment out the first paragraph in kvm_preprocessing.preprocess().
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/3] KVM Test: Add function run_autotest_background and wait_autotest_background.

2010-04-08 Thread Michael Goldish
On 04/07/2010 11:49 AM, Feng Yang wrote:
 Add function run_autotest_background and wait_autotest_background to
 kvm_test_utils.py.  This two functions is used in ioquit test script.
 
 Signed-off-by: Feng Yang fy...@redhat.com
 ---
  client/tests/kvm/kvm_test_utils.py |   68 
 +++-
  1 files changed, 67 insertions(+), 1 deletions(-)
 
 diff --git a/client/tests/kvm/kvm_test_utils.py 
 b/client/tests/kvm/kvm_test_utils.py
 index f512044..2a1054e 100644
 --- a/client/tests/kvm/kvm_test_utils.py
 +++ b/client/tests/kvm/kvm_test_utils.py
 @@ -21,7 +21,7 @@ More specifically:
  @copyright: 2008-2009 Red Hat Inc.
  
  
 -import time, os, logging, re, commands
 +import time, os, logging, re, commands, sys
  from autotest_lib.client.common_lib import error
  from autotest_lib.client.bin import utils
  import kvm_utils, kvm_vm, kvm_subprocess, scan_results
 @@ -402,3 +402,69 @@ def run_autotest(vm, session, control_path, timeout, 
 test_name, outputdir):
  result = bad_results[0]
  raise error.TestFail(Test '%s' ended with %s (reason: '%s')
   % (result[0], result[1], result[3]))
 +
 +
 +def run_autotest_background(vm, session, control_path, timeout, test_name,
 +outputdir):
 +
 +Wrapper of run_autotest() and make it run in the background through 
 fork()
 +and let it run in the child process.
 +1) Flush the stdio.
 +2) Build test params which is recevied from arguments and used by
 +   run_autotest()
 +3) Fork the process and let the run_autotest() run in the child
 +4) Catch the exception raise by run_autotest() and exit the child with
 +   non-zero return code.
 +5) If no exception catched, reutrn 0
 +
 +@param vm: VM object.
 +@param session: A shell session on the VM provided.
 +@param control: An autotest control file.
 +@param timeout: Timeout under which the autotest test must complete.
 +@param test_name: Autotest client test name.
 +@param outputdir: Path on host where we should copy the guest autotest
 +results to.
 +
 +
 +def flush():
 +sys.stdout.flush()
 +sys.stderr.flush()
 +
 +logging.info(Running autotest background ...)
 +flush()
 +pid = os.fork()
 +if pid:
 +# Parent process
 +return pid
 +
 +try:
 +# Launch autotest
 +logging.info(child process of run_autotest_background)
 +run_autotest(vm, session, control_path, timeout, test_name, 
 outputdir)
 +except error.TestFail, message_fail:
 +logging.info([Autotest Background FAIL] %s % message_fail)
 +os._exit(1)
 +except error.TestError, message_error:
 +logging.info([Autotest Background ERROR] %s % message_error)
 +os._exit(2)
 +except:
 +os._exit(3)
 +
 +logging.info([Auototest Background GOOD])
 +os._exit(0)
 +
 +
 +def wait_autotest_background(pid):
 +
 +Wait for background autotest finish.
 +
 +@param pid: Pid of the child process executing background autotest
 +
 +logging.info(Waiting for background autotest to finish ...)
 +
 +(pid, s) = os.waitpid(pid,0)
 +status = os.WEXITSTATUS(s)
 +if status != 0:
 +return False
 +return True
 +

I think these functions are unnecessary.  IMO forking is not the clean
way of running autotest in the background.  The kvm_shell_session
object, used to run autotest in the guest, by default runs things in the
background (e.g. session.sendline() returns immediately).
run_autotest(), which uses kvm_shell_session, blocks until the autotest
test is done.  So in order to run autotest in the background, we should
modify run_autotest(), or break it up into smaller parts, to make it
nonblocking.  There's no need to implement yet another wrapper.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] KVM Test: Add ioquit test case

2010-04-08 Thread Michael Goldish
On 04/07/2010 11:49 AM, Feng Yang wrote:
 Signed-off-by: Feng Yang fy...@redhat.com
 ---
  client/tests/kvm/tests/ioquit.py   |   54 
 
  client/tests/kvm/tests_base.cfg.sample |4 ++
  2 files changed, 58 insertions(+), 0 deletions(-)
  create mode 100644 client/tests/kvm/tests/ioquit.py
 
 diff --git a/client/tests/kvm/tests/ioquit.py 
 b/client/tests/kvm/tests/ioquit.py
 new file mode 100644
 index 000..c75a0e3
 --- /dev/null
 +++ b/client/tests/kvm/tests/ioquit.py
 @@ -0,0 +1,54 @@
 +import logging, time, random, signal, os
 +from autotest_lib.client.common_lib import error
 +import kvm_test_utils, kvm_utils
 +
 +
 +def run_ioquit(test, params, env):
 +
 +Emulate the poweroff under IO workload(dbench so far) using monitor
 +command 'quit'.
 +
 +@param test: Kvm test object
 +@param params: Dictionary with the test parameters.
 +@param env: Dictionary with test environment.
 +

- Can you explain the goal of this test?  Why quit a VM under IO
workload?  What results do you expect?  How can the test ever fail?

- Why is dbench any better for this purpose than dd or some other simple
command?  Using dbench isn't necessarily bad, I'm just curious.

 +vm = kvm_test_utils.get_living_vm(env, params.get(main_vm))
 +session = kvm_test_utils.wait_for_login(vm,
 +  timeout=int(params.get(login_timeout, 360)))
 +session2 = kvm_test_utils.wait_for_login(vm,
 +  timeout=int(params.get(login_timeout, 360)))
 +def is_autotest_launched():
 +if session.get_command_status(pgrep autotest) != 0:
 +logging.debug(Autotest process not found)
 +return False
 +return True
 +
 +test_name = params.get(background_test, dbench)
 +control_file = params.get(control_file, dbench.control)
 +timeout = int(params.get(test_timeout, 300))
 +control_path = os.path.join(test.bindir, autotest_control,
 +control_file)
 +outputdir = test.outputdir
 +
 +pid = kvm_test_utils.run_autotest_background(vm, session2, control_path,
 + timeout, test_name,
 + outputdir)

As mentioned in the other message, I don't think it's necessary to fork
and use run_autotest() in a separate process.  Instead we should modify
run_autotest() to support non-blocking operation (if we need that at all).

 +if pid  0:
 +raise error.TestError(Could not create child process to execute 
 +  autotest background)
 +
 +if kvm_utils.wait_for(is_autotest_launched, 240, 0, 2):
 +logging.debug(Background autotest successfully)
 +else:
 +logging.debug(Background autotest failed, start the test anyway)
 +
 +time.sleep(100 + random.randrange(0,100))
 +logging.info(Kill the virtual machine)
 +vm.process.close()

This will do a 'kill -9' on the qemu process.  Didn't you intend to use
a 'quit'?  To do that, you should use vm.destroy(gracefully=False).

 +logging.info(Kill the tracking process)
 +kvm_utils.safe_kill(pid, signal.SIGKILL)
 +kvm_test_utils.wait_autotest_background(pid)
 +session.close()
 +session2.close()
 +
 diff --git a/client/tests/kvm/tests_base.cfg.sample 
 b/client/tests/kvm/tests_base.cfg.sample
 index 9b12fc2..d8530f6 100644
 --- a/client/tests/kvm/tests_base.cfg.sample
 +++ b/client/tests/kvm/tests_base.cfg.sample
 @@ -305,6 +305,10 @@ variants:
  - ksm_parallel:
  ksm_mode = parallel
  
 +- ioquit:
 +type = ioquit
 +control_file = dbench.control.200
 +background_test = dbench

You should probably add extra_params +=  -snapshot because this test
can break the filesystem.

  # system_powerdown, system_reset and shutdown *must* be the last ones
  # defined (in this order), since the effect of such tests can leave
  # the VM on a bad state.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] KVM test: Make the profiler could be configurated

2010-03-30 Thread Michael Goldish

- Jason Wang jasow...@redhat.com wrote:

 The patch let the profilers could be specified through configuration
 file. kvm_stat was kept as the default profiler.

Looks good.  Some minor style comments:

 Signed-off-by: Jason Wang jasow...@redhat.com
 ---
  client/tests/kvm/kvm_utils.py  |   23
 ++-
  client/tests/kvm/tests_base.cfg.sample |2 +-
  2 files changed, 11 insertions(+), 14 deletions(-)
 
 diff --git a/client/tests/kvm/kvm_utils.py
 b/client/tests/kvm/kvm_utils.py
 index 8531c79..a73d5d4 100644
 --- a/client/tests/kvm/kvm_utils.py
 +++ b/client/tests/kvm/kvm_utils.py
 @@ -866,24 +866,21 @@ def run_tests(test_list, job):
  if dependencies_satisfied:
  test_iterations = int(dict.get(iterations, 1))
  test_tag = dict.get(shortname)
 -# Setting up kvm_stat profiling during test execution.
 -# We don't need kvm_stat profiling on the build tests.
 -if dict.get(run_kvm_stat) == yes:
 -profile = True
 -else:
 -# None because it's the default value on the base_test class
 -# and the value None is specifically checked there.
 -profile = None
 +# Setting up profilers during test execution.
 +profilers = dict.get(profilers)
 +if profilers is not None:

I think it's nicer and shorter to say if profilers instead of
if profilers is not None.
Better yet, use 'profilers = dict.get(profilers, )' so that if
profilers isn't defined, or if the user said 'profilers = ', you can
still call profilers.split(), i.e.:

profilers = dict.get(profilers, )
for profiler in profilers.split():
job.profilers.add(profiler)

and then you don't need the 'if'.
This is also relevant to the job.profilers.delete() code below.

 +for profiler in profilers.split():
 +job.profilers.add(profiler)
  
 -if profile:
 -job.profilers.add('kvm_stat')
  # We need only one execution, profiled, hence we're passing
  # the profile_only parameter to job.run_test().
  current_status = job.run_test(kvm, params=dict, tag=test_tag,
iterations=test_iterations,
 -  profile_only=profile)
 -if profile:
 -job.profilers.delete('kvm_stat')
 +  profile_only= profilers is not 
 None)

AFAIK, profile_only needs to be either True or None (Lucas, please correct
me if I'm wrong).
In that case, it would be appropriate to use

profile_only=bool(profilers) or None

so that if profilers is e.g. kvm_stat, profile_only will be True,
and if profilers is , profile_only will be None.

 +
 +if profilers is not None:
 +for profiler in profilers.split():
 +job.profilers.delete(profiler)
  
  if not current_status:
  failed = True
 diff --git a/client/tests/kvm/tests_base.cfg.sample
 b/client/tests/kvm/tests_base.cfg.sample
 index d162cf8..cc10713 100644
 --- a/client/tests/kvm/tests_base.cfg.sample
 +++ b/client/tests/kvm/tests_base.cfg.sample
 @@ -41,7 +41,7 @@ nic_script = scripts/qemu-ifup
  address_index = 0
  
  # Misc
 -run_kvm_stat = yes
 +profilers = kvm_stat 

We don't need the quotes here now.  We'll need them later if we add
more profilers.  So it's OK to use

profilers = kvm_stat

and then later if we need another profiler:

profilers +=  some_other_profiler

  
  
  # Tests
 
 --
 To unsubscribe from this list: send the line unsubscribe kvm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH] KVM test: kvm_vm: destroy VM if hugepage setup fails

2010-03-30 Thread Michael Goldish
Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_vm.py |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 921414d..047505a 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -486,6 +486,7 @@ class VM:
   qemu command:\n%s % qemu_command)
 logging.error(Output: + kvm_utils.format_str_for_message(
   self.process.get_output()))
+self.destroy()
 return False
 
 logging.debug(VM appears to be alive with PID %d,
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH] KVM test: timedrift: open load sessions before taking initial time

2010-03-24 Thread Michael Goldish
Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/tests/timedrift.py |   18 ++
 1 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/client/tests/kvm/tests/timedrift.py 
b/client/tests/kvm/tests/timedrift.py
index 194f09c..9cb7489 100644
--- a/client/tests/kvm/tests/timedrift.py
+++ b/client/tests/kvm/tests/timedrift.py
@@ -82,15 +82,8 @@ def run_timedrift(test, params, env):
 # Set the VM's CPU affinity
 prev_affinity = set_cpu_affinity(vm.get_pid(), cpu_mask)
 
-# Get time before load
-# (ht stands for host time, gt stands for guest time)
-(ht0, gt0) = kvm_test_utils.get_time(session,
- time_command,
- time_filter_re,
- time_format)
-
 try:
-# Run some load on the guest
+# Open shell sessions with the guest
 logging.info(Starting load on guest...)
 for i in range(guest_load_instances):
 load_session = vm.remote_login()
@@ -99,6 +92,15 @@ def run_timedrift(test, params, env):
 load_session.set_output_prefix((guest load %d)  % i)
 load_session.set_output_func(logging.debug)
 guest_load_sessions.append(load_session)
+
+# Get time before load
+# (ht stands for host time, gt stands for guest time)
+(ht0, gt0) = kvm_test_utils.get_time(session,
+ time_command,
+ time_filter_re,
+ time_format)
+
+# Run some load on the guest
 for load_session in guest_load_sessions:
 load_session.sendline(guest_load_command)
 
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH] KVM test: increase default timeout for autotest.sleeptest

2010-03-24 Thread Michael Goldish
Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/tests_base.cfg.sample |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/client/tests/kvm/tests_base.cfg.sample 
b/client/tests/kvm/tests_base.cfg.sample
index 249f1b4..b8288fc 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -111,7 +111,7 @@ variants:
 variants:
 - sleeptest:
 test_name = sleeptest
-test_timeout = 30
+test_timeout = 120
 test_control_file = sleeptest.control
 - dbench:
 test_name = dbench
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH] KVM test: tests_base.cfg.sample: remove kill_vm_gracefully=no for system_powerdown

2010-03-24 Thread Michael Goldish
There's no good reason to set kill_vm_gracefully=no for system_powerdown.
Furthermore, killing the VM ungracefully (with 'quit') can severely damage the
filesystem (I witnessed that at least once).
Therefore, revert to the default, which is kill_vm_gracefully=yes.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/tests_base.cfg.sample |1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/client/tests/kvm/tests_base.cfg.sample 
b/client/tests/kvm/tests_base.cfg.sample
index b8288fc..c9dfd0b 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -302,7 +302,6 @@ variants:
 shutdown_method = system_powerdown
 sleep_before_powerdown = 20
 kill_vm = yes
-kill_vm_gracefully = no
 
 - system_reset: install setup unattended_install
 type = boot
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH v3] KVM test: take frequent screendumps during all tests

2010-03-23 Thread Michael Goldish
Screendumps are taken regularly and converted to JPEG format.
They are stored in .../debug/screendumps_VMname/.
Requires python-imaging.

- Enabled by 'take_regular_screendumps = yes' (naming suggestions welcome).
- Delay between screendumps is controlled by 'screendump_delay' (default 5).
- Compression quality is controlled by 'screendump_quality' (default 30).
- It's probably a good idea to dump them to /dev/shm before converting them
  in order to minimize disk use.  This can be enabled by
  'screendump_temp_dir = /dev/shm' (enabled by default.)
- Screendumps are removed unless 'keep_screendumps'['_on_error'] is 'yes'.
  The recommended setting when submitting jobs from autoserv is
  'keep_screendumps_on_error = yes', which means screendumps are kept only if
  the test fails.  Keeping all screendumps may use up all of the server's
  storage space.

This patch sets reasonable defaults in tests_base.cfg.sample.

(It also makes sure post_command is executed last in the postprocessing
procedure -- otherwise post_command failure can prevent other postprocessing
steps (like removing the screendump dirs) from taking place.)

Changes from v2:
- When encountering a screendump that has already been stored, create a hard
  link to the existing one instead of a new JPG file.
- By default, use /dev/shm as temporary storage for screendumps.
- Use -mm-dd_hh-mm-ss timestamps in screendump filenames
  (instead of mmdd-hhmmss).

Changes from v1:
Print debug messages when starting or terminating the screendump thread.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_preprocessing.py  |   98 ++--
 client/tests/kvm/tests_base.cfg.sample |   13 +++-
 2 files changed, 102 insertions(+), 9 deletions(-)

diff --git a/client/tests/kvm/kvm_preprocessing.py 
b/client/tests/kvm/kvm_preprocessing.py
index a92282a..b3fef9d 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -1,4 +1,4 @@
-import sys, os, time, commands, re, logging, signal, glob
+import sys, os, time, commands, re, logging, signal, glob, threading, shutil
 from autotest_lib.client.bin import test, utils
 from autotest_lib.client.common_lib import error
 import kvm_vm, kvm_utils, kvm_subprocess, ppm_utils
@@ -11,6 +11,10 @@ except ImportError:
 'distro.')
 
 
+_screendump_thread = None
+_screendump_thread_termination_event = None
+
+
 def preprocess_image(test, params):
 
 Preprocess a single QEMU image according to the instructions in params.
@@ -254,6 +258,15 @@ def preprocess(test, params, env):
 # Preprocess all VMs and images
 process(test, params, env, preprocess_image, preprocess_vm)
 
+# Start the screendump thread
+if params.get(take_regular_screendumps) == yes:
+logging.debug(Starting screendump thread)
+global _screendump_thread, _screendump_thread_termination_event
+_screendump_thread_termination_event = threading.Event()
+_screendump_thread = threading.Thread(target=_take_screendumps,
+  args=(test, params, env))
+_screendump_thread.start()
+
 
 def postprocess(test, params, env):
 
@@ -263,8 +276,16 @@ def postprocess(test, params, env):
 @param params: Dict containing all VM and image parameters.
 @param env: The environment (a dict-like object).
 
+# Postprocess all VMs and images
 process(test, params, env, postprocess_image, postprocess_vm)
 
+# Terminate the screendump thread
+global _screendump_thread, _screendump_thread_termination_event
+if _screendump_thread:
+logging.debug(Terminating screendump thread...)
+_screendump_thread_termination_event.set()
+_screendump_thread.join(10)
+
 # Warn about corrupt PPM files
 for f in glob.glob(os.path.join(test.debugdir, *.ppm)):
 if not ppm_utils.image_verify_ppm_file(f):
@@ -290,11 +311,13 @@ def postprocess(test, params, env):
 for f in glob.glob(os.path.join(test.debugdir, '*.ppm')):
 os.unlink(f)
 
-# Execute any post_commands
-if params.get(post_command):
-process_command(test, params, env, params.get(post_command),
-int(params.get(post_command_timeout, 600)),
-params.get(post_command_noncritical) == yes)
+# Should we keep the screendump dirs?
+if params.get(keep_screendumps) != yes:
+logging.debug('keep_screendumps' not specified; removing screendump 
+  dirs...)
+for d in glob.glob(os.path.join(test.debugdir, screendumps_*)):
+if os.path.isdir(d) and not os.path.islink(d):
+shutil.rmtree(d, ignore_errors=True)
 
 # Kill all unresponsive VMs
 if params.get(kill_unresponsive_vms) == yes:
@@ -318,6 +341,12 @@ def postprocess(test, params, env):
 env[tcpdump].close()
 del env[tcpdump]
 
+# Execute any

[KVM-AUTOTEST PATCH 1/5] KVM test: remote_login(): if rss.exe says Please wait, wait

2010-03-23 Thread Michael Goldish
Recognize rss.exe's Please wait message and give the login procedure more
time to complete.  The message is sent before spawning cmd.exe, which may take
some time under heavy load.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_utils.py |9 +++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index 5834539..8531c79 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -482,7 +482,8 @@ def remote_login(command, password, prompt, linesep=\n, 
timeout=10):
 while True:
 (match, text) = sub.read_until_last_line_matches(
 [r[Aa]re you sure, r[Pp]assword:\s*$, r^\s*[Ll]ogin:\s*$,
- r[Cc]onnection.*closed, r[Cc]onnection.*refused, prompt],
+ r[Cc]onnection.*closed, r[Cc]onnection.*refused,
+ r[Pp]lease wait, prompt],
  timeout=timeout, internal_timeout=0.5)
 if match == 0:  # Are you sure you want to continue connecting
 logging.debug(Got 'Are you sure...'; sending 'yes')
@@ -510,7 +511,11 @@ def remote_login(command, password, prompt, linesep=\n, 
timeout=10):
 logging.debug(Got 'Connection refused')
 sub.close()
 return None
-elif match == 5:  # prompt
+elif match == 5:  # Please wait
+logging.debug(Got 'Please wait')
+timeout = 30
+continue
+elif match == 6:  # prompt
 logging.debug(Got shell prompt -- logged in)
 return sub
 else:  # match == None
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 2/5] KVM test: tests_base.cfg.sample: add /f option to all Windows shutdown commands

2010-03-23 Thread Michael Goldish
It seems that when Windows is locked it refuses to shutdown unless given the /f
option.

- Add /f to all Windows shutdown and reboot commands.
- Remove duplicate shutdown and reboot commands for Win2003, Win2008 and Win7.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/tests_base.cfg.sample |   10 ++
 1 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/client/tests/kvm/tests_base.cfg.sample 
b/client/tests/kvm/tests_base.cfg.sample
index 2a36687..bacbcee 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -687,8 +687,8 @@ variants:
 # Windows section
 - @Windows:
 no autotest linux_s3 vlan_tag
-shutdown_command = shutdown /s /t 0
-reboot_command = shutdown /r /t 0
+shutdown_command = shutdown /s /f /t 0
+reboot_command = shutdown /r /f /t 0
 status_test_command = echo %errorlevel%
 shell_prompt = ^\w:\\.*\s*$
 username = Administrator
@@ -808,8 +808,6 @@ variants:
 - Win2003:
 image_name = win2003
 image_size = 20G
-shutdown_command = shutdown /s /f /t 0
-reboot_command = shutdown /r /f /t 0
 
 variants:
 - 32:
@@ -908,8 +906,6 @@ variants:
 - Win2008:
 image_name = win2008
 image_size = 20G
-shutdown_command = shutdown /s /f /t 0
-reboot_command = shutdown /r /f /t 0
 
 variants:
 - 32sp1:
@@ -985,8 +981,6 @@ variants:
 - Win7:
 image_name = win7
 image_size = 20G
-shutdown_command = shutdown /s /f /t 0
-reboot_command = shutdown /r /f /t 0
 
 variants:
 - 32:
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 3/5] KVM test: timedrift: first open ssh/rss sessions with the guest, then start load

2010-03-23 Thread Michael Goldish
Currently, for each guest load session, a login is performed, followed
immediately by sending the command that initiates the load.  When the second
login is attempted, the guest is already loaded by the first session, and
therefore may respond slowly to the login request.
This patch makes the test open all load sessions first, and then send the load
command to all open sessions.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/tests/timedrift.py |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/client/tests/kvm/tests/timedrift.py 
b/client/tests/kvm/tests/timedrift.py
index b3e8770..194f09c 100644
--- a/client/tests/kvm/tests/timedrift.py
+++ b/client/tests/kvm/tests/timedrift.py
@@ -98,8 +98,9 @@ def run_timedrift(test, params, env):
 raise error.TestFail(Could not log into guest)
 load_session.set_output_prefix((guest load %d)  % i)
 load_session.set_output_func(logging.debug)
-load_session.sendline(guest_load_command)
 guest_load_sessions.append(load_session)
+for load_session in guest_load_sessions:
+load_session.sendline(guest_load_command)
 
 # Run some load on the host
 logging.info(Starting load on host...)
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 4/5] KVM test: stress_boot: make boot timeout controllable

2010-03-23 Thread Michael Goldish
Use parameter 'boot_timeout'.  Defaults to 240.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/tests/stress_boot.py  |9 +
 client/tests/kvm/tests_base.cfg.sample |1 +
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/client/tests/kvm/tests/stress_boot.py 
b/client/tests/kvm/tests/stress_boot.py
index 0b5ec02..24a005c 100644
--- a/client/tests/kvm/tests/stress_boot.py
+++ b/client/tests/kvm/tests/stress_boot.py
@@ -21,7 +21,8 @@ def run_stress_boot(tests, params, env):
 
 logging.info(Waiting for first guest to be up...)
 
-session = kvm_utils.wait_for(vm.remote_login, 240, 0, 2)
+boot_timeout = float(params.get(boot_timeout, 240))
+session = kvm_utils.wait_for(vm.remote_login, boot_timeout, 0, 2)
 if not session:
 raise error.TestFail(Could not log into first guest)
 
@@ -32,9 +33,8 @@ def run_stress_boot(tests, params, env):
 # boot the VMs
 while num = int(params.get(max_vms)):
 try:
-vm_name = vm + str(num)
-
 # clone vm according to the first one
+vm_name = vm + str(num)
 vm_params = vm.get_params().copy()
 vm_params[address_index] = str(address_index)
 curr_vm = vm.clone(vm_name, vm_params)
@@ -43,7 +43,8 @@ def run_stress_boot(tests, params, env):
 kvm_preprocessing.preprocess_vm(tests, vm_params, env, vm_name)
 params['vms'] +=   + vm_name
 
-curr_vm_session = kvm_utils.wait_for(curr_vm.remote_login, 240, 0, 
2)
+curr_vm_session = kvm_utils.wait_for(curr_vm.remote_login,
+ boot_timeout, 0, 2)
 if not curr_vm_session:
 raise error.TestFail(Could not log into guest #%d % num)
 
diff --git a/client/tests/kvm/tests_base.cfg.sample 
b/client/tests/kvm/tests_base.cfg.sample
index bacbcee..249f1b4 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -179,6 +179,7 @@ variants:
 max_vms = 5
 alive_test_cmd = uname -a
 clone_address_index_base = 10
+boot_timeout = 240
 kill_vm = yes
 kill_vm_vm1 = no
 kill_vm_gracefully = no
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 5/5] KVM test: abort-on-error mode

2010-03-23 Thread Michael Goldish
If 'abort_on_error' is set to 'yes' for a test, the entire job will be aborted
when that test fails.  If the parameter is set for all tests, the job will be
aborted as soon as the first test fails.  Before aborting, the filename of the
monitor unix socket of each VM will be printed, as well as the command line
used to start that VM.

Currently this is only supported in serial exceution mode.  Behavior in
parallel mode is undefined.

To enable abort-on-error, and to prevent the postprocessor from killing any
VMs, set the following options:

abort_on_error = yes
kill_vm.* ?= no
kill_unresponsive_vms.* ?= no

These options appear commented out near the end of tests.cfg.sample.

They can also be set for specific tests, either by writing an exception like

WinXP.32\b.*\bmigrate:
abort_on_error = yes
...

in tests.cfg, or by setting the parameters in the test variant itself
(somewhere in tests_base.cfg).

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_preprocessing.py |   13 +
 client/tests/kvm/tests.cfg.sample |5 +
 2 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/client/tests/kvm/kvm_preprocessing.py 
b/client/tests/kvm/kvm_preprocessing.py
index b3fef9d..50db65c 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -347,6 +347,19 @@ def postprocess(test, params, env):
 int(params.get(post_command_timeout, 600)),
 params.get(post_command_noncritical) == yes)
 
+# Abort on error?
+if params.get(abort) == yes:
+exc_string = str(sys.exc_info()[1])
+logging.info(Aborting job (%s), exc_string)
+for vm in kvm_utils.env_get_all_vms(env):
+if not vm.is_dead():
+logging.info(VM '%s' is alive., vm.name)
+logging.info(The monitor unix socket of '%s' is: %s,
+ vm.name, vm.monitor_file_name)
+logging.info(The command line used to start '%s' was:\n%s,
+ vm.name, vm.make_qemu_command())
+raise error.JobError(Abort requested (%s) % exc_string)
+
 
 def postprocess_on_error(test, params, env):
 
diff --git a/client/tests/kvm/tests.cfg.sample 
b/client/tests/kvm/tests.cfg.sample
index b86b6c4..2c17454 100644
--- a/client/tests/kvm/tests.cfg.sample
+++ b/client/tests/kvm/tests.cfg.sample
@@ -74,5 +74,10 @@ variants:
 only Fedora.12.64
 only unattended_install boot shutdown
 
+# Uncomment the following lines to enable abort-on-error mode:
+#abort_on_error = yes
+#kill_vm.* ?= no
+#kill_unresponsive_vms.* ?= no
+
 # Choose your test list from the testsets defined
 only qemu_kvm_f12_quick
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Autotest] [PATCH 4/4] KVM test: Enable timedrift for Linux guests

2010-03-22 Thread Michael Goldish

- Jason Wang jasow...@redhat.com wrote:

 We should also test timedrift for Linux guests especially for guest
 with pvclock. So this patch enable the timedrift for linux guests.
 
 Signed-off-by: Jason Wang jasow...@redhat.com
 ---
  client/tests/kvm/tests_base.cfg.sample |   11 ++-
  1 files changed, 10 insertions(+), 1 deletions(-)
 
 diff --git a/client/tests/kvm/tests_base.cfg.sample
 b/client/tests/kvm/tests_base.cfg.sample
 index 8cc83a9..dcd0dcf 100644
 --- a/client/tests/kvm/tests_base.cfg.sample
 +++ b/client/tests/kvm/tests_base.cfg.sample
 @@ -330,7 +330,7 @@ variants:
  variants:
  # Linux section
  - @Linux:
 -no timedrift autoit
 +no autoit
  shutdown_command = shutdown -h now
  reboot_command = shutdown -r now
  status_test_command = echo $?
 @@ -342,6 +342,15 @@ variants:
  file_transfer_port = 22
  mem_chk_cmd = dmidecode -t 17 | awk -F: '/Size/ {print $2}'
  cpu_chk_cmd = grep -c processor /proc/cpuinfo
 +timedrift:
 +time_command = date +'TIME: %a %m/%d/%Y %H:%M:%S.%N'
 +time_filter_re = (?:TIME: \w\w\w )(.{19})(?:\.\d\d)
 +time_format = %m/%d/%Y %H:%M:%S
 +guest_load_command = dd if=/dev/urandom of=/dev/null
 +guest_load_instances = 2
 +guest_load_clean_cmd = killall -9 dd

I think this should be 'guest_load_stop_command'.
Other than that, looks good to me.

 +host_load_command = bzip2 -c --best /dev/urandom 
 /dev/null
 +host_load_instances = 8
  
  variants:
  - Fedora:
 
 ___
 Autotest mailing list
 autot...@test.kernel.org
 http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH v2] KVM test: kvm_preprocessing.py: minor style corrections

2010-03-22 Thread Michael Goldish
Also, fetch the KVM version before setting up the VMs.

Changes from v1:
Change 'for key in env' back to 'for key in env.keys()', because that loop
may remove entries from the env dictionary, therefore causing an exception
to be raised (RuntimeError: dictionary changed size during iteration).
Also, change 'for k in params.keys()' to 'for k in params' in process_command().

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_preprocessing.py |   58 +++-
 1 files changed, 27 insertions(+), 31 deletions(-)

diff --git a/client/tests/kvm/kvm_preprocessing.py 
b/client/tests/kvm/kvm_preprocessing.py
index e91d1da..a92282a 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -58,8 +58,8 @@ def preprocess_vm(test, params, env, name):
 for_migration = False
 
 if params.get(start_vm_for_migration) == yes:
-logging.debug('start_vm_for_migration' specified; (re)starting VM 
with
-   -incoming option...)
+logging.debug('start_vm_for_migration' specified; (re)starting VM 
+  with -incoming option...)
 start_vm = True
 for_migration = True
 elif params.get(restart_vm) == yes:
@@ -139,7 +139,7 @@ def process_command(test, params, env, command, 
command_timeout,
 @param command_noncritical: If True test will not fail if command fails.
 
 # Export environment vars
-for k in params.keys():
+for k in params:
 os.putenv(KVM_TEST_%s % k, str(params[k]))
 # Execute commands
 try:
@@ -187,12 +187,12 @@ def preprocess(test, params, env):
 @param env: The environment (a dict-like object).
 
 # Start tcpdump if it isn't already running
-if not env.has_key(address_cache):
+if address_cache not in env:
 env[address_cache] = {}
-if env.has_key(tcpdump) and not env[tcpdump].is_alive():
+if tcpdump in env and not env[tcpdump].is_alive():
 env[tcpdump].close()
 del env[tcpdump]
-if not env.has_key(tcpdump):
+if tcpdump not in env:
 command = /usr/sbin/tcpdump -npvi any 'dst port 68'
 logging.debug(Starting tcpdump (%s)..., command)
 env[tcpdump] = kvm_subprocess.kvm_tail(
@@ -213,30 +213,18 @@ def preprocess(test, params, env):
 if not kvm_utils.is_vm(vm):
 continue
 if not vm.name in requested_vms:
-logging.debug(VM '%s' found in environment but not required for
-   test; removing it... % vm.name)
+logging.debug(VM '%s' found in environment but not required for 
+  test; removing it... % vm.name)
 vm.destroy()
 del env[key]
 
-# Execute any pre_commands
-if params.get(pre_command):
-process_command(test, params, env, params.get(pre_command),
-int(params.get(pre_command_timeout, 600)),
-params.get(pre_command_noncritical) == yes)
-
-# Preprocess all VMs and images
-process(test, params, env, preprocess_image, preprocess_vm)
-
 # Get the KVM kernel module version and write it as a keyval
 logging.debug(Fetching KVM module version...)
 if os.path.exists(/dev/kvm):
-kvm_version = os.uname()[2]
 try:
-file = open(/sys/module/kvm/version, r)
-kvm_version = file.read().strip()
-file.close()
+kvm_version = open(/sys/module/kvm/version).read().strip()
 except:
-pass
+kvm_version = os.uname()[2]
 else:
 kvm_version = Unknown
 logging.debug(KVM module not loaded)
@@ -248,16 +236,24 @@ def preprocess(test, params, env):
 qemu_path = kvm_utils.get_path(test.bindir, params.get(qemu_binary,
qemu))
 version_line = commands.getoutput(%s -help | head -n 1 % qemu_path)
-exp = re.compile([Vv]ersion .*?,)
-match = exp.search(version_line)
-if match:
-kvm_userspace_version =  .join(match.group().split()[1:]).strip(,)
+matches = re.findall([Vv]ersion .*?,, version_line)
+if matches:
+kvm_userspace_version =  .join(matches[0].split()[1:]).strip(,)
 else:
 kvm_userspace_version = Unknown
 logging.debug(Could not fetch KVM userspace version)
 logging.debug(KVM userspace version: %s % kvm_userspace_version)
 test.write_test_keyval({kvm_userspace_version: kvm_userspace_version})
 
+# Execute any pre_commands
+if params.get(pre_command):
+process_command(test, params, env, params.get(pre_command),
+int(params.get(pre_command_timeout, 600)),
+params.get(pre_command_noncritical) == yes)
+
+# Preprocess all VMs and images
+process(test, params, env, preprocess_image, preprocess_vm)
+
 
 def postprocess(test, params, env):
 
@@ -276,8 +272,8 @@ def

[KVM-AUTOTEST PATCH v2] KVM test: take frequent screendumps during all tests

2010-03-22 Thread Michael Goldish
Screendumps are taken regularly and converted to JPEG format.
They are stored in .../debug/screendumps_VMname/.
Requires python-imaging.

- Enabled by 'take_regular_screendumps = yes' (naming suggestions welcome).
- Delay between screendumps is controlled by 'screendump_delay' (default 5).
- Compression quality is controlled by 'screendump_quality' (default 30).
- It's probably a good idea to dump them to /dev/shm before converting them
  in order to minimize disk use.  This can be enabled by
  'screendump_temp_dir = /dev/shm' (commented out by default because I'm not
  sure /dev/shm is available on all machines.)
- Screendumps are removed unless 'keep_screendumps'['_on_error'] is 'yes'.
  The recommended setting when submitting jobs from autoserv is
  'keep_screendumps_on_error = yes', which means screendumps are kept only if
  the test fails.  Keeping all screendumps may use up all of the server's
  storage space.

This patch sets reasonable defaults in tests_base.cfg.sample.

(It also makes sure post_command is executed last in the postprocessing
procedure -- otherwise post_command failure can prevent other postprocessing
steps (like removing the screendump dirs) from taking place.)

Changes from v1:
Print debug messages when starting or terminating the screendump thread.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_preprocessing.py  |   87 +--
 client/tests/kvm/tests_base.cfg.sample |   13 -
 2 files changed, 91 insertions(+), 9 deletions(-)

diff --git a/client/tests/kvm/kvm_preprocessing.py 
b/client/tests/kvm/kvm_preprocessing.py
index a92282a..774de3f 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -1,4 +1,4 @@
-import sys, os, time, commands, re, logging, signal, glob
+import sys, os, time, commands, re, logging, signal, glob, threading, shutil
 from autotest_lib.client.bin import test, utils
 from autotest_lib.client.common_lib import error
 import kvm_vm, kvm_utils, kvm_subprocess, ppm_utils
@@ -11,6 +11,10 @@ except ImportError:
 'distro.')
 
 
+_screendump_thread = None
+_screendump_thread_termination_event = None
+
+
 def preprocess_image(test, params):
 
 Preprocess a single QEMU image according to the instructions in params.
@@ -254,6 +258,15 @@ def preprocess(test, params, env):
 # Preprocess all VMs and images
 process(test, params, env, preprocess_image, preprocess_vm)
 
+# Start the screendump thread
+if params.get(take_regular_screendumps) == yes:
+logging.debug(Starting screendump thread)
+global _screendump_thread, _screendump_thread_termination_event
+_screendump_thread_termination_event = threading.Event()
+_screendump_thread = threading.Thread(target=_take_screendumps,
+  args=(test, params, env))
+_screendump_thread.start()
+
 
 def postprocess(test, params, env):
 
@@ -263,8 +276,16 @@ def postprocess(test, params, env):
 @param params: Dict containing all VM and image parameters.
 @param env: The environment (a dict-like object).
 
+# Postprocess all VMs and images
 process(test, params, env, postprocess_image, postprocess_vm)
 
+# Terminate the screendump thread
+global _screendump_thread, _screendump_thread_termination_event
+if _screendump_thread:
+logging.debug(Terminating screendump thread...)
+_screendump_thread_termination_event.set()
+_screendump_thread.join(10)
+
 # Warn about corrupt PPM files
 for f in glob.glob(os.path.join(test.debugdir, *.ppm)):
 if not ppm_utils.image_verify_ppm_file(f):
@@ -290,11 +311,13 @@ def postprocess(test, params, env):
 for f in glob.glob(os.path.join(test.debugdir, '*.ppm')):
 os.unlink(f)
 
-# Execute any post_commands
-if params.get(post_command):
-process_command(test, params, env, params.get(post_command),
-int(params.get(post_command_timeout, 600)),
-params.get(post_command_noncritical) == yes)
+# Should we keep the screendump dirs?
+if params.get(keep_screendumps) != yes:
+logging.debug('keep_screendumps' not specified; removing screendump 
+  dirs...)
+for d in glob.glob(os.path.join(test.debugdir, screendumps_*)):
+if os.path.isdir(d) and not os.path.islink(d):
+shutil.rmtree(d, ignore_errors=True)
 
 # Kill all unresponsive VMs
 if params.get(kill_unresponsive_vms) == yes:
@@ -318,6 +341,12 @@ def postprocess(test, params, env):
 env[tcpdump].close()
 del env[tcpdump]
 
+# Execute any post_commands
+if params.get(post_command):
+process_command(test, params, env, params.get(post_command),
+int(params.get(post_command_timeout, 600)),
+params.get(post_command_noncritical

[KVM-AUTOTEST PATCH 1/5] KVM test: kvm_preprocessing.py: minor style corrections

2010-03-21 Thread Michael Goldish
Also, fetch the KVM version before setting up the VMs.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_preprocessing.py |   58 +++-
 1 files changed, 27 insertions(+), 31 deletions(-)

diff --git a/client/tests/kvm/kvm_preprocessing.py 
b/client/tests/kvm/kvm_preprocessing.py
index e91d1da..e3a5501 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -58,8 +58,8 @@ def preprocess_vm(test, params, env, name):
 for_migration = False
 
 if params.get(start_vm_for_migration) == yes:
-logging.debug('start_vm_for_migration' specified; (re)starting VM 
with
-   -incoming option...)
+logging.debug('start_vm_for_migration' specified; (re)starting VM 
+  with -incoming option...)
 start_vm = True
 for_migration = True
 elif params.get(restart_vm) == yes:
@@ -187,12 +187,12 @@ def preprocess(test, params, env):
 @param env: The environment (a dict-like object).
 
 # Start tcpdump if it isn't already running
-if not env.has_key(address_cache):
+if address_cache not in env:
 env[address_cache] = {}
-if env.has_key(tcpdump) and not env[tcpdump].is_alive():
+if tcpdump in env and not env[tcpdump].is_alive():
 env[tcpdump].close()
 del env[tcpdump]
-if not env.has_key(tcpdump):
+if tcpdump not in env:
 command = /usr/sbin/tcpdump -npvi any 'dst port 68'
 logging.debug(Starting tcpdump (%s)..., command)
 env[tcpdump] = kvm_subprocess.kvm_tail(
@@ -208,35 +208,23 @@ def preprocess(test, params, env):
 
 # Destroy and remove VMs that are no longer needed in the environment
 requested_vms = kvm_utils.get_sub_dict_names(params, vms)
-for key in env.keys():
+for key in env:
 vm = env[key]
 if not kvm_utils.is_vm(vm):
 continue
 if not vm.name in requested_vms:
-logging.debug(VM '%s' found in environment but not required for
-   test; removing it... % vm.name)
+logging.debug(VM '%s' found in environment but not required for 
+  test; removing it... % vm.name)
 vm.destroy()
 del env[key]
 
-# Execute any pre_commands
-if params.get(pre_command):
-process_command(test, params, env, params.get(pre_command),
-int(params.get(pre_command_timeout, 600)),
-params.get(pre_command_noncritical) == yes)
-
-# Preprocess all VMs and images
-process(test, params, env, preprocess_image, preprocess_vm)
-
 # Get the KVM kernel module version and write it as a keyval
 logging.debug(Fetching KVM module version...)
 if os.path.exists(/dev/kvm):
-kvm_version = os.uname()[2]
 try:
-file = open(/sys/module/kvm/version, r)
-kvm_version = file.read().strip()
-file.close()
+kvm_version = open(/sys/module/kvm/version).read().strip()
 except:
-pass
+kvm_version = os.uname()[2]
 else:
 kvm_version = Unknown
 logging.debug(KVM module not loaded)
@@ -248,16 +236,24 @@ def preprocess(test, params, env):
 qemu_path = kvm_utils.get_path(test.bindir, params.get(qemu_binary,
qemu))
 version_line = commands.getoutput(%s -help | head -n 1 % qemu_path)
-exp = re.compile([Vv]ersion .*?,)
-match = exp.search(version_line)
-if match:
-kvm_userspace_version =  .join(match.group().split()[1:]).strip(,)
+matches = re.findall([Vv]ersion .*?,, version_line)
+if matches:
+kvm_userspace_version =  .join(matches[0].split()[1:]).strip(,)
 else:
 kvm_userspace_version = Unknown
 logging.debug(Could not fetch KVM userspace version)
 logging.debug(KVM userspace version: %s % kvm_userspace_version)
 test.write_test_keyval({kvm_userspace_version: kvm_userspace_version})
 
+# Execute any pre_commands
+if params.get(pre_command):
+process_command(test, params, env, params.get(pre_command),
+int(params.get(pre_command_timeout, 600)),
+params.get(pre_command_noncritical) == yes)
+
+# Preprocess all VMs and images
+process(test, params, env, preprocess_image, preprocess_vm)
+
 
 def postprocess(test, params, env):
 
@@ -276,8 +272,8 @@ def postprocess(test, params, env):
 
 # Should we convert PPM files to PNG format?
 if params.get(convert_ppm_files_to_png) == yes:
-logging.debug('convert_ppm_files_to_png' specified; converting PPM
-   files to PNG format...)
+logging.debug('convert_ppm_files_to_png' specified; converting PPM 
+  files to PNG format...)
 try:
 for f in glob.glob(os.path.join

[KVM-AUTOTEST PATCH 2/5] KVM test: kvm.py: make sure all dump_env() calls are inside 'finally' blocks

2010-03-21 Thread Michael Goldish
Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm.py |   29 +++--
 1 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/client/tests/kvm/kvm.py b/client/tests/kvm/kvm.py
index 9b8a10c..c6e146d 100644
--- a/client/tests/kvm/kvm.py
+++ b/client/tests/kvm/kvm.py
@@ -21,6 +21,7 @@ class kvm(test.test):
 (Online doc - Getting started with KVM testing)
 
 version = 1
+
 def run_once(self, params):
 # Report the parameters we've received and write them as keyvals
 logging.debug(Test parameters:)
@@ -33,7 +34,7 @@ class kvm(test.test):
 # Open the environment file
 env_filename = os.path.join(self.bindir, params.get(env, env))
 env = kvm_utils.load_env(env_filename, {})
-logging.debug(Contents of environment: %s % str(env))
+logging.debug(Contents of environment: %s, str(env))
 
 try:
 try:
@@ -50,22 +51,30 @@ class kvm(test.test):
 f.close()
 
 # Preprocess
-kvm_preprocessing.preprocess(self, params, env)
-kvm_utils.dump_env(env, env_filename)
+try:
+kvm_preprocessing.preprocess(self, params, env)
+finally:
+kvm_utils.dump_env(env, env_filename)
 # Run the test function
 run_func = getattr(test_module, run_%s % t_type)
-run_func(self, params, env)
-kvm_utils.dump_env(env, env_filename)
+try:
+run_func(self, params, env)
+finally:
+kvm_utils.dump_env(env, env_filename)
 
 except Exception, e:
 logging.error(Test failed: %s, e)
 logging.debug(Postprocessing on error...)
-kvm_preprocessing.postprocess_on_error(self, params, env)
-kvm_utils.dump_env(env, env_filename)
+try:
+kvm_preprocessing.postprocess_on_error(self, params, env)
+finally:
+kvm_utils.dump_env(env, env_filename)
 raise
 
 finally:
 # Postprocess
-kvm_preprocessing.postprocess(self, params, env)
-logging.debug(Contents of environment: %s, str(env))
-kvm_utils.dump_env(env, env_filename)
+try:
+kvm_preprocessing.postprocess(self, params, env)
+finally:
+kvm_utils.dump_env(env, env_filename)
+logging.debug(Contents of environment: %s, str(env))
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 4/5] KVM test: make kvm_stat usage optional

2010-03-21 Thread Michael Goldish
Relying on the test tag is not cool.  Use a dedicated parameter instead.
By default, all tests except build tests will use kvm_stat.

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_utils.py  |8 
 client/tests/kvm/tests_base.cfg.sample |3 +++
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index cc39b5d..5834539 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -845,8 +845,8 @@ def run_tests(test_list, job):
 @return: True, if all tests ran passed, False if any of them failed.
 
 status_dict = {}
-
 failed = False
+
 for dict in test_list:
 if dict.get(skip) == yes:
 continue
@@ -863,12 +863,12 @@ def run_tests(test_list, job):
 test_tag = dict.get(shortname)
 # Setting up kvm_stat profiling during test execution.
 # We don't need kvm_stat profiling on the build tests.
-if build in test_tag:
+if dict.get(run_kvm_stat) == yes:
+profile = True
+else:
 # None because it's the default value on the base_test class
 # and the value None is specifically checked there.
 profile = None
-else:
-profile = True
 
 if profile:
 job.profilers.add('kvm_stat')
diff --git a/client/tests/kvm/tests_base.cfg.sample 
b/client/tests/kvm/tests_base.cfg.sample
index 9963a44..b13aec4 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -40,6 +40,9 @@ nic_mode = user
 nic_script = scripts/qemu-ifup
 address_index = 0
 
+# Misc
+run_kvm_stat = yes
+
 
 # Tests
 variants:
-- 
1.5.4.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


<    1   2   3   4   5   6   7   >