Generated protobuf messages contain internal data structures
that general purpose comparison functions (e.g., reflect.DeepEqual,
pretty.Compare, etc) do not properly compare. It is already the case
today that these functions may report a difference when two messages
are actually semantically equivalent.
Fix all usages by either calling proto.Equal directly if
the top-level types are themselves proto.Message, or by calling
cmp.Equal with the cmp.Comparer(proto.Equal) option specified.
This option teaches cmp to use proto.Equal anytime it encounters
proto.Message types.
Nobody should directly need to reference these packages.
This is technically a breaking change. However:
- Package dns was exporting a NewBuilder method. This should never have been necessary to use, but if so, it can be replaced by importing the "grpc" package and then using resolver.Get("dns").
- Package passthrough was not exporting any symbols and there was never a need to even blank-import it.
After as much searching as possible, it appears nobody in the open source community is referencing either of these packages.
* Make healthcheck tests in end2end_test.go more readable.
- Made these tests use the default health service implementation
wherever possible.
- Refactored some common code used in these tests into helper functions.
- Added function comments for all these tests to improve readability.
In a follow up PR, I will be moving all these tests into
healthcheck_test.go.
Add a RequestInfo struct which initially is used for passing the full request method (though could later be expanded to pass more info) so that things like GetRequestMetadata can be used to apply logic based on that data.
This is a fix for #3019
`transport/Stream.RecvCompress` returns what the header contains, if present,
or empty string if a context error occurs. However, it "prefers" the header
data even if there is a context error, to prevent a related race. What happens
here is:
1. RPC starts.
2. Client cancels RPC.
3. `RecvCompress` tells `ClientStream.Recv` that compression used is "" because
of the context error. `as.decomp` is left nil, because there is no
compressor to look up in the registry.
4. Server's header and first message hit client.
5. Client sees the header and message and allows grpc's stream to see them.
(We only provide context errors if we need to block.)
6. Client performs a successful `Read` on the stream, receiving the gzipped
payload, then checks `as.decomp`.
7. We have no decompressor but the payload has a bit set indicating the message
is compressed, so this is an error. However, when forming the error string,
`RecvCompress` now returns "gzip" because it doesn't need to block to get
this from the now-received header. This leads to the confusing message
about how "gzip" is not installed even though it is.
This change makes `waitOnHeader` close the stream when context cancellation happens.
Then `RecvCompress` uses whatever value is present in the stream at that time, which
can no longer change because the stream is closed. Also, this will be in sync with
the messages on the stream - if there are any messages present, the headers must
have been processed first, and `RecvCompress` will contain the proper value.
In the event of a race, the first server may not be fully serving before the
client attempt to connect, then the second server may attempt to field the
FullDuplexCall, which it does not implement.
Fix the race by giving the client only the first server's address until after
the FullDuplexCall is started.
- Send a message from the test server that the client can block on to know for sure the RPC's header was sent.
- Don't receive in the test server so we can violate flow control
- Set a deadline on the RPC so it can't hang forever.
Also, two fixes:
- Fix long-standing `.travis.yml` bug where `VET_SKIP_PROTO` was not `export`ed (so not seen by `vet.sh`).
- Update `vet.sh` to work with new `goimports -l` that does not print a `:` after filenames.
Before these fixes, it was possible to see errors on new RPCs after a
connection began draining, and before establishing a new connection. There is
an inherent race between choosing a SubConn and attempting to creating a stream
on it. We should be able to avoid application-visible RPC errors due to this
with transparent retry. However, several bugs were preventing this from
working correctly:
1. Non-wait-for-ready RPCs were skipping transparent retry, though the retry
design calls for retrying them.
2. The transport closed itself (and would consequently error new RPCs) before
notifying the SubConn that it was draining.
3. The SubConn wasn't synchronously updating itself once it was notified about
the closing or draining state.
4. The SubConn would go into the TRANSIENT_FAILURE state instantaneously,
causing RPCs to fail instead of queue.
- Seperated and documented the options for client and server sides.
- Better support for multiple grpc.Servers. This will be used in other
improvements that I have in the works.
- Moved some common functionality from channelz_test.go to
end2end_test.go.
- Added an option to use the default health service implementation, instead
of each test creating a new health.Server and passing it in. The
inidividual tests have not been changed in this PR. I will do that in a
follow up PR to keep the changes to a reasonable size.
- Fixed one of the tests which had to be fixed because of the separation
of client and server configs.
* end2end test cleanup #1
- Removed some old code which has a TODO asking for it's removal once
Go1.6 and Go1.7 support is gone.
- Cleaned up a couple of error messages along with it.
In the end of the test, 10 RPCs are made to make sure data is sent to
the second server. The first RPC of these 10 is made right after the
second server's listener receives a connection. But at this time, the
connectivity state on the client side is not set to READY yet (though
ac's state should be either connecting or ready, the race between ac
and balancer could cause cc to still be in transient failure). So the
first RPC fails due to transient failure, but the following 9 will
succeed.
This test sometimes fails with error creating stream due to
DeadlineExceeded. It's very hard to reproduce (failed twice in 100000
runs). Extend the RPC timeout in case it's too short.
I was trying to run this test and I had copied the name of the function
from the comment, and it took a good while to figure out why
`go test -run` was returning `testing: warning: no tests to run`.
Before this fix, stream is removed from activeStreams in finishStream,
which happens when the service handler returns status, without waiting
for the status to be sent by loopyWriter. If GracefulStop() is called in
between, it will close the connection (because activeStreams is empty),
which causes the RPC to fail with "transport is closing". This change
moves the activeStreams cleanup into loopyWriter, after sending status
on wire.
* Expose a method from the internal package to get to the raw
StatusProto wrapped by the status error, and use it from
http2Server.WriteStatus().
* Add a helper method in internal/testutils to compare two status errors
and update test code to use that instead of reflect.DeepEqual()
This removes RequireHandshakeHybrid support and changes the default behavior
to RequireHandshakeOn. Dial calls will now block and wait for a successful
handshake before proceeding. Users relying on the old hybrid behavior (cmux
users) should consult https://github.com/soheilhy/cmux/issues/64.
Also, several tests have been updated to take this into consideration by
sending settings frames.