blob: a13c53098d79f7377eaddd405ced78c725f923cb [file] [log] [blame]
Kuang-che Wu6e4beca2018-06-27 17:45:02 +08001# -*- coding: utf-8 -*-
Kuang-che Wu88875db2017-07-20 10:47:53 +08002# Copyright 2017 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5"""Test runner.py script"""
6
7from __future__ import print_function
8import argparse
9import unittest
10
Kuang-che Wua5723492019-11-25 20:59:34 +080011try:
12 from unittest import mock
13except ImportError:
14 # TODO(kcwu): remove once migrated to python3
15 import mock
Kuang-che Wu88875db2017-07-20 10:47:53 +080016
17import runner
Kuang-che Wue1b329e2018-03-31 11:39:33 +080018from bisect_kit import common
19from bisect_kit import configure
Kuang-che Wu88875db2017-07-20 10:47:53 +080020
21
22@mock.patch('bisect_kit.common.config_logging', mock.Mock())
23class TestRunner(unittest.TestCase):
24 """Test runner."""
25
Kuang-che Wue1b329e2018-03-31 11:39:33 +080026 def tearDown(self):
27 configure.reset()
28
Kuang-che Wu88875db2017-07-20 10:47:53 +080029 def test_argtype_ratio(self):
30 self.assertEqual(runner.argtype_ratio('=1'), ('=', 1.0))
31 with self.assertRaises(argparse.ArgumentTypeError):
32 runner.argtype_ratio('hello')
33 with self.assertRaises(argparse.ArgumentTypeError):
34 runner.argtype_ratio('>5')
35
36 def test_is_meet_finished(self):
37 self.assertEqual(
38 runner.criteria_is_met(('=', 0), dict(new=0, old=0, skip=1), 0, 'new'),
39 None)
40
41 self.assertEqual(
42 runner.criteria_is_met(('=', 0), dict(new=0, old=3), 0, 'new'), True)
43 self.assertEqual(
44 runner.criteria_is_met(('<', 0.4), dict(new=3, old=7), 0, 'new'), True)
45 self.assertEqual(
46 runner.criteria_is_met(('<=', 0.4), dict(new=3, old=7), 0, 'new'), True)
47 self.assertEqual(
48 runner.criteria_is_met(('>', 0.2), dict(new=3, old=7), 0, 'new'), True)
49 self.assertEqual(
50 runner.criteria_is_met(('>=', 0.2), dict(new=3, old=7), 0, 'new'), True)
51
52 def test_is_meet_rest(self):
53 self.assertEqual(
54 runner.criteria_is_met(('=', 0), dict(new=0, old=0, skip=1), 1, 'new'),
55 None)
56
57 # Between 0.45 and 0.63
58 self.assertEqual(
59 runner.criteria_is_met(('>', 0.5), dict(old=4, new=5), 2, 'new'), None)
60 # Between 0.5 and 0.6
61 self.assertEqual(
62 runner.criteria_is_met(('>', 0.5), dict(old=4, new=5), 1, 'new'), None)
63 # Between 0.5 and 0.6
64 self.assertEqual(
65 runner.criteria_is_met(('>=', 0.5), dict(old=4, new=5), 1, 'new'), True)
66 # Between 0.4 and 0.5
67 self.assertEqual(
68 runner.criteria_is_met(('>=', 0.5), dict(old=5, new=4), 1, 'new'), None)
69 # Between 0.4 and 0.5
70 self.assertEqual(
71 runner.criteria_is_met(('<', 0.5), dict(old=5, new=4), 1, 'new'), None)
72 # Between 0.5 and 0.6
73 self.assertEqual(
74 runner.criteria_is_met(('<=', 0.5), dict(old=4, new=5), 1, 'new'), None)
75 # Between 0.83 and 1.0
76 self.assertEqual(
77 runner.criteria_is_met(('=', 1.0), dict(old=0, new=5), 1, 'new'), None)
78
79 # It's certain because the result count is impossible non-integer.
80 self.assertEqual(
81 runner.criteria_is_met(('=', 0.5), dict(old=1, new=1), 1, 'new'), False)
82
83 def test_run_once_returncode(self):
Kuang-che Wue1b329e2018-03-31 11:39:33 +080084 common.init()
Kuang-che Wu88875db2017-07-20 10:47:53 +080085 parser = runner.create_argument_parser()
86 opts = parser.parse_args(['--new', '--returncode=0', 'true'])
87 self.assertEqual(runner.run_once(opts), runner.NEW)
88
89 opts = parser.parse_args(['--new', '--returncode=0', 'false'])
90 self.assertEqual(runner.run_once(opts), runner.OLD)
91
92 opts = parser.parse_args(['--new', '--returncode=0', 'program.not.found'])
Kuang-che Wu0476d1f2019-03-04 19:27:01 +080093 self.assertEqual(runner.run_once(opts), runner.OLD)
Kuang-che Wu88875db2017-07-20 10:47:53 +080094
95 opts = parser.parse_args(['--new', '--returncode=0', 'sh', '-c', 'kill $$'])
96 self.assertEqual(runner.run_once(opts), runner.FATAL)
97
98 def test_run_once_output(self):
Kuang-che Wue1b329e2018-03-31 11:39:33 +080099 common.init()
Kuang-che Wu88875db2017-07-20 10:47:53 +0800100 parser = runner.create_argument_parser()
101 opts = parser.parse_args(['--old', '--output', 'OLD', 'echo', 'OLD'])
102 self.assertEqual(runner.run_once(opts), runner.OLD)
103
104 opts = parser.parse_args([
105 '--old', '--output', 'OLD', '--precondition_output', 'foo', 'echo',
106 'foo OLD'
107 ])
108 self.assertEqual(runner.run_once(opts), runner.OLD)
109
110 opts = parser.parse_args([
111 '--old', '--output', 'OLD', '--precondition_output', 'foo', 'echo',
112 'bar OLD'
113 ])
114 self.assertEqual(runner.run_once(opts), runner.SKIP)
115
116 def test_run_once_timeout(self):
Kuang-che Wue1b329e2018-03-31 11:39:33 +0800117 common.init()
Kuang-che Wu88875db2017-07-20 10:47:53 +0800118 parser = runner.create_argument_parser()
119 opts = parser.parse_args(['--new', '--timeout=0.1', 'sleep', '0.11'])
120 self.assertEqual(runner.run_once(opts), runner.NEW)
121
122 opts = parser.parse_args(['--new', '--timeout=0.1', 'sleep', '0'])
123 self.assertEqual(runner.run_once(opts), runner.OLD)
124
125 def test_run_once_terminate_output(self):
Kuang-che Wue1b329e2018-03-31 11:39:33 +0800126 common.init()
Kuang-che Wu88875db2017-07-20 10:47:53 +0800127 parser = runner.create_argument_parser()
128 opts = parser.parse_args([
129 '--new', '--output=hello', '--terminate_output', 'hello', 'sh', '-c',
130 'echo hello; sleep 100; echo world'
131 ])
132 self.assertEqual(runner.run_once(opts), runner.NEW)
133
134 opts = parser.parse_args([
135 '--new', '--output=world', '--terminate_output', 'hello', 'sh', '-c',
136 'echo hello; sleep 100; echo world'
137 ])
138 self.assertEqual(runner.run_once(opts), runner.OLD)
139
140 def test_main(self):
141 self.assertEqual(
142 runner.main(['--new', '--output', 'hello', 'echo', 'hello']),
143 runner.NEW)
144 self.assertEqual(
145 runner.main(['--old', '--output', 'hello', 'echo', 'hello']),
146 runner.OLD)
147 self.assertEqual(
148 runner.main(['--new', '--output', 'hello', 'echo', 'world']),
149 runner.OLD)
150 self.assertEqual(
151 runner.main([
152 '--new', '--output', 'hello', '--precondition_output', 'hello',
153 'echo', 'world'
154 ]), runner.SKIP)
155
156 def test_main_fatal(self):
157 self.assertEqual(
158 runner.main(['--new', '--output', 'hello', '/non/existing/path']),
Kuang-che Wu0476d1f2019-03-04 19:27:01 +0800159 runner.OLD)
Kuang-che Wu88875db2017-07-20 10:47:53 +0800160
161 def test_main_shortcut(self):
162 with mock.patch.object(
163 runner, 'run_once', return_value=runner.OLD) as mock_run_once:
164 self.assertEqual(
165 runner.main(['--new', '--output=hello', '--repeat=5', 'foo']),
166 runner.OLD)
167 self.assertEqual(mock_run_once.call_count, 1)
168
169 with mock.patch.object(
170 runner, 'run_once', return_value=runner.OLD) as mock_run_once:
171 self.assertEqual(
172 runner.main(
173 ['--new', '--output=hello', '--repeat=10', '--ratio=>0.3',
174 'foo']), runner.OLD)
175 self.assertEqual(mock_run_once.call_count, 7)
176
177 with mock.patch.object(
178 runner, 'run_once', return_value=runner.OLD) as mock_run_once:
179 self.assertEqual(
180 runner.main([
181 '--new', '--output=hello', '--repeat=10', '--ratio=>0.3',
182 '--noshortcut', 'foo'
183 ]), runner.OLD)
184 self.assertEqual(mock_run_once.call_count, 10)
185
186
187if __name__ == '__main__':
188 unittest.main()