aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/http2_interop
diff options
context:
space:
mode:
authorGravatar Carl Mastrangelo <notcarl@google.com>2015-10-28 11:05:49 -0700
committerGravatar Carl Mastrangelo <notcarl@google.com>2015-11-06 12:37:21 -0800
commitde4491076f861f41d1d86f6611f93f14d4536cd4 (patch)
treecef74057b35f59f770568e0072a02854d4a184d9 /tools/http2_interop
parent5cd55dd441b43e33bb3e5abeaa3dce12644e6e87 (diff)
Add HTTP/2 Interop tests to be run
Diffstat (limited to 'tools/http2_interop')
-rwxr-xr-xtools/http2_interop/http2_interop.testbin0 -> 6210464 bytes
-rw-r--r--tools/http2_interop/http2interop.go137
-rw-r--r--tools/http2_interop/http2interop_test.go95
3 files changed, 178 insertions, 54 deletions
diff --git a/tools/http2_interop/http2_interop.test b/tools/http2_interop/http2_interop.test
new file mode 100755
index 0000000000..0700763dc3
--- /dev/null
+++ b/tools/http2_interop/http2_interop.test
Binary files differ
diff --git a/tools/http2_interop/http2interop.go b/tools/http2_interop/http2interop.go
index f1bca7fe13..8585a044e5 100644
--- a/tools/http2_interop/http2interop.go
+++ b/tools/http2_interop/http2interop.go
@@ -2,15 +2,38 @@ package http2interop
import (
"crypto/tls"
+ "crypto/x509"
"fmt"
"io"
- "log"
+ "net"
+ "testing"
+ "time"
)
const (
Preface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
)
+var (
+ defaultTimeout = 1 * time.Second
+)
+
+type HTTP2InteropCtx struct {
+ // Inputs
+ ServerHost string
+ ServerPort int
+ UseTLS bool
+ UseTestCa bool
+ ServerHostnameOverride string
+
+ T *testing.T
+
+ // Derived
+ serverSpec string
+ authority string
+ rootCAs *x509.CertPool
+}
+
func parseFrame(r io.Reader) (Frame, error) {
fh := FrameHeader{}
if err := fh.Parse(r); err != nil {
@@ -49,22 +72,8 @@ func streamFrame(w io.Writer, f Frame) error {
return nil
}
-func getHttp2Conn(addr string) (*tls.Conn, error) {
- config := &tls.Config{
- InsecureSkipVerify: true,
- NextProtos: []string{"h2"},
- }
-
- conn, err := tls.Dial("tcp", addr, config)
- if err != nil {
- return nil, err
- }
-
- return conn, nil
-}
-
-func testClientShortSettings(addr string, length int) error {
- c, err := getHttp2Conn(addr)
+func testClientShortSettings(ctx *HTTP2InteropCtx, length int) error {
+ c, err := connect(ctx)
if err != nil {
return err
}
@@ -82,22 +91,22 @@ func testClientShortSettings(addr string, length int) error {
Data: make([]byte, length),
}
if err := streamFrame(c, sf); err != nil {
+ ctx.T.Log("Unable to stream frame", sf)
return err
}
for {
- frame, err := parseFrame(c)
- if err != nil {
+ if _, err := parseFrame(c); err != nil {
+ ctx.T.Log("Unable to parse frame")
return err
}
- log.Println(frame)
}
return nil
}
-func testClientPrefaceWithStreamId(addr string) error {
- c, err := getHttp2Conn(addr)
+func testClientPrefaceWithStreamId(ctx *HTTP2InteropCtx) error {
+ c, err := connect(ctx)
if err != nil {
return err
}
@@ -119,18 +128,16 @@ func testClientPrefaceWithStreamId(addr string) error {
}
for {
- frame, err := parseFrame(c)
- if err != nil {
+ if _, err := parseFrame(c); err != nil {
return err
}
- log.Println(frame)
}
return nil
}
-func testUnknownFrameType(addr string) error {
- c, err := getHttp2Conn(addr)
+func testUnknownFrameType(ctx *HTTP2InteropCtx) error {
+ c, err := connect(ctx)
if err != nil {
return err
}
@@ -143,6 +150,7 @@ func testUnknownFrameType(addr string) error {
// Send some settings, which are part of the client preface
sf := &SettingsFrame{}
if err := streamFrame(c, sf); err != nil {
+ ctx.T.Log("Unable to stream frame", sf)
return err
}
@@ -154,6 +162,7 @@ func testUnknownFrameType(addr string) error {
},
}
if err := streamFrame(c, fh); err != nil {
+ ctx.T.Log("Unable to stream frame", fh)
return err
}
}
@@ -162,12 +171,14 @@ func testUnknownFrameType(addr string) error {
Data: []byte("01234567"),
}
if err := streamFrame(c, pf); err != nil {
+ ctx.T.Log("Unable to stream frame", sf)
return err
}
for {
frame, err := parseFrame(c)
if err != nil {
+ ctx.T.Log("Unable to parse frame")
return err
}
if npf, ok := frame.(*PingFrame); !ok {
@@ -183,8 +194,8 @@ func testUnknownFrameType(addr string) error {
return nil
}
-func testShortPreface(addr string, prefacePrefix string) error {
- c, err := getHttp2Conn(addr)
+func testShortPreface(ctx *HTTP2InteropCtx, prefacePrefix string) error {
+ c, err := connect(ctx)
if err != nil {
return err
}
@@ -201,17 +212,15 @@ func testShortPreface(addr string, prefacePrefix string) error {
return err
}
-func testTLSMaxVersion(addr string, version uint16) error {
- config := &tls.Config{
- InsecureSkipVerify: true,
- NextProtos: []string{"h2"},
- MaxVersion: version,
- }
- conn, err := tls.Dial("tcp", addr, config)
+func testTLSMaxVersion(ctx *HTTP2InteropCtx, version uint16) error {
+ config := buildTlsConfig(ctx)
+ config.MaxVersion = version
+ conn, err := connectWithTls(ctx, config)
if err != nil {
return err
}
defer conn.Close()
+ conn.SetDeadline(time.Now().Add(defaultTimeout))
buf := make([]byte, 256)
if n, err := conn.Read(buf); err != nil {
@@ -223,16 +232,15 @@ func testTLSMaxVersion(addr string, version uint16) error {
return nil
}
-func testTLSApplicationProtocol(addr string) error {
- config := &tls.Config{
- InsecureSkipVerify: true,
- NextProtos: []string{"h2c"},
- }
- conn, err := tls.Dial("tcp", addr, config)
+func testTLSApplicationProtocol(ctx *HTTP2InteropCtx) error {
+ config := buildTlsConfig(ctx)
+ config.NextProtos = []string{"h2c"}
+ conn, err := connectWithTls(ctx, config)
if err != nil {
return err
}
defer conn.Close()
+ conn.SetDeadline(time.Now().Add(defaultTimeout))
buf := make([]byte, 256)
if n, err := conn.Read(buf); err != nil {
@@ -243,3 +251,48 @@ func testTLSApplicationProtocol(addr string) error {
}
return nil
}
+
+func connect(ctx *HTTP2InteropCtx) (net.Conn, error) {
+ var conn net.Conn
+ var err error
+ if !ctx.UseTLS {
+ conn, err = connectWithoutTls(ctx)
+ } else {
+ config := buildTlsConfig(ctx)
+ conn, err = connectWithTls(ctx, config)
+ }
+ if err != nil {
+ return nil, err
+ }
+ conn.SetDeadline(time.Now().Add(defaultTimeout))
+
+ return conn, nil
+}
+
+func buildTlsConfig(ctx *HTTP2InteropCtx) *tls.Config {
+ return &tls.Config{
+ RootCAs: ctx.rootCAs,
+ NextProtos: []string{"h2"},
+ ServerName: ctx.authority,
+ MinVersion: tls.VersionTLS12,
+ // TODO(carl-mastrangelo): remove this once all test certificates have been updated.
+ InsecureSkipVerify: true,
+ }
+}
+
+func connectWithoutTls(ctx *HTTP2InteropCtx) (net.Conn, error) {
+ conn, err := net.DialTimeout("tcp", ctx.serverSpec, defaultTimeout)
+ if err != nil {
+ return nil, err
+ }
+ return conn, nil
+}
+
+func connectWithTls(ctx *HTTP2InteropCtx, config *tls.Config) (*tls.Conn, error) {
+ conn, err := connectWithoutTls(ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ return tls.Client(conn, config), nil
+}
diff --git a/tools/http2_interop/http2interop_test.go b/tools/http2_interop/http2interop_test.go
index 3b687c035e..dc2960048f 100644
--- a/tools/http2_interop/http2interop_test.go
+++ b/tools/http2_interop/http2interop_test.go
@@ -2,46 +2,117 @@ package http2interop
import (
"crypto/tls"
+ "crypto/x509"
+ "strings"
"flag"
+ "fmt"
"io"
+ "io/ioutil"
"os"
+ "strconv"
"testing"
)
var (
- serverSpec = flag.String("spec", ":50051", "The server spec to test")
+ serverHost = flag.String("server_host", "", "The host to test")
+ serverPort = flag.Int("server_port", 443, "The port to test")
+ useTls = flag.Bool("use_tls", true, "Should TLS tests be run")
+ // TODO: implement
+ testCase = flag.String("test_case", "", "What test cases to run")
+
+ // The rest of these are unused, but present to fulfill the client interface
+ serverHostOverride = flag.String("server_host_override", "", "Unused")
+ useTestCa = flag.Bool("use_test_ca", false, "Unused")
+ defaultServiceAccount = flag.String("default_service_account", "", "Unused")
+ oauthScope = flag.String("oauth_scope", "", "Unused")
+ serviceAccountKeyFile = flag.String("service_account_key_file", "", "Unused")
)
+func InteropCtx(t *testing.T) *HTTP2InteropCtx {
+ ctx := &HTTP2InteropCtx{
+ ServerHost: *serverHost,
+ ServerPort: *serverPort,
+ ServerHostnameOverride: *serverHostOverride,
+ UseTLS: *useTls,
+ UseTestCa: *useTestCa,
+ T: t,
+ }
+
+ ctx.serverSpec = ctx.ServerHost
+ if ctx.ServerPort != -1 {
+ ctx.serverSpec += ":" + strconv.Itoa(ctx.ServerPort)
+ }
+ if ctx.ServerHostnameOverride == "" {
+ ctx.authority = ctx.ServerHost
+ } else {
+ ctx.authority = ctx.ServerHostnameOverride
+ }
+
+ if ctx.UseTestCa {
+ // It would be odd if useTestCa was true, but not useTls. meh
+ certData, err := ioutil.ReadFile("src/core/tsi/test_creds/ca.pem")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ ctx.rootCAs = x509.NewCertPool()
+ if !ctx.rootCAs.AppendCertsFromPEM(certData) {
+ t.Fatal(fmt.Errorf("Unable to parse pem data"))
+ }
+ }
+
+ return ctx
+}
+
+func (ctx *HTTP2InteropCtx) Close() error {
+ // currently a noop
+ return nil
+}
+
func TestShortPreface(t *testing.T) {
+ ctx := InteropCtx(t)
for i := 0; i < len(Preface)-1; i++ {
- if err := testShortPreface(*serverSpec, Preface[:i]+"X"); err != io.EOF {
+ if err := testShortPreface(ctx, Preface[:i]+"X"); err != io.EOF {
t.Error("Expected an EOF but was", err)
}
}
}
func TestUnknownFrameType(t *testing.T) {
- if err := testUnknownFrameType(*serverSpec); err != nil {
+ ctx := InteropCtx(t)
+ if err := testUnknownFrameType(ctx); err != nil {
t.Fatal(err)
}
}
func TestTLSApplicationProtocol(t *testing.T) {
- if err := testTLSApplicationProtocol(*serverSpec); err != io.EOF {
- t.Fatal("Expected an EOF but was", err)
- }
+ ctx := InteropCtx(t)
+ err := testTLSApplicationProtocol(ctx);
+ matchError(t, err, "EOF")
}
func TestTLSMaxVersion(t *testing.T) {
- if err := testTLSMaxVersion(*serverSpec, tls.VersionTLS11); err != io.EOF {
- t.Fatal("Expected an EOF but was", err)
- }
+ ctx := InteropCtx(t)
+ err := testTLSMaxVersion(ctx, tls.VersionTLS11);
+ matchError(t, err, "EOF", "server selected unsupported protocol")
}
func TestClientPrefaceWithStreamId(t *testing.T) {
- if err := testClientPrefaceWithStreamId(*serverSpec); err != io.EOF {
- t.Fatal("Expected an EOF but was", err)
- }
+ ctx := InteropCtx(t)
+ err := testClientPrefaceWithStreamId(ctx)
+ matchError(t, err, "EOF")
+}
+
+func matchError(t *testing.T, err error, matches ... string) {
+ if err == nil {
+ t.Fatal("Expected an error")
+ }
+ for _, s := range matches {
+ if strings.Contains(err.Error(), s) {
+ return
+ }
+ }
+ t.Fatalf("Error %v not in %+v", err, matches)
}
func TestMain(m *testing.M) {