Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/env python | |
| 2 # Copyright 2017 The LUCI Authors. All rights reserved. | |
| 3 # Use of this source code is governed under the Apache License, Version 2.0 | |
| 4 # that can be found in the LICENSE file. | |
| 5 | |
| 6 import json | |
| 7 import os | |
| 8 import shutil | |
| 9 import subprocess | |
| 10 import sys | |
| 11 import tempfile | |
| 12 import unittest | |
| 13 | |
| 14 | |
| 15 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
| 16 sys.path.insert(0, ROOT_DIR) | |
| 17 import recipe_engine.env | |
| 18 | |
| 19 | |
| 20 from recipe_engine import package | |
| 21 from recipe_engine import package_pb2 | |
| 22 | |
| 23 | |
| 24 class TestTest(unittest.TestCase): | |
| 25 def setUp(self): | |
| 26 root_dir = tempfile.mkdtemp() | |
| 27 config_dir = os.path.join(root_dir, 'infra', 'config') | |
| 28 os.makedirs(config_dir) | |
| 29 | |
| 30 self._root_dir = root_dir | |
| 31 self._recipes_cfg = os.path.join(config_dir, 'recipes.cfg') | |
| 32 self._recipe_tool = os.path.join(ROOT_DIR, 'recipes.py') | |
| 33 | |
| 34 test_pkg = package_pb2.Package( | |
| 35 api_version=1, | |
| 36 project_id='test_pkg', | |
| 37 recipes_path='', | |
| 38 deps=[ | |
| 39 package_pb2.DepSpec( | |
| 40 project_id='recipe_engine', | |
| 41 url='file://'+ROOT_DIR), | |
| 42 ], | |
| 43 ) | |
| 44 package.ProtoFile(self._recipes_cfg).write(test_pkg) | |
| 45 | |
| 46 def tearDown(self): | |
| 47 shutil.rmtree(self._root_dir) | |
| 48 | |
| 49 def _run_recipes(self, *args): | |
| 50 return subprocess.check_output(( | |
| 51 sys.executable, | |
| 52 self._recipe_tool, | |
| 53 '--use-bootstrap', | |
| 54 '--package', self._recipes_cfg, | |
| 55 ) + args) | |
| 56 | |
| 57 def _write_recipe(self, name, deps, step_lines, expect, test_lines=None): | |
| 58 if not test_lines: | |
| 59 test_lines = ['yield api.test("basic")'] | |
| 60 recipes_dir = os.path.join(self._root_dir, 'recipes') | |
| 61 expect_dir = os.path.join(recipes_dir, '%s.expected' % name) | |
| 62 for d in (recipes_dir, expect_dir): | |
| 63 if not os.path.exists(d): | |
| 64 os.makedirs(d) | |
| 65 with open(os.path.join(recipes_dir, '%s.py' % name), 'w') as f: | |
| 66 f.write('\n'.join([ | |
| 67 'from recipe_engine import post_process', | |
| 68 '', | |
| 69 'DEPS = %r' % deps, | |
| 70 '', | |
| 71 'def RunSteps(api):', | |
| 72 ] + [' %s' % l for l in step_lines] + [ | |
| 73 '', | |
| 74 'def GenTests(api):', | |
| 75 ] + [' %s' % l for l in test_lines])) | |
| 76 with open(os.path.join(expect_dir, 'basic.json'), 'w') as f: | |
| 77 json.dump(expect, f) | |
| 78 | |
| 79 def test_list(self): | |
| 80 self._write_recipe( | |
| 81 'foo', [], ['pass'], | |
| 82 [{'name': '$result', 'recipe_result': None, 'status_code': 0}]) | |
|
iannucci
2017/03/08 17:59:20
This invocation is pretty cryptic. Wdyt about
r =
| |
| 83 self.assertEqual( | |
| 84 ['foo.basic'], | |
| 85 self._run_recipes('test', 'list').splitlines()) | |
| 86 | |
| 87 def test_test(self): | |
| 88 self._write_recipe( | |
| 89 'foo', [], ['pass'], | |
| 90 [{'name': '$result', 'recipe_result': None, 'status_code': 0}]) | |
| 91 self._run_recipes('test', 'run') | |
| 92 | |
| 93 def test_test_diff_failure(self): | |
| 94 self._write_recipe( | |
| 95 'foo', [], ['pass'], | |
| 96 None) | |
| 97 with self.assertRaises(subprocess.CalledProcessError) as cm: | |
| 98 self._run_recipes('test', 'run') | |
| 99 self.assertNotIn('FATAL: Insufficient coverage', cm.exception.output) | |
| 100 self.assertNotIn('CHECK(FAIL)', cm.exception.output) | |
| 101 self.assertIn( | |
| 102 'foo.basic failed', | |
| 103 cm.exception.output) | |
| 104 | |
| 105 def test_test_recipe_not_covered(self): | |
| 106 self._write_recipe( | |
| 107 'foo', [], ['if False:', ' pass'], | |
| 108 [{'name': '$result', 'recipe_result': None, 'status_code': 0}]) | |
| 109 with self.assertRaises(subprocess.CalledProcessError) as cm: | |
| 110 self._run_recipes('test', 'run') | |
| 111 self.assertIn('FATAL: Insufficient coverage', cm.exception.output) | |
| 112 self.assertNotIn('CHECK(FAIL)', cm.exception.output) | |
| 113 self.assertNotIn('foo.basic failed', cm.exception.output) | |
| 114 | |
| 115 def test_test_check_failure(self): | |
| 116 self._write_recipe( | |
| 117 'foo', [], ['pass'], | |
| 118 [{'name': '$result', 'recipe_result': None, 'status_code': 0}], | |
| 119 test_lines=['yield api.test("basic") + api.post_process(post_process.Mus tRun, "bar")']) | |
| 120 with self.assertRaises(subprocess.CalledProcessError) as cm: | |
| 121 self._run_recipes('test', 'run') | |
| 122 self.assertNotIn('FATAL: Insufficient coverage', cm.exception.output) | |
| 123 self.assertIn('CHECK(FAIL)', cm.exception.output) | |
| 124 self.assertIn('foo.basic failed', cm.exception.output) | |
| 125 | |
| 126 | |
| 127 if __name__ == '__main__': | |
| 128 sys.exit(unittest.main()) | |
| OLD | NEW |