diff --git a/.pylintrc b/.pylintrc index c48c0ef9..6266a81f 100644 --- a/.pylintrc +++ b/.pylintrc @@ -107,7 +107,7 @@ module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ const-rgx=(([A-Za-z_][A-Za-z0-9_]*)|(__.*__))$ # Regular expression which should only match correct class names -class-rgx=([A-Z_][a-zA-Z0-9]+|TC_\d\d_[a-zA-Z0-9]+)$ +class-rgx=([A-Z_][a-zA-Z0-9]+|TC_\d\d_[a-zA-Z0-9_]+)$ # Regular expression which should only match correct function names function-rgx=[a-z_][a-z0-9_]{2,30}$ diff --git a/qubes/tests/__init__.py b/qubes/tests/__init__.py index 3af4886e..79b22fc9 100644 --- a/qubes/tests/__init__.py +++ b/qubes/tests/__init__.py @@ -40,7 +40,7 @@ import qubes.config import qubes.events XMLPATH = '/var/lib/qubes/qubes-test.xml' -TEMPLATE = 'fedora-21' +TEMPLATE = 'fedora-23' VMPREFIX = 'test-' @@ -492,6 +492,7 @@ def load_tests(loader, tests, pattern): # pylint: disable=unused-argument # tool tests 'qubes.tests.int.tools.qubes_create', + 'qubes.tests.int.tools.qvm_run', ): tests.addTests(loader.loadTestsFromName(modname)) diff --git a/qubes/tests/int/tools/qvm_run.py b/qubes/tests/int/tools/qvm_run.py new file mode 100644 index 00000000..d75e8242 --- /dev/null +++ b/qubes/tests/int/tools/qvm_run.py @@ -0,0 +1,140 @@ +#!/usr/bin/python2 -O +# vim: fileencoding=utf-8 + +# +# The Qubes OS Project, https://www.qubes-os.org/ +# +# Copyright (C) 2015 Joanna Rutkowska +# Copyright (C) 2015 Wojtek Porczyk +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +import os +import StringIO +import sys +import tempfile +import unittest + +import qubes +import qubes.config +import qubes.tools.qvm_run +import qubes.vm + +import qubes.tests + + +@qubes.tests.skipUnlessDom0 +class TC_00_qvm_run(qubes.tests.SystemTestsMixin, qubes.tests.QubesTestCase): + def setUp(self): + super(TC_00_qvm_run, self).setUp() + self.app = qubes.Qubes.create_empty_store(qubes.tests.XMLPATH, + default_kernel=os.listdir(os.path.join( + qubes.config.system_path['qubes_base_dir'], + qubes.config.system_path['qubes_kernels_base_dir']))[0]) + self.app.add_new_vm(qubes.vm.templatevm.TemplateVM, + name=qubes.tests.TEMPLATE, + label='black') + + self.vm1 = self.app.add_new_vm(qubes.vm.appvm.AppVM, + name=self.make_vm_name('vm1'), + template=qubes.tests.TEMPLATE, + label='red') + self.vm1.create_on_disk() + + self.vm1.start() + self.app.save() + + self.sharedopts = ['--qubesxml', qubes.tests.XMLPATH] + + + def tearDown(self): + # clean up after testing --colour-output + sys.stdout = sys.__stdout__ + + + @staticmethod + def get_qvm_run_output(args): + assert '--localcmd' not in args, \ + 'get_qvm_run_output requires no --localcmd' + + outfile = tempfile.NamedTemporaryFile(prefix='qvm-run-output') + args = list(args) + args.insert(0, '--pass-io') + args.insert(1, '--localcmd') + args.insert(2, 'sh -c "dd of={}"'.format(outfile.name)) + + qubes.tools.qvm_run.main(args) + + outfile.seek(0) + output = outfile.read() + outfile.close() + + return output + + + def test_000_basic(self): + self.assertEqual(0, qubes.tools.qvm_run.main( + self.sharedopts + [self.vm1.name, 'true'])) + + def test_001_passio_retcode(self): + self.assertEqual(0, qubes.tools.qvm_run.main( + self.sharedopts + ['--pass-io', self.vm1.name, 'true'])) + self.assertEqual(1, qubes.tools.qvm_run.main( + self.sharedopts + ['--pass-io', self.vm1.name, 'false'])) + + def test_002_passio_localcmd(self): + self.assertEqual('aqq', self.get_qvm_run_output( + self.sharedopts + [self.vm1.name, 'printf aqq'])) + + def test_003_user(self): + self.assertNotEqual('0\n', self.get_qvm_run_output( + self.sharedopts + ['--user', 'user', self.vm1.name, 'id -u'])) + self.assertEqual('0\n', self.get_qvm_run_output( + self.sharedopts + ['--user', 'root', self.vm1.name, 'id -u'])) + + def test_004_autostart(self): + vm2 = self.app.add_new_vm(qubes.vm.appvm.AppVM, + name=self.make_vm_name('vm2'), + template=qubes.tests.TEMPLATE, + label='red') + vm2.create_on_disk() + self.app.save() + # and do not start it + self.assertEqual(-1, qubes.tools.qvm_run.main( + self.sharedopts + [vm2.name, 'true'])) + self.assertEqual(0, qubes.tools.qvm_run.main( + self.sharedopts + ['--autostart', vm2.name, 'true'])) + + def test_005_colour_output(self): + sys.stdout = StringIO.StringIO() + qubes.tools.qvm_run.main( + self.sharedopts + ['--colour-output', '32', self.vm1.name, 'true']) + self.assertEqual('\033[0;32m\033[0m', sys.stdout.getvalue()) + + def test_006_filter_esc(self): + self.assertEqual('\033', self.get_qvm_run_output( + self.sharedopts + ['--no-filter-escape-chars', self.vm1.name, + r'printf \\033'])) + self.assertEqual('_', self.get_qvm_run_output( + self.sharedopts + ['--filter-escape-chars', self.vm1.name, + r'printf \\033'])) + + @unittest.skip('test not implemented') + def test_007_gui(self): + raise NotImplementedError() + +#parser.add_argument('--gui', +#parser.add_argument('--no-gui', '--nogui', diff --git a/rpm_spec/core-dom0.spec b/rpm_spec/core-dom0.spec index d4b612c4..2b2c3489 100644 --- a/rpm_spec/core-dom0.spec +++ b/rpm_spec/core-dom0.spec @@ -271,6 +271,7 @@ fi %dir %{python_sitelib}/qubes/tests/int/tools %{python_sitelib}/qubes/tests/int/tools/__init__.py* %{python_sitelib}/qubes/tests/int/tools/qubes_create.py* +%{python_sitelib}/qubes/tests/int/tools/qvm_run.py* %dir %{python_sitelib}/qubes/qmemman %{python_sitelib}/qubes/qmemman/__init__.py*