From c972803da8b7b06f34d71b2cb4134d585bfa775d Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Tue, 20 Oct 2015 19:33:11 +0000 Subject: [PATCH] http2: update the curl and nghttp2 versions used in tests Also add a new h2load test, disabled by default. Change-Id: I0fcfdbf38cf86481c6347dd7e0a1daed7d9c7b65 Reviewed-on: https://go-review.googlesource.com/16062 Reviewed-by: Andrew Gerrand --- http2/Dockerfile | 15 +++++++++++---- http2/http2_test.go | 21 ++++++++++++++++++++- http2/server_test.go | 40 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/http2/Dockerfile b/http2/Dockerfile index b4e14d55..53fc5257 100644 --- a/http2/Dockerfile +++ b/http2/Dockerfile @@ -17,8 +17,15 @@ RUN apt-get install -y --no-install-recommends \ libcunit1-dev libssl-dev libxml2-dev libevent-dev \ automake autoconf +# The list of packages nghttp2 recommends for h2load: +RUN apt-get install -y --no-install-recommends make binutils \ + autoconf automake autotools-dev \ + libtool pkg-config zlib1g-dev libcunit1-dev libssl-dev libxml2-dev \ + libev-dev libevent-dev libjansson-dev libjemalloc-dev \ + cython python3.4-dev python-setuptools + # Note: setting NGHTTP2_VER before the git clone, so an old git clone isn't cached: -ENV NGHTTP2_VER af24f8394e43f4 +ENV NGHTTP2_VER 895da9a RUN cd /root && git clone https://github.com/tatsuhiro-t/nghttp2.git WORKDIR /root/nghttp2 @@ -31,9 +38,9 @@ RUN make RUN make install WORKDIR /root -RUN wget http://curl.haxx.se/download/curl-7.40.0.tar.gz -RUN tar -zxvf curl-7.40.0.tar.gz -WORKDIR /root/curl-7.40.0 +RUN wget http://curl.haxx.se/download/curl-7.45.0.tar.gz +RUN tar -zxvf curl-7.45.0.tar.gz +WORKDIR /root/curl-7.45.0 RUN ./configure --with-ssl --with-nghttp2=/usr/local RUN make RUN make install diff --git a/http2/http2_test.go b/http2/http2_test.go index 29c52698..938341bc 100644 --- a/http2/http2_test.go +++ b/http2/http2_test.go @@ -91,13 +91,32 @@ func requireCurl(t *testing.T) { } func curl(t *testing.T, args ...string) (container string) { - out, err := exec.Command("docker", append([]string{"run", "-d", "--net=host", "gohttp2/curl"}, args...)...).CombinedOutput() + out, err := exec.Command("docker", append([]string{"run", "-d", "--net=host", "gohttp2/curl"}, args...)...).Output() if err != nil { t.Skipf("Failed to run curl in docker: %v, %s", err, out) } return strings.TrimSpace(string(out)) } +// Verify that h2load exists. +func requireH2load(t *testing.T) { + out, err := dockerLogs(h2load(t, "--version")) + if err != nil { + t.Skipf("failed to probe h2load; skipping test: %s", out) + } + if !strings.Contains(string(out), "h2load nghttp2/") { + t.Skipf("h2load not present; skipping test. (Output=%q)", out) + } +} + +func h2load(t *testing.T, args ...string) (container string) { + out, err := exec.Command("docker", append([]string{"run", "-d", "--net=host", "--entrypoint=/usr/local/bin/h2load", "gohttp2/curl"}, args...)...).Output() + if err != nil { + t.Skipf("Failed to run h2load in docker: %v, %s", err, out) + } + return strings.TrimSpace(string(out)) +} + type puppetCommand struct { fn func(w http.ResponseWriter, r *http.Request) done chan<- bool diff --git a/http2/server_test.go b/http2/server_test.go index ec25bc7e..ec59d257 100644 --- a/http2/server_test.go +++ b/http2/server_test.go @@ -17,6 +17,7 @@ import ( "net/http" "net/http/httptest" "os" + "os/exec" "reflect" "runtime" "strconv" @@ -2240,11 +2241,15 @@ func testServerWithCurl(t *testing.T, permitProhibitedCipherSuites bool) { if err, ok := res.(error); ok { t.Fatal(err) } - if !strings.Contains(string(res.([]byte)), "foo: Bar") { + body := string(res.([]byte)) + // Search for both "key: value" and "key:value", since curl changed their format + // Our Dockerfile contains the latest version (no space), but just in case people + // didn't rebuild, check both. + if !strings.Contains(body, "foo: Bar") && !strings.Contains(body, "foo:Bar") { t.Errorf("didn't see foo: Bar header") - t.Logf("Got: %s", res) + t.Logf("Got: %s", body) } - if !strings.Contains(string(res.([]byte)), "client-proto: HTTP/2") { + if !strings.Contains(body, "client-proto: HTTP/2") && !strings.Contains(body, "client-proto:HTTP/2") { t.Errorf("didn't see client-proto: HTTP/2 header") t.Logf("Got: %s", res) } @@ -2261,6 +2266,35 @@ func testServerWithCurl(t *testing.T, permitProhibitedCipherSuites bool) { } } +var doh2load = flag.Bool("h2load", false, "Run h2load test") + +func TestServerWithH2Load(t *testing.T) { + if !*doh2load { + t.Skip("Skipping without --h2load flag.") + } + if runtime.GOOS != "linux" { + t.Skip("skipping Docker test when not on Linux; requires --net which won't work with boot2docker anyway") + } + requireH2load(t) + + msg := strings.Repeat("Hello, h2load!\n", 5000) + ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, msg) + w.(http.Flusher).Flush() + io.WriteString(w, msg) + })) + ts.StartTLS() + defer ts.Close() + + cmd := exec.Command("docker", "run", "--net=host", "--entrypoint=/usr/local/bin/h2load", "gohttp2/curl", + "-n100000", "-c100", "-m100", ts.URL) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + t.Fatal(err) + } +} + // Issue 12843 func TestServerDoS_MaxHeaderListSize(t *testing.T) { st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {})