1 import random, os, logging 2 from autotest_lib.client.bin import test, utils 3 from autotest_lib.client.common_lib import error 4 5 6 class kvmtest(test.test): 7 version = 1 8 9 def initialize(self): 10 self.job.require_gcc() 11 12 13 def setup(self, tarball = 'kvm-test.tar.gz'): 14 tarball = utils.unmap_url(self.bindir, tarball, self.tmpdir) 15 utils.extract_tarball_to_dir(tarball, self.srcdir) 16 os.chdir(self.srcdir) 17 utils.system('python setup.py install') 18 19 20 def execute(self, testdir = '', args = ''): 21 dirs = [] 22 results = [] 23 passed = 0 24 failed = 0 25 26 # spawn vncserver if needed 27 if not os.environ.has_key('DISPLAY'): 28 logging.info("No DISPLAY set in environment, spawning vncserver...") 29 display = self.__create_vncserver(os.path.expanduser("~/.vnc")) 30 logging.info("Setting DISPLAY=%s"%(display)) 31 os.environ['DISPLAY'] = display 32 33 # build a list of dirs with 'vm.log' files 34 os.path.walk(testdir, self.__has_vmlog, dirs) 35 36 for d in dirs: 37 replaydir = os.path.join(self.resultsdir, os.path.basename(d)) 38 os.mkdir(replaydir) 39 logfile = replaydir + "/%s.log" %(os.path.basename(d)) 40 41 os.chdir(d) 42 rv = utils.system("kvm-test-replay > %s" %(logfile), 1) 43 44 results.append((d, rv)) 45 if rv != 0: 46 screenshot = self.__get_expected_file(logfile) 47 expected = "expected-%03d.png" % random.randint(0, 999) 48 dest = os.path.join(replaydir,expected) 49 50 # make a copy of the screen shot 51 utils.system("cp %s %s" % (screenshot, dest), 1) 52 53 # move the failure 54 utils.system("mv failure-*.png %s" % replaydir, 1) 55 56 # generate html output 57 self.__format_results(results) 58 59 # produce pass/fail output 60 for (x, y) in results: 61 if y != 0: 62 logging.error("FAIL: '%s' with rv %s" % (x, y)) 63 failed = failed + 1 64 else: 65 logging.info("PASS: '%s' with rv %s" % (x, y)) 66 passed = passed + 1 67 68 logging.info("Summary: Passed %d Failed %d" % (passed, failed)) 69 # if we had any tests not passed, fail entire test 70 if failed != 0: 71 raise error.TestError('kvm-test-replay') 72 73 74 def __get_expected_file(self, logfile): 75 # pull out screeshot name from logfile 76 return filter(lambda x: "Expected" in x, 77 open(logfile, 'r').readlines())\ 78 [0].split('{')[1].split('}')[0] 79 80 81 def __create_vncserver(self, dirname): 82 """ 83 this test may run without an X connection in kvm/qemu needs 84 a DISPLAY to push the vga buffer. If a DISPLAY is not set 85 in the environment, then attempt to spawn a vncserver, and 86 change env DISPLAY so that kvmtest can run 87 """ 88 for pidfile in utils.locate("*:*.pid", dirname): 89 pid = open(pidfile, 'r').readline().strip() 90 # if the server is still active, just use it for display 91 if os.path.exists('/proc/%s/status' % pid): 92 vncdisplay = os.path.basename(pidfile)\ 93 .split(":")[1].split(".")[0] 94 logging.info("Found vncserver on port %s, using it" % vncdisplay) 95 return ':%s.0' %(vncdisplay) 96 97 # none of the vncserver were still alive, spawn our own and 98 # return the display whack existing server first, then spawn it 99 vncdisplay = "1" 100 logging.info("Spawning vncserver on port %s" % vncdisplay) 101 utils.system('vncserver :%s' % vncdisplay) 102 return ':%s.0' % vncdisplay 103 104 105 def __has_vmlog(self, arg, dirname, names): 106 if os.path.exists(os.path.join(dirname, 'vm.log')): 107 arg.append(dirname) 108 109 110 def __gen_fail_html(self, testdir): 111 # generate a failure index.html to display the expected and failure 112 # images 113 fail_dir = os.path.join(self.resultsdir, os.path.basename(testdir)) 114 fail_index = os.path.join(fail_dir, "index.html") 115 116 # lambda helpers for pulling out image files 117 is_png = lambda x: x.endswith('.png') 118 failure_filter = lambda x: x.startswith('failure') and is_png(x) 119 expected_filter = lambda x: x.startswith('expected') and is_png(x) 120 121 failure_img = filter(failure_filter, os.listdir(fail_dir))[0] 122 expected_img = filter(expected_filter, os.listdir(fail_dir))[0] 123 if not failure_img or not expected_img: 124 raise "Failed to find images" 125 126 fail_buff = "<html><table border=1><tr><th>Barrier Diff</th>\n" + \ 127 "<th>Expected Barrier</th><th>Failure</th></tr><tr><td></td>\n" 128 for img in expected_img, failure_img: 129 fail_buff = fail_buff + "<td><a href=\"%s\"><img width=320 " \ 130 "height=200 src=\"%s\"></a></td>\n" % (img, img) 131 132 fail_buff = fail_buff + "</tr></table></html>\n" 133 134 fh = open(fail_index, "w+") 135 fh.write(fail_buff) 136 fh.close() 137 138 def __format_results(self, results): 139 # generate kvmtest/index.html and an index.html for each fail 140 test_index = os.path.join(self.outputdir, "index.html") 141 test_buff = "<html><table border=1><tr><th>Test</th>\n" 142 143 for (x,y) in results: 144 test_buff = test_buff + "<th>%s</th>\n" % os.path.basename(x) 145 146 test_buff = test_buff + "</tr><tr><td></td>\n" 147 148 for (x,y) in results: 149 if y != 0: 150 fail = "<td><a href=\"results/%s/\">FAIL</a></td>\n" % os.path.basename(x) 151 test_buff = test_buff + fail 152 self.__gen_fail_html(x) 153 else: 154 test_buff = test_buff + "<td>GOOD</td>\n" 155 156 test_buff = test_buff + "</tr></table></html>" 157 158 fh = open(test_index, "w+") 159 fh.write(test_buff) 160 fh.close() 161