forked from eslint/eslint
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfuzzer-runner.js
81 lines (66 loc) · 3.16 KB
/
fuzzer-runner.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/**
* @fileoverview An opinionated wrapper around eslint-fuzzer
* @author Teddy Katz
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const ProgressBar = require("progress");
const fuzz = require("./eslint-fuzzer");
const eslint = require("..");
const linter = new eslint.Linter({ configType: "eslintrc" });
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
// An estimate of how many times faster it is to do a crash-only fuzzer run versus an autofixing run.
const ESTIMATED_CRASH_AUTOFIX_PERFORMANCE_RATIO = 4;
// The number of crash-only tests to run for each autofix test. Right now, this is mostly arbitrary.
const CRASH_AUTOFIX_TEST_COUNT_RATIO = 3;
//------------------------------------------------------------------------------
// Public API
//------------------------------------------------------------------------------
/**
* Runs the fuzzer and outputs a progress bar
* @param {Object} [options] Options for the fuzzer
* @param {number} [options.amount=300] A positive integer indicating how much testing to do. Larger values result in a higher
* chance of finding bugs, but cause the testing to take longer (linear increase). With the default value, the fuzzer
* takes about 15 seconds to run.
* @param {boolean} [options.fuzzBrokenAutofixes=true] true if the fuzzer should look for invalid autofixes in addition to rule crashes
* @returns {Object[]} A list of objects, where each object represents a problem detected by the fuzzer. The objects have the same
* schema as objects returned from eslint-fuzzer.
*/
function run({ amount = 300, fuzzBrokenAutofixes = true } = {}) {
const crashTestCount = amount * CRASH_AUTOFIX_TEST_COUNT_RATIO;
const autofixTestCount = fuzzBrokenAutofixes ? amount : 0;
/*
* To keep the progress bar moving at a roughly constant speed, apply a different weight for finishing
* a crash-only fuzzer run versus an autofix fuzzer run.
*/
const progressBar = new ProgressBar(
"Fuzzing rules [:bar] :percent, :elapseds elapsed, eta :etas, errors so far: :elapsedErrors",
{ width: 30, total: crashTestCount + autofixTestCount * ESTIMATED_CRASH_AUTOFIX_PERFORMANCE_RATIO }
);
// Start displaying the progress bar.
progressBar.tick(0, { elapsedErrors: 0 });
const crashTestResults = fuzz({
linter,
count: crashTestCount,
checkAutofixes: false,
progressCallback(elapsedErrors) {
progressBar.tick(1, { elapsedErrors });
progressBar.render();
}
});
const autofixTestResults = fuzz({
linter,
count: autofixTestCount,
checkAutofixes: true,
progressCallback(elapsedErrors) {
progressBar.tick(ESTIMATED_CRASH_AUTOFIX_PERFORMANCE_RATIO, { elapsedErrors: crashTestResults.length + elapsedErrors });
progressBar.render();
}
});
return crashTestResults.concat(autofixTestResults);
}
module.exports = { run };