Example #1
0
    def test_kconfig_add(self):
        want_kconfig = kunit_config.Kconfig()
        want_kconfig.add_entry('NOT_REAL', 'y')

        tree = kunit_kernel.LinuxSourceTree('',
                                            kconfig_add=['CONFIG_NOT_REAL=y'])
        self.assertTrue(want_kconfig.is_subset_of(tree._kconfig),
                        msg=tree._kconfig)
Example #2
0
def main(argv, linux=None):
    parser = argparse.ArgumentParser(
        description='Helps writing and running KUnit tests.')
    subparser = parser.add_subparsers(dest='subcommand')

    run_parser = subparser.add_parser('run', help='Runs KUnit tests.')
    run_parser.add_argument('--raw_output',
                            help='don\'t format output from kernel',
                            action='store_true')

    run_parser.add_argument(
        '--timeout',
        help='maximum number of seconds to allow for all tests '
        'to run. This does not include time taken to build the '
        'tests.',
        type=int,
        default=300,
        metavar='timeout')

    run_parser.add_argument(
        '--jobs',
        help='As in the make command, "Specifies  the number of '
        'jobs (commands) to run simultaneously."',
        type=int,
        default=8,
        metavar='jobs')

    run_parser.add_argument(
        '--build_dir',
        help='As in the make command, it specifies the build '
        'directory.',
        type=str,
        default=None,
        metavar='build_dir')

    run_parser.add_argument('--defconfig',
                            help='Uses a default kunitconfig.',
                            action='store_true')

    cli_args = parser.parse_args(argv)

    if cli_args.subcommand == 'run':
        if cli_args.defconfig:
            create_default_kunitconfig()

        if not linux:
            linux = kunit_kernel.LinuxSourceTree()

        request = KunitRequest(cli_args.raw_output, cli_args.timeout,
                               cli_args.jobs, cli_args.build_dir,
                               cli_args.defconfig)
        result = run_tests(linux, request)
        if result.status != KunitStatus.SUCCESS:
            sys.exit(1)
    else:
        parser.print_help()
Example #3
0
    def test_build_reconfig_no_config(self):
        with tempfile.TemporaryDirectory('') as build_dir:
            with open(kunit_kernel.get_kunitconfig_path(build_dir), 'w') as f:
                f.write('CONFIG_KUNIT=y')

            tree = kunit_kernel.LinuxSourceTree(build_dir)
            mock_build_config = mock.patch.object(tree, 'build_config').start()

            # Should generate the .config
            self.assertTrue(tree.build_reconfig(build_dir, make_options=[]))
            mock_build_config.assert_called_once_with(build_dir, [])
Example #4
0
    def test_multiple_kunitconfig_invalid(self):
        with tempfile.TemporaryDirectory('') as dir:
            other = os.path.join(dir, 'otherkunitconfig')
            with open(os.path.join(dir, '.kunitconfig'), 'w') as f:
                f.write('CONFIG_KUNIT=y')
            with open(other, 'w') as f:
                f.write('CONFIG_KUNIT=m')

            with self.assertRaisesRegex(kunit_kernel.ConfigError,
                                        '(?s)Multiple values.*CONFIG_KUNIT'):
                kunit_kernel.LinuxSourceTree('',
                                             kunitconfig_paths=[dir, other])
Example #5
0
    def test_build_reconfig_no_config(self):
        with tempfile.TemporaryDirectory('') as build_dir:
            with open(kunit_kernel.get_kunitconfig_path(build_dir), 'w') as f:
                f.write('CONFIG_KUNIT=y')

            tree = kunit_kernel.LinuxSourceTree(build_dir)
            # Stub out the source tree operations, so we don't have
            # the defaults for any given architecture get in the
            # way.
            tree._ops = kunit_kernel.LinuxSourceTreeOperations('none', None)
            mock_build_config = mock.patch.object(tree, 'build_config').start()

            # Should generate the .config
            self.assertTrue(tree.build_reconfig(build_dir, make_options=[]))
            mock_build_config.assert_called_once_with(build_dir, [])
Example #6
0
def tree_from_args(cli_args: argparse.Namespace) -> kunit_kernel.LinuxSourceTree:
	"""Returns a LinuxSourceTree based on the user's arguments."""
	# Allow users to specify multiple arguments in one string, e.g. '-smp 8'
	qemu_args: List[str] = []
	if cli_args.qemu_args:
		for arg in cli_args.qemu_args:
			qemu_args.extend(shlex.split(arg))

	return kunit_kernel.LinuxSourceTree(cli_args.build_dir,
			kunitconfig_paths=cli_args.kunitconfig,
			kconfig_add=cli_args.kconfig_add,
			arch=cli_args.arch,
			cross_compile=cli_args.cross_compile,
			qemu_config_path=cli_args.qemu_config,
			extra_qemu_args=qemu_args)
Example #7
0
	def test_run_kernel_hits_exception(self):
		def fake_start(unused_args, unused_build_dir):
			return subprocess.Popen(['echo "hi\nbye"'], shell=True, text=True, stdout=subprocess.PIPE)

		with tempfile.TemporaryDirectory('') as build_dir:
			tree = kunit_kernel.LinuxSourceTree(build_dir, load_config=False)
			mock.patch.object(tree._ops, 'start', side_effect=fake_start).start()

			with self.assertRaises(ValueError):
				for line in tree.run_kernel(build_dir=build_dir):
					self.assertEqual(line, 'hi\n')
					raise ValueError('uh oh, did not read all output')

			with open(kunit_kernel.get_outfile_path(build_dir), 'rt') as outfile:
				self.assertEqual(outfile.read(), 'hi\nbye\n', msg='Missing some output')
Example #8
0
    def test_build_reconfig_existing_config(self):
        with tempfile.TemporaryDirectory('') as build_dir:
            # Existing .config is a superset, should not touch it
            with open(kunit_kernel.get_kunitconfig_path(build_dir), 'w') as f:
                f.write('CONFIG_KUNIT=y')
            with open(kunit_kernel.get_old_kunitconfig_path(build_dir),
                      'w') as f:
                f.write('CONFIG_KUNIT=y')
            with open(kunit_kernel.get_kconfig_path(build_dir), 'w') as f:
                f.write('CONFIG_KUNIT=y\nCONFIG_KUNIT_TEST=y')

            tree = kunit_kernel.LinuxSourceTree(build_dir)
            mock_build_config = mock.patch.object(tree, 'build_config').start()

            self.assertTrue(tree.build_reconfig(build_dir, make_options=[]))
            self.assertEqual(mock_build_config.call_count, 0)
Example #9
0
	def test_build_reconfig_add_config_line(self):
		tempConfig = tempfile.NamedTemporaryFile(delete=False, mode="w+")

		kconfig = kunit_config.Kconfig()

		operations = TestLinuxSourceTreeOperationsAddLine(tempConfig.name)

		with mock.patch.object(kunit_kernel, 'KCONFIG_PATH', tempConfig.name):
			tree = kunit_kernel.LinuxSourceTree(kconfig_provider = TestConfigProvider(kconfig),
				linux_build_operations = operations)

			tempConfig.write(str('CONFIG_TEST=n\nCONFIG_MMU=y\n'))
			tempConfig.seek(0)

			returnValue = tree.build_reconfig()
			self.assertEquals(returnValue.status, kunit_kernel.ConfigStatus.SUCCESS,
				returnValue.info)
Example #10
0
    def test_build_reconfig_remove_option(self):
        with tempfile.TemporaryDirectory('') as build_dir:
            # We removed CONFIG_KUNIT_TEST=y from our .kunitconfig...
            with open(kunit_kernel.get_kunitconfig_path(build_dir), 'w') as f:
                f.write('CONFIG_KUNIT=y')
            with open(kunit_kernel.get_old_kunitconfig_path(build_dir),
                      'w') as f:
                f.write('CONFIG_KUNIT=y\nCONFIG_KUNIT_TEST=y')
            with open(kunit_kernel.get_kconfig_path(build_dir), 'w') as f:
                f.write('CONFIG_KUNIT=y\nCONFIG_KUNIT_TEST=y')

            tree = kunit_kernel.LinuxSourceTree(build_dir)
            mock_build_config = mock.patch.object(tree, 'build_config').start()

            # ... so we should trigger a call to build_config()
            self.assertTrue(tree.build_reconfig(build_dir, make_options=[]))
            mock_build_config.assert_called_once_with(build_dir, [])
Example #11
0
    def test_multiple_kunitconfig(self):
        want_kconfig = kunit_config.Kconfig()
        want_kconfig.add_entry('KUNIT', 'y')
        want_kconfig.add_entry('KUNIT_TEST', 'm')

        with tempfile.TemporaryDirectory('') as dir:
            other = os.path.join(dir, 'otherkunitconfig')
            with open(os.path.join(dir, '.kunitconfig'), 'w') as f:
                f.write('CONFIG_KUNIT=y')
            with open(other, 'w') as f:
                f.write('CONFIG_KUNIT_TEST=m')
                pass

            tree = kunit_kernel.LinuxSourceTree('',
                                                kunitconfig_paths=[dir, other])
            self.assertTrue(want_kconfig.is_subset_of(tree._kconfig),
                            msg=tree._kconfig)
Example #12
0
    def test_build_reconfig_existing_config(self):
        with tempfile.TemporaryDirectory('') as build_dir:
            # Existing .config is a superset, should not touch it
            with open(kunit_kernel.get_kunitconfig_path(build_dir), 'w') as f:
                f.write('CONFIG_KUNIT=y')
            with open(kunit_kernel.get_old_kunitconfig_path(build_dir),
                      'w') as f:
                f.write('CONFIG_KUNIT=y')
            with open(kunit_kernel.get_kconfig_path(build_dir), 'w') as f:
                f.write('CONFIG_KUNIT=y\nCONFIG_KUNIT_TEST=y')

            tree = kunit_kernel.LinuxSourceTree(build_dir)
            # Stub out the source tree operations, so we don't have
            # the defaults for any given architecture get in the
            # way.
            tree._ops = kunit_kernel.LinuxSourceTreeOperations('none', None)
            mock_build_config = mock.patch.object(tree, 'build_config').start()

            self.assertTrue(tree.build_reconfig(build_dir, make_options=[]))
            self.assertEqual(mock_build_config.call_count, 0)
Example #13
0
    def test_build_reconfig_remove_option(self):
        with tempfile.TemporaryDirectory('') as build_dir:
            # We removed CONFIG_KUNIT_TEST=y from our .kunitconfig...
            with open(kunit_kernel.get_kunitconfig_path(build_dir), 'w') as f:
                f.write('CONFIG_KUNIT=y')
            with open(kunit_kernel.get_old_kunitconfig_path(build_dir),
                      'w') as f:
                f.write('CONFIG_KUNIT=y\nCONFIG_KUNIT_TEST=y')
            with open(kunit_kernel.get_kconfig_path(build_dir), 'w') as f:
                f.write('CONFIG_KUNIT=y\nCONFIG_KUNIT_TEST=y')

            tree = kunit_kernel.LinuxSourceTree(build_dir)
            # Stub out the source tree operations, so we don't have
            # the defaults for any given architecture get in the
            # way.
            tree._ops = kunit_kernel.LinuxSourceTreeOperations('none', None)
            mock_build_config = mock.patch.object(tree, 'build_config').start()

            # ... so we should trigger a call to build_config()
            self.assertTrue(tree.build_reconfig(build_dir, make_options=[]))
            mock_build_config.assert_called_once_with(build_dir, [])
Example #14
0
 def test_valid_kunitconfig(self):
     with tempfile.NamedTemporaryFile('wt') as kunitconfig:
         tree = kunit_kernel.LinuxSourceTree(
             '', kunitconfig_path=kunitconfig.name)
Example #15
0
 def test_invalid_kunitconfig(self):
     with self.assertRaisesRegex(kunit_kernel.ConfigError,
                                 'nonexistent.* does not exist'):
         kunit_kernel.LinuxSourceTree('',
                                      kunitconfig_path='/nonexistent_file')
Example #16
0
 def test_invalid_arch(self):
     with self.assertRaisesRegex(kunit_kernel.ConfigError,
                                 'not a valid arch, options are.*x86_64'):
         kunit_kernel.LinuxSourceTree('', arch='invalid')
Example #17
0
 def test_dir_kunitconfig(self):
     with tempfile.TemporaryDirectory('') as dir:
         with open(os.path.join(dir, '.kunitconfig'), 'w') as f:
             pass
         tree = kunit_kernel.LinuxSourceTree('', kunitconfig_path=dir)
Example #18
0
import kunit_config
import kunit_kernel
import kunit_parser

parser = argparse.ArgumentParser(description='Runs KUnit tests.')

parser.add_argument('--raw_output', help='don\'t format output from kernel',
		    action='store_true')

parser.add_argument('--timeout', help='maximum number of seconds to allow for '
		    'all tests to run. This does not include time taken to '
		    'build the tests.', type=int, default=300,
		    metavar='timeout')

cli_args = parser.parse_args()
linux = kunit_kernel.LinuxSourceTree()

config_start = time.time()
success = linux.build_reconfig()
config_end = time.time()
if not success:
	quit()

kunit_parser.print_with_timestamp('Building KUnit Kernel ...')

build_start = time.time()
success = linux.build_um_kernel()
build_end = time.time()
if not success:
	quit()
Example #19
0
def main(argv, linux=None):
    parser = argparse.ArgumentParser(
        description='Helps writing and running KUnit tests.')
    subparser = parser.add_subparsers(dest='subcommand')

    # The 'run' command will config, build, exec, and parse in one go.
    run_parser = subparser.add_parser('run', help='Runs KUnit tests.')
    add_common_opts(run_parser)
    add_build_opts(run_parser)
    add_exec_opts(run_parser)
    add_parse_opts(run_parser)

    config_parser = subparser.add_parser(
        'config',
        help='Ensures that .config contains all of '
        'the options in .kunitconfig')
    add_common_opts(config_parser)

    build_parser = subparser.add_parser(
        'build', help='Builds a kernel with KUnit tests')
    add_common_opts(build_parser)
    add_build_opts(build_parser)

    exec_parser = subparser.add_parser('exec',
                                       help='Run a kernel with KUnit tests')
    add_common_opts(exec_parser)
    add_exec_opts(exec_parser)
    add_parse_opts(exec_parser)

    # The 'parse' option is special, as it doesn't need the kernel source
    # (therefore there is no need for a build_dir, hence no add_common_opts)
    # and the '--file' argument is not relevant to 'run', so isn't in
    # add_parse_opts()
    parse_parser = subparser.add_parser(
        'parse',
        help='Parses KUnit results from a file, '
        'and parses formatted results.')
    add_parse_opts(parse_parser)
    parse_parser.add_argument('file',
                              help='Specifies the file to read results from.',
                              type=str,
                              nargs='?',
                              metavar='input_file')

    cli_args = parser.parse_args(argv)

    if get_kernel_root_path():
        os.chdir(get_kernel_root_path())

    if cli_args.subcommand == 'run':
        if not os.path.exists(cli_args.build_dir):
            os.mkdir(cli_args.build_dir)

        if not linux:
            linux = kunit_kernel.LinuxSourceTree(
                cli_args.build_dir,
                kunitconfig_path=cli_args.kunitconfig,
                arch=cli_args.arch,
                cross_compile=cli_args.cross_compile,
                qemu_config_path=cli_args.qemu_config)

        request = KunitRequest(cli_args.raw_output, cli_args.timeout,
                               cli_args.jobs, cli_args.build_dir,
                               cli_args.alltests, cli_args.filter_glob,
                               cli_args.json, cli_args.make_options)
        result = run_tests(linux, request)
        if result.status != KunitStatus.SUCCESS:
            sys.exit(1)
    elif cli_args.subcommand == 'config':
        if cli_args.build_dir and (not os.path.exists(cli_args.build_dir)):
            os.mkdir(cli_args.build_dir)

        if not linux:
            linux = kunit_kernel.LinuxSourceTree(
                cli_args.build_dir,
                kunitconfig_path=cli_args.kunitconfig,
                arch=cli_args.arch,
                cross_compile=cli_args.cross_compile,
                qemu_config_path=cli_args.qemu_config)

        request = KunitConfigRequest(cli_args.build_dir, cli_args.make_options)
        result = config_tests(linux, request)
        kunit_parser.print_with_timestamp(
            ('Elapsed time: %.3fs\n') % (result.elapsed_time))
        if result.status != KunitStatus.SUCCESS:
            sys.exit(1)
    elif cli_args.subcommand == 'build':
        if not linux:
            linux = kunit_kernel.LinuxSourceTree(
                cli_args.build_dir,
                kunitconfig_path=cli_args.kunitconfig,
                arch=cli_args.arch,
                cross_compile=cli_args.cross_compile,
                qemu_config_path=cli_args.qemu_config)

        request = KunitBuildRequest(cli_args.jobs, cli_args.build_dir,
                                    cli_args.alltests, cli_args.make_options)
        result = build_tests(linux, request)
        kunit_parser.print_with_timestamp(
            ('Elapsed time: %.3fs\n') % (result.elapsed_time))
        if result.status != KunitStatus.SUCCESS:
            sys.exit(1)
    elif cli_args.subcommand == 'exec':
        if not linux:
            linux = kunit_kernel.LinuxSourceTree(
                cli_args.build_dir,
                kunitconfig_path=cli_args.kunitconfig,
                arch=cli_args.arch,
                cross_compile=cli_args.cross_compile,
                qemu_config_path=cli_args.qemu_config)

        exec_request = KunitExecRequest(cli_args.timeout, cli_args.build_dir,
                                        cli_args.alltests,
                                        cli_args.filter_glob)
        exec_result = exec_tests(linux, exec_request)
        parse_request = KunitParseRequest(cli_args.raw_output,
                                          exec_result.result,
                                          cli_args.build_dir, cli_args.json)
        result = parse_tests(parse_request)
        kunit_parser.print_with_timestamp(
            ('Elapsed time: %.3fs\n') % (exec_result.elapsed_time))
        if result.status != KunitStatus.SUCCESS:
            sys.exit(1)
    elif cli_args.subcommand == 'parse':
        if cli_args.file == None:
            kunit_output = sys.stdin
        else:
            with open(cli_args.file, 'r') as f:
                kunit_output = f.read().splitlines()
        request = KunitParseRequest(cli_args.raw_output, kunit_output, None,
                                    cli_args.json)
        result = parse_tests(request)
        if result.status != KunitStatus.SUCCESS:
            sys.exit(1)
    else:
        parser.print_help()
Example #20
0
 def test_kconfig_add(self):
     tree = kunit_kernel.LinuxSourceTree('',
                                         kconfig_add=['CONFIG_NOT_REAL=y'])
     self.assertIn(kunit_config.KconfigEntry('NOT_REAL', 'y'),
                   tree._kconfig.entries())
Example #21
0
        'new', help='Prints out boilerplate for writing new tests.')
    new_parser.add_argument('--path',
                            help='Path of source file to be tested.',
                            type=str,
                            required=True)
    new_parser.add_argument('--namespace_prefix',
                            help='Namespace of the code to be tested.',
                            type=str)
    new_parser.add_argument(
        '--print_test_only',
        help='Skip Kconfig and Makefile while printing sample '
        'test.',
        action='store_true')

    cli_args = parser.parse_args(argv)

    if cli_args.subcommand == 'new':
        print_test_skeletons(cli_args)
    elif cli_args.subcommand == 'run':
        request = KunitRequest(cli_args.raw_output, cli_args.timeout,
                               cli_args.jobs, cli_args.external_config)
        result = run_tests(linux, request)
        if result.status != KunitStatus.SUCCESS:
            sys.exit(1)
    else:
        parser.print_help()


if __name__ == '__main__':
    main(sys.argv[1:], kunit_kernel.LinuxSourceTree())