// Copyright 2014 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // See https://code.google.com/p/go/source/browse/CONTRIBUTORS // Licensed under the same terms as Go itself: // https://code.google.com/p/go/source/browse/LICENSE package http2 import ( "errors" "fmt" "io" "net/http" "net/http/httptest" "os/exec" "strconv" "strings" "sync/atomic" "testing" "time" ) func TestServer(t *testing.T) { requireCurl(t) ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "Hello, test.") })) ConfigureServer(ts.Config, &Server{}) ts.TLS = ts.Config.TLSConfig // the httptest.Server has its own copy of this TLS config ts.StartTLS() defer ts.Close() var gotConn int32 testHookOnConn = func() { atomic.StoreInt32(&gotConn, 1) } t.Logf("Running test server for curl to hit at: %s", ts.URL) container := curl(t, "--silent", "--http2", "--insecure", "-v", ts.URL) defer kill(container) resc := make(chan interface{}, 1) go func() { res, err := dockerLogs(container) if err != nil { resc <- err } else { resc <- res } }() select { case res := <-resc: if err, ok := res.(error); ok { t.Fatal(err) } t.Logf("Got: %s", res) case <-time.After(3 * time.Second): t.Errorf("timeout waiting for curl") } if atomic.LoadInt32(&gotConn) == 0 { t.Error("never saw an http2 connection") } } func dockerLogs(container string) ([]byte, error) { out, err := exec.Command("docker", "wait", container).CombinedOutput() if err != nil { return out, err } exitStatus, err := strconv.Atoi(strings.TrimSpace(string(out))) if err != nil { return out, errors.New("unexpected exit status from docker wait") } out, err = exec.Command("docker", "logs", container).CombinedOutput() exec.Command("docker", "rm", container).Run() if err == nil && exitStatus != 0 { err = fmt.Errorf("exit status %d", exitStatus) } return out, err } func kill(container string) { exec.Command("docker", "kill", container).Run() exec.Command("docker", "rm", container).Run() } // Verify that curl has http2. func requireCurl(t *testing.T) { out, err := dockerLogs(curl(t, "--version")) if err != nil { t.Skipf("failed to determine curl features; skipping test") } if !strings.Contains(string(out), "HTTP2") { t.Skip("curl doesn't support HTTP2; skipping test") } } func curl(t *testing.T, args ...string) (container string) { out, err := exec.Command("docker", append([]string{"run", "-d", "--net=host", "gohttp2/curl"}, args...)...).CombinedOutput() if err != nil { t.Fatalf("Failed to run curl in docker: %v, %s", err, out) } return strings.TrimSpace(string(out)) }