blob: d7a2aefc5fbbefe493b748b0aa0c110c99dda28b [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.
"""Provides a web interface for loading graph data from the production server.
This is meant to be used on a dev server only.
"""
import base64
import json
import os
import urllib
from google.appengine.api import app_identity
from google.appengine.api import urlfetch
from google.appengine.ext import ndb
from google.appengine.ext.ndb import model
from dashboard import datastore_hooks
from dashboard import request_handler
from dashboard import update_test_suites
_DEV_APP_ID = 'dev~' + app_identity.get_application_id()
_PROD_DUMP_GRAPH_JSON_URL = 'https://chromeperf.appspot.com/dump_graph_json'
class LoadFromProdHandler(request_handler.RequestHandler):
"""Debugging handler to load data from the production instance."""
def get(self):
if 'Development' not in os.environ['SERVER_SOFTWARE']:
self.RenderHtml('result.html', {
'errors': [
'This should not be run in production, only on dev server.']})
return
self.RenderHtml('load_from_prod.html', {})
def post(self):
"""Loads the requested data from the production server."""
if 'Development' not in os.environ['SERVER_SOFTWARE']:
self.RenderHtml('result.html', {
'errors': [
'This should not be run in production, only on dev server.']})
return
sheriff = self.request.get('sheriff')
test_path = self.request.get('test_path')
if test_path:
num_points = self.request.get('num_points')
end_rev = self.request.get('end_rev')
url = ('%s?test_path=%s&num_points=%s' %
(_PROD_DUMP_GRAPH_JSON_URL, urllib.quote(test_path), num_points))
if end_rev:
url += '&end_rev=%s' % end_rev
elif sheriff:
sheriff_name = self.request.get('sheriff')
num_alerts = self.request.get('num_alerts')
num_points = self.request.get('num_points')
url = ('%s?sheriff=%s&num_alerts=%s&num_points=%s' %
(_PROD_DUMP_GRAPH_JSON_URL, urllib.quote(sheriff_name), num_alerts,
num_points))
else:
self.RenderHtml('result.html', {
'errors': ['Need to specify a test_path or sheriff.']})
return
# This takes a while.
response = urlfetch.fetch(url, deadline=60)
if response.status_code != 200:
self.RenderHtml('result.html', {'errors': ['Could not fetch %s' % url]})
return
protos = json.loads(response.content)
kinds = ['Master', 'Bot', 'Test', 'Row', 'Sheriff', 'Anomaly']
entities = {k: [] for k in kinds}
for proto in protos:
pb = model.entity_pb.EntityProto(base64.b64decode(proto))
# App ID is set in the key and all the ReferenceProperty keys to
# 's~chromeperf'. It won't be found in queries unless we use the
# devserver app ID.
key = pb.mutable_key()
key.set_app(_DEV_APP_ID)
for prop in pb.property_list():
val = prop.mutable_value()
if val.has_referencevalue():
ref = val.mutable_referencevalue()
ref.set_app(_DEV_APP_ID)
entity = ndb.ModelAdapter().pb_to_entity(pb)
entities[entity.key.kind()].append(entity)
for kind in kinds:
ndb.put_multi(entities[kind])
update_test_suites.UpdateTestSuites(datastore_hooks.INTERNAL)
update_test_suites.UpdateTestSuites(datastore_hooks.EXTERNAL)
num_entities = sum(len(entities[kind]) for kind in kinds)
self.RenderHtml('result.html', {
'results': [
{
'name': 'Added data',
'value': '%d entities' % num_entities
}
]
})