-
Notifications
You must be signed in to change notification settings - Fork 108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Debug flaky TestStreamForServer
test
#627
Conversation
TestStreamForServer
testTestStreamForServer
test
But why. Is this intentional? If not, should we better synchronize the closing of the stream so it happens after the body has been read? If it is intentional, seems like we should instead just relax the test assertions to allow
This is not accurate. It is called with A remark on the linked issue:
I don't understand the value of this. It seems to be solely for our test assertions, for which a superior fix is to relax the assertion. IMO, it seems perfectly reasonable that |
I'm not sure
Depends on the behaviour we expect from |
I think it's actually fine as is. Is there actually a problem with the current behavior? If calling code were organized in a way that multiple, independent layers of logic all called The bug in the flaky test sounds to me like an error is reasonable but the assertion is too strict. BTW, I'm still curious: why can |
connect-go/connect_ext_test.go Lines 1525 to 1532 in 20b5723
The func(ctx context.Context, stream *connect.BidiStream[pingv1.CumSumRequest, pingv1.CumSumResponse]) error {
defer stream.Receive() // forces Read, get's io.EOF on Close from client
return stream.Conn().Send("foobar")
} This would force the request body to read the nil message, ensuring EDIT: fix code snippet go routine bug |
newPingClient := func(t *testing.T, pingServer pingv1connect.PingServiceHandler) pingv1connect.PingServiceClient { | ||
t.Helper() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can undo all of the changes in this file, right? Looks like the addition of t
here is unused, and this appears to be the only change in here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The servers close are matched to the clients which is nice. The other change in this file is the two Receives
for the test cases that Send
a non nil message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As in server := memhttptest.NewServer(t, mux)
takes the correct subtests *testing.T
rather than the parent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, okay. That was a bit subtle due to the shadowing of the name t
.
TestStreamForServer
can fail onSend(nil)
returningio.EOF
. This occurs becauseSend(nil)
will try toWrite(nil)
to the request body pipe. In almost all cases this will be read (and therefore succeed) when buffering the request body. However, on the server returning quickly, the request can be closed causing theSend
to fail withio.EOF
error.To ensure a
Send
succeeds we need to match it with a correlatingReceive
in the server. Nil writes will never be guaranteed unless the server tries toReceive
a message, which would read the request body and therefore enforce the successful drain. This is a problem forSend(nil)
as the intended behaviour is to ensure the request headers are sent, which does complete but returns with an unexpected error.To solve for
Send(nil)
we now check if this write caused the request to send and avoid triggering a body write if so. Any other cases and later ifSend(nil)
is called weWrite(nil)
which keeps the same behaviour.Tests
client-stream-conn
andclient-stream-send-msg
write a messageSend(msg)
. For these I've modified the test cases toReceive()
the message to ensure that the write completes and doesn't otherwise affect the test case.Fixes #626