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

Unified Diff: scripts/slave/unittests/recipes_test.py

Issue 15270004: Add step generator protocol, remove annotated_checkout, remove script. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Address comments and change expected json output format Created 7 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « scripts/slave/unittests/recipe_util_test.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: scripts/slave/unittests/recipes_test.py
diff --git a/scripts/slave/unittests/recipes_test.py b/scripts/slave/unittests/recipes_test.py
index 7508b6e1bd21776481d6fdf445321b49112d061c..f568ca2de6c0f1885904e86a5e4c41652580f129 100755
--- a/scripts/slave/unittests/recipes_test.py
+++ b/scripts/slave/unittests/recipes_test.py
@@ -3,6 +3,39 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Provides test coverage for individual recipes.
+
+Recipe tests are located in ../recipes_test/*.py.
+
+Each py file's splitext'd name is expected to match a recipe in ../recipes/*.py.
+
+Each test py file contains one or more test functions:
+ * A test function's name ends with '_test' and takes an instance of TestAPI
+ as its only parameter.
+ * The test should return a dictionary with any of the following keys:
+ * factory_properties
+ * build_properties
+ * test_data
+ * test_data's value should be a dictionary in the form of
+ {stepname -> (retcode, json_data)}
+ * Since the test doesn't run any steps, test_data allows you to simulate
+ return values for particular steps.
+
+Once your test methods are set up, run `recipes_test.py --train`. This will
+take your tests and simulate what steps would have run, given the test inputs,
+and will record them as JSON into files of the form:
+ ../recipes_test/<recipe_name>.<test_name>.expected
+
+If those files look right, make sure they get checked in with your changes.
+
+When this file runs as a test (i.e. as `recipes_test.py`), it will re-evaluate
+the recipes using the test function input data and compare the result to the
+values recorded in the .expected files.
+
+Additionally, this test cannot pass unless every recipe in ../recipes has 100%
+code coverage when executed via the tests in ../recipes_test.
+"""
+
import contextlib
import json
import os
@@ -85,14 +118,14 @@ def execute_test_case(test_fn, recipe_path):
test_data = test_fn(TestAPI())
bp = test_data.get('build_properties', {})
fp = test_data.get('factory_properties', {})
+ td = test_data.get('test_data', {})
fp['recipe'] = os.path.basename(os.path.splitext(recipe_path)[0])
stream = annotator.StructuredAnnotationStream(stream=open(os.devnull, 'w'))
with cover():
with recipe_util.mock_paths():
- retval = annotated_run.make_steps(stream, bp, fp, True)
- assert retval.status_code is None
- return retval.script or retval.steps
+ step_data = annotated_run.run_steps(stream, bp, fp, td).steps_ran.values()
+ return [s.step for s in step_data]
def train_from_tests(recipe_path):
@@ -108,7 +141,18 @@ def train_from_tests(recipe_path):
expected_path = expected_for(recipe_path, name)
print 'Writing', expected_path
with open(expected_path, 'w') as f:
- json.dump(steps, f, indent=2, sort_keys=True)
+ f.write('[')
+ first = True
+ for step in steps:
+ f.write(('' if first else '\n },')+'\n {')
+ first_dict_item = True
+ for key, value in sorted(step.items(), key=lambda x: x[0]):
+ f.write(('' if first_dict_item else ',')+'\n ')
+ f.write('"%s": ' % key)
+ json.dump(value, f, sort_keys=True)
+ first_dict_item = False
+ first = False
+ f.write('\n }\n]')
return True
@@ -139,7 +183,8 @@ def load_tests(loader, _standard_tests, _pattern):
if has_test(recipe_path):
RecipeTest.add_test_methods()
- RecipeTest.__name__ += 'for_%s' % os.path.basename(recipe_path)
+ RecipeTest.__name__ += '_for_%s' % (
+ os.path.splitext(os.path.basename(recipe_path))[0])
return RecipeTest
suite = unittest.TestSuite()
« no previous file with comments | « scripts/slave/unittests/recipe_util_test.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698