-
Notifications
You must be signed in to change notification settings - Fork 14
/
munge_sql.js
202 lines (161 loc) · 6.67 KB
/
munge_sql.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/**
* This script takes the munged JSON files and puts them into a SQLite database.
*/
const sqlite3 = require('sqlite3').verbose();
const fs = require('fs');
const util = require('util');
// first parameter: the output database file
// all the following parameters: the input json files
const dbFile = process.argv[2];
const files = process.argv.slice(3);
if (!dbFile || files.length === 0) {
console.error("Usage: node munge_sql.js <output.db> <input1.json> <input2.json> ...");
process.exit(1);
}
const main = async () => {
let db = new sqlite3.Database(dbFile, (err) => {
if (err) {
console.error(err.message);
}
console.log('Connected to the database.');
});
const run = util.promisify(db.run.bind(db));
// Create the TestResult table if it doesn't exist
await run(`
CREATE TABLE IF NOT EXISTS TestRun (
implementation_id TEXT,
version TEXT,
time DATETIME,
job_url TEXT,
PRIMARY KEY (implementation_id, version)
);
`);
await run(`
CREATE TABLE IF NOT EXISTS TestResult (
test_run_implementation_id TEXT,
test_run_version TEXT,
full_name TEXT,
name TEXT,
outcome TEXT CHECK(outcome IN ('pass', 'fail', 'skip')),
parent_test_full_name TEXT,
PRIMARY KEY (test_run_implementation_id, test_run_version, full_name),
-- parent hierarchy
FOREIGN KEY (test_run_implementation_id, test_run_version, parent_test_full_name)
REFERENCES TestResult (test_run_implementation_id, test_run_version, full_name),
-- test run
FOREIGN KEY (test_run_implementation_id, test_run_version)
REFERENCES TestRun (implementation_id, version)
);
`);
// TODO: verify me.
await run(`
CREATE TABLE IF NOT EXISTS TestMetadata (
test_run_implementation_id TEXT,
test_run_version TEXT,
test_full_name TEXT,
key TEXT,
value JSON,
PRIMARY KEY (test_run_implementation_id, test_run_version, test_full_name, key),
-- test run
FOREIGN KEY (test_run_implementation_id, test_run_version)
REFERENCES TestRun (implementation_id, version)
-- test result
FOREIGN KEY (test_run_implementation_id, test_run_version, test_full_name)
REFERENCES TestResult (test_run_implementation_id, test_run_version, full_name)
);
`)
await run(`
CREATE TABLE IF NOT EXISTS TestLog (
test_run_implementation_id TEXT,
test_run_version TEXT,
test_full_name TEXT,
stdout TEXT,
-- test run
FOREIGN KEY (test_run_implementation_id, test_run_version)
REFERENCES TestRun (implementation_id, version)
-- test result
FOREIGN KEY (test_run_implementation_id, test_run_version, test_full_name)
REFERENCES TestResult (test_run_implementation_id, test_run_version, full_name)
);
`)
// Create the SPECS
await run(`
CREATE TABLE IF NOT EXISTS TestSpecs (
test_run_implementation_id TEXT,
test_run_version TEXT,
test_full_name TEXT,
spec_url TEXT,
PRIMARY KEY (test_run_implementation_id, test_run_version, test_full_name, spec_url),
-- test run
FOREIGN KEY (test_run_implementation_id, test_run_version)
REFERENCES TestRun (implementation_id, version),
-- test result
FOREIGN KEY (test_run_implementation_id, test_run_version, test_full_name)
REFERENCES TestResult (test_run_implementation_id, test_run_version, full_name)
);
`);
for (const file of files) {
const fileName = file.split("/").slice(-1)[0].split(".")[0];
const implemId = fileName;
console.log(`Processing ${file}...`);
const content = JSON.parse(fs.readFileSync(file));
const { TestMetadata, ...tests } = content;
const time = TestMetadata?.time;
const version = TestMetadata?.meta?.version || 'unknown';
const job_url = TestMetadata?.meta?.job_url || null;
await run(`
INSERT INTO TestRun (implementation_id, version, time, job_url)
VALUES (?, ?, ?, ?)
ON CONFLICT (implementation_id, version) DO UPDATE SET
time = excluded.time,
job_url = excluded.job_url
`, [implemId, version, time, job_url]);
// process all the tests. Start with the roots.
const sorted = Object.keys(tests).sort();
for (testId of sorted) {
const test = tests[testId];
const fullName = testId
const name = test.path[test.path.length - 1];
const outcome = test.outcome;
const parentFullName = testId.split('/').slice(0, -1).join("/") || null;
await run(`
INSERT INTO TestResult (test_run_implementation_id, test_run_version, full_name, name, outcome, parent_test_full_name)
VALUES (?, ?, ?, ?, ?, ?)
`, [implemId, version, fullName, name, outcome, parentFullName]);
for (const [key, value] of Object.entries(test.meta ?? {})) {
await run(`
INSERT INTO TestMetadata (test_run_implementation_id, test_run_version, test_full_name, key, value)
VALUES (?, ?, ?, ?, ?)
`, [implemId, version, fullName, key, JSON.stringify(value)]);
}
await run(`
INSERT INTO TestLog (test_run_implementation_id, test_run_version, test_full_name, stdout)
VALUES (?, ?, ?, ?)
`, [implemId, version, fullName, test.output]);
const specsArray = test.meta?.specs || [];
for (const specUrl of specsArray) {
// add `https://` if the specs don't have it
const cleanSpecUrl = specUrl.startsWith("http") ? specUrl : `https://${specUrl}`;
await run(`
INSERT INTO TestSpecs (test_run_implementation_id, test_run_version, test_full_name, spec_url)
VALUES (?, ?, ?, ?)
`, [implemId, version, fullName, cleanSpecUrl]);
}
}
}
// Close the database connection when you're done
db.close((err) => {
if (err) {
console.error(err.message);
}
console.log('Closed the database connection.');
});
}
main()
.then(() => {
console.log("done");
})
.catch((e) => {
console.error(e);
process.exit(1);
})