зеркало из https://github.com/mozilla/eideticker.git
Bug 1017834 - Add support for specifying a branch for dashboard testruns;r=davehunt
This commit is contained in:
Родитель
e264a341f0
Коммит
f64f3d4899
|
@ -134,37 +134,40 @@ r = requests.get(baseurl + 'devices.json')
|
|||
if not validate_json_response(r):
|
||||
print "Can't download device list, exiting"
|
||||
sys.exit(1)
|
||||
devicedict = r.json()
|
||||
|
||||
save_file(os.path.join(outputdir, 'devices.json'), r.content)
|
||||
|
||||
if options.device_id:
|
||||
if options.device_id in r.json()['devices'].keys():
|
||||
device_names = [ options.device_id ]
|
||||
deviceids = [ options.device_id ]
|
||||
else:
|
||||
print "WARNING: Device id '%s' specified but unavailable. Skipping." % \
|
||||
options.device_id
|
||||
device_names = []
|
||||
deviceids = []
|
||||
else:
|
||||
device_names = r.json()['devices'].keys()
|
||||
deviceids = devicedict['devices'].keys()
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor(MAX_WORKERS) as executor:
|
||||
for device_name in device_names:
|
||||
r = requests.get(baseurl + '%s/tests.json' % device_name)
|
||||
if not validate_json_response(r):
|
||||
print "Skipping tests for %s" % device_name
|
||||
continue
|
||||
for deviceid in deviceids:
|
||||
for branchid in devicedict['devices'][deviceid]['branches']:
|
||||
r = requests.get(baseurl + '%s/%s/tests.json' % (deviceid, branchid))
|
||||
if not validate_json_response(r):
|
||||
print "Skipping tests for device: %s, branch: %s" % (
|
||||
deviceid, branchid)
|
||||
continue
|
||||
|
||||
devicedir = os.path.join(outputdir, device_name)
|
||||
create_dir(devicedir)
|
||||
save_file(os.path.join(devicedir, 'tests.json'), r.content)
|
||||
testnames = r.json()['tests'].keys()
|
||||
for testname in testnames:
|
||||
executor.submit(download_testdata,
|
||||
baseurl + '%s/%s.json' % (device_name, testname),
|
||||
baseurl,
|
||||
os.path.join(outputdir, device_name,
|
||||
'%s.json' % testname),
|
||||
options,
|
||||
metadatadir, videodir, profiledir)
|
||||
testdir = os.path.join(outputdir, deviceid, branchid)
|
||||
create_dir(testdir)
|
||||
save_file(os.path.join(testdir, 'tests.json'), r.content)
|
||||
testnames = r.json()['tests'].keys()
|
||||
for testname in testnames:
|
||||
executor.submit(download_testdata,
|
||||
baseurl + '%s/%s/%s.json' % (deviceid, branchid, testname),
|
||||
baseurl,
|
||||
os.path.join(outputdir, deviceid, branchid,
|
||||
'%s.json' % testname),
|
||||
options,
|
||||
metadatadir, videodir, profiledir)
|
||||
|
||||
sys.exit(exit_status)
|
||||
|
|
|
@ -117,8 +117,10 @@ def runtest(dm, device_prefs, options, product, appinfo, testinfo,
|
|||
log_actions=(testtype == 'web' or testtype == 'b2g')))
|
||||
|
||||
# Write testdata
|
||||
eideticker.update_dashboard_testdata(options.dashboard_dir, options.device_id,
|
||||
testinfo, productname, appdate,
|
||||
eideticker.update_dashboard_testdata(options.dashboard_dir,
|
||||
options.device_id,
|
||||
options.branch_id, testinfo,
|
||||
productname, appdate,
|
||||
datapoint, metadata)
|
||||
|
||||
def main(args=sys.argv[1:]):
|
||||
|
@ -132,6 +134,9 @@ def main(args=sys.argv[1:]):
|
|||
parser.add_option("--device-id", action="store", dest="device_id",
|
||||
help="id of device (used in output json)",
|
||||
default=os.environ.get('DEVICE_ID'))
|
||||
parser.add_option("--branch", action="store", dest="branch_id",
|
||||
help="branch under test (used in output json)",
|
||||
default=os.environ.get('BRANCH'))
|
||||
parser.add_option("--device-name", action="store", dest="device_name",
|
||||
help="name of device to display in dashboard (if not "
|
||||
"specified, display model name)",
|
||||
|
@ -155,17 +160,19 @@ def main(args=sys.argv[1:]):
|
|||
default="nightly",
|
||||
help="product name (android-specific, default: "
|
||||
"%default)")
|
||||
|
||||
options, args = parser.parse_args()
|
||||
|
||||
if not args: # need to specify at least one test to run!
|
||||
parser.print_usage()
|
||||
sys.exit(1)
|
||||
|
||||
device_id = options.device_id
|
||||
if not device_id:
|
||||
print "ERROR: Must specify device id (either with --device-id or with "
|
||||
"DEVICE_ID environment variable)"
|
||||
if not options.device_id:
|
||||
print "ERROR: Must specify device id (either with --device-id or with " \
|
||||
"DEVICE_ID environment variable)"
|
||||
sys.exit(1)
|
||||
if not options.branch_id:
|
||||
print "ERROR: Must specify branch (either with --branch or with " \
|
||||
"BRANCH environment variable)"
|
||||
sys.exit(1)
|
||||
|
||||
# get device info
|
||||
|
@ -189,8 +196,8 @@ def main(args=sys.argv[1:]):
|
|||
print "ERROR: Unknown device type '%s'" % options.devicetype
|
||||
|
||||
# update device index
|
||||
eideticker.update_dashboard_device_list(options.dashboard_dir, device_id,
|
||||
device_info)
|
||||
eideticker.update_dashboard_device_list(options.dashboard_dir, options.device_id,
|
||||
options.branch_id, device_info)
|
||||
|
||||
# get application/build info
|
||||
if options.devicetype == "android":
|
||||
|
@ -229,7 +236,8 @@ def main(args=sys.argv[1:]):
|
|||
for testkey in args:
|
||||
testinfo = eideticker.get_testinfo(testkey)
|
||||
|
||||
eideticker.update_dashboard_test_list(options.dashboard_dir, device_id,
|
||||
eideticker.update_dashboard_test_list(options.dashboard_dir, options.device_id,
|
||||
options.branch_id,
|
||||
testinfo)
|
||||
|
||||
current_date = time.strftime("%Y-%m-%d")
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#device-chooser::before {
|
||||
content: "Device";
|
||||
}
|
||||
#branch-chooser::before {
|
||||
content: "Branch";
|
||||
}
|
||||
#test-chooser::before {
|
||||
content: "Test";
|
||||
}
|
||||
|
@ -93,6 +96,7 @@
|
|||
|
||||
<div id="chooser">
|
||||
<div class="list-group" id="device-chooser"></div>
|
||||
<div class="list-group" id="branch-chooser"></div>
|
||||
<div class="list-group" id="test-chooser"></div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ function getResourceURL(path) {
|
|||
return serverPrefix + path;
|
||||
}
|
||||
|
||||
function updateContent(testInfo, deviceId, testId, measureId) {
|
||||
$.getJSON(getResourceURL(deviceId + '/' + testId + '.json'), function(dict) {
|
||||
function updateContent(testInfo, deviceId, branchId, testId, measureId) {
|
||||
$.getJSON(getResourceURL([deviceId, branchId, testId].join('/') + '.json'), function(dict) {
|
||||
if (!dict || !dict['testdata']) {
|
||||
$('#data-view').html("<p><b>No data for that device/test combination. :(</b></p>");
|
||||
return;
|
||||
|
@ -43,7 +43,7 @@ function updateContent(testInfo, deviceId, testId, measureId) {
|
|||
$('#measure-'+measureId).attr("selected", "true");
|
||||
$('#measure').change(function() {
|
||||
var newMeasureId = $(this).val();
|
||||
window.location.hash = '/' + [ deviceId, testId, newMeasureId ].join('/');
|
||||
window.location.hash = '/' + [ deviceId, branchId, testId, newMeasureId ].join('/');
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -286,75 +286,135 @@ $(function() {
|
|||
var devices = deviceData['devices'];
|
||||
var deviceIds = Object.keys(devices).sort();
|
||||
|
||||
$.when.apply($, deviceIds.map(function(deviceId) {
|
||||
return $.getJSON(getResourceURL([deviceId, 'tests.json'].join('/')),
|
||||
var deviceBranchPairs = [];
|
||||
deviceIds.forEach(function(deviceId) {
|
||||
devices[deviceId].branches.forEach(function(branchId) {
|
||||
deviceBranchPairs.push([deviceId, branchId]);
|
||||
});
|
||||
});
|
||||
$.when.apply($, deviceBranchPairs.map(function(pair) {
|
||||
var deviceId = pair[0];
|
||||
var branchId = pair[1];
|
||||
|
||||
return $.getJSON(getResourceURL([deviceId, branchId, 'tests.json'].join('/')),
|
||||
function(testData) {
|
||||
var tests = testData['tests'];
|
||||
devices[deviceId]['tests'] = tests;
|
||||
if (!devices[deviceId][branchId]) {
|
||||
devices[deviceId][branchId] = {};
|
||||
}
|
||||
devices[deviceId][branchId]['tests'] = tests;
|
||||
});
|
||||
})).done(function() {
|
||||
var defaultDeviceId = deviceIds[0];
|
||||
|
||||
// initialize device chooser
|
||||
deviceIds.forEach(function(deviceId) {
|
||||
var tests = devices[deviceId].tests;
|
||||
var firstTestKey = Object.keys(tests).sort()[0];
|
||||
var defaultMeasureId = tests[firstTestKey].defaultMeasureId;
|
||||
function getTestIdForDeviceAndBranch(deviceId, branchId, preferredTest) {
|
||||
var device = devices[deviceId];
|
||||
var tests = device[branchId].tests;
|
||||
var testIds = Object.keys(tests).sort();
|
||||
var testId;
|
||||
if (preferredTest && testIds.indexOf(preferredTest) >= 0) {
|
||||
// this deviceid/branch combo has our preferred test, return it
|
||||
return preferredTest;
|
||||
} else {
|
||||
// this deviceid/branch combo *doesn't* have our preferred test,
|
||||
// fall back to the first one
|
||||
return testIds[0];
|
||||
}
|
||||
}
|
||||
|
||||
var deviceURL = "#/" + [ deviceId, firstTestKey, defaultMeasureId ].join('/');
|
||||
$('<a href="' + deviceURL + '" id="device-' + deviceId + '" deviceid= ' + deviceId + ' class="list-group-item">' + devices[deviceId].name+'</a></li>').appendTo(
|
||||
function updateDeviceChooser(preferredBranchId, preferredTest) {
|
||||
$('#device-chooser').empty();
|
||||
|
||||
deviceIds.forEach(function(deviceId) {
|
||||
var device = devices[deviceId];
|
||||
|
||||
var branchId;
|
||||
if (preferredBranchId && device.branches.indexOf(preferredBranchId) >= 0) {
|
||||
branchId = preferredBranchId;
|
||||
} else {
|
||||
branchId = device.branches.sort()[0];
|
||||
}
|
||||
|
||||
var testId = getTestIdForDeviceAndBranch(deviceId, branchId, preferredTest);
|
||||
var defaultMeasureId = device[branchId].tests[testId].defaultMeasureId;
|
||||
|
||||
var deviceURL = "#/" + [ deviceId, branchId, testId, defaultMeasureId ].join('/');
|
||||
$('<a href="' + deviceURL + '" id="device-' + deviceId + '" deviceid= ' + deviceId + ' class="list-group-item">' + devices[deviceId].name+'</a></li>').appendTo(
|
||||
$('#device-chooser'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function updateBranchChooser(deviceId, preferredTest) {
|
||||
$('#branch-chooser').empty();
|
||||
|
||||
var device = devices[deviceId];
|
||||
device.branches.forEach(function(branchId) {
|
||||
var testId = getTestIdForDeviceAndBranch(deviceId, branchId, preferredTest);
|
||||
var defaultMeasureId = device[branchId].tests[testId].defaultMeasureId;
|
||||
|
||||
var url = "#/" + [ deviceId, branchId, testId, defaultMeasureId ].join('/');
|
||||
$('<a href="' + url + '" id="branch-' + branchId + '" class="list-group-item">' + branchId +'</a></li>').appendTo(
|
||||
$('#branch-chooser'));
|
||||
});
|
||||
}
|
||||
|
||||
var currentBranchId = null;
|
||||
var currentDeviceId = null;
|
||||
var currentTestId = null;
|
||||
|
||||
var routes = {
|
||||
'/:deviceId/:testId/:measureId': {
|
||||
on: function(deviceId, testId, measureId) {
|
||||
if (!devices[deviceId] || !devices[deviceId]['tests'][testId]) {
|
||||
$('#data-view').html("<p><b>That device/test/measure combination does not seem to exist. Maybe you're using an expired link? <a href=''>Reload page</a>?</b></p>");
|
||||
'/:deviceId/:branchId/:testId/:measureId': {
|
||||
on: function(deviceId, branchId, testId, measureId) {
|
||||
if (!devices[deviceId] || !devices[deviceId][branchId] || !devices[deviceId][branchId]['tests'][testId]) {
|
||||
$('#data-view').html("<p><b>That device/branch/test/measure combination does not seem to exist. Maybe you're using an expired link? <a href=''>Reload page</a>?</b></p>");
|
||||
return;
|
||||
}
|
||||
|
||||
// update device chooser
|
||||
$('#device-chooser').children('a').removeClass("active");
|
||||
$('#device-chooser').children('#device-'+deviceId).addClass("active");
|
||||
updateDeviceChooser(branchId, testId);
|
||||
updateBranchChooser(deviceId, testId);
|
||||
|
||||
// update list of tests to be consistent with those of this
|
||||
// particular device (in case it changed)
|
||||
$('#test-chooser').empty();
|
||||
|
||||
var tests = devices[deviceId].tests;
|
||||
var tests = devices[deviceId][branchId].tests;
|
||||
var testKeys = Object.keys(tests).sort();
|
||||
testKeys.forEach(function(testKey) {
|
||||
$('<a id="' + testKey + '" class="list-group-item">' + testKey + '</a>').appendTo($('#test-chooser'));
|
||||
});
|
||||
|
||||
// update all test links to be relative to the new test or device
|
||||
$('#test-chooser').children('a').removeClass("active");
|
||||
$('#test-chooser').children('#'+testId).addClass("active");
|
||||
|
||||
$('#test-chooser').children('a').each(function() {
|
||||
var testIdAttr = $(this).attr('id');
|
||||
if (testIdAttr) {
|
||||
var defaultMeasureId = tests[testIdAttr].defaultMeasureId;
|
||||
$(this).attr('href', '#/' +
|
||||
[ deviceId, testIdAttr,
|
||||
[ deviceId, branchId, testIdAttr,
|
||||
defaultMeasureId ].join('/'));
|
||||
}
|
||||
});
|
||||
|
||||
// highlight chosen selections in choosers
|
||||
$('#device-chooser').children('#device-'+deviceId).addClass("active");
|
||||
$('#branch-chooser').children('#branch-'+branchId.replace('.', '\\.')).addClass("active");
|
||||
$('#test-chooser').children('#'+testId).addClass("active");
|
||||
|
||||
var testInfo = tests[testId];
|
||||
updateFooter();
|
||||
updateContent(testInfo, deviceId, testId, measureId);
|
||||
updateContent(testInfo, deviceId, branchId, testId, measureId);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var defaultDeviceId = deviceIds[0];
|
||||
var initialTestKey = Object.keys(devices[defaultDeviceId]['tests'])[0];
|
||||
var initialTest = devices[defaultDeviceId]['tests'][initialTestKey]
|
||||
var defaultBranchId = devices[defaultDeviceId].branches[0];
|
||||
var defaultTestId = Object.keys(devices[defaultDeviceId][defaultBranchId].tests)[0];
|
||||
var defaultMeasureId = devices[defaultDeviceId][defaultBranchId].tests[defaultTestId].defaultMeasureId;
|
||||
|
||||
var router = Router(routes).init('/' + [ defaultDeviceId,
|
||||
initialTestKey,
|
||||
initialTest.defaultMeasureId ].join('/'));
|
||||
defaultBranchId,
|
||||
defaultTestId,
|
||||
defaultMeasureId ].join('/'));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -66,19 +66,27 @@ def copy_dashboard_files(dashboard_dir, indexfile='index.html'):
|
|||
os.remove(dest)
|
||||
shutil.copyfile(source, dest)
|
||||
|
||||
def update_dashboard_device_list(dashboard_dir, device_id, device_info):
|
||||
def update_dashboard_device_list(dashboard_dir, device_id, branch_id, device_info):
|
||||
devices = {}
|
||||
device_filename = os.path.join(dashboard_dir, 'devices.json')
|
||||
if os.path.isfile(device_filename):
|
||||
devices = json.loads(open(device_filename).read())['devices']
|
||||
|
||||
branches = []
|
||||
if devices.get(device_id):
|
||||
branches = devices[device_id].get('branches', [])
|
||||
if branch_id not in branches:
|
||||
branches.append(branch_id)
|
||||
|
||||
devices[device_id] = device_info
|
||||
devices[device_id]['branches'] = branches
|
||||
with open(device_filename, 'w') as f:
|
||||
f.write(json.dumps({'devices': devices}))
|
||||
|
||||
def update_dashboard_test_list(dashboard_dir, device_id, testinfo):
|
||||
testsdirname = os.path.join(dashboard_dir, device_id)
|
||||
def update_dashboard_test_list(dashboard_dir, device_id, branch_id, testinfo):
|
||||
testsdirname = os.path.join(dashboard_dir, device_id, branch_id)
|
||||
if not os.path.exists(testsdirname):
|
||||
os.mkdir(testsdirname)
|
||||
os.makedirs(testsdirname)
|
||||
|
||||
tests = {}
|
||||
testsfilename = os.path.join(testsdirname, 'tests.json')
|
||||
|
@ -91,10 +99,11 @@ def update_dashboard_test_list(dashboard_dir, device_id, testinfo):
|
|||
with open(testsfilename, 'w') as f:
|
||||
f.write(json.dumps({'tests': tests}))
|
||||
|
||||
def update_dashboard_testdata(dashboard_dir, device_id, testinfo, productname,
|
||||
productdate, datapoint, metadata):
|
||||
def update_dashboard_testdata(dashboard_dir, device_id, branch_id, testinfo,
|
||||
productname, productdate, datapoint, metadata):
|
||||
# get existing data
|
||||
fname = os.path.join(dashboard_dir, device_id, '%s.json' % testinfo['key'])
|
||||
fname = os.path.join(dashboard_dir, device_id, branch_id,
|
||||
'%s.json' % testinfo['key'])
|
||||
testdata = NestedDict()
|
||||
if os.path.isfile(fname):
|
||||
testdata.update(json.loads(open(fname).read()))
|
||||
|
|
Загрузка…
Ссылка в новой задаче