Skip to content

Commit

Permalink
improve ufuzz duty cycle heuristic (#4153)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexlamsl authored Sep 25, 2020
1 parent 6e105c5 commit 40f36b9
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 67 deletions.
9 changes: 3 additions & 6 deletions .github/workflows/ufuzz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
env:
BASE_URL: https://api.github.com/repos/${{ github.repository }}
CAUSE: ${{ github.event_name }}
RUN_NUM: ${{ github.run_number }}
TOKEN: ${{ github.token }}
jobs:
ufuzz:
Expand Down Expand Up @@ -36,12 +37,8 @@ jobs:
npm config set update-notifier false
npm --version
while !(npm install); do echo "'npm install' failed - retrying..."; done
PERIOD=-5000
if [[ $CAUSE == "schedule" ]]; then
PERIOD=`node test/ufuzz/actions $BASE_URL $TOKEN`
fi
if (( $PERIOD == 0 )); then
echo "too many jobs in queue - skipping..."
node test/ufuzz/job $BASE_URL $TOKEN $RUN_NUM
else
node test/ufuzz/job $PERIOD
node test/ufuzz/job 5000
fi
64 changes: 35 additions & 29 deletions test/ufuzz/actions.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,42 @@
require("../../tools/exit");

var get = require("https").get;
var parse = require("url").parse;
var base = process.argv[2];
var token = process.argv[3];
var queued = 0, total = 0, earliest, now = Date.now();
process.on("beforeExit", function() {
if (queued > 3) {
process.stdout.write("0");
} else {
var average = total > 2 && (now - earliest) / (total - 1);
process.stdout.write(Math.min(Math.max(20 * average, 2700000), 18000000).toFixed(0));
}
});
read(base + "/actions/workflows/ufuzz.yml/runs?event=schedule", function(reply) {
check(reply, "workflow_runs").filter(function(workflow) {
return /^(in_progress|queued|)$/.test(workflow.status);
}).forEach(function(workflow) {
read(workflow.jobs_url, function(reply) {
check(reply, "jobs").forEach(function(job) {
if (job.status == "queued") queued++;
total++;
var start = Date.parse(job.started_at);
if (!(earliest < start)) earliest = start;
});

var base, token, run_number, eldest = true;
exports.init = function(url, auth, num) {
base = url;
token = auth;
run_number = num;
};
exports.should_stop = function(callback) {
read(base + "/actions/runs?per_page=100", function(reply) {
if (!reply || !Array.isArray(reply.workflow_runs)) return;
var runs = reply.workflow_runs.filter(function(workflow) {
return workflow.status != "completed";
}).sort(function(a, b) {
return b.run_number - a.run_number;
});
if (runs.length < 10) return;
var found = false, remaining = 20;
(function next() {
if (!runs.length) return;
var workflow = runs.pop();
if (workflow.run_number == run_number) found = true;
read(workflow.jobs_url, function(reply) {
if (!reply || !Array.isArray(reply.jobs)) return;
if (!reply.jobs.every(function(job) {
if (job.status == "completed") return true;
remaining--;
return found;
})) return;
if (remaining >= 0) {
next();
} else {
callback();
}
});
})();
});
});
};

function read(url, callback) {
var options = parse(url);
Expand All @@ -44,7 +54,3 @@ function read(url, callback) {
});
});
}

function check(reply, field) {
return reply && Array.isArray(reply[field]) ? reply[field] : [];
}
84 changes: 52 additions & 32 deletions test/ufuzz/job.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,63 @@
var actions = require("./actions");
var child_process = require("child_process");

var ping = 5 * 60 * 1000;
var period = +process.argv[2];
var endTime = period < 0 ? period : Date.now() + period;
for (var i = 0; i < 2; i++) spawn(endTime);

function spawn(endTime) {
var args = [
"--max-old-space-size=2048",
"test/ufuzz"
];
if (endTime < 0) args.push(-endTime);
var child = child_process.spawn("node", args, {
stdio: [ "ignore", "pipe", "pipe" ]
}).on("exit", respawn);
var stdout = "";
child.stdout.on("data", function(data) {
stdout += data;
var args = [
"--max-old-space-size=2048",
"test/ufuzz",
];
var iterations;
switch (process.argv.length) {
case 3:
iterations = +process.argv[2];
args.push(iterations);
break;
case 5:
actions.init(process.argv[2], process.argv[3], +process.argv[4]);
break;
default:
throw new Error("invalid parameters");
}
var tasks = [ run(), run() ];
if (iterations) return;
var alive = setInterval(function() {
actions.should_stop(function() {
clearInterval(alive);
tasks.forEach(function(kill) {
kill();
});
});
var stderr = "";
child.stderr.on("data", trap).pipe(process.stdout);
var keepAlive = setInterval(function() {
var end = stdout.lastIndexOf("\r");
console.log(stdout.slice(stdout.lastIndexOf("\r", end - 1) + 1, end));
stdout = stdout.slice(end + 1);
}, ping);
if (endTime < 0) return;
var timer = setTimeout(function() {
clearInterval(keepAlive);
}, 8 * 60 * 1000);

function run() {
var child, stdout, stderr, log;
spawn();
return function() {
clearInterval(log);
child.removeListener("exit", respawn);
child.kill();
}, endTime - Date.now());
};

function spawn() {
child = child_process.spawn("node", args, {
stdio: [ "ignore", "pipe", "pipe" ]
}).on("exit", respawn);
stdout = "";
child.stdout.on("data", function(data) {
stdout += data;
});
stderr = "";
child.stderr.on("data", trap).pipe(process.stdout);
log = setInterval(function() {
var end = stdout.lastIndexOf("\r");
console.log(stdout.slice(stdout.lastIndexOf("\r", end - 1) + 1, end));
stdout = stdout.slice(end + 1);
}, 5 * 60 * 1000);
}

function respawn() {
console.log(stdout.replace(/[^\r\n]*\r/g, ""));
clearInterval(keepAlive);
if (endTime < 0) return;
clearTimeout(timer);
spawn(endTime);
clearInterval(log);
if (!iterations) spawn();
}

function trap(data) {
Expand Down

0 comments on commit 40f36b9

Please sign in to comment.