1# Code Snippets 2 3It is possible to directly execute code on a production instance of the performance dashboard. This is one way to directly query information about the state of the datastore, and make quick adjustments to data in the datastore. 4 5There are two places where production code can be run (admins only): 6 7 - https://chromeperf.appspot.com/\_ah/dev\_console/interactive 8 - https://chromeperf.appspot.com/\_ah/stats/shell 9 10## List tests frequently marked as invalid 11 12```python 13import collections 14from google.appengine.ext import ndb 15from speed.dashboard import utils 16from dashboard.models import anomaly 17 18sheriff = ndb.Key('Sheriff', 'Chromium Perf Sheriff') 19query = anomaly.Anomaly.query(anomaly.Anomaly.bug_id == -1) 20query = query.filter(anomaly.Anomaly.sheriff == sheriff) 21query = query.order(-anomaly.Anomaly.timestamp) 22alerts = query.fetch(limit=5000) 23 24total_alerts = len(alerts) 25print 'Fetched {} "invalid" alerts.'.format(len(alerts)) 26 27occurrences = [[], [], []] 28for a in alerts: 29 parts = utils.TestPath(a.test).split('/', 3)[1:] 30 for i, part in enumerate(parts): 31 occurrences[i].append(part) 32 33types = ['bot', 'benchmark', 'subtest'] 34counters = [(type, collections.Counter(x)) for type, x in zip(types, occurrences)] 35for type, counter in counters: 36 print 'nTop {}s marked invalid:'.format(type) 37 print ' {0:>5} {1:>13} {2}'.format('Count', '% of invalid', 'Name') 38 for name, count in counter.most_common(10): 39 percent = 100 * float(count) / total_alerts 40 print ' {0:>5} {1:>12}% {2}'.format(count, percent, name) 41``` 42 43## List unique test suite names 44 45```python 46from dashboard.models import graph_data 47 48LIMIT = 10000 49 50query = graph_data.Test.query(graph_data.Test.parent_test == None) 51test_keys = query.fetch(limit=LIMIT, keys_only=True) 52unique = sorted(set(k.string_id() for k in test_keys)) 53print 'Fetched %d Test keys, %d unique names.' % (len(test_keys), len(unique)) 54for name in unique: 55 print name 56``` 57 58## List deprecated test suites 59 60```python 61from dashboard import utils 62from dashboard.models import graph_data 63 64LIMIT = 10000 65 66query = graph_data.Test.query( 67 graph_data.Test.parent_test == None, 68 graph_data.Test.deprecated == True) 69 test_keys = query.fetch(limit=LIMIT, keys_only=True) 70 print 'Fetched %d Test keys.' % len(test_keys) 71for key in test_keys: 72 print utils.TestPath(key) 73``` 74 75## List all sub-tests of a particular test 76 77```python 78from google.appengine.ext import ndb 79from dashboard import utils 80from dashboard.models import graph_data 81 82ancestor = utils.TestKey('ChromiumPerf/linux-release/sunspider') 83keys = graph_data.Test.query(ancestor=ancestor).fetch(keys_only=True) 84 85print 'Fetched %d keys.' % len(keys) 86for key in keys: 87 print utils.TestPath(key) 88``` 89 90## Delete a particular sheriff or other entity 91 92```python 93from google.appengine.ext import ndb 94 95key = ndb.Key('Sheriff', 'Sheriff name') 96print 'Deleting: %s\n%s' % (key.string_id(), key.get()) 97key.delete() 98``` 99 100## Clear the LastAddedRevision entities for a Test 101 102This allows point IDs that are much higher or lower to be posted. 103 104```python 105from google.appengine.ext import ndb 106from dashboard import utils 107from dashboard.models import graph_data 108 109ancestor_key = utils.TestKey('Master/bot/test') 110test_query = graph_data.Test.query(ancestor=ancestor_key) 111test_keys = test_query.fetch(keys_only=True) 112to_delete = [] 113for test_key in test_keys: 114 to_delete.append(ndb.Key('LastAddedRevision', utils.TestPath(test_key))) 115print 'Deleting up to %d LastAddedRevision entities.' % len(to_delete) 116ndb.delete_multi(to_delete) 117``` 118 119## Delete a few specific points (dangerous) 120 121```python 122from google.appengine.ext import ndb 123from dashboard.models import graph_data 124 125POINTIDS = [] 126TEST_PATHS = [] 127 128to_delete = [] 129for id in IDS: 130 for path in TEST_PATHS: 131 to_delete.append(ndb.Key('TestContainer', path, 'Row', id)) 132 133print 'Deleting %d rows.' % len(to_delete) 134ndb.delete_multi(to_delete) 135``` 136 137## Delete Rows and Tests under a particular Master or Bot (dangerous) 138 139```python 140from google.appengine.ext import ndb 141from dashboard import utils 142from dashboard.models import graph_data 143 144ancestor_key = utils.TestKey('ChromiumEndure') 145test_keys = graph_data.Test.query(ancestor=ancestor_key).fetch(keys_only=True) 146print len(test_keys) 147to_delete = [] 148for test_key in test_keys: 149 row_keys = graph_data.Row.query( 150 graph_data.Row.parent_test == test_key).fetch(keys_only=True, limit=100) 151 to_delete.extend(row_keys) 152 if not row_keys: 153 to_delete.append(test_key) 154print len(to_delete) 155ndb.delete_multi(to_delete[:1000]) 156``` 157