1 # Code Snippets 2 3 It 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 5 There 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 13 import collections 14 from google.appengine.ext import ndb 15 from speed.dashboard import utils 16 from dashboard.models import anomaly 17 18 sheriff = ndb.Key('Sheriff', 'Chromium Perf Sheriff') 19 query = anomaly.Anomaly.query(anomaly.Anomaly.bug_id == -1) 20 query = query.filter(anomaly.Anomaly.sheriff == sheriff) 21 query = query.order(-anomaly.Anomaly.timestamp) 22 alerts = query.fetch(limit=5000) 23 24 total_alerts = len(alerts) 25 print 'Fetched {} "invalid" alerts.'.format(len(alerts)) 26 27 occurrences = [[], [], []] 28 for 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 33 types = ['bot', 'benchmark', 'subtest'] 34 counters = [(type, collections.Counter(x)) for type, x in zip(types, occurrences)] 35 for 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 46 from dashboard.models import graph_data 47 48 LIMIT = 10000 49 50 query = graph_data.Test.query(graph_data.Test.parent_test == None) 51 test_keys = query.fetch(limit=LIMIT, keys_only=True) 52 unique = sorted(set(k.string_id() for k in test_keys)) 53 print 'Fetched %d Test keys, %d unique names.' % (len(test_keys), len(unique)) 54 for name in unique: 55 print name 56 ``` 57 58 ## List deprecated test suites 59 60 ```python 61 from dashboard import utils 62 from dashboard.models import graph_data 63 64 LIMIT = 10000 65 66 query = 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) 71 for key in test_keys: 72 print utils.TestPath(key) 73 ``` 74 75 ## List all sub-tests of a particular test 76 77 ```python 78 from google.appengine.ext import ndb 79 from dashboard import utils 80 from dashboard.models import graph_data 81 82 ancestor = utils.TestKey('ChromiumPerf/linux-release/sunspider') 83 keys = graph_data.Test.query(ancestor=ancestor).fetch(keys_only=True) 84 85 print 'Fetched %d keys.' % len(keys) 86 for key in keys: 87 print utils.TestPath(key) 88 ``` 89 90 ## Delete a particular sheriff or other entity 91 92 ```python 93 from google.appengine.ext import ndb 94 95 key = ndb.Key('Sheriff', 'Sheriff name') 96 print 'Deleting: %s\n%s' % (key.string_id(), key.get()) 97 key.delete() 98 ``` 99 100 ## Clear the LastAddedRevision entities for a Test 101 102 This allows point IDs that are much higher or lower to be posted. 103 104 ```python 105 from google.appengine.ext import ndb 106 from dashboard import utils 107 from dashboard.models import graph_data 108 109 ancestor_key = utils.TestKey('Master/bot/test') 110 test_query = graph_data.Test.query(ancestor=ancestor_key) 111 test_keys = test_query.fetch(keys_only=True) 112 to_delete = [] 113 for test_key in test_keys: 114 to_delete.append(ndb.Key('LastAddedRevision', utils.TestPath(test_key))) 115 print 'Deleting up to %d LastAddedRevision entities.' % len(to_delete) 116 ndb.delete_multi(to_delete) 117 ``` 118 119 ## Delete a few specific points (dangerous) 120 121 ```python 122 from google.appengine.ext import ndb 123 from dashboard.models import graph_data 124 125 POINTIDS = [] 126 TEST_PATHS = [] 127 128 to_delete = [] 129 for id in IDS: 130 for path in TEST_PATHS: 131 to_delete.append(ndb.Key('TestContainer', path, 'Row', id)) 132 133 print 'Deleting %d rows.' % len(to_delete) 134 ndb.delete_multi(to_delete) 135 ``` 136 137 ## Delete Rows and Tests under a particular Master or Bot (dangerous) 138 139 ```python 140 from google.appengine.ext import ndb 141 from dashboard import utils 142 from dashboard.models import graph_data 143 144 ancestor_key = utils.TestKey('ChromiumEndure') 145 test_keys = graph_data.Test.query(ancestor=ancestor_key).fetch(keys_only=True) 146 print len(test_keys) 147 to_delete = [] 148 for 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) 154 print len(to_delete) 155 ndb.delete_multi(to_delete[:1000]) 156 ``` 157