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

Side by Side Diff: bin/au_test_harness/au_test.py

Issue 6614029: Add ability to pass a base test root and create results dirs relative. (Closed) Base URL: http://git.chromium.org/git/crosutils.git@master
Patch Set: ws Created 9 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | bin/au_test_harness/au_worker.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 (c) 2011 The Chromium OS Authors. All rights reserved. 1 # Copyright (c) 2011 The Chromium OS 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 """Module containing a test suite that is run to test auto updates.""" 5 """Module containing a test suite that is run to test auto updates."""
6 6
7 import os 7 import os
8 import tempfile
8 import time 9 import time
9 import unittest 10 import unittest
10 11
11 import cros_build_lib as cros_lib 12 import cros_build_lib as cros_lib
12 13
13 import cros_test_proxy 14 import cros_test_proxy
14 import dummy_au_worker 15 import dummy_au_worker
15 import real_au_worker 16 import real_au_worker
16 import vm_au_worker 17 import vm_au_worker
17 18
18 19
19 class AUTest(unittest.TestCase): 20 class AUTest(unittest.TestCase):
20 """Test harness that uses an au_worker to perform and validate updates. 21 """Test harness that uses an au_worker to perform and validate updates.
21 22
22 Defines a test suite that is run using an au_worker. An au_worker can 23 Defines a test suite that is run using an au_worker. An au_worker can
23 be created to perform and validates updates on both virtual and real devices. 24 be created to perform and validates updates on both virtual and real devices.
24 See documentation for au_worker for more information. 25 See documentation for au_worker for more information.
25 """ 26 """
27 test_results_root = None
28
26 @classmethod 29 @classmethod
27 def ProcessOptions(cls, options, use_dummy_worker): 30 def ProcessOptions(cls, options, use_dummy_worker):
28 """Processes options for the test suite and sets up the worker class. 31 """Processes options for the test suite and sets up the worker class.
29 32
30 Args: 33 Args:
31 options: options class to be parsed from main class. 34 options: options class to be parsed from main class.
32 use_dummy_worker: If True, use a dummy_worker_class rather than deriving 35 use_dummy_worker: If True, use a dummy_worker_class rather than deriving
33 one from options.type. 36 one from options.type.
34 """ 37 """
35 cls.base_image_path = options.base_image 38 cls.base_image_path = options.base_image
(...skipping 12 matching lines...) Expand all
48 if not cls.base_image_path: 51 if not cls.base_image_path:
49 cros_lib.Die('Need path to base image for vm.') 52 cros_lib.Die('Need path to base image for vm.')
50 elif not os.path.exists(cls.base_image_path): 53 elif not os.path.exists(cls.base_image_path):
51 cros_lib.Die('%s does not exist' % cls.base_image_path) 54 cros_lib.Die('%s does not exist' % cls.base_image_path)
52 55
53 if not cls.target_image_path: 56 if not cls.target_image_path:
54 cros_lib.Die('Need path to target image to update with.') 57 cros_lib.Die('Need path to target image to update with.')
55 elif not os.path.exists(cls.target_image_path): 58 elif not os.path.exists(cls.target_image_path):
56 cros_lib.Die('%s does not exist' % cls.target_image_path) 59 cros_lib.Die('%s does not exist' % cls.target_image_path)
57 60
61 # Initialize test root.
62 if not cls.test_results_root:
63 if options.test_results_root:
64 cls.test_results_root = options.test_results_root
65 else:
66 cls.test_results_root = tempfile.mkdtemp(prefix='au_test_harness')
67
68 cros_lib.Info('Using %s as the test results root' % cls.test_results_root)
69
58 # Cache away options to instantiate workers later. 70 # Cache away options to instantiate workers later.
59 cls.options = options 71 cls.options = options
60 72
61 def AttemptUpdateWithPayloadExpectedFailure(self, payload, expected_msg): 73 def AttemptUpdateWithPayloadExpectedFailure(self, payload, expected_msg):
62 """Attempt a payload update, expect it to fail with expected log""" 74 """Attempt a payload update, expect it to fail with expected log"""
63 try: 75 try:
64 self.worker.UpdateUsingPayload(payload) 76 self.worker.UpdateUsingPayload(payload)
65 except UpdateException as err: 77 except UpdateException as err:
66 # Will raise ValueError if expected is not found. 78 # Will raise ValueError if expected is not found.
67 if re.search(re.escape(expected_msg), err.stdout, re.MULTILINE): 79 if re.search(re.escape(expected_msg), err.stdout, re.MULTILINE):
(...skipping 23 matching lines...) Expand all
91 proxy.shutdown() 103 proxy.shutdown()
92 104
93 # --- UNITTEST SPECIFIC METHODS --- 105 # --- UNITTEST SPECIFIC METHODS ---
94 106
95 def setUp(self): 107 def setUp(self):
96 """Overrides unittest.TestCase.setUp and called before every test. 108 """Overrides unittest.TestCase.setUp and called before every test.
97 109
98 Sets instance specific variables and initializes worker. 110 Sets instance specific variables and initializes worker.
99 """ 111 """
100 unittest.TestCase.setUp(self) 112 unittest.TestCase.setUp(self)
101 self.worker = self.worker_class(self.options) 113 self.worker = self.worker_class(self.options, AUTest.test_results_root)
102 self.crosutils = os.path.join(os.path.dirname(__file__), '..', '..') 114 self.crosutils = os.path.join(os.path.dirname(__file__), '..', '..')
103 self.download_folder = os.path.join(self.crosutils, 'latest_download') 115 self.download_folder = os.path.join(self.crosutils, 'latest_download')
104 if not os.path.exists(self.download_folder): 116 if not os.path.exists(self.download_folder):
105 os.makedirs(self.download_folder) 117 os.makedirs(self.download_folder)
106 118
107 def tearDown(self): 119 def tearDown(self):
108 """Overrides unittest.TestCase.tearDown and called after every test.""" 120 """Overrides unittest.TestCase.tearDown and called after every test."""
109 self.worker.CleanUp() 121 self.worker.CleanUp()
110 122
111 def testUpdateKeepStateful(self): 123 def testUpdateKeepStateful(self):
112 """Tests if we can update normally. 124 """Tests if we can update normally.
113 125
114 This test checks that we can update by updating the stateful partition 126 This test checks that we can update by updating the stateful partition
115 rather than wiping it. 127 rather than wiping it.
116 """ 128 """
129 self.worker.InitializeResultsDirectory()
117 # Just make sure some tests pass on original image. Some old images 130 # Just make sure some tests pass on original image. Some old images
118 # don't pass many tests. 131 # don't pass many tests.
119 self.worker.PrepareBase(self.base_image_path) 132 self.worker.PrepareBase(self.base_image_path)
120 # TODO(sosa): move to 100% once we start testing using the autotest paired 133 # TODO(sosa): move to 100% once we start testing using the autotest paired
121 # with the dev channel. 134 # with the dev channel.
122 percent_passed = self.worker.VerifyImage(self, 10) 135 percent_passed = self.worker.VerifyImage(self, 10)
123 136
124 # Update to - all tests should pass on new image. 137 # Update to - all tests should pass on new image.
125 self.worker.PerformUpdate(self.target_image_path, self.base_image_path) 138 self.worker.PerformUpdate(self.target_image_path, self.base_image_path)
126 percent_passed = self.worker.VerifyImage(self) 139 percent_passed = self.worker.VerifyImage(self)
127 140
128 # Update from - same percentage should pass that originally passed. 141 # Update from - same percentage should pass that originally passed.
129 self.worker.PerformUpdate(self.base_image_path, self.target_image_path) 142 self.worker.PerformUpdate(self.base_image_path, self.target_image_path)
130 self.worker.VerifyImage(self, percent_passed) 143 self.worker.VerifyImage(self, percent_passed)
131 144
132 def testUpdateWipeStateful(self): 145 def testUpdateWipeStateful(self):
133 """Tests if we can update after cleaning the stateful partition. 146 """Tests if we can update after cleaning the stateful partition.
134 147
135 This test checks that we can update successfully after wiping the 148 This test checks that we can update successfully after wiping the
136 stateful partition. 149 stateful partition.
137 """ 150 """
151 self.worker.InitializeResultsDirectory()
138 # Just make sure some tests pass on original image. Some old images 152 # Just make sure some tests pass on original image. Some old images
139 # don't pass many tests. 153 # don't pass many tests.
140 self.worker.PrepareBase(self.base_image_path) 154 self.worker.PrepareBase(self.base_image_path)
141 percent_passed = self.worker.VerifyImage(self, 10) 155 percent_passed = self.worker.VerifyImage(self, 10)
142 156
143 # Update to - all tests should pass on new image. 157 # Update to - all tests should pass on new image.
144 self.worker.PerformUpdate(self.target_image_path, self.base_image_path, 158 self.worker.PerformUpdate(self.target_image_path, self.base_image_path,
145 'clean') 159 'clean')
146 self.worker.VerifyImage(self) 160 self.worker.VerifyImage(self)
147 161
(...skipping 27 matching lines...) Expand all
175 outbound will be closed. 189 outbound will be closed.
176 """ 190 """
177 if self.close_count < 3: 191 if self.close_count < 3:
178 if self.data_size > (2 * 1024 * 1024): 192 if self.data_size > (2 * 1024 * 1024):
179 self.close_count += 1 193 self.close_count += 1
180 return None 194 return None
181 195
182 self.data_size += len(data) 196 self.data_size += len(data)
183 return data 197 return data
184 198
199 self.worker.InitializeResultsDirectory()
185 self.AttemptUpdateWithFilter(InterruptionFilter(), proxy_port=8082) 200 self.AttemptUpdateWithFilter(InterruptionFilter(), proxy_port=8082)
186 201
187 def testDelayedUpdate(self): 202 def testDelayedUpdate(self):
188 """Tests what happens if some data is delayed during update delivery""" 203 """Tests what happens if some data is delayed during update delivery"""
189 204
190 class DelayedFilter(cros_test_proxy.Filter): 205 class DelayedFilter(cros_test_proxy.Filter):
191 """Causes intermittent delays in data transmission. 206 """Causes intermittent delays in data transmission.
192 207
193 It does this by inserting 3 20 second delays when transmitting 208 It does this by inserting 3 20 second delays when transmitting
194 data after 2M has been sent. 209 data after 2M has been sent.
(...skipping 10 matching lines...) Expand all
205 are delayed by 20 seconds. 220 are delayed by 20 seconds.
206 """ 221 """
207 if self.delay_count < 3: 222 if self.delay_count < 3:
208 if self.data_size > (2 * 1024 * 1024): 223 if self.data_size > (2 * 1024 * 1024):
209 self.delay_count += 1 224 self.delay_count += 1
210 time.sleep(20) 225 time.sleep(20)
211 226
212 self.data_size += len(data) 227 self.data_size += len(data)
213 return data 228 return data
214 229
230 self.worker.InitializeResultsDirectory()
215 self.AttemptUpdateWithFilter(DelayedFilter(), proxy_port=8083) 231 self.AttemptUpdateWithFilter(DelayedFilter(), proxy_port=8083)
216 232
217 def SimpleTest(self): 233 def SimpleTest(self):
218 """A simple update that updates once from a base image to a target. 234 """A simple update that updates once from a base image to a target.
219 235
220 We explicitly don't use test prefix so that isn't run by default. Can be 236 We explicitly don't use test prefix so that isn't run by default. Can be
221 run using test_prefix option. 237 run using test_prefix option.
222 """ 238 """
239 self.worker.InitializeResultsDirectory()
223 self.worker.PrepareBase(self.base_image_path) 240 self.worker.PrepareBase(self.base_image_path)
224 self.worker.PerformUpdate(self.target_image_path, self.base_image_path) 241 #self.worker.PerformUpdate(self.target_image_path, self.base_image_path)
225 self.worker.VerifyImage(self) 242 self.worker.VerifyImage(self)
226 243
227 # --- DISABLED TESTS --- 244 # --- DISABLED TESTS ---
228 245
229 # TODO(sosa): Get test to work with verbose. 246 # TODO(sosa): Get test to work with verbose.
230 def NotestPartialUpdate(self): 247 def NotestPartialUpdate(self):
231 """Tests what happens if we attempt to update with a truncated payload.""" 248 """Tests what happens if we attempt to update with a truncated payload."""
249 self.worker.InitializeResultsDirectory()
232 # Preload with the version we are trying to test. 250 # Preload with the version we are trying to test.
233 self.worker.PrepareBase(self.target_image_path) 251 self.worker.PrepareBase(self.target_image_path)
234 252
235 # Image can be updated at: 253 # Image can be updated at:
236 # ~chrome-eng/chromeos/localmirror/autest-images 254 # ~chrome-eng/chromeos/localmirror/autest-images
237 url = 'http://gsdview.appspot.com/chromeos-localmirror/' \ 255 url = 'http://gsdview.appspot.com/chromeos-localmirror/' \
238 'autest-images/truncated_image.gz' 256 'autest-images/truncated_image.gz'
239 payload = os.path.join(self.download_folder, 'truncated_image.gz') 257 payload = os.path.join(self.download_folder, 'truncated_image.gz')
240 258
241 # Read from the URL and write to the local file 259 # Read from the URL and write to the local file
242 urllib.urlretrieve(url, payload) 260 urllib.urlretrieve(url, payload)
243 261
244 expected_msg = 'download_hash_data == update_check_response_hash failed' 262 expected_msg = 'download_hash_data == update_check_response_hash failed'
245 self.AttemptUpdateWithPayloadExpectedFailure(payload, expected_msg) 263 self.AttemptUpdateWithPayloadExpectedFailure(payload, expected_msg)
246 264
247 # TODO(sosa): Get test to work with verbose. 265 # TODO(sosa): Get test to work with verbose.
248 def NotestCorruptedUpdate(self): 266 def NotestCorruptedUpdate(self):
249 """Tests what happens if we attempt to update with a corrupted payload.""" 267 """Tests what happens if we attempt to update with a corrupted payload."""
268 self.worker.InitializeResultsDirectory()
250 # Preload with the version we are trying to test. 269 # Preload with the version we are trying to test.
251 self.worker.PrepareBase(self.target_image_path) 270 self.worker.PrepareBase(self.target_image_path)
252 271
253 # Image can be updated at: 272 # Image can be updated at:
254 # ~chrome-eng/chromeos/localmirror/autest-images 273 # ~chrome-eng/chromeos/localmirror/autest-images
255 url = 'http://gsdview.appspot.com/chromeos-localmirror/' \ 274 url = 'http://gsdview.appspot.com/chromeos-localmirror/' \
256 'autest-images/corrupted_image.gz' 275 'autest-images/corrupted_image.gz'
257 payload = os.path.join(self.download_folder, 'corrupted.gz') 276 payload = os.path.join(self.download_folder, 'corrupted.gz')
258 277
259 # Read from the URL and write to the local file 278 # Read from the URL and write to the local file
260 urllib.urlretrieve(url, payload) 279 urllib.urlretrieve(url, payload)
261 280
262 # This update is expected to fail... 281 # This update is expected to fail...
263 expected_msg = 'zlib inflate() error:-3' 282 expected_msg = 'zlib inflate() error:-3'
264 self.AttemptUpdateWithPayloadExpectedFailure(payload, expected_msg) 283 self.AttemptUpdateWithPayloadExpectedFailure(payload, expected_msg)
OLDNEW
« no previous file with comments | « no previous file | bin/au_test_harness/au_worker.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698