lunarmodules / busted

Elegant Lua unit testing.
https://lunarmodules.github.io/busted/
MIT License
1.4k stars 185 forks source link

Using busted to test something using an FFI lib produces a "cannot change a protected metatable" error when run with luajit #630

Closed drhayes closed 4 years ago

drhayes commented 4 years ago

I'm using an FFI library called brinevector (https://github.com/novemberisms/brinevector). When writing unit tests against code using that library, I get a "cannot change a protected metatable" error when running my tests.

It sure looks like it's because busted loads the module twice, but I'm not sure what's going on. Any insight there? Is this a bug in brinevector or in busted?

Tieske commented 4 years ago

please provide some more details, minimal reproduction, and the exact error message and location

drhayes commented 4 years ago

Turns out it only happens if I run with luajit!

Here's the repo with the repro: https://github.com/drhayes/busted-repro

I'm unit testing code that will eventually run under luajit, but not sure if I need to run my tests with luajit as well, I'll double-check. Also not sure if busted is supposed to run under luajit?

EDIT: I'm depending on bit32 being available, might be able to find a replacement or something..?

Tieske commented 4 years ago

it's another ffi singleton that needs patching.

add helper.lua with this code:


local isJit = (tostring(assert):match('builtin') ~= nil)
if isJit then
  local ffi = require "ffi"
  local ffi_metatype = ffi.metatype
  local metatype_store = {}
  ffi.metatype = function (ct, mt)
    if metatype_store[ct] then
      return metatype_store[ct]
    end
    local success, result, err = pcall(ffi_metatype, ct, mt)
    if not success then
      -- hard error was thrown
      error(result, 2)
    end
    if not result then
      -- soft error was returned
      return result, err
    end
    -- it worked, store and return
    metatype_store[ct] = result
    return result
  end
end

And then run the tests using busted --helper=helper.lua

Tieske commented 4 years ago

Please try the fix in #631 and see whether it fixes the issue.

drhayes commented 4 years ago

Using the helper fixed my issue. Not sure how to patch my local busted since I installed it with luarocks and I'm a relative lua newbie, but I'll dig around in the next day and learn how to do it.

Tieske commented 4 years ago

would be nice if you could test my PR branch;

To clone the repo and install the PR branch do:

git clone https://github.com/olivine-labs/busted.git
cd busted
git checkout luajit/metatype
luarocks make

the final luarocks command will install the version from the checked out repo.

Tieske commented 4 years ago

if it works for you, then I'll merge the PR

drhayes commented 4 years ago

I'll test it today and get back to you.

drhayes commented 4 years ago

It works! The tests that I expected to fail right now fail, no error seen. Thanks for helping me get you the repro.