Skip to content

Commit

Permalink
Merge pull request #1518 from orbs-network/bugfix/marvin/github-comme…
Browse files Browse the repository at this point in the history
…nt-fix

Fix Github comment
  • Loading branch information
itamararjuan authored Jan 17, 2020
2 parents 7223d6c + 1a3c8d4 commit 8f2e535
Show file tree
Hide file tree
Showing 9 changed files with 333 additions and 128 deletions.
102 changes: 8 additions & 94 deletions .circleci/marvin/github.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const fetch = require('node-fetch');
const { sprintf } = require('sprintf-js');
const { createAppAuth } = require("@octokit/auth-app");
const {createAppAuth} = require("@octokit/auth-app");
const fs = require('fs');
const path = require('path');
const {createGithubCommentWithMessage} = require('./util');
const pathToMarvinPrivateKey = path.join(__dirname, 'marvin.pem');
const privateKey = fs.readFileSync(pathToMarvinPrivateKey, 'utf-8');

Expand All @@ -14,37 +14,27 @@ const auth = createAppAuth({
clientSecret: process.env.MARVIN_CLIENT_SECRET
});

function secondsToHumanReadable(seconds) {
var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600);
var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60);
var numseconds = (((seconds % 31536000) % 86400) % 3600) % 60;
let humanReadable = '';

humanReadable += (numhours > 0) ? numhours + " hours " : '';
humanReadable += (numminutes > 0) ? numminutes + " minutes " : '';
humanReadable += (numseconds > 0) ? numseconds + " seconds " : '';

return humanReadable;
}

async function getPullRequest(id) {
const response = await fetch(`https://api.github.com/repos/orbs-network/orbs-network-go/pulls/${id}`);
return response.json();
}

async function commentWithMarvinOnGitHub({ id, data, master }) {
async function commentWithMarvinOnGitHub({id, data, master}) {
const pullRequest = await getPullRequest(id);

const commentsUrl = pullRequest.comments_url;

const commentAsString = createCommentMessage({ data, master });
const commentAsString = createGithubCommentWithMessage({data, master});

console.log(`[GITHUB] Posting comment to Github: ${commentAsString}`);

const body = {
body: commentAsString
};

const installationAuthentication = await auth({ type: "installation" });
const { token } = installationAuthentication;
const installationAuthentication = await auth({type: "installation"});
const {token} = installationAuthentication;

const commentResult = await fetch(commentsUrl, {
method: 'post',
Expand All @@ -58,82 +48,6 @@ async function commentWithMarvinOnGitHub({ id, data, master }) {
return commentResult.json();
}

function calculateSign(c, m) {
if (c > m) {
const gain = c - m;
const gainPercent = gain / m;
const textualGain = sprintf("%.1f", gainPercent * 100);

return `*+%${textualGain}*`;
} else if (m > c) {
const loss = m - c;
const lossPercent = loss / c;
const textualLoss = sprintf("%.1f", lossPercent * 100);

return `*-%${textualLoss}*`;
} else {
return "";
}
}

function createCommentMessage({ data, master }) {
const branchStats = getStatsFromRun(data);
const masterStats = getStatsFromRun(master);
let message = sprintf("Hey, I've completed an endurance test on this code <br />" +
"for a duration of %s <br />" +
"Key metrics from the run (compared to master):<br />", secondsToHumanReadable(branchStats.durationInSeconds));

message += sprintf(
"*%f* transactions processed successfully %s(%f)<br />",
branchStats.totalTxCount,
calculateSign(branchStats.totalTxCount, masterStats.totalTxCount),
masterStats.totalTxCount
);

message += sprintf(
"*%d* transactions failed %s(%d)<br />",
branchStats.totalTxErrorCount,
calculateSign(branchStats.totalTxErrorCount, masterStats.totalTxErrorCount),
masterStats.totalTxErrorCount,
);

message += sprintf(
"average service time: *%dms* %s(%dms)<br />",
branchStats.avgServiceTimeInMilis,
calculateSign(branchStats.avgServiceTimeInMilis, masterStats.avgServiceTimeInMilis),
masterStats.avgServiceTimeInMilis,
);

message += sprintf(
"Memory consumption: *%.2fMB* %s(%.2fMB)<br />",
branchStats.totalMemoryConsumptionInMegabytes,
calculateSign(branchStats.totalMemoryConsumptionInMegabytes, masterStats.totalMemoryConsumptionInMegabytes),
masterStats.totalMemoryConsumptionInMegabytes,
);

return message;
}

function getStatsFromRun(o) {
const firstUpdate = o.updates[0];
const lastUpdate = o.updates[o.updates.length - 1];

const durationInSeconds = o.meta.duration_sec;
const totalTxCount = lastUpdate.summary.total_tx_count;
const totalTxErrorCount = lastUpdate.summary.err_tx_count;
const avgServiceTimeInMilis = lastUpdate.summary.avg_service_time_ms;
const totalMemoryConsumptionInBytes = parseInt(lastUpdate.summary.max_alloc_mem) - parseInt(firstUpdate.summary.max_alloc_mem);
const totalMemoryConsumptionInMegabytes = totalMemoryConsumptionInBytes / 1000000;

return {
durationInSeconds,
totalTxCount,
totalTxErrorCount,
avgServiceTimeInMilis,
totalMemoryConsumptionInBytes,
totalMemoryConsumptionInMegabytes,
};
}

module.exports = {
commentWithMarvinOnGitHub,
Expand Down
6 changes: 4 additions & 2 deletions .circleci/marvin/marvin-analyze.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,17 @@ const { passed } = require('@orbs-network/judge-dredd');
(async function () {
try {
// Let's see if we can report something to GitHub
if (pullRequestUrl.length > 0) {
if (pullRequestUrl.length > 0 && lastMasterJob) {
const prLinkParts = pullRequestUrl.split('/');
const prNumber = parseInt(prLinkParts[prLinkParts.length - 1]);

console.log(`Posting comment on Github for PR ${prNumber}`);
await commentWithMarvinOnGitHub({
id: prNumber,
data: jobResults,
master: lastMasterJob,
});
} else {
console.log(`Not posting to Github because either PR number is not available or no details for last master test run`);
}

const result = await passed({ current: jobResults, previous: lastMasterJob, config: null });
Expand Down
47 changes: 26 additions & 21 deletions .circleci/marvin/marvin-endurance.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#!/usr/bin/env node

const fetch = require('node-fetch');

const marvinUrl = process.env.MARVIN_ORCHESTRATOR_URL;
Expand Down Expand Up @@ -46,7 +44,7 @@ if (!writeTargetPath) {
const body = {
vchain,
tpm: 18000,
duration_sec: 3600,
duration_sec: 300,
client_timeout_sec: 60,
gitBranch,
target_ips: [targetIp]
Expand Down Expand Up @@ -108,24 +106,31 @@ async function waitUntilDone({jobId, timeoutInSeconds = 30, acceptableDurationIn

const res = await fetch(`${marvinUrl}/jobs/${jobId}/status`);
const response = await res.json();

const latestSummary = response.updates[response.updates.length - 1].summary;

console.log('');
console.log(`------------------------------------------`);
console.log(`JobId: ${response.jobId} - ${response.duration_sec} seconds at ${response.tpm} tx/minute on vchain ${response.vchain}`);
console.log(`Status #${tick}: ${response.status}`);
console.log(`Time: ${new Date().toISOString()}`);
console.log(`Updates so far: ${response.updates.length}`);
console.log(`Total successful transactions: ${latestSummary.total_tx_count}`);
console.log(`Total erroneous transactions: ${latestSummary.err_tx_count}`);
console.log(`Average service time: ${latestSummary.avg_service_time_ms}`);
console.log(`------------------------------------------`);
console.log('');

if (response.status === 'DONE') {
returnValue = true;
break;
if (!response || !response.meta || response.updates.length === 0) {
console.log('No update from Marvin Orchestrator, skip printing update.');
} else {

const latestUpdate = response.updates[response.updates.length - 1];
const latestSummary = latestUpdate.summary;

console.log('');
console.log(`------------------------------------------`);
console.log(`JobId: ${response.jobId} - ${response.meta.duration_sec} seconds at ${response.meta.tpm} tx/minute on vchain ${response.meta.vchain}`);
console.log(`Status #${tick}: ${response.status}`);
console.log(`Time: ${new Date().toISOString()}. Runtime so far: ${latestUpdate.runtime}ms`);
console.log(`Updates so far: ${response.updates.length}`);
console.log(`Total successful transactions: ${latestSummary.total_tx_count}`);
console.log(`Total erroneous transactions: ${latestSummary.err_tx_count}`);
console.log(`Average service time: ${latestSummary.avg_service_time_ms}`);
console.log(`P99 service time: ${latestSummary.p99_service_time_ms}`);
console.log(`Max service time: ${latestSummary.max_service_time_ms}`);
console.log(`------------------------------------------`);
console.log('');

if (response.status === 'DONE') {
returnValue = true;
break;
}
}

await pSleep(90);
Expand Down
2 changes: 1 addition & 1 deletion .circleci/marvin/marvin-endurance.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ npm install
# Get the vchains to act upon from CircleCI's workspace
echo "Running Marvin tests on deployed app chain ($APP_CHAIN_ID) on IP: $TESTNET_IP"

./.circleci/marvin/marvin-endurance.js "${APP_CHAIN_ID}" "${TESTNET_IP}" workspace/job_id
node .circleci/marvin/marvin-endurance.js "${APP_CHAIN_ID}" "${TESTNET_IP}" workspace/job_id
7 changes: 1 addition & 6 deletions .circleci/marvin/marvin-reporter.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
#!/usr/bin/env node

const {
getSlackUsernameForGithubUser,
getCommitterUsernameByCommitHash,
getCommitFromMetricsURL,
createSlackMessageJobError,
createSlackMessageJobDone,
notifySlack,
Expand Down Expand Up @@ -45,7 +40,7 @@ if (!jobAnalysisFile) {
process.exit(2);
}

console.log(`Sending message to Slack: ${msg}`);
console.log(`[SLACK] Posting message to Slack: ${msg}`);
notifySlack(slackUrl, msg);
})();

2 changes: 1 addition & 1 deletion .circleci/marvin/marvin-reporter.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ fi

npm install

./.circleci/marvin/marvin-reporter.js "${JOB_ANALYSIS_FILE}"
node .circleci/marvin/marvin-reporter.js "${JOB_ANALYSIS_FILE}"
6 changes: 3 additions & 3 deletions .circleci/marvin/reporter-lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ async function readJobAnalysis(jobResultsFilePath) {
// Read a url from the environment variables
function notifySlack(slackUrl, message) {
if (slackUrl.length === 0) {
throw `Failed to notify Slack, missing Slack URL`;
throw `[SLACK] Failed to notify Slack, missing Slack URL`;
}

const baseCommand = `curl -s -X POST --data-urlencode "payload={\\"text\\": \\"${message}\\"}" ${slackUrl}`;
try {
execSync(baseCommand);
} catch (ex) {
throw `Failed to notify Slack: ${ex}`;
throw `[SLACK] Failed to notify Slack: ${ex}`;
}
}

Expand Down Expand Up @@ -123,7 +123,7 @@ function getSlackUsernameForGithubUser(githubLoginHandle) {
'andr444': 'UCX7XHX1A'
};

console.log(githubLoginHandle);
console.log(`getSlackUsernameForGithubUser(): committer's Github login handle is [${githubLoginHandle}]`);
if (!githubLoginHandle || githubLoginHandle.length === 0) {
return 'NA';
}
Expand Down
Loading

0 comments on commit 8f2e535

Please sign in to comment.