Files
GentleGC/tests/test_wp_minor.lua

122 lines
4.6 KiB
Lua

-- weirdperformance cycles: a heap drop with the threshold reset by the normal rule is not an unknown addon.
-- Simulates the 1.12 client's collector (1.25x).
-- Run: lua5.0 tests/test_wp_minor.lua GentleGC.lua
format = string.format
local now = 1000
function GetTime() return now end
function UnitAffectingCombat() return false end
function UnitIsAFK() return false end
local log = {}
DEFAULT_CHAT_FRAME = { AddMessage = function(_, m) table.insert(log, m); print(" " .. m) end }
SlashCmdList = {}
FRAMES = {}
function CreateFrame()
local f = { scripts = {} }
function f:RegisterEvent() end
function f:UnregisterEvent() end
function f:SetScript(k, fn) self.scripts[k] = fn end
table.insert(FRAMES, f)
return f
end
local caller = nil
function debugstack()
local s = "Interface\\AddOns\\GentleGC\\GentleGC.lua:400: in function `WrappedCollect'\n"
if caller then s = s .. "Interface\\AddOns\\" .. caller .. "\\core.lua:12: in function `x'\n" end
return s
end
-- the client's collector: full collections leave the threshold at 1.25x live,
-- and take 10 ms + 8 ms per MB freed (simulated on the clock)
local origCG = collectgarbage
local function setThreshold() local u = gcinfo(); origCG(math.floor(u * 1.25)) end
local timed = false
collectgarbage = function(n)
if n == nil or n == 0 then
local before = gcinfo()
origCG(); setThreshold()
if timed then now = now + 0.010 + 0.008 * (before - gcinfo()) / 1024 end
else
origCG(n)
end
end
local unwrapped = collectgarbage -- what an addon holds if it loaded before us
LIVE = {}
for i = 1, 300000 do LIVE[i] = { i } end
origCG(); setThreshold()
function GetWeirdUtilsVersion(m)
if m == "weirdperformance" then return "1.2.1" end
return { weirdperformance = "1.2.1" }
end
dofile(arg[1])
local F = FRAMES[1]
event, arg1 = "ADDON_LOADED", "GentleGC"; this = F; F.scripts.OnEvent()
local SF = FRAMES[4]
local cmd = SlashCmdList.GENTLEGC
cmd("debug 2")
local function count(pat) local n = 0; for _, m in ipairs(log) do if string.find(m, pat) then n = n + 1 end end; return n end
local function lastMatch(pat) for i = table.getn(log), 1, -1 do if string.find(log[i], pat) then return log[i] end end; return "" end
local function check(name, c) print((c and "PASS " or "FAIL ") .. name); if not c then FAILED = true end end
local function frame(dt) now = now + dt; SF.scripts.OnUpdate(); arg1 = dt; this = F; F.scripts.OnUpdate() end
local function seconds(n) for i = 1, n * 10 do frame(0.1) end end
local function clear() log = {} end
local function has(pat) return count(pat) > 0 end
-- room above the heap so the real Lua collector doesn't fire while we allocate
local function roomy() origCG(gcinfo() + 200000) end
seconds(40)
roomy()
seconds(2)
local _, T = gcinfo()
print("1. heap drops, threshold back at the normal rule: a weirdperformance cycle")
clear()
GARB = {}
for i = 1, 6 * 7000 do GARB[i] = { i, i } end
seconds(1) -- the per-frame sample sees the grown heap
GARB = nil
origCG() -- frees it (and moves the threshold, as any collection does)
origCG(math.floor(gcinfo() * 1.25)) -- threshold reset by the normal rule, as weirdperformance's shrink does
seconds(2)
check("recognized as a minor sweep", has("weirdperformance cycle: freed"))
check("not counted as an unknown addon", not has("collection by unknown addon"))
check("not counted as an automatic collection", not has("automatic GC detected"))
cmd("status")
check("status counts it", has("weirdperformance minor sweeps: 1,"))
check("not in 'by other addons'", not has("by other addons"))
print("2. heap drops and the threshold moves too: still an unknown collection, now with the numbers")
roomy()
seconds(2)
_, T = gcinfo()
clear()
GARB = {}
for i = 1, 6 * 7000 do GARB[i] = { i, i } end
seconds(1)
GARB = nil
origCG() -- threshold left where the collection put it (2x live)
seconds(2)
check("unknown addon, as before", has("collection by unknown addon"))
check("with heap and threshold numbers", string.find(lastMatch("collection by unknown addon"), "%[heap [%d%.]+ %-> [%d%.]+mb, threshold [%d%.]+ %-> [%d%.]+mb%]") ~= nil)
cmd("status")
check("listed under other addons", has("by other addons: 1"))
print("3. a drop of a few KB is not counted")
roomy()
seconds(2)
clear()
GARB = {}
for i = 1, 300 do GARB[i] = { i } end
seconds(1)
GARB = nil
origCG(); origCG(math.floor(gcinfo() * 1.25))
seconds(2)
check("tiny drop not printed as a cycle", not has("weirdperformance cycle: freed"))
check("tiny drop not an unknown addon", not has("collection by unknown addon"))
print(FAILED and "SOME TESTS FAILED" or "ALL TESTS PASSED")