def xxxNOT_WORKING_YETxxxtestUpdateDirtyWithResultTimeKey(self): ua_string = ('Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.6) ' 'Gecko/2009011912 Firefox/3.0.6') result_parent = ResultParent.AddResult(self.test_set, '12.2.2.11', ua_string, 'apple=0,banana=99,coconut=101', skip_update_dirty=True) skip_rt, update_rt, next_rt = result_parent.GetResultTimes() # Make so there is only one ResultTime to schedule after first update. skip_rt.dirty = False skip_rt.put() self.mox.StubOutWithMock(ResultTime, 'UpdateStats') self.mox.StubOutWithMock(ResultParent, 'ScheduleUpdateDirty') ResultTime.UpdateStats(update_rt) ResultParent.ScheduleUpdateDirty(next_rt.key()) self.mox.ReplayAll() response = self.client.get('/admin/update_dirty/some_category', {'result_time_key': update_rt.key()}, **mock_data.UNIT_TEST_UA) self.mox.VerifyAll()
def ScheduleCategoryUpdate(result_parent_key): """Add a task to update a category's statistics. The task is handled by base.admin.UpdateCategory which then calls UpdateCategory below. """ # Give the task a name to ensure only one task for each ResultParent. result_parent = ResultParent.get(result_parent_key) category = result_parent.category name = 'categoryupdate-%s' % str(result_parent_key).replace('_', '-under-') url = '/_ah/queue/update-category/%s/%s' % (category, result_parent_key) task = taskqueue.Task(url=url, name=name, params={ 'category': category, 'user_agent_key': result_parent.user_agent.key(), }) attempt = 0 while attempt < 3: try: task.add(queue_name='update-category') break except: attempt += 1 logging.info('Cannot add task(attempt %s): %s:%s' % (attempt, sys.exc_type, sys.exc_value))
def MakeDirty(request): """For testing purposes, make some tests dirty.""" query = ResultParent.all() result_times = [] for result_parent in query.fetch(10): for result_time in ResultTime.all().ancestor(result_parent).fetch(1000): result_time.dirty = True result_times.append(result_time) db.put(result_times) return http.HttpResponse('Made %s result_times dirty' % len(result_times))
def testAddResult(self): parent = ResultParent.AddResult( self.test_set, '12.2.2.25', mock_data.GetUserAgentString('Firefox 3.5'), 'apple=1,banana=11,coconut=111') expected_results = { 'apple': 1, 'banana': 11, 'coconut': 111, } self.assertEqual(expected_results, parent.GetResults())
def testGetMedianAndNumScores(self): for scores in ((0, 0, 500), (1, 1, 200), (0, 2, 300), (1, 3, 100), (0, 4, 400)): parent = ResultParent.AddResult( self.test_set, '12.2.2.25', mock_data.GetUserAgentString('Firefox 3.5'), 'apple=%s,banana=%s,coconut=%s' % scores) rankers = self.test_set.GetRankers('Firefox 3') self.assertEqual( [(0, 5), (2, 5), (300, 5)], [ranker.GetMedianAndNumScores() for ranker in rankers])
def MakeDirty(request): """For testing purposes, make some tests dirty.""" query = ResultParent.all() result_times = [] for result_parent in query.fetch(10): for result_time in ResultTime.all().ancestor(result_parent).fetch( 1000): result_time.dirty = True result_times.append(result_time) db.put(result_times) return http.HttpResponse('Made %s result_times dirty' % len(result_times))
def testGetMedianAndNumScoresWithParams(self): params = test_set_params.Params('w-params', 'a=b', 'c=d', 'e=f') self.test_set.default_params = params for scores in ((1, 0, 2), (1, 1, 1), (0, 2, 200)): parent = ResultParent.AddResult( self.test_set, '12.2.2.25', mock_data.GetUserAgentString('Firefox 3.5'), 'apple=%s,banana=%s,coconut=%s' % scores, params_str=str(params)) ranker = self.test_set.GetTest('coconut').GetRanker('Firefox 3') self.assertEqual((2, 3), ranker.GetMedianAndNumScores())
def testRecentTestsBasic(self): result_parents = [] for scores in ((1, 4, 50), (1, 1, 20), (0, 2, 30)): result = ResultParent.AddResult( self.test_set, '1.2.2.5', mock_data.GetUserAgentString('Firefox 3.5'), 'apple=%s,banana=%s,coconut=%s' % scores) result_parents.append(result) params = {} response = self.client.get('/cron/update_recent_tests', params) recent_tests = memcache.get(key=util.RECENT_TESTS_MEMCACHE_KEY)
def UpdateOldDirty(): """Update dirty queries from the past.""" num_scheduled = 0 seen_result_parent_keys = set() dirty_query = ResultTime.all(keys_only=True).filter('dirty =', True) for i, result_time_key in enumerate(dirty_query.fetch(500)): result_parent_key = result_time_key.parent() if result_parent_key not in seen_result_parent_keys: seen_result_parent_keys.add(result_parent_key) result_parent = ResultParent.get(result_parent_key) category = result_parent.category age = datetime.datetime.now() - result_parent.created if age.days > 0 or age.seconds > OLD_SECONDS: logging.info( 'Schedule old dirty:%d:%d: %s, age=%s, result_parent=%s, result_time=%s', i, num_scheduled, category, age, result_parent_key, result_time_key) if ResultParent.ScheduleUpdateDirty(result_time_key, category, count=-1): num_scheduled += 1 if num_scheduled == 10: break
def testUpdateDirtyGeneral(self): ua_string = ('Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.6) ' 'Gecko/2009011912 Firefox/3.0.6') self.mox.StubOutWithMock(manage_dirty, 'ScheduleCategoryUpdate') manage_dirty.ScheduleCategoryUpdate(mox.IgnoreArg()) self.mox.ReplayAll() # AddResult schedules the dirty update. result_parent = ResultParent.AddResult( self.test_set, '12.2.2.11', ua_string, 'apple=0,banana=99,coconut=101') self.mox.VerifyAll() self.assertEqual([False, False, False], [x.dirty for x in result_parent.GetResultTimes()])
def testAddResultWithExpando(self): AddAdjustResults(self.test_set) parent = ResultParent.AddResult( self.test_set, '12.2.2.25', mock_data.GetUserAgentString('Firefox 3.5'), 'apple=1,banana=49,coconut=499') self.assertEqual(1, parent.apple) self.assertEqual(49, parent.banana) self.assertEqual(499, parent.coconut) expected_results = { 'apple': 1, 'banana': 25, 'coconut': 250, } self.assertEqual(expected_results, parent.GetResults())
def testAddResultForTestSetWithAdjustResults(self): AddAdjustResults(self.test_set) parent = ResultParent.AddResult( self.test_set, '12.2.2.25', mock_data.GetUserAgentString('Firefox 3.5'), 'apple=0,banana=80,coconut=200') self.assertEqual(0, parent.apple) self.assertEqual(80, parent.banana) self.assertEqual(200, parent.coconut) expected_results = { 'apple': 0, 'banana': 40, 'coconut': 100, } self.assertEqual(expected_results, parent.GetResults())
def testAddResult(self): chrome_ua_string = ('Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) ' 'AppleWebKit/530.1 (KHTML, like Gecko) ' 'Chrome/2.0.169.1 Safari/530.1') ua_string = ( 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 6.0; Trident/4.0; ' 'chromeframe; SLCC1; .NET CLR 2.0.5077; 3.0.30729),gzip(gfe),gzip(gfe)' ) parent = ResultParent.AddResult(self.test_set, '12.2.2.25', ua_string, 'apple=1,banana=3,coconut=500', js_user_agent_string=chrome_ua_string) self.assertEqual(chrome_ua_string, parent.user_agent.js_user_agent_string)
def UpdateOldDirty(): """Update dirty queries from the past.""" num_scheduled = 0 seen_result_parent_keys = set() dirty_query = ResultTime.all(keys_only=True).filter('dirty =', True) for i, result_time_key in enumerate(dirty_query.fetch(500)): result_parent_key = result_time_key.parent() if result_parent_key not in seen_result_parent_keys: seen_result_parent_keys.add(result_parent_key) result_parent = ResultParent.get(result_parent_key) category = result_parent.category age = datetime.datetime.now() - result_parent.created if age.days > 0 or age.seconds > OLD_SECONDS: logging.info( 'Schedule old dirty:%d:%d: %s, age=%s, result_parent=%s, result_time=%s', i, num_scheduled, category, age, result_parent_key, result_time_key) if ResultParent.ScheduleUpdateDirty( result_time_key, category, count=-1): num_scheduled += 1 if num_scheduled == 10: break
def UpdateDirty(request): """Updates any dirty tests, adding its score to the appropriate ranker.""" logging.debug('UpdateDirty start.') task_name_prefix = request.REQUEST.get('task_name_prefix', '') result_time_key = request.REQUEST.get('result_time_key') category = request.REQUEST.get('category') count = int(request.REQUEST.get('count', 0)) if result_time_key: result_time = ResultTime.get(result_time_key) try: ResultTime.UpdateStats(result_time) except: logging.info('UpdateStats: %s:%s' % (sys.exc_type, sys.exc_value)) result_parent_key = result_time.parent_key() else: result_parent_key = request.REQUEST.get('result_parent_key') if result_parent_key: result_parent_key = db.Key(result_parent_key) else: UpdateOldDirty() return http.HttpResponse('Done scheduling old results.') # Create a task for the next dirty ResultTime to update. dirty_query = ResultTime.all(keys_only=True) dirty_query.filter('dirty =', True) dirty_query.ancestor(result_parent_key) next_result_time_key = dirty_query.get() if next_result_time_key: logging.debug('Schedule next ResultTime: %s', next_result_time_key) ResultParent.ScheduleUpdateDirty(next_result_time_key, category, count + 1, task_name_prefix) else: logging.debug('Done with result_parent: %s', result_parent_key) ScheduleCategoryUpdate(result_parent_key) shardedcounter.increment(category) return http.HttpResponse('Done.')
def DataDump(request): """This is used by bin/data_dump.py to replicate the datastore.""" model = request.REQUEST.get('model') key_prefix = request.REQUEST.get('key_prefix', '') keys_list = request.REQUEST.get('keys') time_limit = int(request.REQUEST.get('time_limit', 3)) if keys_list: keys = ['%s%s' % (key_prefix, key) for key in keys_list.split(',')] else: return http.HttpResponseBadRequest('"keys" is a required parameter.') start_time = datetime.datetime.now() if model == 'ResultParent': query = pager.PagerQuery(ResultParent, keys_only=True) elif model == 'UserAgent': query = pager.PagerQuery(UserAgent) else: return http.HttpResponseBadRequest( 'model must be one of "ResultParent", "UserAgent".') data = [] error = None if model == 'ResultParent': result_time_query = ResultTime.gql('WHERE ANCESTOR IS :1') for result_parent_key in keys: if (datetime.datetime.now() - start_time).seconds > time_limit: error = 'Over time limit' break try: p = ResultParent.get(result_parent_key) except db.Timeout: error = 'db.Timeout: ResultParent' break if not p: data.append({ 'model_class': 'ResultParent', 'lost_key': result_parent_key, }) continue result_time_query.bind(p.key()) try: result_times = result_time_query.fetch(1000) except db.Timeout: error = 'db.Timeout: ResultTime' break row_data = [{ 'model_class': 'ResultParent', 'result_parent_key': result_parent_key, 'category': p.category, 'user_agent_key': str( ResultParent.user_agent.get_value_for_datastore(p)), 'ip': p.ip, 'user_id': p.user and p.user.user_id() or None, 'created': p.created and p.created.isoformat() or None, 'params_str': p.params_str, 'loader_id': hasattr(p, 'loader_id') and p.loader_id or None, }] is_dirty = False for result_time in result_times: if result_time.dirty: is_dirty = True break row_data.append({ 'model_class': 'ResultTime', 'result_time_key': str(result_time.key()), 'result_parent_key': str(result_parent_key), 'test': result_time.test, 'score': result_time.score, }) if is_dirty: data.append({'dirty_key': result_parent_key,}) else: data.extend(row_data) elif model == 'UserAgent': try: user_agents = UserAgent.get(keys) except db.Timeout: error = 'db.Timeout: UserAgent' else: for key, ua in zip(keys, user_agents): if ua: data.append({ 'model_class': 'UserAgent', 'user_agent_key': key, 'string': ua.string, 'family': ua.family, 'v1': ua.v1, 'v2': ua.v2, 'v3': ua.v3, 'confirmed': ua.confirmed, 'created': ua.created and ua.created.isoformat() or None, 'js_user_agent_string': (hasattr(ua, 'js_user_agent_string') and ua.js_user_agent_string or None), }) else: data.append({ 'model_class': 'UserAgent', 'lost_key': key, }) response_params = { 'data': data, } if error: response_params['error'] = error return http.HttpResponse(content=simplejson.dumps(response_params), content_type='application/json')
def testGetStats(self): add_result_params = ( # ((apple, banana, coconut), firefox_version) ((0, 0, 500), 'Firefox 3.0.7'), ((1, 1, 200), 'Firefox 3.0.7'), ((0, 2, 300), 'Firefox 3.0.7'), ((1, 3, 100), 'Firefox 3.5'), ((0, 4, 400), 'Firefox 3.5')) for scores, browser in add_result_params: parent = ResultParent.AddResult( self.test_set, '12.2.2.25', mock_data.GetUserAgentString(browser), 'apple=%s,banana=%s,coconut=%s' % scores) level_1_stats = { 'Firefox 3': { 'summary_score': 605, 'summary_display': '302', 'total_runs': 5, 'results': { 'coconut': { 'score': 600, 'raw_score': 300, 'display': 'd:600' }, 'apple': { 'score': 1, 'raw_score': 0, 'display': 'no' }, 'banana': { 'score': 4, 'raw_score': 2, 'display': 'd:4' } } }, 'total_runs': 5, } self.assertEqual( level_1_stats, result_stats.CategoryStatsManager.GetStats( self.test_set, browsers=('Firefox 3', ), test_keys=['apple', 'banana', 'coconut'])) level_3_stats = { 'Firefox 3.0.7': { 'summary_score': 603, 'summary_display': '301', 'total_runs': 3, 'results': { 'coconut': { 'score': 600, 'raw_score': 300, 'display': 'd:600' }, 'apple': { 'score': 1, 'raw_score': 0, 'display': 'no' }, 'banana': { 'score': 2, 'raw_score': 1, 'display': 'd:2' } } }, 'Firefox 3.5': { 'summary_score': 908, 'summary_display': '405', 'total_runs': 2, 'results': { 'coconut': { 'score': 800, 'raw_score': 400, 'display': 'd:800' }, 'apple': { 'score': 100, 'raw_score': 1, 'display': 'yes' }, 'banana': { 'score': 8, 'raw_score': 4, 'display': 'd:8' } } }, 'total_runs': 5, } self.assertEqual( level_3_stats, result_stats.CategoryStatsManager.GetStats( self.test_set, browsers=('Firefox 3.0.7', 'Firefox 3.5'), test_keys=['apple', 'banana', 'coconut']))