Skip to content

Conversation

@gnprice
Copy link
Member

@gnprice gnprice commented Jul 18, 2025

Fixes #1712.

Our CI has been failing in this test file since yesterday; this change fixes that.

This test had been having the store handle a RealmUserUpdateEvent affecting eg.selfUser. That means the store mutates the actual User object it has... which, in this test context, means the value that eg.selfUser is bound to as a final variable.

As a result, when the test gets cleaned up with testBinding.reset, the store gets discarded as usual so that the next test will get a fresh store... but the User object at eg.selfUser is still the one that's been mutated by this test.

That's buggy in principle. Concretely, here, it causes the self-user to have a non-null avatar. When a later test sends a message and causes an outbox-message to appear in the tree, that results in a NetworkImage. And that throws an error, because no HttpClient provider has been set, because that latter test wasn't expecting to create any NetworkImages. That's the failure we've been seeing in CI.

It's still a bit mysterious why this had previously been working (or anyway these tests hadn't been failing). It started failing with an upstream change merged yesterday, which makes changes to NetworkImage that look innocuous: its == and hashCode become
finer-grained, and its toString more detailed. In any case,
the bug is ours to fix.

It'd also be good to follow up here by systematically preventing this sort of state leak between tests. But that comes after getting our CI passing again.

Fixes zulip#1712.

Our CI has been failing in this test file since yesterday;
this change fixes that.

This test had been having the store handle a RealmUserUpdateEvent
affecting `eg.selfUser`.  That means the store mutates the actual
User object it has... which, in this test context, means the value
that `eg.selfUser` is bound to as a final variable.

As a result, when the test gets cleaned up with testBinding.reset,
the store gets discarded as usual so that the next test will get a
fresh store... but the User object at `eg.selfUser` is still the one
that's been mutated by this test.

That's buggy in principle.  Concretely, here, it causes the self-user
to have a non-null avatar.  When a later test sends a message and
causes an outbox-message to appear in the tree, that results in a
NetworkImage.  And that throws an error, because no HttpClient
provider has been set, because that latter test wasn't expecting to
create any `NetworkImage`s.  That's the failure we've been seeing
in CI.

It's still a bit mysterious why this had previously been working
(or anyway these tests hadn't been failing).  It started failing
with an upstream change merged yesterday, which makes changes to
NetworkImage that look innocuous: its `==` and `hashCode` become
finer-grained, and its `toString` more detailed.   In any case,
the bug is ours to fix.

It'd also be good to follow up here by systematically preventing
this sort of state leak between tests.  But that comes after getting
our CI passing again.
@gnprice gnprice merged commit a04b44e into zulip:main Jul 18, 2025
1 check passed
@gnprice gnprice deleted the pr-selfuser-state-leak branch July 18, 2025 01:13
gnprice added a commit to gnprice/zulip-flutter that referenced this pull request Jul 18, 2025
This is the same sort of state leak that caused zulip#1712; this instance
of it just hasn't happened to break any tests for us yet.

We'll soon arrange things so that this sort of state-leaking mutation
causes an immediate error.  This is one of the three total places
where it turns out we had such mutations, including the one we just
fixed in a04b44e (zulip#1713).

The second of these tests ("no error if recipient was deactivated …")
wasn't actually mutating the shared example user `eg.otherUser`,
because secretly `setupToMessageActionSheet` makes a new User object
with the same user ID and puts that in the store.  Still, it *looked*
like it was; best to do something that clearly looks correct instead.

The first of these tests was indeed mutating `eg.selfUser`, just as it
looks like it's doing.
chrisbobbe pushed a commit that referenced this pull request Jul 22, 2025
This is the same sort of state leak that caused #1712; this instance
of it just hasn't happened to break any tests for us yet.

We'll soon arrange things so that this sort of state-leaking mutation
causes an immediate error.  This is one of the three total places
where it turns out we had such mutations, including the one we just
fixed in a04b44e (#1713).

The second of these tests ("no error if recipient was deactivated …")
wasn't actually mutating the shared example user `eg.otherUser`,
because secretly `setupToMessageActionSheet` makes a new User object
with the same user ID and puts that in the store.  Still, it *looked*
like it was; best to do something that clearly looks correct instead.

The first of these tests was indeed mutating `eg.selfUser`, just as it
looks like it's doing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CI broken by NetworkImage change

1 participant