Merge branch 'tests-20171020'
* tests-20171020: tests: fix asyncio usage some more places tests: fix reporting in network tests tests: domain-shutdown event race condition tests: improve events tests tests: fix logic error in wait_for_window() tests: cleanup QubesDB connection on domain remove
This commit is contained in:
commit
e2eaa57f65
@ -656,6 +656,16 @@ class SystemTestCase(QubesTestCase):
|
|||||||
|
|
||||||
self.addCleanup(self.cleanup_app)
|
self.addCleanup(self.cleanup_app)
|
||||||
|
|
||||||
|
self.app.add_handler('domain-delete', self.close_qdb_on_remove)
|
||||||
|
|
||||||
|
def close_qdb_on_remove(self, app, event, vm, **kwargs):
|
||||||
|
# only close QubesDB connection, do not perform other (destructive)
|
||||||
|
# actions of vm.close()
|
||||||
|
if vm._qdb_connection_watch is not None:
|
||||||
|
asyncio.get_event_loop().remove_reader(
|
||||||
|
vm._qdb_connection_watch.watch_fd())
|
||||||
|
vm._qdb_connection_watch.close()
|
||||||
|
vm._qdb_connection_watch = None
|
||||||
|
|
||||||
def cleanup_app(self):
|
def cleanup_app(self):
|
||||||
self.remove_test_vms()
|
self.remove_test_vms()
|
||||||
@ -943,7 +953,7 @@ class SystemTestCase(QubesTestCase):
|
|||||||
wait_count = 0
|
wait_count = 0
|
||||||
while subprocess.call(['xdotool', 'search', '--name', title],
|
while subprocess.call(['xdotool', 'search', '--name', title],
|
||||||
stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) \
|
stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) \
|
||||||
== int(not show):
|
!= int(not show):
|
||||||
wait_count += 1
|
wait_count += 1
|
||||||
if wait_count > timeout*10:
|
if wait_count > timeout*10:
|
||||||
self.fail("Timeout while waiting for {} window to {}".format(
|
self.fail("Timeout while waiting for {} window to {}".format(
|
||||||
|
@ -83,8 +83,10 @@ class TC_10_property(qubes.tests.QubesTestCase):
|
|||||||
|
|
||||||
def test_010_set(self):
|
def test_010_set(self):
|
||||||
self.holder.testprop1 = 'testvalue'
|
self.holder.testprop1 = 'testvalue'
|
||||||
self.assertEventFired(self.holder, 'property-pre-set:testprop1')
|
self.assertEventFired(self.holder, 'property-pre-set:testprop1',
|
||||||
self.assertEventFired(self.holder, 'property-set:testprop1')
|
kwargs={'name': 'testprop1', 'newvalue': 'testvalue'})
|
||||||
|
self.assertEventFired(self.holder, 'property-set:testprop1',
|
||||||
|
kwargs={'name': 'testprop1', 'newvalue': 'testvalue'})
|
||||||
|
|
||||||
def test_020_get(self):
|
def test_020_get(self):
|
||||||
self.holder.testprop1 = 'testvalue'
|
self.holder.testprop1 = 'testvalue'
|
||||||
@ -113,6 +115,14 @@ class TC_10_property(qubes.tests.QubesTestCase):
|
|||||||
self.assertEqual(holder.testprop1, 'defaultvalue')
|
self.assertEqual(holder.testprop1, 'defaultvalue')
|
||||||
holder.testprop1 = 'testvalue'
|
holder.testprop1 = 'testvalue'
|
||||||
self.assertEqual(holder.testprop1, 'testvalue')
|
self.assertEqual(holder.testprop1, 'testvalue')
|
||||||
|
self.assertEventFired(holder, 'property-pre-set:testprop1',
|
||||||
|
kwargs={'name': 'testprop1',
|
||||||
|
'newvalue': 'testvalue',
|
||||||
|
'oldvalue': 'defaultvalue'})
|
||||||
|
self.assertEventFired(holder, 'property-set:testprop1',
|
||||||
|
kwargs={'name': 'testprop1',
|
||||||
|
'newvalue': 'testvalue',
|
||||||
|
'oldvalue': 'defaultvalue'})
|
||||||
|
|
||||||
def test_030_set_setter(self):
|
def test_030_set_setter(self):
|
||||||
def setter(self2, prop, value):
|
def setter(self2, prop, value):
|
||||||
@ -127,6 +137,10 @@ class TC_10_property(qubes.tests.QubesTestCase):
|
|||||||
|
|
||||||
holder.testprop1 = 'testvalue'
|
holder.testprop1 = 'testvalue'
|
||||||
self.assertEqual(holder.testprop1, 'settervalue')
|
self.assertEqual(holder.testprop1, 'settervalue')
|
||||||
|
self.assertEventFired(holder, 'property-pre-set:testprop1',
|
||||||
|
kwargs={'name': 'testprop1', 'newvalue': 'settervalue'})
|
||||||
|
self.assertEventFired(holder, 'property-set:testprop1',
|
||||||
|
kwargs={'name': 'testprop1', 'newvalue': 'settervalue'})
|
||||||
|
|
||||||
def test_031_set_type(self):
|
def test_031_set_type(self):
|
||||||
class MyTestHolder(qubes.tests.TestEmitter, qubes.PropertyHolder):
|
class MyTestHolder(qubes.tests.TestEmitter, qubes.PropertyHolder):
|
||||||
@ -136,6 +150,10 @@ class TC_10_property(qubes.tests.QubesTestCase):
|
|||||||
holder.testprop1 = '5'
|
holder.testprop1 = '5'
|
||||||
self.assertEqual(holder.testprop1, 5)
|
self.assertEqual(holder.testprop1, 5)
|
||||||
self.assertNotEqual(holder.testprop1, '5')
|
self.assertNotEqual(holder.testprop1, '5')
|
||||||
|
self.assertEventFired(holder, 'property-pre-set:testprop1',
|
||||||
|
kwargs={'name': 'testprop1', 'newvalue': 5})
|
||||||
|
self.assertEventFired(holder, 'property-set:testprop1',
|
||||||
|
kwargs={'name': 'testprop1', 'newvalue': 5})
|
||||||
|
|
||||||
def test_080_delete(self):
|
def test_080_delete(self):
|
||||||
self.holder.testprop1 = 'testvalue'
|
self.holder.testprop1 = 'testvalue'
|
||||||
@ -150,6 +168,11 @@ class TC_10_property(qubes.tests.QubesTestCase):
|
|||||||
with self.assertRaises(AttributeError):
|
with self.assertRaises(AttributeError):
|
||||||
self.holder.testprop1
|
self.holder.testprop1
|
||||||
|
|
||||||
|
self.assertEventFired(self.holder, 'property-pre-del:testprop1',
|
||||||
|
kwargs={'name': 'testprop1', 'oldvalue': 'testvalue'})
|
||||||
|
self.assertEventFired(self.holder, 'property-del:testprop1',
|
||||||
|
kwargs={'name': 'testprop1', 'oldvalue': 'testvalue'})
|
||||||
|
|
||||||
def test_081_delete_by_assign(self):
|
def test_081_delete_by_assign(self):
|
||||||
self.holder.testprop1 = 'testvalue'
|
self.holder.testprop1 = 'testvalue'
|
||||||
try:
|
try:
|
||||||
@ -178,6 +201,10 @@ class TC_10_property(qubes.tests.QubesTestCase):
|
|||||||
del holder.testprop1
|
del holder.testprop1
|
||||||
|
|
||||||
self.assertEqual(holder.testprop1, 'defaultvalue')
|
self.assertEqual(holder.testprop1, 'defaultvalue')
|
||||||
|
self.assertEventFired(holder, 'property-pre-del:testprop1', kwargs={
|
||||||
|
'name': 'testprop1', 'oldvalue': 'testvalue'})
|
||||||
|
self.assertEventFired(holder, 'property-del:testprop1', kwargs={
|
||||||
|
'name': 'testprop1', 'oldvalue': 'testvalue'})
|
||||||
|
|
||||||
def test_090_write_once_set(self):
|
def test_090_write_once_set(self):
|
||||||
class MyTestHolder(qubes.tests.TestEmitter, qubes.PropertyHolder):
|
class MyTestHolder(qubes.tests.TestEmitter, qubes.PropertyHolder):
|
||||||
|
@ -124,6 +124,68 @@ class TC_00_Basic(qubes.tests.SystemTestCase):
|
|||||||
# one after another, private volume is gone
|
# one after another, private volume is gone
|
||||||
self.loop.run_until_complete(self.vm.storage.verify())
|
self.loop.run_until_complete(self.vm.storage.verify())
|
||||||
|
|
||||||
|
def _test_201_on_domain_pre_start(self, vm, event, **_kwargs):
|
||||||
|
'''Simulate domain crash just after startup'''
|
||||||
|
if not self.domain_shutdown_handled and not self.test_failure_reason:
|
||||||
|
self.test_failure_reason = \
|
||||||
|
'domain-shutdown event was not dispatched before subsequent ' \
|
||||||
|
'start'
|
||||||
|
self.domain_shutdown_handled = False
|
||||||
|
|
||||||
|
def _test_201_domain_shutdown_handler(self, vm, event, **kwargs):
|
||||||
|
if self.domain_shutdown_handled and not self.test_failure_reason:
|
||||||
|
self.test_failure_reason = 'domain-shutdown event received twice'
|
||||||
|
self.domain_shutdown_handled = True
|
||||||
|
|
||||||
|
@unittest.expectedFailure
|
||||||
|
def test_201_shutdown_event_race(self):
|
||||||
|
'''Regression test for 3164 - pure events edition'''
|
||||||
|
vmname = self.make_vm_name('appvm')
|
||||||
|
|
||||||
|
self.vm = self.app.add_new_vm(qubes.vm.appvm.AppVM,
|
||||||
|
name=vmname, template=self.app.default_template,
|
||||||
|
label='red')
|
||||||
|
# help the luck a little - don't wait for qrexec to easier win the race
|
||||||
|
self.vm.features['qrexec'] = False
|
||||||
|
self.loop.run_until_complete(self.vm.create_on_disk())
|
||||||
|
|
||||||
|
# do not throw exception from inside event handler - test framework
|
||||||
|
# will not recover from it (various objects leaks)
|
||||||
|
self.test_failure_reason = None
|
||||||
|
self.domain_shutdown_handled = False
|
||||||
|
self.vm.add_handler('domain-shutdown',
|
||||||
|
self._test_201_domain_shutdown_handler)
|
||||||
|
|
||||||
|
self.loop.run_until_complete(self.vm.start())
|
||||||
|
|
||||||
|
if self.test_failure_reason:
|
||||||
|
self.fail(self.test_failure_reason)
|
||||||
|
|
||||||
|
self.vm.add_handler('domain-pre-start',
|
||||||
|
self._test_201_on_domain_pre_start)
|
||||||
|
|
||||||
|
# kill it the way it does not give a chance for domain-shutdown it
|
||||||
|
# execute
|
||||||
|
self.vm.libvirt_domain.destroy()
|
||||||
|
|
||||||
|
# now, lets try to start the VM again, before domain-shutdown event
|
||||||
|
# got handled (#3164), and immediately trigger second domain-shutdown
|
||||||
|
self.vm.add_handler('domain-start', self._test_200_on_domain_start)
|
||||||
|
self.loop.run_until_complete(self.vm.start())
|
||||||
|
|
||||||
|
if self.test_failure_reason:
|
||||||
|
self.fail(self.test_failure_reason)
|
||||||
|
|
||||||
|
# and give a chance for both domain-shutdown handlers to execute
|
||||||
|
self.loop.run_until_complete(asyncio.sleep(1))
|
||||||
|
|
||||||
|
if self.test_failure_reason:
|
||||||
|
self.fail(self.test_failure_reason)
|
||||||
|
|
||||||
|
self.assertTrue(self.domain_shutdown_handled,
|
||||||
|
'second domain-shutdown event was not dispatched after domain '
|
||||||
|
'shutdown')
|
||||||
|
|
||||||
|
|
||||||
class TC_01_Properties(qubes.tests.SystemTestCase):
|
class TC_01_Properties(qubes.tests.SystemTestCase):
|
||||||
# pylint: disable=attribute-defined-outside-init
|
# pylint: disable=attribute-defined-outside-init
|
||||||
|
@ -53,7 +53,6 @@ class TC_04_DispVM(qubes.tests.SystemTestCase):
|
|||||||
self.app.default_dispvm = None
|
self.app.default_dispvm = None
|
||||||
super(TC_04_DispVM, self).tearDown()
|
super(TC_04_DispVM, self).tearDown()
|
||||||
|
|
||||||
@unittest.expectedFailure
|
|
||||||
def test_002_cleanup(self):
|
def test_002_cleanup(self):
|
||||||
self.loop.run_until_complete(self.testvm.start())
|
self.loop.run_until_complete(self.testvm.start())
|
||||||
|
|
||||||
@ -71,7 +70,6 @@ class TC_04_DispVM(qubes.tests.SystemTestCase):
|
|||||||
self.loop.run_until_complete(asyncio.sleep(1))
|
self.loop.run_until_complete(asyncio.sleep(1))
|
||||||
self.assertNotIn(dispvm_name, self.app.domains)
|
self.assertNotIn(dispvm_name, self.app.domains)
|
||||||
|
|
||||||
@unittest.expectedFailure
|
|
||||||
def test_003_cleanup_destroyed(self):
|
def test_003_cleanup_destroyed(self):
|
||||||
"""
|
"""
|
||||||
Check if DispVM is properly removed even if it terminated itself (#1660)
|
Check if DispVM is properly removed even if it terminated itself (#1660)
|
||||||
@ -152,6 +150,7 @@ class TC_20_DispVMMixin(object):
|
|||||||
p.stdin.write("xterm -e "
|
p.stdin.write("xterm -e "
|
||||||
"\"sh -c 'echo \\\"\033]0;{}\007\\\";read x;'\"\n".
|
"\"sh -c 'echo \\\"\033]0;{}\007\\\";read x;'\"\n".
|
||||||
format(window_title).encode())
|
format(window_title).encode())
|
||||||
|
self.loop.run_until_complete(p.stdin.drain())
|
||||||
self.wait_for_window(window_title)
|
self.wait_for_window(window_title)
|
||||||
|
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
@ -160,11 +159,15 @@ class TC_20_DispVMMixin(object):
|
|||||||
self.wait_for_window(window_title, show=False)
|
self.wait_for_window(window_title, show=False)
|
||||||
finally:
|
finally:
|
||||||
p.stdin.close()
|
p.stdin.close()
|
||||||
|
del p
|
||||||
finally:
|
finally:
|
||||||
self.loop.run_until_complete(dispvm.cleanup())
|
self.loop.run_until_complete(dispvm.cleanup())
|
||||||
dispvm_name = dispvm.name
|
dispvm_name = dispvm.name
|
||||||
del dispvm
|
del dispvm
|
||||||
|
|
||||||
|
# give it a time for shutdown + cleanup
|
||||||
|
self.loop.run_until_complete(asyncio.sleep(2))
|
||||||
|
|
||||||
self.assertNotIn(dispvm_name, self.app.domains,
|
self.assertNotIn(dispvm_name, self.app.domains,
|
||||||
"DispVM not removed from qubes.xml")
|
"DispVM not removed from qubes.xml")
|
||||||
|
|
||||||
@ -224,7 +227,6 @@ class TC_20_DispVMMixin(object):
|
|||||||
|
|
||||||
@unittest.skipUnless(spawn.find_executable('xdotool'),
|
@unittest.skipUnless(spawn.find_executable('xdotool'),
|
||||||
"xdotool not installed")
|
"xdotool not installed")
|
||||||
@unittest.expectedFailure
|
|
||||||
def test_030_edit_file(self):
|
def test_030_edit_file(self):
|
||||||
self.testvm1 = self.app.add_new_vm(qubes.vm.appvm.AppVM,
|
self.testvm1 = self.app.add_new_vm(qubes.vm.appvm.AppVM,
|
||||||
name=self.make_vm_name('vm1'),
|
name=self.make_vm_name('vm1'),
|
||||||
|
@ -769,7 +769,8 @@ class VmUpdatesMixin(object):
|
|||||||
self.testvm1 = self.app.domains[self.testvm1.qid]
|
self.testvm1 = self.app.domains[self.testvm1.qid]
|
||||||
self.loop.run_until_complete(self.testvm1.start())
|
self.loop.run_until_complete(self.testvm1.start())
|
||||||
p = self.loop.run_until_complete(
|
p = self.loop.run_until_complete(
|
||||||
self.testvm1.run(self.update_cmd, user='root'))
|
self.testvm1.run(self.update_cmd, user='root',
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE))
|
||||||
(stdout, stderr) = self.loop.run_until_complete(p.communicate())
|
(stdout, stderr) = self.loop.run_until_complete(p.communicate())
|
||||||
self.assertIn(p.returncode, self.exit_code_ok,
|
self.assertIn(p.returncode, self.exit_code_ok,
|
||||||
'{}: {}\n{}'.format(self.update_cmd, stdout, stderr))
|
'{}: {}\n{}'.format(self.update_cmd, stdout, stderr))
|
||||||
@ -844,11 +845,13 @@ SHA256:
|
|||||||
if self.template.count("debian") or self.template.count("whonix"):
|
if self.template.count("debian") or self.template.count("whonix"):
|
||||||
self.create_repo_apt()
|
self.create_repo_apt()
|
||||||
self.loop.run_until_complete(self.netvm_repo.run(
|
self.loop.run_until_complete(self.netvm_repo.run(
|
||||||
'cd /tmp/apt-repo && python -m SimpleHTTPServer 8080'))
|
'cd /tmp/apt-repo && python -m SimpleHTTPServer 8080',
|
||||||
|
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL))
|
||||||
elif self.template.count("fedora"):
|
elif self.template.count("fedora"):
|
||||||
self.create_repo_yum()
|
self.create_repo_yum()
|
||||||
self.loop.run_until_complete(self.netvm_repo.run(
|
self.loop.run_until_complete(self.netvm_repo.run(
|
||||||
'cd /tmp/yum-repo && python -m SimpleHTTPServer 8080'))
|
'cd /tmp/yum-repo && python -m SimpleHTTPServer 8080',
|
||||||
|
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL))
|
||||||
else:
|
else:
|
||||||
# not reachable...
|
# not reachable...
|
||||||
self.skipTest("Template {} not supported by this test".format(
|
self.skipTest("Template {} not supported by this test".format(
|
||||||
@ -923,14 +926,16 @@ SHA256:
|
|||||||
|
|
||||||
# install test package
|
# install test package
|
||||||
p = self.loop.run_until_complete(self.testvm1.run(
|
p = self.loop.run_until_complete(self.testvm1.run(
|
||||||
self.install_cmd.format('test-pkg'), user='root'))
|
self.install_cmd.format('test-pkg'), user='root',
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE))
|
||||||
(stdout, stderr) = self.loop.run_until_complete(p.communicate())
|
(stdout, stderr) = self.loop.run_until_complete(p.communicate())
|
||||||
self.assertIn(self.loop.run_until_complete(p.wait()), self.exit_code_ok,
|
self.assertIn(self.loop.run_until_complete(p.wait()), self.exit_code_ok,
|
||||||
'{}: {}\n{}'.format(self.update_cmd, stdout, stderr))
|
'{}: {}\n{}'.format(self.update_cmd, stdout, stderr))
|
||||||
|
|
||||||
# verify if it was really installed
|
# verify if it was really installed
|
||||||
p = self.loop.run_until_complete(self.testvm1.run(
|
p = self.loop.run_until_complete(self.testvm1.run(
|
||||||
self.install_test_cmd.format('test-pkg'), user='root'))
|
self.install_test_cmd.format('test-pkg'), user='root',
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE))
|
||||||
(stdout, stderr) = self.loop.run_until_complete(p.communicate())
|
(stdout, stderr) = self.loop.run_until_complete(p.communicate())
|
||||||
self.assertIn(self.loop.run_until_complete(p.wait()), self.exit_code_ok,
|
self.assertIn(self.loop.run_until_complete(p.wait()), self.exit_code_ok,
|
||||||
'{}: {}\n{}'.format(self.update_cmd, stdout, stderr))
|
'{}: {}\n{}'.format(self.update_cmd, stdout, stderr))
|
||||||
|
@ -774,14 +774,14 @@ class TC_00_AppVMMixin(object):
|
|||||||
finally:
|
finally:
|
||||||
self.app.clockvm = None
|
self.app.clockvm = None
|
||||||
|
|
||||||
@unittest.expectedFailure
|
|
||||||
def test_250_resize_private_img(self):
|
def test_250_resize_private_img(self):
|
||||||
"""
|
"""
|
||||||
Test private.img resize, both offline and online
|
Test private.img resize, both offline and online
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
# First offline test
|
# First offline test
|
||||||
self.testvm1.storage.resize('private', 4*1024**3)
|
self.loop.run_until_complete(
|
||||||
|
self.testvm1.storage.resize('private', 4*1024**3))
|
||||||
self.loop.run_until_complete(self.testvm1.start())
|
self.loop.run_until_complete(self.testvm1.start())
|
||||||
df_cmd = '( df --output=size /rw || df /rw | awk \'{print $2}\' )|' \
|
df_cmd = '( df --output=size /rw || df /rw | awk \'{print $2}\' )|' \
|
||||||
'tail -n 1'
|
'tail -n 1'
|
||||||
@ -797,7 +797,7 @@ class TC_00_AppVMMixin(object):
|
|||||||
new_size, _ = self.loop.run_until_complete(
|
new_size, _ = self.loop.run_until_complete(
|
||||||
self.testvm1.run_for_stdio(df_cmd))
|
self.testvm1.run_for_stdio(df_cmd))
|
||||||
# some safety margin for FS metadata
|
# some safety margin for FS metadata
|
||||||
self.assertGreater(int(new_size.strip()), 5.8*1024**2)
|
self.assertGreater(int(new_size.strip()), 5.7*1024**2)
|
||||||
|
|
||||||
@unittest.skipUnless(spawn.find_executable('xdotool'),
|
@unittest.skipUnless(spawn.find_executable('xdotool'),
|
||||||
"xdotool not installed")
|
"xdotool not installed")
|
||||||
@ -902,8 +902,11 @@ int main(int argc, char **argv) {
|
|||||||
# passing is unreliable while the process is still running
|
# passing is unreliable while the process is still running
|
||||||
alloc1.stdin.write(b'\n')
|
alloc1.stdin.write(b'\n')
|
||||||
yield from alloc1.stdin.drain()
|
yield from alloc1.stdin.drain()
|
||||||
alloc_out = yield from alloc1.stdout.read(
|
try:
|
||||||
|
alloc_out = yield from alloc1.stdout.readexactly(
|
||||||
len('Stage1\nStage2\nStage3\n'))
|
len('Stage1\nStage2\nStage3\n'))
|
||||||
|
except asyncio.IncompleteReadError as e:
|
||||||
|
alloc_out = e.partial
|
||||||
|
|
||||||
if b'Stage3' not in alloc_out:
|
if b'Stage3' not in alloc_out:
|
||||||
# read stderr only in case of failed assert (), but still have nice
|
# read stderr only in case of failed assert (), but still have nice
|
||||||
@ -923,11 +926,11 @@ int main(int argc, char **argv) {
|
|||||||
# help xdotool a little...
|
# help xdotool a little...
|
||||||
yield from asyncio.sleep(2)
|
yield from asyncio.sleep(2)
|
||||||
# get window ID
|
# get window ID
|
||||||
winid = yield from asyncio.get_event_loop().run_in_executor(
|
winid = (yield from asyncio.get_event_loop().run_in_executor(None,
|
||||||
subprocess.check_output,
|
subprocess.check_output,
|
||||||
['xdotool', 'search', '--sync', '--onlyvisible', '--class',
|
['xdotool', 'search', '--sync', '--onlyvisible', '--class',
|
||||||
self.testvm1.name + ':.*erminal']).decode()
|
self.testvm1.name + ':.*erminal'])).decode()
|
||||||
xprop = yield from asyncio.get_event_loop().run_in_executor(
|
xprop = yield from asyncio.get_event_loop().run_in_executor(None,
|
||||||
subprocess.check_output,
|
subprocess.check_output,
|
||||||
['xprop', '-notype', '-id', winid, '_QUBES_VMWINDOWID'])
|
['xprop', '-notype', '-id', winid, '_QUBES_VMWINDOWID'])
|
||||||
vm_winid = xprop.decode().strip().split(' ')[4]
|
vm_winid = xprop.decode().strip().split(' ')[4]
|
||||||
@ -943,7 +946,7 @@ int main(int argc, char **argv) {
|
|||||||
# some memory
|
# some memory
|
||||||
alloc2 = yield from self.testvm1.run(
|
alloc2 = yield from self.testvm1.run(
|
||||||
'ulimit -l unlimited; /home/user/allocator {}'.format(memory_pages),
|
'ulimit -l unlimited; /home/user/allocator {}'.format(memory_pages),
|
||||||
user='root')
|
user='root', stdout=subprocess.PIPE)
|
||||||
yield from alloc2.stdout.read(len('Stage1\n'))
|
yield from alloc2.stdout.read(len('Stage1\n'))
|
||||||
|
|
||||||
# wait for damage notify - top updates every 3 sec by default
|
# wait for damage notify - top updates every 3 sec by default
|
||||||
@ -955,7 +958,7 @@ int main(int argc, char **argv) {
|
|||||||
vm_image, _ = yield from self.testvm1.run_for_stdio(
|
vm_image, _ = yield from self.testvm1.run_for_stdio(
|
||||||
'import -window {} pnm:-'.format(vm_winid))
|
'import -window {} pnm:-'.format(vm_winid))
|
||||||
|
|
||||||
dom0_image = yield from asyncio.get_event_loop().run_in_executor(
|
dom0_image = yield from asyncio.get_event_loop().run_in_executor(None,
|
||||||
subprocess.check_output, ['import', '-window', winid, 'pnm:-'])
|
subprocess.check_output, ['import', '-window', winid, 'pnm:-'])
|
||||||
|
|
||||||
if vm_image != dom0_image:
|
if vm_image != dom0_image:
|
||||||
|
Loading…
Reference in New Issue
Block a user