testilo 7.0.5 → 7.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/aim.js +10 -3
- package/call.js +11 -33
- package/digest.js +1 -1
- package/merge.js +19 -37
- package/multiScore.js +11 -8
- package/package.json +1 -1
- package/score.js +2 -2
package/README.md
CHANGED
|
@@ -107,7 +107,7 @@ Execution by a module:
|
|
|
107
107
|
|
|
108
108
|
```javaScript
|
|
109
109
|
const {merge} = require('testilo/merge');
|
|
110
|
-
merge('tp25', 'weborgs')
|
|
110
|
+
merge('tp25', 'weborgs', 'developer@w3.org')
|
|
111
111
|
.then(() => {
|
|
112
112
|
console.log('Merger complete');
|
|
113
113
|
});
|
|
@@ -116,10 +116,10 @@ merge('tp25', 'weborgs')
|
|
|
116
116
|
Execution by a user:
|
|
117
117
|
|
|
118
118
|
```bash
|
|
119
|
-
node call merge tp25 weborgs
|
|
119
|
+
node call merge tp25 weborgs developer@w3.org
|
|
120
120
|
```
|
|
121
121
|
|
|
122
|
-
In these examples, a copy of the script file named `tp25.json` in the `SCRIPTDIR` directory is aimed at all the hosts in the batch file named `weborgs.json` in the `BATCHDIR` directory, and the resulting
|
|
122
|
+
In these examples, a copy of the script file named `tp25.json` in the `SCRIPTDIR` directory is aimed at all the hosts in the batch file named `weborgs.json` in the `BATCHDIR` directory, and the resulting jobs are saved in the `JOBDIR` directory. Each job has a `sources` property that identifies an email address to be notified after the job has been run.
|
|
123
123
|
|
|
124
124
|
### `score`
|
|
125
125
|
|
package/aim.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/*
|
|
2
2
|
aim.js
|
|
3
3
|
Module for aiming a script at a host.
|
|
4
|
+
Arguments:
|
|
5
|
+
0. script object.
|
|
6
|
+
1. host object.
|
|
7
|
+
2. email address to be notified of completion.
|
|
8
|
+
3?. time stamp.
|
|
4
9
|
*/
|
|
5
10
|
|
|
6
11
|
// ########## FUNCTIONS
|
|
@@ -8,7 +13,7 @@
|
|
|
8
13
|
// Returns a string representing the date and time.
|
|
9
14
|
const nowString = () => (new Date()).toISOString().slice(0, 19);
|
|
10
15
|
// Returns a script, aimed at a host, as a job.
|
|
11
|
-
exports.aim = (script, host, requester) => {
|
|
16
|
+
exports.aim = (script, host, requester, timeStamp = '') => {
|
|
12
17
|
// Initialize a job based on the script.
|
|
13
18
|
const job = JSON.parse(JSON.stringify(script));
|
|
14
19
|
// Make all url commands in the script visit the host.
|
|
@@ -22,11 +27,13 @@ exports.aim = (script, host, requester) => {
|
|
|
22
27
|
// Add source information to the script.
|
|
23
28
|
job.sources = {
|
|
24
29
|
script: script.id,
|
|
30
|
+
batch: '',
|
|
25
31
|
host,
|
|
26
32
|
requester
|
|
27
33
|
}
|
|
28
|
-
// Create a job-creation time stamp.
|
|
29
|
-
|
|
34
|
+
// Create a job-creation time stamp, if not specified.
|
|
35
|
+
|
|
36
|
+
timeStamp = timeStamp || Math.floor((Date.now() - Date.UTC(2022, 1)) / 2000).toString(36);
|
|
30
37
|
// Change the script ID to a job ID.
|
|
31
38
|
job.id = `${timeStamp}-${script.id}-${host.id}`;
|
|
32
39
|
// Add the job-creation time to the script.
|
package/call.js
CHANGED
|
@@ -71,8 +71,8 @@ const callAim = async (scriptName, hostURL, hostName, hostID, requester) => {
|
|
|
71
71
|
console.log(`Script ${scriptID} aimed at ${hostName} saved as job ${jobID}.json in ${jobDir}`);
|
|
72
72
|
};
|
|
73
73
|
// Fulfills a merger request.
|
|
74
|
-
const callMerge = async (scriptName, batchName) => {
|
|
75
|
-
await merge(scriptName, batchName);
|
|
74
|
+
const callMerge = async (scriptName, batchName, requester) => {
|
|
75
|
+
await merge(scriptName, batchName, requester);
|
|
76
76
|
console.log(`Batch ${batchName}.json merged into script ${scriptName} in ${jobDir}`);
|
|
77
77
|
};
|
|
78
78
|
// Fulfills a scoring request.
|
|
@@ -117,34 +117,12 @@ const callScore = async (scoreProcID, reportIDStart = '') => {
|
|
|
117
117
|
};
|
|
118
118
|
// Fulfills a multiple-report scoring request.
|
|
119
119
|
const callMultiScore = async scoreProcID => {
|
|
120
|
-
//
|
|
121
|
-
|
|
122
|
-
const rawReportNames = rawFileNames.filter(fileName => fileName.endsWith('.json'));
|
|
123
|
-
// If any exist:
|
|
124
|
-
if (rawReportNames.length) {
|
|
125
|
-
// For each of them:
|
|
126
|
-
const {scorer} = require(`${scoreProcDir}/${scoreProcID}.js`);
|
|
127
|
-
for (const rawReportName of rawReportNames) {
|
|
128
|
-
// Score it.
|
|
129
|
-
const rawReportJSON = await fs.readFile(`${rawDir}/${rawReportName}.json`);
|
|
130
|
-
const rawReport = JSON.parse(rawReportJSON);
|
|
131
|
-
const scoredReport = score(scorer, rawReport);
|
|
132
|
-
// Save it, scored.
|
|
133
|
-
await fs.writeFile(
|
|
134
|
-
`${scoredDir}/${scoredReport.id}.json`, JSON.stringify(scoredReport, null, 2)
|
|
135
|
-
);
|
|
136
|
-
console.log(`Report ${rawReport.id} scored and saved in ${scoredDir}`);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
// Otherwise, i.e. if no raw report exists:
|
|
140
|
-
else {
|
|
141
|
-
// Report this.
|
|
142
|
-
console.log('ERROR: No raw report found');
|
|
143
|
-
}
|
|
120
|
+
// Score all raw reports.
|
|
121
|
+
await multiScore(scoreProcID);
|
|
144
122
|
};
|
|
145
123
|
// Prepares to fulfill a digesting request.
|
|
146
124
|
const digestPrep = async digestProcID => {
|
|
147
|
-
const {digest} = require('
|
|
125
|
+
const {digest} = require('./digest');
|
|
148
126
|
const {makeQuery} = require(`${digestProcDir}/${digestProcID}/index`);
|
|
149
127
|
const digestTemplate = await fs.readFile(`${digestProcDir}/${digestProcID}/index.html`, 'utf8');
|
|
150
128
|
// Identify the scored reports.
|
|
@@ -162,12 +140,12 @@ const digestPrep = async digestProcID => {
|
|
|
162
140
|
// Digests and saves a report.
|
|
163
141
|
const digestReport = async (scoredReportName, prepData) => {
|
|
164
142
|
// Digest the specified report.
|
|
165
|
-
const scoredReportJSON = await fs.readFile(`${scoredDir}/${scoredReportName}
|
|
143
|
+
const scoredReportJSON = await fs.readFile(`${scoredDir}/${scoredReportName}`, 'utf8');
|
|
166
144
|
const scoredReport = JSON.parse(scoredReportJSON);
|
|
167
145
|
const digestedReport = digest(prepData.digestTemplate, prepData.makeQuery, scoredReport);
|
|
168
146
|
// Save it, digested.
|
|
169
|
-
await fs.writeFile(`${digestedDir}/${
|
|
170
|
-
console.log(`
|
|
147
|
+
await fs.writeFile(`${digestedDir}/${scoredReport.job.id}.html`, digestedReport);
|
|
148
|
+
console.log(`Digested report ${scoredReport.job.id} saved in ${digestedDir}`);
|
|
171
149
|
};
|
|
172
150
|
// Fulfills a digesting request.
|
|
173
151
|
const callDigest = async (digestProcID, reportIDStart = '') => {
|
|
@@ -218,14 +196,14 @@ const callMultiDigest = async digestProcID => {
|
|
|
218
196
|
console.log('ERROR: No raw report found');
|
|
219
197
|
}
|
|
220
198
|
console.log(
|
|
221
|
-
`Digesting completed. Digest proc: ${digestProcID}. Report count: ${prepData.scoredReportNames.length}. Directory: ${digestedDir}
|
|
199
|
+
`Digesting completed. Digest proc: ${digestProcID}. Report count: ${prepData.scoredReportNames.length}. Directory: ${digestedDir}.`
|
|
222
200
|
);
|
|
223
201
|
};
|
|
224
202
|
// Fulfills a comparison request.
|
|
225
203
|
const callCompare = async (compareProcID, comparisonNameBase) => {
|
|
226
204
|
await compare(compareProcID, comparisonNameBase);
|
|
227
205
|
console.log(
|
|
228
|
-
`Comparison completed. Comparison proc: ${compareProcID}. Directory: ${comparisonDir}
|
|
206
|
+
`Comparison completed. Comparison proc: ${compareProcID}. Directory: ${comparisonDir}.`
|
|
229
207
|
);
|
|
230
208
|
};
|
|
231
209
|
|
|
@@ -238,7 +216,7 @@ if (fn === 'aim' && fnArgs.length === 5) {
|
|
|
238
216
|
console.log('Execution completed');
|
|
239
217
|
});
|
|
240
218
|
}
|
|
241
|
-
else if (fn === 'merge' && fnArgs.length ===
|
|
219
|
+
else if (fn === 'merge' && fnArgs.length === 3) {
|
|
242
220
|
callMerge(... fnArgs)
|
|
243
221
|
.then(() => {
|
|
244
222
|
console.log('Execution completed');
|
package/digest.js
CHANGED
|
@@ -20,6 +20,6 @@ exports.digest = (digestTemplate, digestProc, scoredReport) => {
|
|
|
20
20
|
// Use it to replace the placeholders in the template.
|
|
21
21
|
const digest = replaceHolders(digestTemplate, query);
|
|
22
22
|
// Return the digest.
|
|
23
|
-
console.log(`Report ${scoredReport.id} digested`);
|
|
23
|
+
console.log(`Report ${scoredReport.job.id} digested`);
|
|
24
24
|
return digest;
|
|
25
25
|
};
|
package/merge.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/*
|
|
2
2
|
merge.js
|
|
3
|
-
Merges a batch and a script to produce
|
|
3
|
+
Merges a batch and a script to produce jobs.
|
|
4
4
|
Arguments:
|
|
5
5
|
0. base of name of script located in process.env.SCRIPTDIR.
|
|
6
6
|
1. base of name of batch located in process.env.BATCHDIR.
|
|
7
|
+
2. email address to be notified of completion.
|
|
7
8
|
Usage example:
|
|
8
|
-
node merge
|
|
9
|
-
Note: The subdirectory for
|
|
9
|
+
node merge tp25 weborgs developer@w3.org
|
|
10
|
+
Note: The subdirectory for jobs will be created if it does not exist.
|
|
10
11
|
*/
|
|
11
12
|
|
|
12
13
|
// ########## IMPORTS
|
|
@@ -15,6 +16,8 @@
|
|
|
15
16
|
require('dotenv').config();
|
|
16
17
|
// Module to read and write files.
|
|
17
18
|
const fs = require('fs/promises');
|
|
19
|
+
// Module to aim a script at a host.
|
|
20
|
+
const {aim} = require('./aim');
|
|
18
21
|
|
|
19
22
|
// ########## CONSTANTS
|
|
20
23
|
|
|
@@ -24,46 +27,25 @@ const jobDir = process.env.JOBDIR || 'watch';
|
|
|
24
27
|
|
|
25
28
|
// ########## FUNCTIONS
|
|
26
29
|
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
//
|
|
30
|
-
exports.merge = async (scriptName, batchName) => {
|
|
30
|
+
// Merges a batch into a script and writes jobs.
|
|
31
|
+
exports.merge = async (scriptName, batchName, requester) => {
|
|
32
|
+
// Get the script and the batch.
|
|
31
33
|
const scriptJSON = await fs.readFile(`${scriptDir}/${scriptName}.json`, 'utf8');
|
|
32
34
|
const batchJSON = await fs.readFile(`${batchDir}/${batchName}.json`, 'utf8');
|
|
33
35
|
const script = JSON.parse(scriptJSON);
|
|
34
36
|
const batch = JSON.parse(batchJSON);
|
|
35
|
-
// Create the watch directory if it does not exist.
|
|
36
|
-
await fs.mkdir(jobDir, {recursive: true});
|
|
37
|
-
// Create a job-creation time stamp.
|
|
38
37
|
const timeStamp = Math.floor((Date.now() - Date.UTC(2022, 1)) / 2000).toString(36);
|
|
38
|
+
// Create the job directory if it does not exist.
|
|
39
|
+
await fs.mkdir(jobDir, {recursive: true});
|
|
39
40
|
// For each host in the batch:
|
|
40
41
|
const {hosts} = batch;
|
|
41
|
-
const
|
|
42
|
-
//
|
|
43
|
-
const
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
command.which = host.which;
|
|
49
|
-
command.what = host.what;
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
// Add source information to the script.
|
|
53
|
-
newScript.sources = {
|
|
54
|
-
script: script.id,
|
|
55
|
-
batch: batch.id
|
|
56
|
-
}
|
|
57
|
-
// Add the job-creation time to the script.
|
|
58
|
-
newScript.jobCreationTime = nowString();
|
|
59
|
-
// Change the script ID to a job ID.
|
|
60
|
-
newScript.id = `${timeStamp}-${newScript.id}-${host.id}`;
|
|
61
|
-
// Return the host-specific script.
|
|
62
|
-
return newScript;
|
|
63
|
-
});
|
|
64
|
-
// Write the host-specific scripts.
|
|
65
|
-
for (const newScript of newScripts) {
|
|
66
|
-
await fs.writeFile(`${jobDir}/${newScript.id}.json`, JSON.stringify(newScript, null, 2));
|
|
42
|
+
for (const host of hosts) {
|
|
43
|
+
// Aim the script at the host.
|
|
44
|
+
const job = await aim(script, host, requester, timeStamp);
|
|
45
|
+
// Add the batch name to the job.
|
|
46
|
+
job.sources.batch = batchName;
|
|
47
|
+
// Save the job.
|
|
48
|
+
await fs.writeFile(`${jobDir}/${job.id}.json`, JSON.stringify(job, null, 2));
|
|
67
49
|
};
|
|
68
|
-
console.log(`Merger completed.
|
|
50
|
+
console.log(`Merger completed. Job count: ${hosts.length}. Time stamp ${timeStamp}.`);
|
|
69
51
|
};
|
package/multiScore.js
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
require('dotenv').config();
|
|
15
15
|
// Module to read and write files.
|
|
16
16
|
const fs = require('fs/promises');
|
|
17
|
+
// Module to score reports.
|
|
18
|
+
const {score} = require('./score');
|
|
17
19
|
|
|
18
20
|
// ########## CONSTANTS
|
|
19
21
|
|
|
@@ -25,21 +27,22 @@ const scoreProcDir = process.env.SCOREPROCDIR || `${__dirname}/procs/score`;
|
|
|
25
27
|
|
|
26
28
|
// Score the specified reports and return their count.
|
|
27
29
|
exports.multiScore = async scoreProcID => {
|
|
30
|
+
// Get the score proc.
|
|
31
|
+
const {scorer} = require(`${scoreProcDir}/${scoreProcID}`);
|
|
28
32
|
// Identify the reports to be scored.
|
|
29
33
|
let reportFileNames = await fs.readdir(reportDirRaw);
|
|
30
34
|
reportFileNames = reportFileNames.filter(fileName => fileName.endsWith('.json'));
|
|
31
35
|
// For each of them:
|
|
32
|
-
const {scorer} = require(`${scoreProcDir}/${scoreProcID}`);
|
|
33
36
|
for (const fileName of reportFileNames) {
|
|
34
37
|
// Score it.
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
await scorer
|
|
38
|
-
report.scoreProcID = scoreProcID;
|
|
38
|
+
const rawReportJSON = await fs.readFile(`${reportDirRaw}/${fileName}`, 'utf8');
|
|
39
|
+
const rawReport = JSON.parse(rawReportJSON);
|
|
40
|
+
const scoredReport = await score(scorer, rawReport);
|
|
39
41
|
// Write it to a file.
|
|
40
|
-
const scoredReportJSON = JSON.stringify(
|
|
42
|
+
const scoredReportJSON = JSON.stringify(scoredReport, null, 2);
|
|
41
43
|
await fs.writeFile(`${reportDirScored}/${fileName}`, `${scoredReportJSON}\n`);
|
|
42
|
-
console.log(`Report ${fileName.slice(0, -5)} scored and saved`);
|
|
43
44
|
};
|
|
44
|
-
|
|
45
|
+
console.log(
|
|
46
|
+
`Scored reports saved in ${reportDirScored}. Report count: ${reportFileNames.length}.`
|
|
47
|
+
);
|
|
45
48
|
};
|
package/package.json
CHANGED
package/score.js
CHANGED
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
// ########## FUNCTIONS
|
|
10
10
|
|
|
11
11
|
// Score the specified raw report and return it, scored.
|
|
12
|
-
exports.score = async (
|
|
12
|
+
exports.score = async (scorer, rawReport) => {
|
|
13
13
|
// Initialize a scored report.
|
|
14
14
|
const scoredReport = JSON.parse(JSON.stringify(rawReport));
|
|
15
15
|
// Score it.
|
|
16
|
-
await
|
|
16
|
+
await scorer(scoredReport);
|
|
17
17
|
console.log(`Report ${rawReport.job.id} scored`);
|
|
18
18
|
return scoredReport;
|
|
19
19
|
};
|