diff --git a/tests/test-leak-client.lua b/tests/test-leak-client.lua new file mode 100644 index 00000000..205e4824 --- /dev/null +++ b/tests/test-leak-client.lua @@ -0,0 +1,78 @@ +-- Some memory leak checks involving clients as integration tests. +local awful = require("awful") +local wibox = require("wibox") + +-- "Enable" titlebars (so that the titlebar can prevent garbage collection) +client.connect_signal("manage", function (c) + local buttons = awful.util.table.join( + awful.button({ }, 1, function() + client.focus = c + c:raise() + awful.mouse.client.move(c) + end), + awful.button({ }, 3, function() + client.focus = c + c:raise() + awful.mouse.client.resize(c) + end) + ) + + -- Widgets that are aligned to the left + local left_layout = wibox.layout.fixed.horizontal(awful.titlebar.widget.iconwidget(c)) + left_layout:buttons(buttons) + + -- The title goes in the middle + local title = awful.titlebar.widget.titlewidget(c) + title:set_align("center") + local middle_layout = wibox.layout.flex.horizontal(title) + middle_layout:buttons(buttons) + + awful.titlebar(c):set_widget(wibox.layout.align.horizontal( + left_layout, + middle_layout, + wibox.layout.fixed.horizontal( + awful.titlebar.widget.floatingbutton(c), + awful.titlebar.widget.maximizedbutton(c), + awful.titlebar.widget.stickybutton(c), + awful.titlebar.widget.ontopbutton(c), + awful.titlebar.widget.closebutton(c) + )), { position = "bottom"}) +end) + +-- We tell the garbage collector when to work, disable it +collectgarbage("stop") + +-- We try to get a client representing an already-closed client. +-- The first iteration starts xterm, the second keeps a weak reference to it and +-- closes it and the last one checks that the client object is GC'able. +local objs = nil +local steps = { + function(count) + if count == 1 then + awful.spawn("xterm") + elseif not objs then + local c = client.get()[1] + if c then + objs = setmetatable({ c }, { __mode = "v" }) + c:kill() + end + else + assert(#objs == 1) + + -- Test that we have a client and that it's invalid (tostring() + -- causes an "invalid object" error) + local success, msg = pcall(function() tostring(objs[1]) end) + assert(not success) + assert(msg:find("invalid object"), msg) + + -- Check that it is garbage-collectable + collectgarbage("collect") + assert(#objs == 0) + return true + end + end, +} + +require("_runner").run_steps(steps) + +-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80