blob: 7a35d036f48f872ccbb8304b0e489e3bb3ff9480 [file] [log] [blame]
Greg Edelston9cd16f52020-11-12 10:50:28 -07001#!/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 platform_json.py
8
9"""
10
Greg Edelstonf70963a2020-11-17 14:36:06 -070011import collections
12import io
13import json
Greg Edelston9cd16f52020-11-12 10:50:28 -070014import os
Greg Edelstonf70963a2020-11-17 14:36:06 -070015import sys
Greg Edelston9cd16f52020-11-12 10:50:28 -070016import tempfile
17import unittest
18
19import platform_json
20
21MOCK_CONSOLIDATED_JSON_CONTENTS = \
22'''{
23 "DEFAULTS": {
24 "platform": null,
25 "parent": null,
26 "field1": 5,
27 "field2": 5,
28 "field3": 5,
29 "field4": 5
30 },
31 "my_platform": {
32 "platform": "my_platform",
33 "parent": "my_parent",
34 "field1": 1,
35 "models": {
36 "my_model": {
37 "field1": 4
38 }
39 }
40 },
41 "my_parent": {
42 "platform": "my_parent",
43 "parent": "my_grandparent",
44 "field1": 2,
45 "field2": 2
46 },
47 "my_grandparent": {
48 "platform": "my_grandparent",
49 "field1": 3,
50 "field2": 3,
51 "field3": 3
52 }
53}'''
54
Greg Edelston9cd16f52020-11-12 10:50:28 -070055
Greg Edelstonf70963a2020-11-17 14:36:06 -070056def _run_main(argv):
57 """Run platform_json.main(argv), capturing and returning stdout."""
58 original_stdout = sys.stdout
59 capture_io = io.StringIO()
60 sys.stdout = capture_io
61 try:
62 platform_json.main(argv)
63 return capture_io.getvalue()
64 finally:
65 capture_io.close()
66 sys.stdout = original_stdout
67
68
69class _AbstractMockConfigTestCase(object):
70 """Parent class to handle setup and teardown of mock configs."""
71
72 def setUp(self): # pylint:disable=invalid-name
Greg Edelston9cd16f52020-11-12 10:50:28 -070073 """Write mock JSON to a temporary file"""
74 _, self.mock_filepath = tempfile.mkstemp()
75 with open(self.mock_filepath, 'w') as mock_file:
76 mock_file.write(MOCK_CONSOLIDATED_JSON_CONTENTS)
77
Greg Edelstonf70963a2020-11-17 14:36:06 -070078 def tearDown(self): # pylint:disable=invalid-name
79 """Destroy the mock JSON file"""
80 os.remove(self.mock_filepath)
81
82
83class InheritanceTestCase(_AbstractMockConfigTestCase, unittest.TestCase):
84 """Ensure that all levels of inheritance are handled correctly"""
85
Greg Edelston9cd16f52020-11-12 10:50:28 -070086 def runTest(self): # pylint:disable=invalid-name
87 """Load platform config and check that it looks correct"""
88 my_platform = platform_json.calculate_platform_json('my_platform',
89 None,
90 self.mock_filepath)
91 self.assertEqual(my_platform['field1'], 1) # No inheritance
92 self.assertEqual(my_platform['field2'], 2) # Direct inheritance
93 self.assertEqual(my_platform['field3'], 3) # Recursive inheritance
94 self.assertEqual(my_platform['field4'], 5) # Inherit from DEFAULTS
95 my_model = platform_json.calculate_platform_json('my_platform',
96 'my_model',
97 self.mock_filepath)
98 self.assertEqual(my_model['field1'], 4) # Model override
99 self.assertEqual(my_model['field2'], 2) # Everything else is the same
100 self.assertEqual(my_model['field3'], 3)
101 self.assertEqual(my_model['field4'], 5)
102
103
Greg Edelstonf70963a2020-11-17 14:36:06 -0700104class EndToEndPlatformTestCase(_AbstractMockConfigTestCase, unittest.TestCase):
105 """End-to-end testing for specifying the platform name."""
106
107 def runTest(self): #pylint: disable=invalid-name
108 """Main test logic"""
109 # Basic platform specification
110 argv = ['my_platform', '-c', self.mock_filepath]
111 expected_json = collections.OrderedDict({
112 'platform': 'my_platform',
113 'parent': 'my_parent',
114 'field1': 1,
115 'field2': 2,
116 'field3': 3,
117 'field4': 5
118 })
119 expected_output = json.dumps(expected_json, indent=4) + '\n'
120 self.assertEqual(_run_main(argv), expected_output)
121
122 # Condensed output
123 argv.append('--condense-output')
124 expected_output = json.dumps(expected_json, indent=None)
125 self.assertEqual(_run_main(argv), expected_output)
126
127 # Non-existent platform should raise an error
128 argv = ['fake_platform', '-c', self.mock_filepath]
129 with self.assertRaises(platform_json.PlatformNotFoundError):
130 _run_main(argv)
131
132
133class EndToEndFieldTestCase(_AbstractMockConfigTestCase, unittest.TestCase):
134 """End-to-end testing for specifying the field name."""
135
136 def runTest(self): # pylint: disable=invalid-name
137 """Main test logic"""
138 # Basic field specification
139 argv = ['my_platform', '-f', 'field1', '-c', self.mock_filepath]
140 self.assertEqual(_run_main(argv), '1\n')
141
142 # Condensed output should yield no newline
143 argv.append('--condense-output')
144 self.assertEqual(_run_main(argv), '1')
145
146 # Non-existent field should raise an error
147 argv = ['my_platform', '-f', 'fake_field', '-c', self.mock_filepath]
148 with self.assertRaises(platform_json.FieldNotFoundError):
149 _run_main(argv)
Greg Edelston9cd16f52020-11-12 10:50:28 -0700150
151
152if __name__ == '__main__':
153 unittest.main()