Closed tcoopman closed 6 months ago
Is there any chance you can create a single failing test file that can be run standalone using Mix.install()
? The general format is this:
# example_test.exs
Mix.install([
{:mneme, "0.6.0"},
...
])
ExUnit.start()
Mneme.start()
defmodule ExampleTest do
use ExUnit.Case
use Mneme
# test case that causes internal error
...
end
ExUnit.run()
If all is set up correctly, you should just be able to run elixir example_test.exs
and see the crash. This should make it possible for me to reproduce and fix. Thanks!
I'll try again later, but couldn't reproduce it yet.
If it helps you: The repo is here btw: https://github.com/tcoopman/eventstore_sqlite
link to a failing test: https://github.com/tcoopman/eventstore_sqlite/blob/943fe83134e36c998408c628fc59ba7244c60f83/test/eventstore_sqlite_test.exs#L318
Can you share the Elixir and OTP versions you're using?
elixir --version
Erlang/OTP 26 [erts-14.2.4] [source] [64-bit] [smp:32:32] [ds:32:32:10] [async-threads:1] [jit:ns]
Elixir 1.16.2 (compiled with Erlang/OTP 26)
The change 1.15 to 1.16 could be the issue
This error is quite baffling. So I found an old discussion about a somewhat similar issue that pointed to an explanation that José wrote, but I'm not sure it applies here.
The relevant lines that led up to the crash essentially look like:
defp do_to_patterns(%struct{} = value, context, vars) do
...
struct_to_patterns(struct, value, context, vars, [])
end
defp struct_to_patterns(struct, value, context, vars, notes) do
# crash
defaults = struct.__struct__()
...
end
So it's possible that, in some weird code-path, a %Complex{}
(which desugars to %{__struct__: Complex, ...}
) was returned by a function without the Complex
module actually being loaded.
Well, now I'm super confused.
I've just changed my test to:
defmodule EventstoreSqliteTest do
use ExUnit.Case
use Mneme
use EventstoreSqlite.DataCase
use TypedStruct
doctest EventstoreSqlite
typedstruct module: FooTestEvent do
field(:text, :string)
end
# typedstruct module: Complex2 do
# field(:c, :string)
# end
# typedstruct module: ComplexEvent do
# field(:complex2, Complex2.t())
# end
describe "append_to_stream/2" do
test "$all stream" do
event_1 = %FooTestEvent{text: "1"}
event_2 = %FooTestEvent{text: "2"}
event_3 = %FooTestEvent{text: "3"}
:ok = EventstoreSqlite.append_to_stream("stream-1", [event_1, event_2, event_3])
:ok = EventstoreSqlite.append_to_stream("stream-2", [event_2, event_3])
auto_assert(
[
%EventstoreSqlite.RecordedEvent{
data: %FooTestEvent{text: "3"},
type: "Elixir.EventstoreSqliteTest.FooTestEvent"
},
%EventstoreSqlite.RecordedEvent{
data: %FooTestEvent{text: "2"},
type: "Elixir.EventstoreSqliteTest.FooTestEvent"
},
%EventstoreSqlite.RecordedEvent{
data: %FooTestEvent{text: "3"},
type: "Elixir.EventstoreSqliteTest.FooTestEvent"
},
%EventstoreSqlite.RecordedEvent{
data: %FooTestEvent{text: "2"},
type: "Elixir.EventstoreSqliteTest.FooTestEvent"
},
%EventstoreSqlite.RecordedEvent{
data: %FooTestEvent{text: "1"},
type: "Elixir.EventstoreSqliteTest.FooTestEvent"
}
] <- EventstoreSqlite.read_stream_backward("$all")
)
end
end
end
and removed _build
, run the test again and I get the exact same failure. About module Complex
not being available.
Where is it coming from??? I don't have any Complex
modules anymore in my code
I've found it. Stupid me.
I've ran a benchmark against the test database and also loaded a Complex
module (but a different one) in the db.
The benchmark didn't clean up the database, so the tests were loading an incorrect module that didn't exist...
Sorry for the trouble
Really weird. How are you running the test? mix test test/eventstore_sqlite_test.exs
?
Ah! Makes sense. No worries at all and thanks for continuing to dig into it!
This does give me some ideas though, because it's possible to trigger this with:
defmodule Repro do
use ExUnit.Case
use Mneme
test "repro" do
auto_assert(%{__struct__: Foo})
end
end
So minimally, I should be guarding against this!
version: 0.6.0
code:
error:
The weird thing is that other tests that seem to do similar things in the file succeed. But it's not at random, the same tests always fail, also when run in isolation.
If I delete the pattern so
mneme
has to create a new one, mneme stil fails.Notice that the
Complex
struct mentioned in the error(UndefinedFunctionError) function Complex.__struct__/0 is undefined (module Complex is not available)
is nowhere to be found in the code of the test though...There was a time when this worked - but it also fails on 0.5.0 now that I test it. And I'm confused, because I believe it used to work on that version...