improve ufuzz duty cycle heuristic (#4153)
This commit is contained in:
9
.github/workflows/ufuzz.yml
vendored
9
.github/workflows/ufuzz.yml
vendored
@@ -6,6 +6,7 @@ on:
|
|||||||
env:
|
env:
|
||||||
BASE_URL: https://api.github.com/repos/${{ github.repository }}
|
BASE_URL: https://api.github.com/repos/${{ github.repository }}
|
||||||
CAUSE: ${{ github.event_name }}
|
CAUSE: ${{ github.event_name }}
|
||||||
|
RUN_NUM: ${{ github.run_number }}
|
||||||
TOKEN: ${{ github.token }}
|
TOKEN: ${{ github.token }}
|
||||||
jobs:
|
jobs:
|
||||||
ufuzz:
|
ufuzz:
|
||||||
@@ -36,12 +37,8 @@ jobs:
|
|||||||
npm config set update-notifier false
|
npm config set update-notifier false
|
||||||
npm --version
|
npm --version
|
||||||
while !(npm install); do echo "'npm install' failed - retrying..."; done
|
while !(npm install); do echo "'npm install' failed - retrying..."; done
|
||||||
PERIOD=-5000
|
|
||||||
if [[ $CAUSE == "schedule" ]]; then
|
if [[ $CAUSE == "schedule" ]]; then
|
||||||
PERIOD=`node test/ufuzz/actions $BASE_URL $TOKEN`
|
node test/ufuzz/job $BASE_URL $TOKEN $RUN_NUM
|
||||||
fi
|
|
||||||
if (( $PERIOD == 0 )); then
|
|
||||||
echo "too many jobs in queue - skipping..."
|
|
||||||
else
|
else
|
||||||
node test/ufuzz/job $PERIOD
|
node test/ufuzz/job 5000
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,32 +1,42 @@
|
|||||||
require("../../tools/exit");
|
|
||||||
|
|
||||||
var get = require("https").get;
|
var get = require("https").get;
|
||||||
var parse = require("url").parse;
|
var parse = require("url").parse;
|
||||||
var base = process.argv[2];
|
|
||||||
var token = process.argv[3];
|
var base, token, run_number, eldest = true;
|
||||||
var queued = 0, total = 0, earliest, now = Date.now();
|
exports.init = function(url, auth, num) {
|
||||||
process.on("beforeExit", function() {
|
base = url;
|
||||||
if (queued > 3) {
|
token = auth;
|
||||||
process.stdout.write("0");
|
run_number = num;
|
||||||
} else {
|
};
|
||||||
var average = total > 2 && (now - earliest) / (total - 1);
|
exports.should_stop = function(callback) {
|
||||||
process.stdout.write(Math.min(Math.max(20 * average, 2700000), 18000000).toFixed(0));
|
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) {
|
||||||
read(base + "/actions/workflows/ufuzz.yml/runs?event=schedule", function(reply) {
|
return workflow.status != "completed";
|
||||||
check(reply, "workflow_runs").filter(function(workflow) {
|
}).sort(function(a, b) {
|
||||||
return /^(in_progress|queued|)$/.test(workflow.status);
|
return b.run_number - a.run_number;
|
||||||
}).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;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
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) {
|
function read(url, callback) {
|
||||||
var options = parse(url);
|
var options = parse(url);
|
||||||
@@ -44,7 +54,3 @@ function read(url, callback) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function check(reply, field) {
|
|
||||||
return reply && Array.isArray(reply[field]) ? reply[field] : [];
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,43 +1,63 @@
|
|||||||
|
var actions = require("./actions");
|
||||||
var child_process = require("child_process");
|
var child_process = require("child_process");
|
||||||
|
|
||||||
var ping = 5 * 60 * 1000;
|
var args = [
|
||||||
var period = +process.argv[2];
|
"--max-old-space-size=2048",
|
||||||
var endTime = period < 0 ? period : Date.now() + period;
|
"test/ufuzz",
|
||||||
for (var i = 0; i < 2; i++) spawn(endTime);
|
];
|
||||||
|
var iterations;
|
||||||
function spawn(endTime) {
|
switch (process.argv.length) {
|
||||||
var args = [
|
case 3:
|
||||||
"--max-old-space-size=2048",
|
iterations = +process.argv[2];
|
||||||
"test/ufuzz"
|
args.push(iterations);
|
||||||
];
|
break;
|
||||||
if (endTime < 0) args.push(-endTime);
|
case 5:
|
||||||
var child = child_process.spawn("node", args, {
|
actions.init(process.argv[2], process.argv[3], +process.argv[4]);
|
||||||
stdio: [ "ignore", "pipe", "pipe" ]
|
break;
|
||||||
}).on("exit", respawn);
|
default:
|
||||||
var stdout = "";
|
throw new Error("invalid parameters");
|
||||||
child.stdout.on("data", function(data) {
|
}
|
||||||
stdout += data;
|
var tasks = [ run(), run() ];
|
||||||
|
if (iterations) return;
|
||||||
|
var alive = setInterval(function() {
|
||||||
|
actions.should_stop(function() {
|
||||||
|
clearInterval(alive);
|
||||||
|
tasks.forEach(function(kill) {
|
||||||
|
kill();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
var stderr = "";
|
}, 8 * 60 * 1000);
|
||||||
child.stderr.on("data", trap).pipe(process.stdout);
|
|
||||||
var keepAlive = setInterval(function() {
|
function run() {
|
||||||
var end = stdout.lastIndexOf("\r");
|
var child, stdout, stderr, log;
|
||||||
console.log(stdout.slice(stdout.lastIndexOf("\r", end - 1) + 1, end));
|
spawn();
|
||||||
stdout = stdout.slice(end + 1);
|
return function() {
|
||||||
}, ping);
|
clearInterval(log);
|
||||||
if (endTime < 0) return;
|
|
||||||
var timer = setTimeout(function() {
|
|
||||||
clearInterval(keepAlive);
|
|
||||||
child.removeListener("exit", respawn);
|
child.removeListener("exit", respawn);
|
||||||
child.kill();
|
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() {
|
function respawn() {
|
||||||
console.log(stdout.replace(/[^\r\n]*\r/g, ""));
|
console.log(stdout.replace(/[^\r\n]*\r/g, ""));
|
||||||
clearInterval(keepAlive);
|
clearInterval(log);
|
||||||
if (endTime < 0) return;
|
if (!iterations) spawn();
|
||||||
clearTimeout(timer);
|
|
||||||
spawn(endTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function trap(data) {
|
function trap(data) {
|
||||||
|
|||||||
Reference in New Issue
Block a user