Move the test-only methods to a new internal package so as to not
pollute the godoc, and to prevent people from using them. (Packages
named internal or under internal are private, and enforced by the go
tool)
The http.Handler-based transport body reader was returning error types
not understood by the recvMsg parser. See #557 for some background and
examples.
Fix the http.Handler transport and add tests. I copied in a subset of
the http2 package's serverTest type, adapted slightly to work with
grpc. In the process of adding tests, I discovered that
ErrUnexpectedEOF was also not handled by the regular server
transport. Document the rules and fix that crash as well.
Unrelated stuff in this CL:
* make tests listen on localhost:0 instead of :0, to avoid Mac firewall
pop-up dialogs.
* rename parser.s field to parser.r, to be more idiomatic that it's an
io.Reader and not anything fancier. (it's not acting like type
stream, even if that's the typical concrete type)
* move 5 byte temp buffer into parser, rather than allocating it for
each new message. (drop in the bucket improvement in garbage; more
to do later)
* rename http2RSTErrConvTab to http2ErrConvTab, per Qi's earlier
CL. Also add the HTTP/1.1-required error mapping for completeness,
not that it should ever arise with gRPC, also per Qi's earlier CL
referenced in #557.
This removes serverSetUp and clientSetUp. They had too many positional
parameters and weren't readable at the call sites.
With this change, it's now much more obvious how a test differs from
others just be looking at what is tinkered with after newTest.
Change-Id: I59bb06f8029af166002033f2c3f7b8f0b2d20940
Filter expected log output by default, unless a flag is provided, or a
test fails.
This makes it possible to see unexpected things. Having noisy tests
makes it too easy to miss actual problems.
It wasn't closing the recvBuffer body in all cases during shutdown.
This change also:
* adds a new test with concurrent streams doing their own serial sends.
This test was part of earlier debugging, but exists now to add more
test coverage around concurrency.
* starts a cleanup of the end2end testing code, to be continued later.
but the cleanup was necessary when writing the new test to be clean
and not add more positional parameters.
* documents the concurrency expectations of the ServerTransport
interface, cleaning up some other nearby documentation in the
process.
* speeds up TestCancelNoIO to cancel some contexts once no longer
needed, adding some comments about what the test is doing, adds some
TODOs, and reduces some overly-long sleeps.
This adds new http.Handler-based ServerTransport in the process,
reusing the HTTP/2 server code in x/net/http2 or Go 1.6+.
All end2end tests pass with this new ServerTransport.
Fixesgrpc/grpc-go#75
Also:
Updates grpc/grpc-go#495 (lets user fix it with middleware in front)
Updates grpc/grpc-go#468 (x/net/http2 validates)
Updates grpc/grpc-go#147 (possible with x/net/http2)
Updates grpc/grpc-go#104 (x/net/http2 does this)
The go race detector has a limit on how many goroutines it can track.
This test is only barely acceptable and the presence of any new
goroutines push it over the edge. Shorten this test is race mode.
The docs at https://golang.org/pkg/testing/#T.FailNow say:
> FailNow must be called from the goroutine running the test or
> benchmark function, not from other goroutines created during the
> test.
(Fatalf is documented as "Fatalf is equivalent to Logf followed by
FailNow.")
This was manifesting itself as a race with two concurrently failing
goroutines in my other CL, masking whatever the real problem was.
This commit introduces the first microbenchmark for grpc, wherein
`encode` is benchmarked according to message size. A conclusion of
the benchmark is that the removal of type switching found in
`binary.Write`, which is used in `encode` produces the following
encoding time and memory allocation footprint:
```
$ # Return to previous commit but benchmark.
$ go test ./... -test.bench="Benchmark*" > /tmp/before
$ # Return to working copy.
$ go test ./... -test.bench="Benchmark*" > /tmp/after
$ benchcmp /tmp/before /tmp/after
benchmark old ns/op new ns/op delta
BenchmarkEncode1B 1282 936 -26.99%
BenchmarkEncode1KiB 4865 4184 -14.00%
BenchmarkEncode8KiB 22686 21560 -4.96%
BenchmarkEncode64KiB 134451 116762 -13.16%
BenchmarkEncode512KiB 514044 361224 -29.73%
BenchmarkEncode1MiB 767096 636725 -17.00%
benchmark old MB/s new MB/s speedup
BenchmarkEncode1B 6.24 8.55 1.37x
BenchmarkEncode1KiB 212.11 246.63 1.16x
BenchmarkEncode8KiB 361.46 380.33 1.05x
BenchmarkEncode64KiB 487.50 561.35 1.15x
BenchmarkEncode512KiB 1019.94 1451.45 1.42x
BenchmarkEncode1MiB 1366.95 1646.84 1.20x
benchmark old allocs new allocs delta
BenchmarkEncode1B 6 3 -50.00%
BenchmarkEncode1KiB 8 5 -37.50%
BenchmarkEncode8KiB 8 5 -37.50%
BenchmarkEncode64KiB 8 5 -37.50%
BenchmarkEncode512KiB 8 5 -37.50%
BenchmarkEncode1MiB 8 5 -37.50%
benchmark old bytes new bytes delta
BenchmarkEncode1B 384 328 -14.58%
BenchmarkEncode1KiB 2816 2760 -1.99%
BenchmarkEncode8KiB 17283 17227 -0.32%
BenchmarkEncode64KiB 147856 147802 -0.04%
BenchmarkEncode512KiB 1065344 1065288 -0.01%
BenchmarkEncode1MiB 2113920 2113864 -0.00%
```
..., which is apropos of the comment in [encoding/binary]
(http://golang.org/pkg/encoding/binary), wherein ...
> This package favors simplicity over efficiency.
... is stated.
If `encode` is deemed to need further memory efficiencies, a mechanism
whereby a `proto.Buffer` is retained may be warranted, which is why the
original TODO remains. The proposed improvement in this change is
simple and low-hanging.
I did not want to introduce yet-another protocol buffer message for
tests, but the ones under ...
> interop/grpc_testing/test.proto
> test/grpc_testing/test.proto
... have a fundamental dependency on `grpc` package due to their
generated stubs, which produces a cycle in the imports if the benchmark
were to attempt to import them for profiling. The newly created ...
> test/grpc_message/test.proto
... protocol buffer package has no generated RPC service stubs, which
means it can be imported into the `grpc` package root without cycle.
This commit applies two bulk changes to the grpc error reporting
mechanisms:
(1.) Error strings for errors that originate within grpc are prefixed
with the package name for better clarity for where they originate
since they could percolate up in the users call chains to the
originator.
(2.) Errors that are, in fact, singletons have been converted from
fmt.Errorf to errors.New and assigned as package-level variables.
This bodes particularly well for enabling API customers to elect to
handle these errors upon receipt via equality comparison. This had
been previous impossible with the original API.
Supplementarily, ``gofmt -w -s=true`` has been run on the repository to
cleanup residual defects, and it has detected and repaired a few.
TEST=Manual go test ./...