summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2011-08-23 19:18:23 +0300
committerAlon Levy <alevy@redhat.com>2011-08-23 19:18:23 +0300
commit51ac99dbf4b270ab70a78b361cc34ff7077012c8 (patch)
treed2f0b90ff8b06dbc5bf77ed71f6fb4744f10a29f
parent0b169b7014d657da6a64848168db7136ecbb191f (diff)
server: add tester and todo for multiple client support
-rw-r--r--TODO.multiclient16
-rwxr-xr-xserver/tests/test_multiple.py121
2 files changed, 137 insertions, 0 deletions
diff --git a/TODO.multiclient b/TODO.multiclient
new file mode 100644
index 00000000..92d8a7d5
--- /dev/null
+++ b/TODO.multiclient
@@ -0,0 +1,16 @@
+Real secondary clients:
+ currently the "main" is the client that connects when there are no clients. Main
+ should be one of the clients, determined by any means - seniority is fine.
+
+SPICE_MSG_MAIN_CHANNEL_IN_USE
+SPICE_MSG_MAIN_CHANNEL_AVAILABLE
+SPICE_MSG_MAIN_CHANNEL_NEW
+ - allow channels to become available or not. Useful for USB redirection
+ and later chardev remoting in the case where there chardev/usbredir channel is
+ single user only, so only one of the clients can use it.
+
+Chardev channel: allow adding a chardev channel without any server changes:
+ qemu -spicevmc name=generic,channelname=bla,id=bla -mon chardev=bla
+ Note: client will still need to decide what to do with it of course. So the channelname
+ will have to have a predefined meaning.
+
diff --git a/server/tests/test_multiple.py b/server/tests/test_multiple.py
new file mode 100755
index 00000000..ce03c94e
--- /dev/null
+++ b/server/tests/test_multiple.py
@@ -0,0 +1,121 @@
+#!/usr/bin/python
+
+"""
+Example usage:
+./test_multiple.py test_display_no_ssl --log test.log
+
+Resulting test.log file (single test, stopped with Ctrl-C with 15 clients):
+
+0 162212
+1 154156
+2 154424
+3 154952
+4 155352
+5 155616
+6 156280
+7 222084
+8 222612
+9 230820
+10 230820
+11 230820
+12 230820
+13 296356
+14 296356
+
+"""
+
+import argparse
+import os
+import sys
+import subprocess
+import atexit
+import socket
+import time
+
+def killall(procs):
+ for p in procs:
+ print "killing %d" % p.pid
+ p.kill()
+ p.wait()
+
+def cleanup():
+ killall(clients + [test_process])
+
+def wait_for_port(port):
+ if not port:
+ return
+ # TODO: do this without actually opening the port - maybe just look at /proc/qemu_process_id/fd?
+ s = socket.socket(socket.AF_INET)
+ while True:
+ try:
+ s.connect(('localhost', port))
+ s.close()
+ break
+ except:
+ time.sleep(1)
+ pass
+
+def get_vm_size(pid):
+ """ read from /proc/<pid>/status, VmSize, in KiloBytes """
+ return int([x for x in open('/proc/%s/status' % pid).readlines() if 'VmSize' in x][0].split()[1])
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--client', default='spicy')
+parser.add_argument('--start-count', default=1, type=int)
+parser.add_argument('--end-count', default=50, type=int)
+parser.add_argument('--log', default='-')
+parser.add_argument('--sleep', default=3, type=int)
+args, rest = parser.parse_known_args(sys.argv[1:])
+client = os.popen('which %s' % args.client).read().strip()
+if not os.path.exists(client):
+ print "supply a valid client. %s does not exist" % (args.client)
+ sys.exit(1)
+
+if not rest or len(rest) < 1 or not os.path.exists(rest[0]):
+ print "supply one argument that is the tester you wish to run"
+ sys.exit(1)
+
+prog = rest[0]
+port = {
+'test_display_no_ssl': 5912,
+'test_display_streaming': 5912,
+'test_just_sockets_no_ssl': 5912,
+'test_playback': 5701,
+}.get(prog, None)
+
+if args.log == '-':
+ log = sys.stdout
+else:
+ log = open(args.log, 'a+')
+
+log.write('#%s\n' % time.time())
+
+# kill leftovers from previous invocation
+os.system('killall lt-%s' % prog)
+
+if prog[0] != '/':
+ prog = os.path.join('.', prog)
+
+if not port:
+ print "unknown port for %r" % prog
+
+print "prog = %r" % prog
+print "client = %r" % client
+print "range = %d..%d" % (args.start_count, args.end_count)
+atexit.register(cleanup)
+os.environ['SPICE_DEBUG_ALLOW_MC'] = '1'
+test_process = subprocess.Popen([prog], executable=prog)
+wait_for_port(port)
+for count in xrange(args.start_count, args.end_count):
+ print "starting %d clients" % count
+ clients = [subprocess.Popen(args=[client, '-h', 'localhost', '-p', str(port)],
+ executable=client) for i in xrange(count)]
+ print "sleeping %d" % (args.sleep * count)
+ time.sleep(args.sleep * count)
+ vmsize = "%d %d" % (i, get_vm_size(test_process.pid))
+ print vmsize
+ log.write(vmsize + '\n')
+ log.flush()
+ killall(clients)
+
+test_process.wait()