forked from rogueg/zen
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjournal.js
60 lines (51 loc) · 1.83 KB
/
journal.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
const path = require('path')
const util = require('./util')
module.exports = class Journal {
constructor() {
this.path = path.join(Zen.config.tmpDir, 'journal.json')
this.state = JSON.parse(util.readFile(this.path) || '{}')
}
record(test) {
let entry = (this.state[test.fullName] = this.state[test.fullName] || {})
entry.error = !!test.error
if (test.error) entry.tFail = test.time
else entry.tPass = test.time
if (test.time > 2000) console.log(`{${test.time}} - ${test.fullName}`)
this.lazyFlush()
}
guessRuntime(fullName) {
let entry = this.state[fullName] || {}
if (entry.error) return Math.max(entry.tPass || 0, entry.tFail || 0)
else return entry.tPass || 200
}
groupTests(tests, concurrency) {
let runGroups = []
tests
.sortBy((name) => -this.guessRuntime(name))
.forEach((fullName) => {
let min = runGroups[0]
let time = this.guessRuntime(fullName)
let newTime = min ? min.time + time : time
// Assign tests to whichever group has the lowest total time. Groups can grow to about 500ms
// before we create a new one, and never create more than the concurrency limit.
if ((!min || newTime > 500) && runGroups.length < concurrency)
min = { tests: [], time: 0 }
else runGroups.shift()
min.tests.push(fullName)
min.time += time
// sorted insert into runGroups
let pos = runGroups.findIndex((g) => g.time > min.time)
pos == -1 ? runGroups.push(min) : runGroups.splice(pos, 0, min)
})
return runGroups
}
lazyFlush() {
this.flushTimeout =
this.flushTimeout || setTimeout(this.flush.bind(this), 5000)
}
async flush() {
clearTimeout(this.flushTimeout)
this.flushTimeout = null
await util.writeFile(this.path, JSON.stringify(this.state))
}
}