REGRESSION (r279751): WebContent process often crashes when hovering over content...
[WebKit-https.git] / Websites / perf.webkit.org / tools / run-analysis.js
1 #!/usr/local/bin/node
2
3 const fs = require('fs');
4 const parseArguments = require('./js/parse-arguments.js').parseArguments;
5 const RemoteAPI = require('./js/remote.js').RemoteAPI;
6 const MeasurementSetAnalyzer = require('./js/measurement-set-analyzer.js').MeasurementSetAnalyzer;
7 const AnalysisResultsNotifier = require('./js/analysis-results-notifier.js').AnalysisResultsNotifier;
8 const Subprocess = require('./js/subprocess.js').Subprocess;
9 require('./js/v3-models.js');
10 global.PrivilegedAPI = require('./js/privileged-api.js').PrivilegedAPI;
11
12 function main(argv)
13 {
14     const options = parseArguments(argv, [
15         {name: '--server-config-json', required: true},
16         {name: '--notification-config-json', required: true},
17         {name: '--analysis-range-in-days', type: parseFloat, default: 10},
18         {name: '--seconds-to-sleep', type: parseFloat, default: 1200},
19         {name: '--max-retry-factor', type: parseFloat, default: 3},
20     ]);
21
22     if (!options)
23         return;
24
25     analysisLoop(options);
26 }
27
28 async function analysisLoop(options)
29 {
30     const secondsToSleep = options['--seconds-to-sleep'];
31     try {
32         const serverConfig = JSON.parse(fs.readFileSync(options['--server-config-json'], 'utf-8'));
33         const analysisRangeInDays = options['--analysis-range-in-days'];
34
35         global.RemoteAPI = new RemoteAPI(serverConfig.server);
36         PrivilegedAPI.configure(serverConfig.worker.name, serverConfig.worker.password);
37
38         const manifest = await Manifest.fetch();
39         const measurementSetList = MeasurementSetAnalyzer.measurementSetListForAnalysis(manifest);
40
41         const endTime = Date.now();
42         const startTime = endTime - analysisRangeInDays * 24 * 3600 * 1000;
43         const analyzer = new MeasurementSetAnalyzer(measurementSetList, startTime, endTime, console);
44
45         console.log(`Start analyzing last ${analysisRangeInDays} days measurement sets.`);
46         await analyzer.analyzeOnce();
47     } catch (error) {
48         console.error(`Failed to analyze measurement sets due to ${error}`);
49     }
50
51     const maxRetryFactor = options['--max-retry-factor'];
52     const testGroupsMayNeedMoreRequests = await TestGroup.fetchAllThatMayNeedMoreRequests();
53     try {
54         for (const testGroup of testGroupsMayNeedMoreRequests) {
55             const retryCount = await testGroup.scheduleMoreRequestsOrClearFlag(maxRetryFactor);
56             if (!retryCount)
57                 continue;
58             const analysisTask = await testGroup.fetchTask();
59             console.log(`Added ${retryCount} build request(s) to "${testGroup.name()}" of analysis task: ${analysisTask.id()} - "${analysisTask.name()}"`);
60         }
61     } catch (error) {
62         console.error(error);
63         if (typeof(error.stack) == 'string') {
64             for (let line of error.stack.split('\n'))
65                 console.error(line);
66         }
67     }
68
69     try {
70         const notificationConfig = JSON.parse(fs.readFileSync(options['--notification-config-json'], 'utf-8'));
71         const testGroupsNeedNotification = await TestGroup.fetchAllWithNotificationReady();
72         const notificationRemoteAPI = new RemoteAPI(notificationConfig.notificationServerConfig);
73         const notificationMessageConfig = notificationConfig.notificationMessageConfig;
74         const notifier = new AnalysisResultsNotifier(notificationMessageConfig.messageTemplate, notificationMessageConfig.finalizeScript,
75             notificationMessageConfig.messageConstructionRules, notificationRemoteAPI, notificationConfig.notificationServerConfig.path, new Subprocess);
76
77         await notifier.sendNotificationsForTestGroups(testGroupsNeedNotification);
78     } catch (error) {
79         console.error(`Failed to send notification for test groups due to ${error}`);
80     }
81
82     console.log(`Sleeping for ${secondsToSleep} seconds.`);
83     setTimeout(() => analysisLoop(options), secondsToSleep * 1000);
84 }
85
86
87 main(process.argv);