blob: 433f0623b1e791d5085be2781c38c4058309cffa [file] [log] [blame]
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import json
import unittest
import webapp2
import webtest
from google.appengine.ext import ndb
from dashboard import datastore_hooks
from dashboard import layered_cache
from dashboard import list_tests
from dashboard import testing_common
from dashboard import utils
from dashboard.models import graph_data
class ListTestsTest(testing_common.TestCase):
def setUp(self):
super(ListTestsTest, self).setUp()
app = webapp2.WSGIApplication(
[('/list_tests', list_tests.ListTestsHandler)])
self.testapp = webtest.TestApp(app)
datastore_hooks.InstallHooks()
self.UnsetCurrentUser()
testing_common.SetIsInternalUser('internal@chromium.org', True)
testing_common.SetIsInternalUser('foo@chromium.org', False)
def _AddSampleData(self):
testing_common.AddTests(
['Chromium'],
['win7', 'mac'],
{
'dromaeo': {
'dom': {},
'jslib': {},
},
'scrolling': {
'commit_time': {
'www.yahoo.com': {},
'www.cnn.com': {},
},
'commit_time_ref': {},
},
'really': {
'nested': {
'very': {
'deeply': {
'subtest': {}
}
},
'very_very': {}
}
},
})
def tearDown(self):
self.testbed.deactivate()
def testGetSubTests_FetchAndCacheBehavior(self):
self._AddSampleData()
# Set the has_rows flag to true on two of the Test entities.
for test_path in [
'Chromium/win7/really/nested/very/deeply/subtest',
'Chromium/win7/really/nested/very_very']:
test = utils.TestKey(test_path).get()
test.has_rows = True
test.put()
# A tree-structured dict of dicts is constructed, and the 'has_rows'
# flag is set to true for two of these tests. These two tests and
# their parents are all included in the result.
response = self.testapp.post('/list_tests', {
'type': 'sub_tests',
'suite': 'really',
'bots': 'Chromium/win7,Chromium/mac'})
self.assertEqual('*', response.headers.get('Access-Control-Allow-Origin'))
expected = {
'nested': {
'has_rows': False,
'sub_tests': {
'very': {
'has_rows': False,
'sub_tests': {
'deeply': {
'has_rows': False,
'sub_tests': {
'subtest': {
'has_rows': True,
'sub_tests': {}
}
}
}
}
},
'very_very': {
'has_rows': True,
'sub_tests': {}
}
}
}
}
# The response should be as expected.
self.assertEqual(expected, json.loads(response.body))
# The cache should be set for the win7 bot with the expected response.
self.assertEqual(expected, layered_cache.Get(
graph_data.LIST_TESTS_SUBTEST_CACHE_KEY % (
'Chromium', 'win7', 'really')))
# Change mac subtests in cache. Should be merged with win7.
mac_subtests = {
'mactest': {
'has_rows': False,
'sub_tests': {
'graph': {
'has_rows': True,
'sub_tests': {}
}
}
}
}
layered_cache.Set(
graph_data.LIST_TESTS_SUBTEST_CACHE_KEY % ('Chromium', 'mac', 'really'),
mac_subtests)
response = self.testapp.post('/list_tests', {
'type': 'sub_tests',
'suite': 'really',
'bots': 'Chromium/win7,Chromium/mac'})
self.assertEqual('*', response.headers.get('Access-Control-Allow-Origin'))
expected.update(mac_subtests)
self.assertEqual(expected, json.loads(response.body))
def testGetSubTests_ReturnsOnlyNonDeprecatedTests(self):
# Sub-tests with the same name may be deprecated on only one bot, and not
# deprecated on another bot; only non-deprecated tests should be returned.
self._AddSampleData()
# Set the deprecated flag to True for one test on one platform.
test = utils.TestKey('Chromium/mac/dromaeo/jslib').get()
test.deprecated = True
test.put()
# Set the has_rows flag to true for all of the test entities.
for test_path in [
'Chromium/win7/dromaeo/dom',
'Chromium/win7/dromaeo/jslib',
'Chromium/mac/dromaeo/dom',
'Chromium/mac/dromaeo/jslib']:
test = utils.TestKey(test_path).get()
test.has_rows = True
test.put()
# When a request is made for subtests for the platform wherein that a
# subtest is deprecated, that subtest will not be listed.
response = self.testapp.post('/list_tests', {
'type': 'sub_tests',
'suite': 'dromaeo',
'bots': 'Chromium/mac'})
self.assertEqual('*', response.headers.get('Access-Control-Allow-Origin'))
expected = {
'dom': {
'has_rows': True,
'sub_tests': {}
},
'jslib': {
'has_rows': True,
'sub_tests': {},
'deprecated': True
}
}
self.assertEqual(expected, json.loads(response.body))
def testGetSubTests_InternalData_OnlyReturnedForAuthorizedUsers(self):
# When the user has a an internal account, internal-only data is given.
self.SetCurrentUser('internal@chromium.org')
self._AddSampleData()
# Set internal_only on a bot and top-level test.
bot = ndb.Key('Master', 'Chromium', 'Bot', 'win7').get()
bot.internal_only = True
bot.put()
test = graph_data.Test.get_by_id('dromaeo', parent=bot.key)
test.internal_only = True
test.put()
# Set internal_only and has_rows to true on two subtests.
for name in ['dom', 'jslib']:
subtest = graph_data.Test.get_by_id(name, parent=test.key)
subtest.internal_only = True
subtest.has_rows = True
subtest.put()
# All of the internal-only tests are returned.
response = self.testapp.post('/list_tests', {
'type': 'sub_tests', 'suite': 'dromaeo', 'bots': 'Chromium/win7'})
expected = {
'dom': {
'has_rows': True,
'sub_tests': {}
},
'jslib': {
'has_rows': True,
'sub_tests': {}
}
}
self.assertEqual(expected, json.loads(response.body))
# After setting the user to another domain, an empty dict is returned.
self.SetCurrentUser('foo@chromium.org')
response = self.testapp.post('/list_tests', {
'type': 'sub_tests', 'suite': 'dromaeo', 'bots': 'Chromium/win7'})
self.assertEqual({}, json.loads(response.body))
def testMergeSubTestsDict(self):
a = {
'foo': {
'has_rows': True,
'sub_tests': {'a': {'has_rows': True, 'sub_tests': {}}},
},
'bar': {
'has_rows': False,
'sub_tests': {
'b': {
'has_rows': False,
'sub_tests': {
'c': {
'has_rows': False,
'deprecated': True,
'sub_tests': {},
},
},
},
},
},
}
b = {
'bar': {
'has_rows': True,
'sub_tests': {
'b': {
'has_rows': False,
'sub_tests': {
'c': {
'has_rows': False,
'sub_tests': {},
},
},
},
},
},
'baz': {'has_rows': False, 'sub_tests': {}},
}
self.assertEqual(
{
'foo': {
'has_rows': True,
'sub_tests': {'a': {'has_rows': True, 'sub_tests': {}}},
},
'bar': {
'has_rows': True,
'sub_tests': {
'b': {
'has_rows': False,
'sub_tests': {
'c': {'has_rows': False, 'sub_tests': {}},
},
},
},
},
'baz': {'has_rows': False, 'sub_tests': {}},
},
list_tests._MergeSubTestsDict(a, b))
def testSubTestsDict(self):
paths = [
'a/b/c',
'a/b/c',
'a/b/d',
]
expected = {
'a': {
'has_rows': False,
'sub_tests': {
'b': {
'has_rows': False,
'sub_tests': {
'c': {'has_rows': True, 'sub_tests': {}},
'd': {'has_rows': True, 'sub_tests': {}},
},
},
},
},
}
self.assertEqual(
expected, list_tests._SubTestsDict(paths, False))
def testPost_GetTestsMatchingPattern(self):
"""Tests the basic functionality of the GetTestsMatchingPattern function."""
self._AddSampleData()
# A pattern can match tests with a particular bot and with a particular
# number of levels of nesting.
# The results are lexicographically ordered by test path.
response = self.testapp.post('/list_tests', {
'type': 'pattern',
'p': 'Chromium/mac/*/*/www*'})
expected = [
'Chromium/mac/scrolling/commit_time/www.cnn.com',
'Chromium/mac/scrolling/commit_time/www.yahoo.com',
]
self.assertEqual(expected, json.loads(response.body))
# The same thing is returned if has_rows is set to '0' or another string
# that is not '1'.
response = self.testapp.post('/list_tests', {
'type': 'pattern',
'has_rows': '0',
'p': '*/mac/*/*/www*'})
self.assertEqual(expected, json.loads(response.body))
response = self.testapp.post('/list_tests', {
'type': 'pattern',
'has_rows': 'foo',
'p': '*/mac/*/*/www*'})
self.assertEqual(expected, json.loads(response.body))
def testPost_GetTestsMatchingPattern_OnlyWithRows(self):
"""Tests GetTestsMatchingPattern with the parameter only_with_rows set."""
self._AddSampleData()
# When no Test entities have has_rows set, filtering with the parameter
# 'has_rows' set to '1' results in no rows being returned.
response = self.testapp.post('/list_tests', {
'type': 'pattern',
'has_rows': '1',
'p': '*/mac/dromaeo/*'})
self.assertEqual([], json.loads(response.body))
# Set the has_rows flag on one of the tests.
test = utils.TestKey('Chromium/mac/dromaeo/dom').get()
test.has_rows = True
test.put()
# Even though multiple tests could match the pattern, only the test with
# has_rows set is returned.
response = self.testapp.post('/list_tests', {
'type': 'pattern',
'has_rows': '1',
'p': '*/mac/dromaeo/*'})
self.assertEqual(['Chromium/mac/dromaeo/dom'], json.loads(response.body))
if __name__ == '__main__':
unittest.main()