make CI tests faster + more precise
This commit is contained in:
parent
e84e01cb8c
commit
81b0718a8f
1 changed files with 72 additions and 5 deletions
|
|
@ -2,6 +2,11 @@ discard """
|
||||||
outputsub: "no leak: "
|
outputsub: "no leak: "
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
## this test makes sure getOccupiedMem() is constant after a few iterations
|
||||||
|
## for --gc:bohem, --gc:markAndSweep, --gc:arc, --gc:orc.
|
||||||
|
## and for other gc, it consists of cycles with constant min/max after a few cycles.
|
||||||
|
## This ensures we have no leaks.
|
||||||
|
|
||||||
when defined(GC_setMaxPause):
|
when defined(GC_setMaxPause):
|
||||||
GC_setMaxPause 2_000
|
GC_setMaxPause 2_000
|
||||||
|
|
||||||
|
|
@ -14,13 +19,75 @@ proc makeObj(): TTestObj =
|
||||||
result.x = "Hello"
|
result.x = "Hello"
|
||||||
result.s = @[1,2,3]
|
result.s = @[1,2,3]
|
||||||
|
|
||||||
|
const collectAlways = defined(gcMarkAndSweep) or defined(boehmgc)
|
||||||
|
const isDeterministic = collectAlways or defined(gcArc) or defined(gcOrc)
|
||||||
|
## when isDeterministic, we expect memory to reach a fixed point
|
||||||
|
## after `numIterStable` iterations
|
||||||
|
|
||||||
|
var memMax = 0 # peak
|
||||||
|
|
||||||
|
when isDeterministic:
|
||||||
|
const numIterStable = 3
|
||||||
|
# stabilize after this many iterations
|
||||||
|
else:
|
||||||
|
const numCycleStable = when defined(useRealtimeGC): 6 else: 4
|
||||||
|
# stabilize after this many cycles; empirically determined
|
||||||
|
# after running all combinations of gc's with / without -d:release
|
||||||
|
var memPrevious = 0
|
||||||
|
var memMin = int.high # right after a peak
|
||||||
|
var numCollections = 0
|
||||||
|
|
||||||
|
let numIter = when isDeterministic: 1_000 else: 1_000_000
|
||||||
|
## full collection is expensive, and the memory doesn't change after
|
||||||
|
## each iteration so there's no point in a large `numIter` (this was taking
|
||||||
|
## 350s for `nim c -r -d:release --gc:boehm` + `nim c -r --gc:boehm`, 50%
|
||||||
|
## of running time of `testament/testament all`.
|
||||||
|
|
||||||
proc inProc() =
|
proc inProc() =
|
||||||
for i in 1 .. 1_000_000:
|
for i in 1 .. numIter:
|
||||||
when defined(gcMarkAndSweep) or defined(boehmgc):
|
when collectAlways: GC_fullcollect()
|
||||||
GC_fullcollect()
|
|
||||||
var obj: TTestObj
|
var obj: TTestObj
|
||||||
obj = makeObj()
|
obj = makeObj()
|
||||||
if getOccupiedMem() > 300_000: quit("still a leak!")
|
let mem = getOccupiedMem()
|
||||||
|
when isDeterministic:
|
||||||
|
if i <= numIterStable:
|
||||||
|
memMax = mem
|
||||||
|
doAssert memMax <= 50_000 # adjust as needed
|
||||||
|
else:
|
||||||
|
# memory shouldn't increase after 1st few iterations
|
||||||
|
# on linux 386 it somehow takes 3 iters to converge
|
||||||
|
doAssert mem <= memMax
|
||||||
|
else:
|
||||||
|
if mem < memPrevious:
|
||||||
|
# a collection happened, it peaked at memPrevious
|
||||||
|
# echo (mem, memMin, memMax, numCollections, numIter, i) # for debugging
|
||||||
|
numCollections.inc
|
||||||
|
if numCollections <= numCycleStable:
|
||||||
|
# this is the 1st few collections, we update the min/max
|
||||||
|
doAssert memPrevious < 300_000 # adjust as needed
|
||||||
|
if memMin < mem: # `<` intentional; the valley may increase
|
||||||
|
memMin = mem
|
||||||
|
if memMax < memPrevious:
|
||||||
|
memMax = memPrevious
|
||||||
|
else:
|
||||||
|
# after a collection, we always go back to same level
|
||||||
|
doAssert mem <= memMin, $(mem, memMin)
|
||||||
|
|
||||||
|
if numCollections >= numCycleStable:
|
||||||
|
# after a few cycles, the max stabilizes
|
||||||
|
doAssert mem <= memMax, $(mem, memMax)
|
||||||
|
|
||||||
|
memPrevious = mem
|
||||||
|
|
||||||
inProc()
|
inProc()
|
||||||
echo "no leak: ", getOccupiedMem()
|
let mem = getOccupiedMem()
|
||||||
|
var msg = "no leak: "
|
||||||
|
when isDeterministic:
|
||||||
|
msg.add $(mem, memMax)
|
||||||
|
echo msg
|
||||||
|
else:
|
||||||
|
msg.add $(mem, memMin, memMax, numCollections, numIter)
|
||||||
|
echo msg
|
||||||
|
# make sure some collections did happen, otherwise the previous tests
|
||||||
|
# are meaningless
|
||||||
|
doAssert numCollections > 1000 # 3999 on local OSX; leaving some slack
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue