Bug 1612229 - Push Health Usage Dashboard (#6137)

This commit is contained in:
Cameron Dawson 2020-03-16 14:25:11 -07:00 коммит произвёл GitHub
Родитель 85cf8d342c
Коммит 61ebbb30e8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 2303 добавлений и 2 удалений

Просмотреть файл

@ -67,4 +67,10 @@ if [[ -v NEW_RELIC_CONFIG_FILE ]]; then
"$USER"
fi
echo "-----> PRE-DEPLOY: New Relic API Key check"
if [[ -z "$NEW_RELIC_INSIGHTS_API_KEY" ]]; then
echo "Error: missing NEW_RELIC_INSIGHTS_API_KEY"
exit 1
fi
echo "-----> PRE-DEPLOY: Complete!"

Просмотреть файл

@ -25,6 +25,7 @@ services:
- TREEHERDER_DEBUG=True
- TREEHERDER_DJANGO_SECRET_KEY=secret-key-of-at-least-50-characters-to-pass-check-deploy
- NEW_RELIC_DEVELOPER_MODE=True
- NEW_RELIC_INSIGHTS_API_KEY=${NEW_RELIC_INSIGHTS_API_KEY:-}
entrypoint: './docker/entrypoint.sh'
command: './manage.py runserver 0.0.0.0:8000'
# Django's runserver doesn't listen to the default of SIGTERM, so docker-compose

Просмотреть файл

@ -0,0 +1,68 @@
import datetime
import json
import os
import pytest
import responses
from treeherder.config import settings
from treeherder.model.models import Push
from treeherder.push_health.usage import (get_latest,
get_peak,
get_usage)
@pytest.fixture
def push_usage(test_base_dir):
usage_path = os.path.join(test_base_dir, 'sample_data', 'push_usage_data.json')
with open(usage_path) as f:
return json.load(f)
def test_peak(push_usage):
peak = get_peak(push_usage['facets'][0])
assert peak['needInvestigation'] == 149.0
assert peak['time'] == 1584035553
def test_latest(push_usage):
latest = get_latest(push_usage['facets'][0])
assert latest['needInvestigation'] == 30.0
assert latest['time'] == 1584042753
@responses.activate
def test_get_usage(push_usage, test_repository):
nrql = "SELECT%20max(needInvestigation)%20FROM%20push_health_need_investigation%20FACET%20revision%20SINCE%201%20DAY%20AGO%20TIMESERIES%20where%20repo%3D'{}'%20AND%20appName%3D'{}'".format(
'try', 'treeherder-prod')
new_relic_url = '{}?nrql={}'.format(settings.NEW_RELIC_INSIGHTS_API_URL, nrql)
responses.add(
responses.GET,
new_relic_url,
body=json.dumps(push_usage),
status=200, content_type='application/json',
match_querystring=True)
# create the Pushes that match the usage response
for rev in [
'4c45a777949168d16c03a4cba167678b7ab65f76',
'1cd5f1062ce081636af8083eb5b87e45d0f03d01',
'c73645027199ac3e092002452b436dde461bbe28',
'b6e5cd6373370c40d315b0e266c6c3e9aa48ae12',
]:
Push.objects.create(
revision=rev,
repository=test_repository,
author='phydeaux@dog.org',
time=datetime.datetime.now()
)
usage = get_usage()
facet = usage[0]
assert len(usage) == 4
assert facet['push']['revision'] == '4c45a777949168d16c03a4cba167678b7ab65f76'
assert facet['peak']['needInvestigation'] == 149.0
assert facet['latest']['needInvestigation'] == 30.0

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -25,3 +25,6 @@ BUGFILER_API_URL = "https://thisisnotbugzilla.org"
AUTHENTICATION_BACKENDS = (
'treeherder.auth.backends.AuthBackend',
)
# For Push Health Usage dashboard
NEW_RELIC_INSIGHTS_API_KEY = "123"

Просмотреть файл

@ -0,0 +1,431 @@
{
"usage": [
{
"push": {
"id": 662539,
"revision": "9afdc6aea965f311b4e9754f3a46315cc3a10b67",
"author": "mozilla@christophkerschbaumer.com",
"revisions": [
{
"result_set_id": 662539,
"repository_id": 4,
"revision": "9afdc6aea965f311b4e9754f3a46315cc3a10b67",
"author": "Christoph Kerschbaumer <ckerschb@christophkerschbaumer.com>",
"comments": "Try Chooser Enhanced (2327 tasks selected)\n\nPushed via `mach try chooser`"
},
{
"result_set_id": 662539,
"repository_id": 4,
"revision": "f5d81c848b43942236aaa8b37888258891dfc25a",
"author": "Christoph Kerschbaumer <ckerschb@christophkerschbaumer.com>",
"comments": "Bug 1508292: Implement Sec-Fetch-*. r=baku"
}
],
"revision_count": 2,
"push_timestamp": 1584103367,
"repository_id": 4
},
"peak": { "needInvestigation": 152.0, "time": 1584115883 },
"latest": { "needInvestigation": 152.0, "time": 1584115883 }
},
{
"push": {
"id": 656451,
"revision": "bedb34ce02171f3044c9aaa3fa6de216e85e03bb",
"author": "neil@mozilla.com",
"revisions": [
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "bedb34ce02171f3044c9aaa3fa6de216e85e03bb",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "try: -b do -p linux64-valgrind,win32,linux64,android-api-16,macosx64 -u crashtest,crashtest-ipc,marionette,mochitests,reftest,reftest-ipc,reftest-no-accel,web-platform-tests,xpcshell -t none\n\nPushed via `mach try syntax`"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "d2e0f2f794f80fa0c810a58aafca5adf6d13bfd3",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "imported patch actor-reader"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "dc4e45c996c0fd9f8a5a6a61a4486e23394348ba",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "imported patch remotepagemanager-obsolete"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "03902f8f04c50a9c551aec6db186de3bda23f6fb",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "imported patch actor-abouttabcrashed"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "db847dfa11f8daff137703170b9466e5f3af50ba",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "z# HG changeset patch\n# User Neil Deakin <neil@mozilla.com>\n# Parent 343442f3d9dfcc8faec1e2884ebbb21cd6c57f31"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "09875986e315ecc6f8f91b57284cfb9b0bd17aff",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "imported patch actor-newinstall"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "7bf9796fe8930ef6a9eab50cc2518e964dd0e984",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "imported patch actor-aboutprivatebrowsing"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "6e2053158c829b62ff65558450e36cbf035e7db2",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "imported patch actor-protections"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "378e1b6f6028f0aa82c1210867d12f605a548a90",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "imported patch nomm-formautocomplete"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "ec92553a5c747fb92b33dc4d5e4f1c2b6ccc7664",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "imported patch nomm-nscontextmenu"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "d650544aa7a1f57e1b31036d95db60ced0467062",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "Bug 1619952, remove message manager from browser_windowactivation.js and replace with SpecialPowers.spawn, r=gijs"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "2fb0745b65db894e398e09dd381f3a7e4ce215d8",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "Bug 1619950, remove message manager from browser_documentnavigation.js and replace with separate calls to SpecialPowers.spawn, r=gijs"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "39d7a1e41dcf655654d02b48201d72e147fe65d5",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "Bug 1619951, remove message manager from browser_tab_dragdrop.js and replace with SpecialPowers.spawn, r=jaws"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "107cac421012655f2ce553a650ae1db9ee21a57c",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "Bug 1619949, remove message manager from browser_backButtonFitts.js test and replace with BrowserTestUtils.waitForContentEvent, r=jaws"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "5aa987d21328303e91115f28b1e4e6b7d181c1d6",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "Bug 1599780, remove unused offline apps legacy actor.\n\nThe one message it responds to is never sent since bug 1574480 removed it, and the one event it listens to only ends up adding the window to a manifest set which is no longer used for anything since bug 1579444 removed it, r=johannh"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "8698548b45c57b529778f563f46287bbd5272dad",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "Bug 1598305, supply the return value of checkFn in calls to addContentEventListener to the listener so that the parent can retrieve information about the matching event, r=mccr8"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "41ebea1988dd9c58c3dd6b124e262a6e6aeaad48",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "Bug 1614713, move neterror actor over to the actor-based RemotePageChild, and move neterror-specific functions to the NetErrorChild subclass so that they cannot be accessed via other pages"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "20189ebdec04e56c89cb4f1d9c6b312d74a91f7e",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "Bug 1614713, add a remote page manager like object that uses JSWindowActor instead. Move access management into a separate module that can be used within a child or parent process. Ensure all RPM calls go through the access manager.\n\nDifferential Revision: https://phabricator.services.mozilla.com/D63713"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "410e1ef65d00e02d3cabf12a39660c98c1df8a0d",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "Bug 1558520, test that controllers work with out of process iframes of various arrangements, r=smaug\n\nDifferential Revision: https://phabricator.services.mozilla.com/D58795"
},
{
"result_set_id": 656451,
"repository_id": 4,
"revision": "edc5707b3941418d71bca4e55cd7e9c30f9d5226",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "[mq]: actor-controllers-lessactor"
}
],
"revision_count": 21,
"push_timestamp": 1583431885,
"repository_id": 4
},
"peak": { "needInvestigation": 105.0, "time": 1584110483 },
"latest": { "needInvestigation": 105.0, "time": 1584112283 }
},
{
"push": {
"id": 661471,
"revision": "1e5bca3f28e29a32d6ec04dabdf2e6433d31197c",
"author": "nchevobbe@mozilla.com",
"revisions": [
{
"result_set_id": 661471,
"repository_id": 4,
"revision": "1e5bca3f28e29a32d6ec04dabdf2e6433d31197c",
"author": "Nicolas Chevobbe <nchevobbe@mozilla.com>",
"comments": "Fuzzy query='node-debugger | 'node-devtools&query='mozlint-eslint&query='mochitest-devtools-chrome-e10s | 'mochitest-chrome-1proc 'linux '64/&query='xpcshell-e10s 'linux '64/\n\nPushed via `mach try fuzzy`"
},
{
"result_set_id": 661471,
"repository_id": 4,
"revision": "84f5f6d157805efc1b211e5a6e23a460eb582b59",
"author": "Nicolas Chevobbe <nchevobbe@mozilla.com>",
"comments": "Bug XXX - Switch ActorPool usage to Pools. r=jdescottes."
}
],
"revision_count": 2,
"push_timestamp": 1584007702,
"repository_id": 4
},
"peak": { "needInvestigation": 76.0, "time": 1584096083 },
"latest": { "needInvestigation": 76.0, "time": 1584097883 }
},
{
"push": {
"id": 662438,
"revision": "10ca1becca39a7d61a218395056d9562562067e2",
"author": "gaurijove@gmail.com",
"revisions": [
{
"result_set_id": 662438,
"repository_id": 4,
"revision": "10ca1becca39a7d61a218395056d9562562067e2",
"author": "jayati <gaurijove@gmail.com>",
"comments": "Try Chooser Enhanced (156 tasks selected)\n\nPushed via `mach try chooser`"
},
{
"result_set_id": 662438,
"repository_id": 4,
"revision": "854a11ac7078c9b13ee00adddf739b6c5f42e480",
"author": "jayati <gaurijove@gmail.com>",
"comments": "Bug 1619318- Ensures \"X\" button is focused when navigating using Tab key. r=prathiksha\n\nDifferential Revision: https://phabricator.services.mozilla.com/D66646"
}
],
"revision_count": 2,
"push_timestamp": 1584090744,
"repository_id": 4
},
"peak": { "needInvestigation": 37.0, "time": 1584094283 },
"latest": { "needInvestigation": 37.0, "time": 1584094283 }
},
{
"push": {
"id": 659404,
"revision": "fb400084210c7bac63a8c6b51079f9cde4fe7ac2",
"author": "mozilla@christophkerschbaumer.com",
"revisions": [
{
"result_set_id": 659404,
"repository_id": 4,
"revision": "fb400084210c7bac63a8c6b51079f9cde4fe7ac2",
"author": "Christoph Kerschbaumer <ckerschb@christophkerschbaumer.com>",
"comments": "Try Chooser Enhanced (658 tasks selected)\n\nPushed via `mach try chooser`"
},
{
"result_set_id": 659404,
"repository_id": 4,
"revision": "e2caa259c1f87cb2a647de4bdc09127d1ccd7a46",
"author": "Christoph Kerschbaumer <ckerschb@christophkerschbaumer.com>",
"comments": "Bug 1599131: Remove carve outs for downloads within x-frame-options when fission enabled. r=smaug,mattwoodrow"
}
],
"revision_count": 2,
"push_timestamp": 1583830647,
"repository_id": 4
},
"peak": { "needInvestigation": 24.0, "time": 1584042083 },
"latest": { "needInvestigation": 24.0, "time": 1584043883 }
},
{
"push": {
"id": 662529,
"revision": "f3716cfeebc22f6b0a7d3716bcc691402d77a4c1",
"author": "neil@mozilla.com",
"revisions": [
{
"result_set_id": 662529,
"repository_id": 4,
"revision": "f3716cfeebc22f6b0a7d3716bcc691402d77a4c1",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "try: -b do -p linux64-valgrind,win32,linux64,android-api-16,macosx64 -u crashtest,crashtest-ipc,marionette,mochitests,reftest,reftest-ipc,reftest-no-accel,web-platform-tests,xpcshell -t none\n\nPushed via `mach try syntax`"
},
{
"result_set_id": 662529,
"repository_id": 4,
"revision": "ad739fcce7edea019da665af7c7596f3acd42efd",
"author": "Neil Deakin <neil@mozilla.com>",
"comments": "[mq]: controllers-test-debug"
}
],
"revision_count": 2,
"push_timestamp": 1584101890,
"repository_id": 4
},
"peak": { "needInvestigation": 16.0, "time": 1584110483 },
"latest": { "needInvestigation": 16.0, "time": 1584110483 }
},
{
"push": {
"id": 653072,
"revision": "bdb000dbec165634372c03ad2a8692ed81bf98a1",
"author": "mozilla@christophkerschbaumer.com",
"revisions": [
{
"result_set_id": 653072,
"repository_id": 4,
"revision": "bdb000dbec165634372c03ad2a8692ed81bf98a1",
"author": "Christoph Kerschbaumer <ckerschb@christophkerschbaumer.com>",
"comments": "Try Chooser Enhanced (658 tasks selected)\n\nPushed via `mach try chooser`"
},
{
"result_set_id": 653072,
"repository_id": 4,
"revision": "13909a3fd936f343d50c201a62c8e4a5f096a706",
"author": "Christoph Kerschbaumer <ckerschb@christophkerschbaumer.com>",
"comments": "Bug 1599131: Remove carve outs for downloads within x-frame-options when fission enabled. r=bz\n\nTags: #secure-revision\n\nBug #: 1599131\n\nDifferential Revision: https://phabricator.services.mozilla.com/D64947"
}
],
"revision_count": 2,
"push_timestamp": 1583156900,
"repository_id": 4
},
"peak": { "needInvestigation": 11.0, "time": 1584043883 },
"latest": { "needInvestigation": 5.0, "time": 1584051083 }
},
{
"push": {
"id": 662497,
"revision": "0f372a5d92b39a9ae01cb3d70e2a3577a5f70092",
"author": "nchevobbe@mozilla.com",
"revisions": [
{
"result_set_id": 662497,
"repository_id": 4,
"revision": "0f372a5d92b39a9ae01cb3d70e2a3577a5f70092",
"author": "Nicolas Chevobbe <nchevobbe@mozilla.com>",
"comments": "Fuzzy query='node-debugger | 'node-devtools&query='mozlint-eslint&query='mochitest-devtools-chrome-e10s | 'mochitest-chrome-1proc 'windows10-64/ | 'macosx1014-64&query='mochitest-devtools-chrome-e10s | 'mochitest-chrome-1proc | 'mochitest-devtools-chrome-fis-e10s linux '64/&query='xpcshell-e10s 'linux '64/\n\nPushed via `mach try fuzzy`"
},
{
"result_set_id": 662497,
"repository_id": 4,
"revision": "ee9bb99389fa0cdd57291c1f36cdcf9d304c9e99",
"author": "Nicolas Chevobbe <nchevobbe@mozilla.com>",
"comments": "Bug XXX - Switch ActorPool usage to Pools. r=jdescottes."
}
],
"revision_count": 2,
"push_timestamp": 1584097536,
"repository_id": 4
},
"peak": { "needInvestigation": 8.0, "time": 1584112283 },
"latest": { "needInvestigation": 8.0, "time": 1584119483 }
},
{
"push": {
"id": 661828,
"revision": "26ced03ab8c668486c15274bc883a5b38e8d0554",
"author": "jodvarko@mozilla.com",
"revisions": [
{
"result_set_id": 661828,
"repository_id": 4,
"revision": "26ced03ab8c668486c15274bc883a5b38e8d0554",
"author": "Jan Odvarko <odvarko@gmail.com>",
"comments": "try: -b do -p win64,linux64,macosx64 -u mochitest-dt -t none --artifact\n\nPushed via `mach try syntax`"
},
{
"result_set_id": 661828,
"repository_id": 4,
"revision": "1565503e1f1511e4c1fd5302edd41fe6a3cbf0aa",
"author": "Jan Odvarko <odvarko@gmail.com>",
"comments": "imported patch resize.diff"
}
],
"revision_count": 2,
"push_timestamp": 1584034194,
"repository_id": 4
},
"peak": { "needInvestigation": 8.0, "time": 1584042083 },
"latest": { "needInvestigation": 8.0, "time": 1584043883 }
},
{
"push": {
"id": 662187,
"revision": "e2395b2ce641797d8b02eb41e5186523fe3007e9",
"author": "dmu@mozilla.com",
"revisions": [
{
"result_set_id": 662187,
"repository_id": 4,
"revision": "e2395b2ce641797d8b02eb41e5186523fe3007e9",
"author": "Daosheng Mu <daoshengmu@gmail.com>",
"comments": "Try Chooser Enhanced (987 tasks selected)\n\nPushed via `mach try chooser`\n"
},
{
"result_set_id": 662187,
"repository_id": 4,
"revision": "1bbf3104a491faeda7fcd6cc464d44700afc834b",
"author": "Daosheng Mu <daoshengmu@gmail.com>",
"comments": "Bug 1621369 - Part 4: Support WebXR to WebVR gamepad button/axis re-mapping.\r\n\r\nDifferential Revision: https://phabricator.services.mozilla.com/D66680"
},
{
"result_set_id": 662187,
"repository_id": 4,
"revision": "ab2b27a297408102e57169ddce1e14097749fe9d",
"author": "Daosheng Mu <daoshengmu@gmail.com>",
"comments": "Bug 1621369 - Part 3: Adjust Oculus controller button/axis order for WebXR.\r\n\r\nDifferential Revision: https://phabricator.services.mozilla.com/D66679"
},
{
"result_set_id": 662187,
"repository_id": 4,
"revision": "189fddf1bffe4ecfd5eb9197415b17a7712efd36",
"author": "Daosheng Mu <daoshengmu@gmail.com>",
"comments": "Bug 1621369 - Part 2: Replace OpenVRControllerType with VRControllerType in IPC.\r\n\r\nDifferential Revision: https://phabricator.services.mozilla.com/D66678"
},
{
"result_set_id": 662187,
"repository_id": 4,
"revision": "302316bf6fac373c97ce9a9341f1e1e3a0746486",
"author": "Daosheng Mu <daoshengmu@gmail.com>",
"comments": "Bug 1621369 - Part 1: Refactor OpenVR controller and adjust its button/axis order for WebXR.\n\nDifferential Revision: https://phabricator.services.mozilla.com/D66677\n"
}
],
"revision_count": 5,
"push_timestamp": 1584053793,
"repository_id": 4
},
"peak": { "needInvestigation": 6.0, "time": 1584058283 },
"latest": { "needInvestigation": 6.0, "time": 1584058283 }
}
]
}

Просмотреть файл

@ -0,0 +1,37 @@
import React from 'react';
import fetchMock from 'fetch-mock';
import { render, cleanup, waitForElement } from '@testing-library/react';
import Usage from '../../../ui/push-health/Usage';
import healthUsage from '../mock/health_usage';
beforeEach(() => {
fetchMock.get('/api/project/try/push/health_usage/', healthUsage);
});
afterEach(() => {
cleanup();
fetchMock.reset();
});
describe('Usage', () => {
const revision = 'bdb000dbec165634372c03ad2a8692ed81bf98a1';
test('should show 10 facets', async () => {
const { getAllByTestId } = render(<Usage />);
const facets = await waitForElement(() => getAllByTestId('facet-link'));
expect(facets).toHaveLength(10);
});
test('should show details about each revision', async () => {
const { getByTestId } = render(<Usage />);
const facet = await waitForElement(() => getByTestId(`facet-${revision}`));
const { children } = facet;
expect(children[0].children[0].text).toBe(revision);
expect(children[1].textContent).toBe('mozilla@christophkerschbaumer.com');
expect(children[3].textContent).toBe('11');
expect(children[5].textContent).toBe('5');
});
});

Просмотреть файл

@ -26,6 +26,9 @@ DEBUG = env.bool("TREEHERDER_DEBUG", default=False)
NEW_RELIC_DEVELOPER_MODE = env.bool("NEW_RELIC_DEVELOPER_MODE", default=True if DEBUG else False)
NEW_RELIC_INSIGHTS_API_KEY = env("NEW_RELIC_INSIGHTS_API_KEY", default=None)
NEW_RELIC_INSIGHTS_API_URL = 'https://insights-api.newrelic.com/v1/accounts/677903/query'
# Papertrail logs WARNING messages. This env variable allows modifying the behaviour
LOGGING_LEVEL = env.str("LOGGING_LEVEL", default='INFO')

Просмотреть файл

@ -19,7 +19,7 @@ CSP_DIRECTIVES = [
"font-src 'self' https://fonts.gstatic.com",
# The `data:` is required for images that were inlined by webpack's url-loader (as an optimisation).
"img-src 'self' data:",
"connect-src 'self' https://community-tc.services.mozilla.com https://firefox-ci-tc.services.mozilla.com https://*.taskcluster-artifacts.net https://taskcluster-artifacts.net https://treestatus.mozilla-releng.net https://bugzilla.mozilla.org https://auth.mozilla.auth0.com https://stage.taskcluster.nonprod.cloudops.mozgcp.net/ https://artifacts.tcstage.mozaws.net/ https://*.artifacts.tcstage.mozaws.net/",
"connect-src 'self' https://community-tc.services.mozilla.com https://firefox-ci-tc.services.mozilla.com https://*.taskcluster-artifacts.net https://taskcluster-artifacts.net https://treestatus.mozilla-releng.net https://bugzilla.mozilla.org https://auth.mozilla.auth0.com https://stage.taskcluster.nonprod.cloudops.mozgcp.net/ https://artifacts.tcstage.mozaws.net/ https://*.artifacts.tcstage.mozaws.net/ https://insights-api.newrelic.com",
# Required since auth0-js performs session renewals in an iframe.
"frame-src 'self' https://auth.mozilla.auth0.com",
"report-uri {}".format(reverse('csp-report')),

Просмотреть файл

@ -0,0 +1,59 @@
import logging
from treeherder.config import settings
from treeherder.model.models import Push
from treeherder.utils.http import make_request
from treeherder.webapp.api.serializers import PushSerializer
logger = logging.getLogger(__name__)
def get_peak(facet):
peak = 0
date = 0
for item in facet['timeSeries']:
max = item['results'][-1]['max']
if item['inspectedCount'] > 0 and max > peak:
peak = max
date = item['endTimeSeconds']
return {'needInvestigation': peak, 'time': date}
def get_latest(facet):
for item in reversed(facet['timeSeries']):
if item['inspectedCount'] > 0:
latest = item['results'][-1]
return {
'needInvestigation': latest['max'],
'time': item['endTimeSeconds']
}
def get_usage():
nrql = "SELECT%20max(needInvestigation)%20FROM%20push_health_need_investigation%20FACET%20revision%20SINCE%201%20DAY%20AGO%20TIMESERIES%20where%20repo%3D'{}'%20AND%20appName%3D'{}'".format(
'try', 'treeherder-prod')
new_relic_url = '{}?nrql={}'.format(settings.NEW_RELIC_INSIGHTS_API_URL, nrql)
headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-Query-Key': settings.NEW_RELIC_INSIGHTS_API_KEY,
}
# TODO: make this check happen during deploy or setup? Not here.
if not settings.NEW_RELIC_INSIGHTS_API_KEY:
logger.error('NEW_RELIC_INSIGHTS_API_KEY not set.')
resp = make_request(new_relic_url, headers=headers)
data = resp.json()
push_revisions = [facet['name'] for facet in data['facets']]
pushes = Push.objects.filter(revision__in=push_revisions)
results = [{
'push': PushSerializer(pushes.get(revision=facet['name'])).data,
'peak': get_peak(facet),
'latest': get_latest(facet)
} for facet in data['facets']]
return results

Просмотреть файл

@ -18,6 +18,7 @@ from treeherder.push_health.compare import get_commit_history
from treeherder.push_health.linting import get_lint_failures
from treeherder.push_health.performance import get_perf_failures
from treeherder.push_health.tests import get_test_failures
from treeherder.push_health.usage import get_usage
from treeherder.webapp.api.serializers import PushSerializer
from treeherder.webapp.api.utils import (REPO_GROUPS,
to_datetime,
@ -230,6 +231,11 @@ class PushViewSet(viewsets.ViewSet):
'unsupported': len(push_health_test_failures['unsupported']),
})
@action(detail=False)
def health_usage(self, request, project):
usage = get_usage()
return Response({'usage': usage})
@action(detail=False)
def health(self, request, project):
"""
@ -276,6 +282,7 @@ class PushViewSet(viewsets.ViewSet):
'repo': repository.name,
'needInvestigation': len(push_health_test_failures['needInvestigation']),
'unsupported': len(push_health_test_failures['unsupported']),
'author': push.author,
})
return Response({

Просмотреть файл

@ -4,6 +4,7 @@ import { BrowserRouter, Route, Switch } from 'react-router-dom';
import NotFound from './NotFound';
import Health from './Health';
import Usage from './Usage';
function hasProps(search) {
const params = new URLSearchParams(search);
@ -24,7 +25,7 @@ const App = () => {
hasProps(props.location.search) ? (
<Health {...props} />
) : (
<NotFound {...props} />
<Usage {...props} />
)
}
/>

96
ui/push-health/Usage.jsx Normal file
Просмотреть файл

@ -0,0 +1,96 @@
import React, { Component } from 'react';
import { Alert, Table, Jumbotron, Badge } from 'reactstrap';
import { getData } from '../helpers/http';
import { getProjectUrl } from '../helpers/location';
import { toShortDateStr } from '../helpers/display';
class Usage extends Component {
constructor(props) {
super(props);
this.state = {
usage: [],
failureMessage: null,
};
}
async componentDidMount() {
const { data, failureStatus } = await getData(
getProjectUrl('/push/health_usage/', 'try'),
);
if (!failureStatus) {
const { usage } = data;
this.setState({ usage });
} else {
this.setState({ failureMessage: data });
}
}
render() {
const { usage, failureMessage } = this.state;
return (
<div>
<Jumbotron>
<h4>Push Health Try Usage</h4>
<p>
This shows the difference in count of Need intermittents by push
over time.
</p>
</Jumbotron>
<Table>
<thead>
<tr>
<th>Push</th>
<th>Author</th>
<th>Push Time</th>
<th>Peak</th>
<th>Peak Time</th>
<th>Latest</th>
<th>Latest Time</th>
<th>Delta</th>
</tr>
</thead>
<tbody>
{usage.map(rev => {
const {
push: { revision, push_timestamp: pushTimestamp, author },
peak: { needInvestigation: peakNI, time: peakTime },
latest: { needInvestigation: latestNI, time: latestTime },
} = rev;
return (
<tr key={revision} data-testid={`facet-${revision}`}>
<td data-testid="facet-link">
<a
href={`/pushhealth.html?repo=try&revision=${revision}`}
title="See Push Health"
>
{revision}
</a>
</td>
<td>{author}</td>
<td>{toShortDateStr(pushTimestamp)}</td>
<td>{peakNI}</td>
<td>{toShortDateStr(peakTime)}</td>
<td>{latestNI}</td>
<td>{toShortDateStr(latestTime)}</td>
<td>
<Badge color="success">
{peakNI - latestNI > 0 && peakNI - latestNI}
</Badge>
</td>
</tr>
);
})}
</tbody>
</Table>
{failureMessage && <Alert color="danger">{failureMessage}</Alert>}
</div>
);
}
}
export default Usage;

Просмотреть файл

@ -11,6 +11,7 @@ const choices = [
{ url: '/', text: 'Treeherder' },
{ url: '/perf.html', text: 'Perfherder' },
{ url: '/intermittent-failures.html', text: 'Intermittent Failures View' },
{ url: '/pushhealth.html', text: 'Push Health Usage' },
];
export default class LogoMenu extends React.PureComponent {