Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(388)

Side by Side Diff: chrome/test/mini_installer/test_installer.py

Issue 22480002: Use unittest framework in the Automated Installer Testing Framework. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/test/mini_installer/settings.py ('k') | chrome/test/mini_installer/verifier.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2013 The Chromium Authors. All rights reserved. 1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """This script tests the installer with test cases specified in the config file. 5 """This script tests the installer with test cases specified in the config file.
6 6
7 For each test case, it checks that the machine states after the execution of 7 For each test case, it checks that the machine states after the execution of
8 each command match the expected machine states. For more details, take a look at 8 each command match the expected machine states. For more details, take a look at
9 the design documentation at http://goo.gl/Q0rGM6 9 the design documentation at http://goo.gl/Q0rGM6
10 """ 10 """
11 11
12 import argparse 12 import argparse
13 import json 13 import json
14 import os 14 import os
15 import subprocess 15 import subprocess
16 import unittest
16 17
17 import settings
18 import verifier 18 import verifier
19 19
20 20
21 class Config: 21 class Config:
22 """Describes the machine states, actions, and test cases. 22 """Describes the machine states, actions, and test cases.
23 23
24 A state is a dictionary where each key is a verifier's name and the 24 A state is a dictionary where each key is a verifier's name and the
25 associated value is the input to that verifier. An action is a shorthand for 25 associated value is the input to that verifier. An action is a shorthand for
26 a command. A test is array of alternating state names and action names, 26 a command. A test is array of alternating state names and action names,
27 starting and ending with state names. An instance of this class stores a map 27 starting and ending with state names. An instance of this class stores a map
28 from state names to state objects, a map from action names to commands, and 28 from state names to state objects, a map from action names to commands, and
29 an array of test objects. 29 an array of test objects.
30 """ 30 """
31 def __init__(self): 31 def __init__(self):
32 self.states = {} 32 self.states = {}
33 self.actions = {} 33 self.actions = {}
34 self.tests = [] 34 self.tests = []
35 35
36 36
37 class InstallerTest(unittest.TestCase):
38 """Tests a test case in the config file."""
39
40 def __init__(self, test, config):
41 """Constructor.
42
43 Args:
44 test: An array of alternating state names and action names, starting and
45 ending with state names.
46 config: The Config object.
47 """
48 super(InstallerTest, self).__init__()
49 self.test = test
50 self.config = config
51
52 def runTest(self):
53 """Run the test case."""
54 test = self.test
55
56 # |test| is an array of alternating state names and action names, starting
57 # and ending with state names. Therefore, its length must be odd.
58 self.assertEqual(len(test) % 2, 1, 'The length of test array must be odd')
59
60 self._RunResetCommand()
61
62 current_state = test[0]
63 self._VerifyState(current_state)
64
65 for i in range(1, len(test), 2):
66 action = test[i]
67 self._RunCommand(self.config.actions[action])
68
69 current_state = test[i + 1]
70 self._VerifyState(current_state)
71
72 def __str__(self):
73 return 'Test: %s' % ('-> '.join(self.test))
74
75 def shortDescription(self):
76 """Returns None as the short description to suppress its printing.
77
78 The default implementation of this method returns the docstring of the
79 runTest method, which is not useful since it's the same for every test case.
80 The description from the __str__ method is informative enough.
81 """
82 return None
83
84 def _VerifyState(self, state):
85 """Verifies that the current machine states match the given machine states.
86
87 Args:
88 state: The current state.
89 """
90 try:
91 verifier.Verify(self.config.states[state], self)
92 except AssertionError as e:
93 error_msg = "In state '%s', %s" % (state, e)
robertshield 2013/08/06 21:42:22 It seems like the whole config struct is passed do
sukolsak 2013/08/06 23:43:06 True, but I would like to keep the assertions as s
94 raise AssertionError(error_msg)
95
96 def _RunCommand(self, command):
97 subprocess.call(command, shell=True)
98
99 def _RunResetCommand(self):
100 # TODO(sukolsak): Need to figure how exactly we want to reset.
101 pass
102
103
37 def MergePropertyDictionaries(current_property, new_property): 104 def MergePropertyDictionaries(current_property, new_property):
38 """Merges the new property dictionary into the current property dictionary. 105 """Merges the new property dictionary into the current property dictionary.
39 106
40 This is different from general dictionary merging in that, in case there are 107 This is different from general dictionary merging in that, in case there are
41 keys with the same name, we merge values together in the first level, and we 108 keys with the same name, we merge values together in the first level, and we
42 override earlier values in the second level. For more details, take a look at 109 override earlier values in the second level. For more details, take a look at
43 http://goo.gl/uE0RoR 110 http://goo.gl/uE0RoR
44 111
45 Args: 112 Args:
46 current_property: The property dictionary to be modified. 113 current_property: The property dictionary to be modified.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 config = Config() 160 config = Config()
94 config.tests = config_data['tests'] 161 config.tests = config_data['tests']
95 for state_name, state_property_filenames in config_data['states']: 162 for state_name, state_property_filenames in config_data['states']:
96 config.states[state_name] = ParsePropertyFiles(directory, 163 config.states[state_name] = ParsePropertyFiles(directory,
97 state_property_filenames) 164 state_property_filenames)
98 for action_name, action_command in config_data['actions']: 165 for action_name, action_command in config_data['actions']:
99 config.actions[action_name] = action_command 166 config.actions[action_name] = action_command
100 return config 167 return config
101 168
102 169
103 def VerifyState(config, state):
104 """Verifies that the current machine states match the given machine states.
105
106 Args:
107 config: A Config object.
108 state: The current state.
109 """
110 # TODO(sukolsak): Think of ways of preserving the log when the test fails but
111 # not printing these when the test passes.
112 print settings.PRINT_STATE_PREFIX + state
113 verifier.Verify(config.states[state])
114
115
116 def RunCommand(command):
117 print settings.PRINT_COMMAND_PREFIX + command
118 subprocess.call(command, shell=True)
119
120
121 def RunResetCommand():
122 print settings.PRINT_COMMAND_PREFIX + 'Reset'
123 # TODO(sukolsak): Need to figure how exactly we want to reset.
124
125
126 def Test(config): 170 def Test(config):
127 """Tests the installer using the given Config object. 171 """Tests the installer using the given Config object.
128 172
129 Args: 173 Args:
130 config: A Config object. 174 config: A Config object.
131 """ 175 """
176 suite = unittest.TestSuite()
132 for test in config.tests: 177 for test in config.tests:
133 print settings.PRINT_TEST_PREFIX + ' -> '.join(test) 178 suite.addTest(InstallerTest(test, config))
134 179 unittest.TextTestRunner(verbosity=2).run(suite)
135 # A Test object is an array of alternating state names and action names.
136 # The array starts and ends with states. Therefore, the length must be odd.
137 assert(len(test) % 2 == 1)
138
139 RunResetCommand()
140
141 current_state = test[0]
142 VerifyState(config, current_state)
143 # TODO(sukolsak): Quit the test early if VerifyState fails at any point.
144
145 for i in range(1, len(test), 2):
146 action = test[i]
147 RunCommand(config.actions[action])
148
149 current_state = test[i + 1]
150 VerifyState(config, current_state)
151 180
152 181
153 def main(): 182 def main():
154 parser = argparse.ArgumentParser(description='Test the installer.') 183 parser = argparse.ArgumentParser(description='Test the installer.')
155 parser.add_argument('config_filename', 184 parser.add_argument('config_filename',
156 help='The relative/absolute path to the config file.') 185 help='The relative/absolute path to the config file.')
157 args = parser.parse_args() 186 args = parser.parse_args()
158 187
159 config = ParseConfigFile(args.config_filename) 188 config = ParseConfigFile(args.config_filename)
160 Test(config) 189 Test(config)
161 190
162 191
163 if __name__ == '__main__': 192 if __name__ == '__main__':
164 main() 193 main()
OLDNEW
« no previous file with comments | « chrome/test/mini_installer/settings.py ('k') | chrome/test/mini_installer/verifier.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698