OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # Copyright 2016 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 subprocess |
| 9 import sys |
| 10 import unittest |
| 11 import copy |
| 12 |
| 13 from collections import OrderedDict |
| 14 |
| 15 import test_env |
| 16 |
| 17 import mock |
| 18 |
| 19 from expect_tests import CheckFrame |
| 20 from recipe_engine import checker |
| 21 |
| 22 |
| 23 class TestChecker(unittest.TestCase): |
| 24 def sanitize(self, checkframe): |
| 25 return checkframe._replace(line=0, fname='') |
| 26 |
| 27 def mk(self, fname, code, varmap): |
| 28 return CheckFrame( |
| 29 fname='', line=0, function=fname, code=code, varmap=varmap) |
| 30 |
| 31 def test_no_calls(self): |
| 32 c = checker.Checker('<filename>', 0, lambda: None, (), {}) |
| 33 def body(_): |
| 34 pass |
| 35 body(c) |
| 36 self.assertEqual(len(c.failed_checks), 0) |
| 37 |
| 38 def test_success_call(self): |
| 39 c = checker.Checker('<filename>', 0, lambda: None, (), {}) |
| 40 def body(check): |
| 41 check(True is True) |
| 42 body(c) |
| 43 self.assertEqual(len(c.failed_checks), 0) |
| 44 |
| 45 def test_simple_fail(self): |
| 46 c = checker.Checker('<filename>', 0, lambda: None, (), {}) |
| 47 def body(check): |
| 48 check(True is False) |
| 49 body(c) |
| 50 self.assertEqual(len(c.failed_checks), 1) |
| 51 self.assertEqual(len(c.failed_checks[0].frames), 1) |
| 52 self.assertEqual( |
| 53 self.sanitize(c.failed_checks[0].frames[0]), |
| 54 self.mk('body', 'check((True is False))', {})) |
| 55 |
| 56 def test_simple_fail_multiline(self): |
| 57 c = checker.Checker('<filename>', 0, lambda: None, (), {}) |
| 58 def body(check): |
| 59 falsey = lambda: False |
| 60 check( |
| 61 True is |
| 62 |
| 63 falsey() |
| 64 ) |
| 65 body(c) |
| 66 self.assertEqual(len(c.failed_checks), 1) |
| 67 self.assertEqual(len(c.failed_checks[0].frames), 1) |
| 68 self.assertEqual( |
| 69 self.sanitize(c.failed_checks[0].frames[0]), |
| 70 self.mk('body', 'check((True is falsey()))', {})) |
| 71 |
| 72 def test_simple_fail_multiline_multistatement(self): |
| 73 c = checker.Checker('<filename>', 0, lambda: None, (), {}) |
| 74 def body(check): |
| 75 other = 'thing' |
| 76 falsey = lambda: False |
| 77 check( |
| 78 True is |
| 79 |
| 80 falsey()); other # pylint: disable=pointless-statement |
| 81 body(c) |
| 82 self.assertEqual(len(c.failed_checks), 1) |
| 83 self.assertEqual(len(c.failed_checks[0].frames), 1) |
| 84 self.assertEqual( |
| 85 self.sanitize(c.failed_checks[0].frames[0]), |
| 86 self.mk('body', 'check((True is falsey())); other', { |
| 87 'other': "'thing'" })) |
| 88 |
| 89 def test_fail_nested_statement(self): |
| 90 c = checker.Checker('<filename>', 0, lambda: None, (), {}) |
| 91 def body(check): |
| 92 other = 'thing' |
| 93 falsey = lambda: False |
| 94 if True: |
| 95 while True: |
| 96 try: |
| 97 check( |
| 98 True is |
| 99 |
| 100 falsey()); other # pylint: disable=pointless-statement |
| 101 break |
| 102 except Exception: |
| 103 pass |
| 104 body(c) |
| 105 self.assertEqual(len(c.failed_checks), 1) |
| 106 self.assertEqual(len(c.failed_checks[0].frames), 1) |
| 107 self.assertEqual( |
| 108 self.sanitize(c.failed_checks[0].frames[0]), |
| 109 self.mk('body', 'check((True is falsey())); other', { |
| 110 'other': "'thing'" })) |
| 111 |
| 112 def test_var_fail(self): |
| 113 c = checker.Checker('<filename>', 0, lambda: None, (), {}) |
| 114 def body(check): |
| 115 val = True |
| 116 check(val is False) |
| 117 body(c) |
| 118 self.assertEqual(len(c.failed_checks), 1) |
| 119 self.assertEqual(len(c.failed_checks[0].frames), 1) |
| 120 self.assertEqual( |
| 121 self.sanitize(c.failed_checks[0].frames[0]), |
| 122 self.mk('body', 'check((val is False))', {'val': 'True'})) |
| 123 |
| 124 def test_dict_membership(self): |
| 125 c = checker.Checker('<filename>', 0, lambda: None, (), {}) |
| 126 def body(check): |
| 127 targ = {'a': 'b', 'c': 'd'} |
| 128 check('a' not in targ) |
| 129 body(c) |
| 130 self.assertEqual(len(c.failed_checks), 1) |
| 131 self.assertEqual(len(c.failed_checks[0].frames), 1) |
| 132 self.assertEqual( |
| 133 self.sanitize(c.failed_checks[0].frames[0]), |
| 134 self.mk('body', "check(('a' not in targ))", |
| 135 {'targ.keys()': "['a', 'c']"})) |
| 136 |
| 137 def test_dict_lookup(self): |
| 138 c = checker.Checker('<filename>', 0, lambda: None, (), {}) |
| 139 def body(check): |
| 140 targ = {'a': {'sub': 'b'}, 'c': 'd'} |
| 141 check('cow' in targ['a']) |
| 142 body(c) |
| 143 self.assertEqual(len(c.failed_checks), 1) |
| 144 self.assertEqual(len(c.failed_checks[0].frames), 1) |
| 145 self.assertEqual( |
| 146 self.sanitize(c.failed_checks[0].frames[0]), |
| 147 self.mk('body', "check(('cow' in targ['a']))", |
| 148 {"targ['a'].keys()": "['sub']"})) |
| 149 |
| 150 def test_dict_lookup_nest(self): |
| 151 c = checker.Checker('<filename>', 0, lambda: None, (), {}) |
| 152 def body(check): |
| 153 sub = 'sub' |
| 154 targ = {'a': {'sub': 'whee'}, 'c': 'd'} |
| 155 check('me' == targ['a'][sub]) |
| 156 body(c) |
| 157 self.assertEqual(len(c.failed_checks), 1) |
| 158 self.assertEqual(len(c.failed_checks[0].frames), 1) |
| 159 self.assertEqual( |
| 160 self.sanitize(c.failed_checks[0].frames[0]), |
| 161 self.mk('body', "check(('me' == targ['a'][sub]))", |
| 162 {"targ['a'][sub]": "'whee'", 'sub': "'sub'"})) |
| 163 |
| 164 def test_lambda_call(self): |
| 165 c = checker.Checker('<filename>', 0, lambda: None, (), {}) |
| 166 def body(check): |
| 167 vals = ['whee', 'sub'] |
| 168 targ = {'a': {'sub': 'whee'}, 'c': 'd'} |
| 169 map(lambda v: check(v in targ['a']), vals) |
| 170 body(c) |
| 171 self.assertEqual(len(c.failed_checks), 1) |
| 172 self.assertEqual(len(c.failed_checks[0].frames), 2) |
| 173 self.assertEqual( |
| 174 self.sanitize(c.failed_checks[0].frames[0]), |
| 175 self.mk('body', "map((lambda v: check((v in targ['a']))), vals)", None)) |
| 176 self.assertEqual( |
| 177 self.sanitize(c.failed_checks[0].frames[1]), |
| 178 self.mk('<lambda>', "map((lambda v: check((v in targ['a']))), vals)", |
| 179 {"targ['a'].keys()": "['sub']", 'v': "'whee'"})) |
| 180 |
| 181 |
| 182 class TestVerifySubset(unittest.TestCase): |
| 183 @staticmethod |
| 184 def mkData(*steps): |
| 185 return OrderedDict([ |
| 186 (s, { |
| 187 'cmd': ['list', 'of', 'things'], |
| 188 'env': { |
| 189 'dict': 'of', |
| 190 'many': 'strings,' |
| 191 }, |
| 192 'name': s, |
| 193 'status_code': 1, |
| 194 }) for s in steps |
| 195 ]) |
| 196 |
| 197 def setUp(self): |
| 198 self.v = checker.VerifySubset |
| 199 self.d = self.mkData('a', 'b', 'c') |
| 200 self.c = copy.deepcopy(self.d) |
| 201 |
| 202 def test_types(self): |
| 203 self.assertIn( |
| 204 "type mismatch: 'str' v 'OrderedDict'", |
| 205 self.v('hi', self.d)) |
| 206 |
| 207 self.assertIn( |
| 208 "type mismatch: 'list' v 'OrderedDict'", |
| 209 self.v(['hi'], self.d)) |
| 210 |
| 211 def test_empty(self): |
| 212 self.assertIsNone(self.v({}, self.d)) |
| 213 self.assertIsNone(self.v(OrderedDict(), self.d)) |
| 214 |
| 215 def test_single_removal(self): |
| 216 del self.c['c'] |
| 217 self.assertIsNone(self.v(self.c, self.d)) |
| 218 |
| 219 def test_add(self): |
| 220 self.c['d'] = self.c['a'] |
| 221 self.assertIn( |
| 222 "added key 'd'", |
| 223 self.v(self.c, self.d)) |
| 224 |
| 225 def test_add_key(self): |
| 226 self.c['c']['blort'] = 'cake' |
| 227 self.assertIn( |
| 228 "added key 'blort'", |
| 229 self.v(self.c, self.d)) |
| 230 |
| 231 def test_key_alter(self): |
| 232 self.c['c']['cmd'] = 'cake' |
| 233 self.assertEqual( |
| 234 "['c']['cmd']: type mismatch: 'str' v 'list'", |
| 235 self.v(self.c, self.d)) |
| 236 |
| 237 def test_list_add(self): |
| 238 self.c['c']['cmd'].append('something') |
| 239 self.assertIn( |
| 240 "['c']['cmd']: too long: 4 v 3", |
| 241 self.v(self.c, self.d)) |
| 242 |
| 243 self.c['c']['cmd'].pop(0) |
| 244 self.assertIn( |
| 245 "['c']['cmd']: added 1 elements", |
| 246 self.v(self.c, self.d)) |
| 247 |
| 248 def test_list_of_dict(self): |
| 249 self.assertIsNone( |
| 250 self.v( |
| 251 [{'c': 'd', 'a': 'cat'}], |
| 252 [{'a': 'b'}, {'c': 'd'}])) |
| 253 |
| 254 def test_ordereddict(self): |
| 255 a = self.c['a'] |
| 256 del self.c['a'] |
| 257 self.c['a'] = a |
| 258 self.assertIn( |
| 259 "key 'a' is out of order", |
| 260 self.v(self.c, self.d)) |
| 261 |
| 262 |
| 263 if __name__ == '__main__': |
| 264 sys.exit(unittest.main()) |
OLD | NEW |