1from importlib.util import module_from_spec, spec_from_file_location
2import json
3from pathlib import Path
4from tempfile import TemporaryDirectory
5import unittest
6from unittest.mock import patch
7
8
9spec = spec_from_file_location('ci', Path(__file__).with_name('ci.py'))
10ci = module_from_spec(spec)
11spec.loader.exec_module(ci)
12
13
14class TestExecutableIdentity(unittest.TestCase):
15 def test_same_named_library_and_integration_test_keep_separate_results(self):
16 with TemporaryDirectory() as temporary:
17 root = Path(temporary)
18 artifacts = []
19 for package, name, kind, executable in [
20 ('relay', 'relay', 'test', '/tests/relay-integration'),
21 ('relay', 'relay', 'lib', '/tests/relay-library'),
22 ('relay', 'snowbound-relay', 'bin', '/tests/relay-bin'),
23 ('other', 'other', 'lib', '/tests/other'),
24 ]:
25 artifacts.append(json.dumps({
26 'reason': 'compiler-artifact', 'profile': {'test': True},
27 'manifest_path': str(root / package / 'Cargo.toml'),
28 'target': {'name': name, 'kind': [kind]}, 'executable': executable,
29 }))
30
31 class RecordedRun:
32 folder = root
33 calls = []
34
35 def execute(self, command, log, deadline, **kwargs):
36 self.calls.append((command, log, kwargs.get('cwd')))
37 if log.name == 'test.log':
38 log.write_text('\n'.join(artifacts))
39 return 0
40 with log.open('a') as stream:
41 stream.write(' '.join(command) + '\n')
42 return 1 if command == ['/tests/relay-library'] else 0
43
44 (root / 'test-seconds.json').write_text(json.dumps({
45 'relay.relay.test': 10, 'relay.snowbound-relay.bin': 20, 'doctests': 1,
46 }))
47 run = RecordedRun()
48 with patch.object(ci, 'RUNS', root):
49 status, logs, parts = ci.run_tests(run, 1, ['relay'], 1)
50
51 by_name = {part['name']: part for part in parts}
52 self.assertEqual(status, 'failed')
53 self.assertEqual(set(by_name), {
54 'relay.relay.test', 'relay.relay.lib', 'relay.snowbound-relay.bin', 'doctests',
55 })
56 self.assertEqual(by_name['relay.relay.test']['status'], 'passed')
57 self.assertEqual(by_name['relay.relay.lib']['status'], 'failed')
58 self.assertEqual(len({part['log'] for part in parts}), 4)
59 self.assertEqual([path.name for path in logs], ['test.log', 'relay.relay.lib.log'])
60 self.assertEqual(Path(by_name['relay.relay.lib']['log']).read_text(), '/tests/relay-library\n')
61 self.assertEqual(Path(by_name['relay.relay.test']['log']).read_text(), '/tests/relay-integration\n')
62 self.assertEqual([call[0] for call in run.calls[1:4]], [
63 ['/tests/relay-library'], ['/tests/relay-bin'], ['/tests/relay-integration'],
64 ])
65 self.assertEqual([call[2] for call in run.calls[1:4]], [root / 'relay'] * 3)
66 self.assertFalse(any(call[0] == ['/tests/other'] for call in run.calls))
67 timings = json.loads((root / 'test-seconds.json').read_text())
68 self.assertIn('relay.relay.lib', timings)
69 self.assertIn('relay.relay.test', timings)
70
71
72if __name__ == '__main__':
73 unittest.main()