• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5import unittest
6
7import webapp2
8import webtest
9
10from google.appengine.api import users
11
12from dashboard import edit_anomaly_configs
13from dashboard import edit_config_handler
14from dashboard import list_tests
15from dashboard import put_entities_task
16from dashboard import testing_common
17from dashboard import xsrf
18from dashboard.models import anomaly_config
19from dashboard.models import graph_data
20
21
22class 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@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@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@chromium.org', is_admin=True)
84    master = graph_data.Master(id='TheMaster').put()
85    bot = graph_data.Bot(id='TheBot', parent=master).put()
86    suite1 = graph_data.Test(id='Suite1', parent=bot).put()
87    suite2 = graph_data.Test(id='Suite2', parent=bot).put()
88    test_aaa = graph_data.Test(id='aaa', parent=suite1, has_rows=True).put()
89    test_bbb = graph_data.Test(id='bbb', parent=suite1, has_rows=True).put()
90    test_ccc = graph_data.Test(id='ccc', parent=suite1, has_rows=True).put()
91    test_ddd = graph_data.Test(id='ddd', parent=suite2, has_rows=True).put()
92    anomaly_config.AnomalyConfig(id='1-Suite1-specific', config={'a': 10}).put()
93    anomaly_config.AnomalyConfig(id='2-Suite1-general', config={'b': 20}).put()
94
95    self.testapp.post('/edit_anomaly_configs', {
96        'add-edit': 'edit',
97        'edit-name': '1-Suite1-specific',
98        'config': '{"a": 10}',
99        'patterns': '*/*/Suite1/aaa',
100        'xsrf_token': xsrf.GenerateToken(users.get_current_user()),
101    })
102    self.ExecuteTaskQueueTasks(
103        '/put_entities_task', edit_config_handler._TASK_QUEUE_NAME)
104    self.testapp.post('/edit_anomaly_configs', {
105        'add-edit': 'edit',
106        'edit-name': '2-Suite1-general',
107        'config': '{"b": 20}',
108        'patterns': '*/*/Suite1/*',
109        'xsrf_token': xsrf.GenerateToken(users.get_current_user()),
110    })
111    self.ExecuteTaskQueueTasks(
112        '/put_entities_task', edit_config_handler._TASK_QUEUE_NAME)
113
114    # The lists of test patterns in the AnomalyConfig entities in the datastore
115    # should be set based on what was added in the two requests above.
116    self.assertEqual(
117        ['*/*/Suite1/*'],
118        anomaly_config.AnomalyConfig.get_by_id('2-Suite1-general').patterns)
119    self.assertEqual(
120        ['*/*/Suite1/aaa'],
121        anomaly_config.AnomalyConfig.get_by_id('1-Suite1-specific').patterns)
122
123    # The 1-Suite1-specific config applies instead of the other config
124    # because its name comes first according to sort order.
125    self.assertEqual(
126        '1-Suite1-specific',
127        test_aaa.get().overridden_anomaly_config.string_id())
128    # The 2-Suite1-specific config applies to the other tests under Suite1.
129    self.assertEqual(
130        '2-Suite1-general',
131        test_bbb.get().overridden_anomaly_config.string_id())
132    self.assertEqual(
133        '2-Suite1-general',
134        test_ccc.get().overridden_anomaly_config.string_id())
135
136    # Note that Suite2/ddd has no config, and nor do the parent tests.
137    self.assertIsNone(test_ddd.get().overridden_anomaly_config)
138    self.assertIsNone(suite1.get().overridden_anomaly_config)
139    self.assertIsNone(suite2.get().overridden_anomaly_config)
140
141  def testEdit_RemovePattern(self):
142    """Tests removing a pattern from an AnomalyConfig."""
143    self.SetCurrentUser('sullivan@chromium.org', is_admin=True)
144    anomaly_config_key = anomaly_config.AnomalyConfig(
145        id='Test Config', config={'a': 10},
146        patterns=['*/*/one', '*/*/two']).put()
147    master = graph_data.Master(id='TheMaster').put()
148    bot = graph_data.Bot(id='TheBot', parent=master).put()
149    test_one = graph_data.Test(
150        id='one', parent=bot, overridden_anomaly_config=anomaly_config_key,
151        has_rows=True).put()
152    test_two = graph_data.Test(
153        id='two', parent=bot, overridden_anomaly_config=anomaly_config_key,
154        has_rows=True).put()
155
156    # Verify the state of the data before making the request.
157    self.assertEqual(['*/*/one', '*/*/two'], anomaly_config_key.get().patterns)
158    self.assertEqual(
159        ['TheMaster/TheBot/one'],
160        list_tests.GetTestsMatchingPattern('*/*/one'))
161
162    self.testapp.post('/edit_anomaly_configs', {
163        'add-edit': 'edit',
164        'edit-name': 'Test Config',
165        'config': '{"a": 10}',
166        'patterns': ['*/*/two'],
167        'xsrf_token': xsrf.GenerateToken(users.get_current_user()),
168    })
169    self.ExecuteTaskQueueTasks(
170        '/put_entities_task', edit_config_handler._TASK_QUEUE_NAME)
171
172    self.assertEqual(['*/*/two'], anomaly_config_key.get().patterns)
173    self.assertIsNone(test_one.get().overridden_anomaly_config)
174    self.assertEqual(
175        'Test Config', test_two.get().overridden_anomaly_config.string_id())
176
177
178if __name__ == '__main__':
179  unittest.main()
180