1 # Copyright 2015 The Chromium Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 import unittest 6 7 import webapp2 8 import webtest 9 10 from google.appengine.api import users 11 12 from dashboard import edit_anomaly_configs 13 from dashboard import edit_config_handler 14 from dashboard import list_tests 15 from dashboard import put_entities_task 16 from dashboard import testing_common 17 from dashboard import xsrf 18 from dashboard.models import anomaly_config 19 from dashboard.models import graph_data 20 21 22 class EditAnomalyConfigsTest(testing_common.TestCase): 23 24 # This test case tests post requests to /edit_anomaly_configs. 25 # Each post request is either a request to add an entity or to edit one. 26 27 def setUp(self): 28 super(EditAnomalyConfigsTest, self).setUp() 29 app = webapp2.WSGIApplication( 30 [ 31 ('/edit_anomaly_configs', 32 edit_anomaly_configs.EditAnomalyConfigsHandler), 33 ('/put_entities_task', put_entities_task.PutEntitiesTaskHandler), 34 ]) 35 self.testapp = webtest.TestApp(app) 36 37 def tearDown(self): 38 super(EditAnomalyConfigsTest, self).tearDown() 39 self.UnsetCurrentUser() 40 41 def testAdd(self): 42 """Tests changing the config property of an existing AnomalyConfig.""" 43 self.SetCurrentUser('qyearsley (at] chromium.org', is_admin=True) 44 45 self.testapp.post('/edit_anomaly_configs', { 46 'add-edit': 'add', 47 'add-name': 'New Config', 48 'config': '{"foo": 10}', 49 'patterns': 'M/b/ts/*\nM/b/ts/*/*\n', 50 'xsrf_token': xsrf.GenerateToken(users.get_current_user()), 51 }) 52 53 anomaly_configs = anomaly_config.AnomalyConfig.query().fetch() 54 self.assertEqual(len(anomaly_configs), 1) 55 config = anomaly_configs[0] 56 self.assertEqual('New Config', config.key.string_id()) 57 self.assertEqual({'foo': 10}, config.config) 58 self.assertEqual(['M/b/ts/*', 'M/b/ts/*/*'], config.patterns) 59 60 def testEdit(self): 61 """Tests changing the config property of an existing AnomalyConfig.""" 62 self.SetCurrentUser('sullivan (at] chromium.org', is_admin=True) 63 anomaly_config.AnomalyConfig( 64 id='Existing Config', config={'old': 11}, 65 patterns=['MyMaster/*/*/*']).put() 66 67 self.testapp.post('/edit_anomaly_configs', { 68 'add-edit': 'edit', 69 'edit-name': 'Existing Config', 70 'config': '{"new": 10}', 71 'patterns': 'MyMaster/*/*/*', 72 'xsrf_token': xsrf.GenerateToken(users.get_current_user()), 73 }) 74 75 anomaly_configs = anomaly_config.AnomalyConfig.query().fetch() 76 self.assertEqual(len(anomaly_configs), 1) 77 self.assertEqual('Existing Config', anomaly_configs[0].key.string_id()) 78 self.assertEqual({'new': 10}, anomaly_configs[0].config) 79 self.assertEqual(['MyMaster/*/*/*'], anomaly_configs[0].patterns) 80 81 def testEdit_AddPattern(self): 82 """Tests changing the patterns list of an existing AnomalyConfig.""" 83 self.SetCurrentUser('sullivan (at] chromium.org', is_admin=True) 84 master = graph_data.Master(id='TheMaster').put() 85 graph_data.Bot(id='TheBot', parent=master).put() 86 suite1 = graph_data.TestMetadata(id='TheMaster/TheBot/Suite1').put() 87 suite2 = graph_data.TestMetadata(id='TheMaster/TheBot/Suite2').put() 88 test_aaa = graph_data.TestMetadata( 89 id='TheMaster/TheBot/Suite1/aaa', has_rows=True).put() 90 test_bbb = graph_data.TestMetadata( 91 id='TheMaster/TheBot/Suite1/bbb', has_rows=True).put() 92 test_ccc = graph_data.TestMetadata( 93 id='TheMaster/TheBot/Suite1/ccc', has_rows=True).put() 94 test_ddd = graph_data.TestMetadata( 95 id='TheMaster/TheBot/Suite2/ddd', has_rows=True).put() 96 anomaly_config.AnomalyConfig(id='1-Suite1-specific', config={'a': 10}).put() 97 anomaly_config.AnomalyConfig(id='2-Suite1-general', config={'b': 20}).put() 98 99 self.testapp.post('/edit_anomaly_configs', { 100 'add-edit': 'edit', 101 'edit-name': '1-Suite1-specific', 102 'config': '{"a": 10}', 103 'patterns': '*/*/Suite1/aaa', 104 'xsrf_token': xsrf.GenerateToken(users.get_current_user()), 105 }) 106 self.ExecuteTaskQueueTasks( 107 '/put_entities_task', edit_config_handler._TASK_QUEUE_NAME) 108 self.testapp.post('/edit_anomaly_configs', { 109 'add-edit': 'edit', 110 'edit-name': '2-Suite1-general', 111 'config': '{"b": 20}', 112 'patterns': '*/*/Suite1/*', 113 'xsrf_token': xsrf.GenerateToken(users.get_current_user()), 114 }) 115 self.ExecuteTaskQueueTasks( 116 '/put_entities_task', edit_config_handler._TASK_QUEUE_NAME) 117 118 # The lists of test patterns in the AnomalyConfig entities in the datastore 119 # should be set based on what was added in the two requests above. 120 self.assertEqual( 121 ['*/*/Suite1/*'], 122 anomaly_config.AnomalyConfig.get_by_id('2-Suite1-general').patterns) 123 self.assertEqual( 124 ['*/*/Suite1/aaa'], 125 anomaly_config.AnomalyConfig.get_by_id('1-Suite1-specific').patterns) 126 127 # The 1-Suite1-specific config applies instead of the other config 128 # because its name comes first according to sort order. 129 self.assertEqual( 130 '1-Suite1-specific', 131 test_aaa.get().overridden_anomaly_config.string_id()) 132 # The 2-Suite1-specific config applies to the other tests under Suite1. 133 self.assertEqual( 134 '2-Suite1-general', 135 test_bbb.get().overridden_anomaly_config.string_id()) 136 self.assertEqual( 137 '2-Suite1-general', 138 test_ccc.get().overridden_anomaly_config.string_id()) 139 140 # Note that Suite2/ddd has no config, and nor do the parent tests. 141 self.assertIsNone(test_ddd.get().overridden_anomaly_config) 142 self.assertIsNone(suite1.get().overridden_anomaly_config) 143 self.assertIsNone(suite2.get().overridden_anomaly_config) 144 145 def testEdit_RemovePattern(self): 146 """Tests removing a pattern from an AnomalyConfig.""" 147 self.SetCurrentUser('sullivan (at] chromium.org', is_admin=True) 148 anomaly_config_key = anomaly_config.AnomalyConfig( 149 id='Test Config', config={'a': 10}, 150 patterns=['*/*/one', '*/*/two']).put() 151 master = graph_data.Master(id='TheMaster').put() 152 graph_data.Bot(id='TheBot', parent=master).put() 153 test_one = graph_data.TestMetadata( 154 id='TheMaster/TheBot/one', overridden_anomaly_config=anomaly_config_key, 155 has_rows=True).put() 156 test_two = graph_data.TestMetadata( 157 id='TheMaster/TheBot/two', overridden_anomaly_config=anomaly_config_key, 158 has_rows=True).put() 159 160 # Verify the state of the data before making the request. 161 self.assertEqual(['*/*/one', '*/*/two'], anomaly_config_key.get().patterns) 162 self.assertEqual( 163 ['TheMaster/TheBot/one'], 164 list_tests.GetTestsMatchingPattern('*/*/one')) 165 166 self.testapp.post('/edit_anomaly_configs', { 167 'add-edit': 'edit', 168 'edit-name': 'Test Config', 169 'config': '{"a": 10}', 170 'patterns': ['*/*/two'], 171 'xsrf_token': xsrf.GenerateToken(users.get_current_user()), 172 }) 173 self.ExecuteTaskQueueTasks( 174 '/put_entities_task', edit_config_handler._TASK_QUEUE_NAME) 175 176 self.assertEqual(['*/*/two'], anomaly_config_key.get().patterns) 177 self.assertIsNone(test_one.get().overridden_anomaly_config) 178 self.assertEqual( 179 'Test Config', test_two.get().overridden_anomaly_config.string_id()) 180 181 182 if __name__ == '__main__': 183 unittest.main() 184