blob: f66263241ad8f9ac68f1f8426862ecf77db0c0a1 [file] [log] [blame]
Greg Edelstonfa649212020-10-13 14:40:38 -06001#!/usr/bin/env python3
2# Copyright 2020 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""
7Unit tests for consolidate.py.
8
9"""
10
11import collections
12import json
13import os
14import pathlib
15import tempfile
16import unittest
17
18import consolidate
19
20
21class TestParseArgs(unittest.TestCase):
22 """Test case for parse_args()."""
23
24 def setUp(self):
25 """
26 Change the current working directory.
27
28 This will ensure that even if the script is run from elsewhere,
29 input_dir arg still defaults to fw-testing-configs.
30 """
31 self.original_cwd = os.getcwd()
32 os.chdir('/tmp')
33
34 def tearDown(self):
35 """Restore the original working directory."""
36 os.chdir(self.original_cwd)
37
38 def test_command_line_args(self):
39 """Test with specified command-line args."""
40 input_dir = 'foo'
41 output_file = 'bar'
42 argv = ['-i', input_dir, '-o', output_file]
43 args = consolidate.parse_args(argv)
44 self.assertEqual(args.input_dir, input_dir)
45 self.assertEqual(args.output, output_file)
46
47 def test_defaults(self):
48 """Test with no command-line args."""
Jeremy Bettis6f885332021-05-04 16:39:58 -060049 args = consolidate.parse_args([])
Greg Edelstonfa649212020-10-13 14:40:38 -060050 self.assertEqual(args.output, consolidate.DEFAULT_OUTPUT_FILEPATH)
51 # Note: This assertion is not hermetic!
52 self.assertTrue('fw-testing-configs' in args.input_dir)
53 # Note: This assertion is not hermetic!
54 self.assertTrue('DEFAULTS.json' in os.listdir(args.input_dir))
55
56
57class TestGetPlatformNames(unittest.TestCase):
58 """Test case for get_platform_names()."""
59
60 def setUp(self):
61 """Create mock fw-testing-configs directory."""
62 self.mock_fwtc_dir = tempfile.TemporaryDirectory()
63 mock_platform_names = ['z', 'a', 'b', 'DEFAULTS', 'CONSOLIDATED']
64 for platform in mock_platform_names:
65 mock_filepath = os.path.join(self.mock_fwtc_dir.name,
66 platform + '.json')
67 pathlib.Path(mock_filepath).touch()
68
69 def tearDown(self):
70 """Destroy mock fw-testing-configs directory."""
71 self.mock_fwtc_dir.cleanup()
72
73 def test_get_platform_names(self):
74 """
75 Verify that platform names load in the correct order.
76
77 The correct order is starting with DEFAULTS, then alphabetical.
78 The .json file extension should not be included.
79 """
80 platforms = consolidate.get_platform_names(self.mock_fwtc_dir.name)
81 self.assertEqual(platforms, ['DEFAULTS', 'a', 'b', 'z'])
82
83
84class TestLoadJSON(unittest.TestCase):
85 """Test case for load_json()."""
86
87 def setUp(self):
88 """Setup mock fw-testing-configs directory."""
89 self.mock_fwtc_dir = tempfile.TemporaryDirectory()
90 a_filename = os.path.join(self.mock_fwtc_dir.name, 'a.json')
91 with open(a_filename, 'w') as a_file:
92 a_file.write('{\n' +
93 '\t"platform": "a",\n' +
94 '\t"ec_capability": [\n' +
95 '\t\t"usb",\n'
96 '\t\t"x86"\n' +
97 '\t]\n' +
98 '}')
99 defaults_filename = os.path.join(self.mock_fwtc_dir.name,
100 'DEFAULTS.json')
101 with open(defaults_filename, 'w') as defaults_file:
102 defaults_file.write('{\n' +
103 '\t"platform": null,\n' +
104 '\t"platform_DOC": "foo",\n' +
105 '\t"ec_capability": []\n' +
106 '}')
107
108 def tearDown(self):
109 self.mock_fwtc_dir.cleanup()
110
111 def test_load_json(self):
112 """Verify that we correctly load platform JSON contents."""
113 expected = collections.OrderedDict()
114 expected['DEFAULTS'] = collections.OrderedDict()
115 expected['DEFAULTS']['platform'] = None
116 expected['DEFAULTS']['platform_DOC'] = 'foo'
117 expected['DEFAULTS']['ec_capability'] = []
118 expected['a'] = collections.OrderedDict()
119 expected['a']['platform'] = 'a'
120 expected['a']['ec_capability'] = ['usb', 'x86']
121 actual = consolidate.load_json(self.mock_fwtc_dir.name,
122 ['DEFAULTS', 'a'])
123 self.assertEqual(actual, expected)
124
125
126class TestWriteOutput(unittest.TestCase):
127 """Test case for write_output()."""
128 output_fp = '/tmp/CONSOLIDATED.json'
129
130 def tearDown(self):
131 """Clean up output_fp"""
132 if os.path.isfile(TestWriteOutput.output_fp):
133 os.remove(TestWriteOutput.output_fp)
134
135 def test_write_output(self):
136 """Verify that write_output writes JSON and sets to read-only."""
137 # Run the function
138 mock_json = collections.OrderedDict({'foo': 'bar', 'bar': 'baz'})
139 consolidate.write_output(mock_json, TestWriteOutput.output_fp)
140
141 # Verify file contents
142 with open(TestWriteOutput.output_fp) as output_file:
143 output_contents = output_file.readlines()
Greg Edelston2e032a32020-11-23 11:39:34 -0700144 expected = ['{\n',
145 '\t"foo": "bar",\n',
146 '\t"bar": "baz"\n',
147 '}']
148 self.assertEqual(output_contents, expected)
Greg Edelstonfa649212020-10-13 14:40:38 -0600149
150 # Verify that file is read-only
151 with self.assertRaises(PermissionError):
152 with open(TestWriteOutput.output_fp, 'w') as output_file:
153 output_file.write('foo')
154
155
156class TestMain(unittest.TestCase):
157 """End-to-end test case for main()."""
158 output_fp = '/tmp/CONSOLIDATED.json'
159
160 def setUp(self):
161 """Create and populate mock fw-testing-configs directory."""
162 self.mock_fwtc_dir = tempfile.TemporaryDirectory()
163 a_json_fp = os.path.join(self.mock_fwtc_dir.name, 'a.json')
164 with open(a_json_fp, 'w') as a_json_file:
165 a_json = collections.OrderedDict({'platform': 'a',
166 'firmware_screen': 0.5,
167 'ec_capability': ['usb', 'x86']})
168 json.dump(a_json, a_json_file)
169 z_json_fp = os.path.join(self.mock_fwtc_dir.name, 'z.json')
170 with open(z_json_fp, 'w') as z_json_file:
171 z_json = collections.OrderedDict({'platform': 'z',
172 'parent': 'a',
173 'firmware_screen': 10})
174 json.dump(z_json, z_json_file)
175 defaults_json_fp = os.path.join(self.mock_fwtc_dir.name,
176 'DEFAULTS.json')
177 with open(defaults_json_fp, 'w') as defaults_json_file:
178 defaults_json = collections.OrderedDict({'platform': None,
179 'platform_DOC': 'foo',
180 'ec_capability': []})
181 json.dump(defaults_json, defaults_json_file)
182
183 def tearDown(self):
184 """Delete output file and mock fw-testing-configs directory."""
185 self.mock_fwtc_dir.cleanup()
186 if os.path.isfile(TestMain.output_fp):
187 os.remove(TestMain.output_fp)
188
189 def test_main(self):
190 """Verify that the whole script works, end-to-end."""
Greg Edelston2e032a32020-11-23 11:39:34 -0700191 expected_output = ['{\n',
192 '\t"DEFAULTS": {\n',
193 '\t\t"platform": null,\n',
194 '\t\t"platform_DOC": "foo",\n',
195 '\t\t"ec_capability": []\n',
196 '\t},\n',
197 '\t"a": {\n',
198 '\t\t"platform": "a",\n',
199 '\t\t"firmware_screen": 0.5,\n',
200 '\t\t"ec_capability": [\n',
201 '\t\t\t"usb",\n',
202 '\t\t\t"x86"\n',
203 '\t\t]\n',
204 '\t},\n',
205 '\t"z": {\n',
206 '\t\t"platform": "z",\n',
207 '\t\t"parent": "a",\n',
208 '\t\t"firmware_screen": 10\n',
209 '\t}\n',
210 '}']
Greg Edelstonfa649212020-10-13 14:40:38 -0600211
212 # Run the script twice to verify idempotency.
213 for _ in range(2):
214 # Run the script.
215 argv = ['-i', self.mock_fwtc_dir.name, '-o', TestMain.output_fp]
216 consolidate.main(argv)
217
218 # Verify the output.
219 with open(TestMain.output_fp) as output_file:
Greg Edelston2e032a32020-11-23 11:39:34 -0700220 output_contents = output_file.readlines()
Greg Edelstonfa649212020-10-13 14:40:38 -0600221 self.assertEqual(output_contents, expected_output)
222
223 # Verify the final output is read-only.
224 with self.assertRaises(PermissionError):
225 with open(TestMain.output_fp, 'w') as output_file:
226 output_file.write('foo')
227
228
229if __name__ == '__main__':
230 unittest.main()