xref: /aosp_15_r20/external/grpc-grpc/tools/http2_interop/http2interop_test.go (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard Worker// Copyright 2019 The gRPC Authors
2*cc02d7e2SAndroid Build Coastguard Worker//
3*cc02d7e2SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*cc02d7e2SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*cc02d7e2SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*cc02d7e2SAndroid Build Coastguard Worker//
7*cc02d7e2SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*cc02d7e2SAndroid Build Coastguard Worker//
9*cc02d7e2SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*cc02d7e2SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*cc02d7e2SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*cc02d7e2SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*cc02d7e2SAndroid Build Coastguard Worker// limitations under the License.
14*cc02d7e2SAndroid Build Coastguard Worker
15*cc02d7e2SAndroid Build Coastguard Workerpackage http2interop
16*cc02d7e2SAndroid Build Coastguard Worker
17*cc02d7e2SAndroid Build Coastguard Workerimport (
18*cc02d7e2SAndroid Build Coastguard Worker	"crypto/tls"
19*cc02d7e2SAndroid Build Coastguard Worker	"crypto/x509"
20*cc02d7e2SAndroid Build Coastguard Worker	"encoding/json"
21*cc02d7e2SAndroid Build Coastguard Worker	"flag"
22*cc02d7e2SAndroid Build Coastguard Worker	"fmt"
23*cc02d7e2SAndroid Build Coastguard Worker	"io/ioutil"
24*cc02d7e2SAndroid Build Coastguard Worker	"os"
25*cc02d7e2SAndroid Build Coastguard Worker	"strconv"
26*cc02d7e2SAndroid Build Coastguard Worker	"strings"
27*cc02d7e2SAndroid Build Coastguard Worker	"testing"
28*cc02d7e2SAndroid Build Coastguard Worker)
29*cc02d7e2SAndroid Build Coastguard Worker
30*cc02d7e2SAndroid Build Coastguard Workervar (
31*cc02d7e2SAndroid Build Coastguard Worker	serverHost = flag.String("server_host", "", "The host to test")
32*cc02d7e2SAndroid Build Coastguard Worker	serverPort = flag.Int("server_port", 443, "The port to test")
33*cc02d7e2SAndroid Build Coastguard Worker	useTls     = flag.Bool("use_tls", true, "Should TLS tests be run")
34*cc02d7e2SAndroid Build Coastguard Worker	testCase   = flag.String("test_case", "", "What test cases to run (tls, framing)")
35*cc02d7e2SAndroid Build Coastguard Worker
36*cc02d7e2SAndroid Build Coastguard Worker	// The rest of these are unused, but present to fulfill the client interface
37*cc02d7e2SAndroid Build Coastguard Worker	serverHostOverride    = flag.String("server_host_override", "", "Unused")
38*cc02d7e2SAndroid Build Coastguard Worker	useTestCa             = flag.Bool("use_test_ca", false, "Unused")
39*cc02d7e2SAndroid Build Coastguard Worker	defaultServiceAccount = flag.String("default_service_account", "", "Unused")
40*cc02d7e2SAndroid Build Coastguard Worker	oauthScope            = flag.String("oauth_scope", "", "Unused")
41*cc02d7e2SAndroid Build Coastguard Worker	serviceAccountKeyFile = flag.String("service_account_key_file", "", "Unused")
42*cc02d7e2SAndroid Build Coastguard Worker)
43*cc02d7e2SAndroid Build Coastguard Worker
44*cc02d7e2SAndroid Build Coastguard Workerfunc InteropCtx(t *testing.T) *HTTP2InteropCtx {
45*cc02d7e2SAndroid Build Coastguard Worker	ctx := &HTTP2InteropCtx{
46*cc02d7e2SAndroid Build Coastguard Worker		ServerHost:             *serverHost,
47*cc02d7e2SAndroid Build Coastguard Worker		ServerPort:             *serverPort,
48*cc02d7e2SAndroid Build Coastguard Worker		ServerHostnameOverride: *serverHostOverride,
49*cc02d7e2SAndroid Build Coastguard Worker		UseTLS:                 *useTls,
50*cc02d7e2SAndroid Build Coastguard Worker		UseTestCa:              *useTestCa,
51*cc02d7e2SAndroid Build Coastguard Worker		T:                      t,
52*cc02d7e2SAndroid Build Coastguard Worker	}
53*cc02d7e2SAndroid Build Coastguard Worker
54*cc02d7e2SAndroid Build Coastguard Worker	ctx.serverSpec = ctx.ServerHost
55*cc02d7e2SAndroid Build Coastguard Worker	if ctx.ServerPort != -1 {
56*cc02d7e2SAndroid Build Coastguard Worker		ctx.serverSpec += ":" + strconv.Itoa(ctx.ServerPort)
57*cc02d7e2SAndroid Build Coastguard Worker	}
58*cc02d7e2SAndroid Build Coastguard Worker	if ctx.ServerHostnameOverride == "" {
59*cc02d7e2SAndroid Build Coastguard Worker		ctx.authority = ctx.ServerHost
60*cc02d7e2SAndroid Build Coastguard Worker	} else {
61*cc02d7e2SAndroid Build Coastguard Worker		ctx.authority = ctx.ServerHostnameOverride
62*cc02d7e2SAndroid Build Coastguard Worker	}
63*cc02d7e2SAndroid Build Coastguard Worker
64*cc02d7e2SAndroid Build Coastguard Worker	if ctx.UseTestCa {
65*cc02d7e2SAndroid Build Coastguard Worker		// It would be odd if useTestCa was true, but not useTls.  meh
66*cc02d7e2SAndroid Build Coastguard Worker		certData, err := ioutil.ReadFile("src/core/tsi/test_creds/ca.pem")
67*cc02d7e2SAndroid Build Coastguard Worker		if err != nil {
68*cc02d7e2SAndroid Build Coastguard Worker			t.Fatal(err)
69*cc02d7e2SAndroid Build Coastguard Worker		}
70*cc02d7e2SAndroid Build Coastguard Worker
71*cc02d7e2SAndroid Build Coastguard Worker		ctx.rootCAs = x509.NewCertPool()
72*cc02d7e2SAndroid Build Coastguard Worker		if !ctx.rootCAs.AppendCertsFromPEM(certData) {
73*cc02d7e2SAndroid Build Coastguard Worker			t.Fatal(fmt.Errorf("Unable to parse pem data"))
74*cc02d7e2SAndroid Build Coastguard Worker		}
75*cc02d7e2SAndroid Build Coastguard Worker	}
76*cc02d7e2SAndroid Build Coastguard Worker
77*cc02d7e2SAndroid Build Coastguard Worker	return ctx
78*cc02d7e2SAndroid Build Coastguard Worker}
79*cc02d7e2SAndroid Build Coastguard Worker
80*cc02d7e2SAndroid Build Coastguard Workerfunc (ctx *HTTP2InteropCtx) Close() error {
81*cc02d7e2SAndroid Build Coastguard Worker	// currently a noop
82*cc02d7e2SAndroid Build Coastguard Worker	return nil
83*cc02d7e2SAndroid Build Coastguard Worker}
84*cc02d7e2SAndroid Build Coastguard Worker
85*cc02d7e2SAndroid Build Coastguard Workerfunc TestSoonClientShortSettings(t *testing.T) {
86*cc02d7e2SAndroid Build Coastguard Worker	defer Report(t)
87*cc02d7e2SAndroid Build Coastguard Worker	if *testCase != "framing" {
88*cc02d7e2SAndroid Build Coastguard Worker		t.SkipNow()
89*cc02d7e2SAndroid Build Coastguard Worker	}
90*cc02d7e2SAndroid Build Coastguard Worker	ctx := InteropCtx(t)
91*cc02d7e2SAndroid Build Coastguard Worker	for i := 1; i <= 5; i++ {
92*cc02d7e2SAndroid Build Coastguard Worker		err := testClientShortSettings(ctx, i)
93*cc02d7e2SAndroid Build Coastguard Worker		matchError(t, err, "EOF")
94*cc02d7e2SAndroid Build Coastguard Worker	}
95*cc02d7e2SAndroid Build Coastguard Worker}
96*cc02d7e2SAndroid Build Coastguard Worker
97*cc02d7e2SAndroid Build Coastguard Workerfunc TestSoonShortPreface(t *testing.T) {
98*cc02d7e2SAndroid Build Coastguard Worker	defer Report(t)
99*cc02d7e2SAndroid Build Coastguard Worker	if *testCase != "framing" {
100*cc02d7e2SAndroid Build Coastguard Worker		t.SkipNow()
101*cc02d7e2SAndroid Build Coastguard Worker	}
102*cc02d7e2SAndroid Build Coastguard Worker	ctx := InteropCtx(t)
103*cc02d7e2SAndroid Build Coastguard Worker	for i := 0; i < len(Preface)-1; i++ {
104*cc02d7e2SAndroid Build Coastguard Worker		err := testShortPreface(ctx, Preface[:i]+"X")
105*cc02d7e2SAndroid Build Coastguard Worker		matchError(t, err, "EOF")
106*cc02d7e2SAndroid Build Coastguard Worker	}
107*cc02d7e2SAndroid Build Coastguard Worker}
108*cc02d7e2SAndroid Build Coastguard Worker
109*cc02d7e2SAndroid Build Coastguard Workerfunc TestSoonUnknownFrameType(t *testing.T) {
110*cc02d7e2SAndroid Build Coastguard Worker	defer Report(t)
111*cc02d7e2SAndroid Build Coastguard Worker	if *testCase != "framing" {
112*cc02d7e2SAndroid Build Coastguard Worker		t.SkipNow()
113*cc02d7e2SAndroid Build Coastguard Worker	}
114*cc02d7e2SAndroid Build Coastguard Worker	ctx := InteropCtx(t)
115*cc02d7e2SAndroid Build Coastguard Worker	if err := testUnknownFrameType(ctx); err != nil {
116*cc02d7e2SAndroid Build Coastguard Worker		t.Fatal(err)
117*cc02d7e2SAndroid Build Coastguard Worker	}
118*cc02d7e2SAndroid Build Coastguard Worker}
119*cc02d7e2SAndroid Build Coastguard Worker
120*cc02d7e2SAndroid Build Coastguard Workerfunc TestSoonClientPrefaceWithStreamId(t *testing.T) {
121*cc02d7e2SAndroid Build Coastguard Worker	defer Report(t)
122*cc02d7e2SAndroid Build Coastguard Worker	if *testCase != "framing" {
123*cc02d7e2SAndroid Build Coastguard Worker		t.SkipNow()
124*cc02d7e2SAndroid Build Coastguard Worker	}
125*cc02d7e2SAndroid Build Coastguard Worker	ctx := InteropCtx(t)
126*cc02d7e2SAndroid Build Coastguard Worker	err := testClientPrefaceWithStreamId(ctx)
127*cc02d7e2SAndroid Build Coastguard Worker	matchError(t, err, "EOF")
128*cc02d7e2SAndroid Build Coastguard Worker}
129*cc02d7e2SAndroid Build Coastguard Worker
130*cc02d7e2SAndroid Build Coastguard Workerfunc TestSoonTLSApplicationProtocol(t *testing.T) {
131*cc02d7e2SAndroid Build Coastguard Worker	defer Report(t)
132*cc02d7e2SAndroid Build Coastguard Worker	if *testCase != "tls" {
133*cc02d7e2SAndroid Build Coastguard Worker		t.SkipNow()
134*cc02d7e2SAndroid Build Coastguard Worker	}
135*cc02d7e2SAndroid Build Coastguard Worker	ctx := InteropCtx(t)
136*cc02d7e2SAndroid Build Coastguard Worker	err := testTLSApplicationProtocol(ctx)
137*cc02d7e2SAndroid Build Coastguard Worker	matchError(t, err, "EOF", "broken pipe")
138*cc02d7e2SAndroid Build Coastguard Worker}
139*cc02d7e2SAndroid Build Coastguard Worker
140*cc02d7e2SAndroid Build Coastguard Workerfunc TestSoonTLSMaxVersion(t *testing.T) {
141*cc02d7e2SAndroid Build Coastguard Worker	defer Report(t)
142*cc02d7e2SAndroid Build Coastguard Worker	if *testCase != "tls" {
143*cc02d7e2SAndroid Build Coastguard Worker		t.SkipNow()
144*cc02d7e2SAndroid Build Coastguard Worker	}
145*cc02d7e2SAndroid Build Coastguard Worker	ctx := InteropCtx(t)
146*cc02d7e2SAndroid Build Coastguard Worker	err := testTLSMaxVersion(ctx, tls.VersionTLS11)
147*cc02d7e2SAndroid Build Coastguard Worker	// TODO(carl-mastrangelo): maybe this should be some other error.  If the server picks
148*cc02d7e2SAndroid Build Coastguard Worker	// the wrong protocol version, that's bad too.
149*cc02d7e2SAndroid Build Coastguard Worker	matchError(t, err, "EOF", "server selected unsupported protocol")
150*cc02d7e2SAndroid Build Coastguard Worker}
151*cc02d7e2SAndroid Build Coastguard Worker
152*cc02d7e2SAndroid Build Coastguard Workerfunc TestSoonTLSBadCipherSuites(t *testing.T) {
153*cc02d7e2SAndroid Build Coastguard Worker	defer Report(t)
154*cc02d7e2SAndroid Build Coastguard Worker	if *testCase != "tls" {
155*cc02d7e2SAndroid Build Coastguard Worker		t.SkipNow()
156*cc02d7e2SAndroid Build Coastguard Worker	}
157*cc02d7e2SAndroid Build Coastguard Worker	ctx := InteropCtx(t)
158*cc02d7e2SAndroid Build Coastguard Worker	err := testTLSBadCipherSuites(ctx)
159*cc02d7e2SAndroid Build Coastguard Worker	matchError(t, err, "EOF", "Got goaway frame")
160*cc02d7e2SAndroid Build Coastguard Worker}
161*cc02d7e2SAndroid Build Coastguard Worker
162*cc02d7e2SAndroid Build Coastguard Workerfunc matchError(t *testing.T, err error, matches ...string) {
163*cc02d7e2SAndroid Build Coastguard Worker	if err == nil {
164*cc02d7e2SAndroid Build Coastguard Worker		t.Fatal("Expected an error")
165*cc02d7e2SAndroid Build Coastguard Worker	}
166*cc02d7e2SAndroid Build Coastguard Worker	for _, s := range matches {
167*cc02d7e2SAndroid Build Coastguard Worker		if strings.Contains(err.Error(), s) {
168*cc02d7e2SAndroid Build Coastguard Worker			return
169*cc02d7e2SAndroid Build Coastguard Worker		}
170*cc02d7e2SAndroid Build Coastguard Worker	}
171*cc02d7e2SAndroid Build Coastguard Worker	t.Fatalf("Error %v not in %+v", err, matches)
172*cc02d7e2SAndroid Build Coastguard Worker}
173*cc02d7e2SAndroid Build Coastguard Worker
174*cc02d7e2SAndroid Build Coastguard Workerfunc TestMain(m *testing.M) {
175*cc02d7e2SAndroid Build Coastguard Worker	flag.Parse()
176*cc02d7e2SAndroid Build Coastguard Worker	m.Run()
177*cc02d7e2SAndroid Build Coastguard Worker	var fatal bool
178*cc02d7e2SAndroid Build Coastguard Worker	var any bool
179*cc02d7e2SAndroid Build Coastguard Worker	for _, ci := range allCaseInfos.Cases {
180*cc02d7e2SAndroid Build Coastguard Worker		if ci.Skipped {
181*cc02d7e2SAndroid Build Coastguard Worker			continue
182*cc02d7e2SAndroid Build Coastguard Worker		}
183*cc02d7e2SAndroid Build Coastguard Worker		any = true
184*cc02d7e2SAndroid Build Coastguard Worker		if !ci.Passed && ci.Fatal {
185*cc02d7e2SAndroid Build Coastguard Worker			fatal = true
186*cc02d7e2SAndroid Build Coastguard Worker		}
187*cc02d7e2SAndroid Build Coastguard Worker	}
188*cc02d7e2SAndroid Build Coastguard Worker
189*cc02d7e2SAndroid Build Coastguard Worker	if err := json.NewEncoder(os.Stderr).Encode(&allCaseInfos); err != nil {
190*cc02d7e2SAndroid Build Coastguard Worker		fmt.Println("Failed to encode", err)
191*cc02d7e2SAndroid Build Coastguard Worker	}
192*cc02d7e2SAndroid Build Coastguard Worker	var code int
193*cc02d7e2SAndroid Build Coastguard Worker	if !any || fatal {
194*cc02d7e2SAndroid Build Coastguard Worker		code = 1
195*cc02d7e2SAndroid Build Coastguard Worker	}
196*cc02d7e2SAndroid Build Coastguard Worker	os.Exit(code)
197*cc02d7e2SAndroid Build Coastguard Worker}
198