Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 1 | import asyncio |
| 2 | import os |
| 3 | import pathlib |
| 4 | import subprocess |
| 5 | import tempfile |
| 6 | import unittest.mock |
| 7 | |
| 8 | from oeqa.selftest.case import OESelftestTestCase |
| 9 | |
| 10 | runfvp = pathlib.Path(__file__).parents[5] / "scripts" / "runfvp" |
| 11 | testdir = pathlib.Path(__file__).parent / "tests" |
| 12 | |
| 13 | class RunFVPTests(OESelftestTestCase): |
| 14 | def setUpLocal(self): |
| 15 | self.assertTrue(runfvp.exists()) |
| 16 | |
| 17 | def run_fvp(self, *args, should_succeed=True): |
| 18 | """ |
| 19 | Call runfvp passing any arguments. If check is True verify return stdout |
| 20 | on exit code 0 or fail the test, otherwise return the CompletedProcess |
| 21 | instance. |
| 22 | """ |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 23 | cli = [runfvp,] + list(args) |
| 24 | print(f"Calling {cli}") |
Patrick Williams | 8dd6848 | 2022-10-04 07:57:18 -0500 | [diff] [blame^] | 25 | # Set cwd to testdir so that any mock FVPs are found |
| 26 | ret = subprocess.run(cli, cwd=testdir, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 27 | if should_succeed: |
| 28 | self.assertEqual(ret.returncode, 0, f"runfvp exit {ret.returncode}, output: {ret.stdout}") |
| 29 | return ret.stdout |
| 30 | else: |
| 31 | self.assertNotEqual(ret.returncode, 0, f"runfvp exit {ret.returncode}, output: {ret.stdout}") |
| 32 | return ret.stdout |
| 33 | |
| 34 | def test_help(self): |
| 35 | output = self.run_fvp("--help") |
| 36 | self.assertIn("Run images in a FVP", output) |
| 37 | |
| 38 | def test_bad_options(self): |
| 39 | self.run_fvp("--this-is-an-invalid-option", should_succeed=False) |
| 40 | |
| 41 | def test_run_auto_tests(self): |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 42 | cases = list(testdir.glob("auto-*.json")) |
| 43 | if not cases: |
| 44 | self.fail("No tests found") |
| 45 | for case in cases: |
| 46 | with self.subTest(case=case.stem): |
| 47 | self.run_fvp(case) |
| 48 | |
| 49 | def test_fvp_options(self): |
| 50 | # test-parameter sets one argument, add another manually |
| 51 | self.run_fvp(testdir / "test-parameter.json", "--", "--parameter", "board.dog=woof") |
| 52 | |
| 53 | class ConfFileTests(OESelftestTestCase): |
| 54 | def test_no_exe(self): |
| 55 | from fvp import conffile |
| 56 | with tempfile.NamedTemporaryFile('w') as tf: |
| 57 | tf.write('{}') |
| 58 | tf.flush() |
| 59 | |
| 60 | with self.assertRaises(ValueError): |
| 61 | conffile.load(tf.name) |
| 62 | |
| 63 | def test_minimal(self): |
| 64 | from fvp import conffile |
| 65 | with tempfile.NamedTemporaryFile('w') as tf: |
| 66 | tf.write('{"exe": "FVP_Binary"}') |
| 67 | tf.flush() |
| 68 | |
| 69 | conf = conffile.load(tf.name) |
| 70 | self.assertTrue('fvp-bindir' in conf) |
| 71 | self.assertTrue('fvp-bindir' in conf) |
| 72 | self.assertTrue("exe" in conf) |
| 73 | self.assertTrue("parameters" in conf) |
| 74 | self.assertTrue("data" in conf) |
| 75 | self.assertTrue("applications" in conf) |
| 76 | self.assertTrue("terminals" in conf) |
| 77 | self.assertTrue("args" in conf) |
| 78 | self.assertTrue("consoles" in conf) |
Patrick Williams | 8dd6848 | 2022-10-04 07:57:18 -0500 | [diff] [blame^] | 79 | self.assertTrue("env" in conf) |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 80 | |
| 81 | |
| 82 | class RunnerTests(OESelftestTestCase): |
| 83 | def create_mock(self): |
| 84 | return unittest.mock.patch("asyncio.create_subprocess_exec") |
| 85 | |
| 86 | def test_start(self): |
| 87 | from fvp import runner |
| 88 | with self.create_mock() as m: |
| 89 | fvp = runner.FVPRunner(self.logger) |
| 90 | asyncio.run(fvp.start({ |
| 91 | "fvp-bindir": "/usr/bin", |
| 92 | "exe": "FVP_Binary", |
| 93 | "parameters": {'foo': 'bar'}, |
| 94 | "data": ['data1'], |
| 95 | "applications": {'a1': 'file'}, |
| 96 | "terminals": {}, |
| 97 | "args": ['--extra-arg'], |
Patrick Williams | 8dd6848 | 2022-10-04 07:57:18 -0500 | [diff] [blame^] | 98 | "env": {"FOO": "BAR"} |
Brad Bishop | bec4ebc | 2022-08-03 09:55:16 -0400 | [diff] [blame] | 99 | })) |
| 100 | |
| 101 | m.assert_called_once_with('/usr/bin/FVP_Binary', |
| 102 | '--parameter', 'foo=bar', |
| 103 | '--data', 'data1', |
| 104 | '--application', 'a1=file', |
| 105 | '--extra-arg', |
| 106 | stdin=unittest.mock.ANY, |
| 107 | stdout=unittest.mock.ANY, |
Patrick Williams | 8dd6848 | 2022-10-04 07:57:18 -0500 | [diff] [blame^] | 108 | stderr=unittest.mock.ANY, |
| 109 | env={"FOO":"BAR"}) |
| 110 | |
| 111 | @unittest.mock.patch.dict(os.environ, {"DISPLAY": ":42", "WAYLAND_DISPLAY": "wayland-42"}) |
| 112 | def test_env_passthrough(self): |
| 113 | from fvp import runner |
| 114 | with self.create_mock() as m: |
| 115 | fvp = runner.FVPRunner(self.logger) |
| 116 | asyncio.run(fvp.start({ |
| 117 | "fvp-bindir": "/usr/bin", |
| 118 | "exe": "FVP_Binary", |
| 119 | "parameters": {}, |
| 120 | "data": [], |
| 121 | "applications": {}, |
| 122 | "terminals": {}, |
| 123 | "args": [], |
| 124 | "env": {"FOO": "BAR"} |
| 125 | })) |
| 126 | |
| 127 | m.assert_called_once_with('/usr/bin/FVP_Binary', |
| 128 | stdin=unittest.mock.ANY, |
| 129 | stdout=unittest.mock.ANY, |
| 130 | stderr=unittest.mock.ANY, |
| 131 | env={"DISPLAY":":42", "FOO": "BAR", "WAYLAND_DISPLAY": "wayland-42"}) |