@@ -23,37 +23,27 @@ import (
2323 "strings"
2424 "testing"
2525
26- v3corepb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
2726 "github.com/google/go-cmp/cmp"
28- "google.golang.org/grpc/internal/envconfig"
29- "google.golang.org/grpc/internal/testutils"
27+ "google.golang.org/grpc/internal/grpctest"
3028 "google.golang.org/grpc/internal/xds/bootstrap"
3129 "google.golang.org/grpc/metadata"
30+
31+ v3corepb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
32+ accesstokenpb "github.com/envoyproxy/go-control-plane/envoy/extensions/grpc_service/call_credentials/access_token/v3"
3233 "google.golang.org/protobuf/types/known/anypb"
3334 "google.golang.org/protobuf/types/known/durationpb"
3435)
3536
36- const target = "dns:///my-service:443"
37+ type s struct {
38+ grpctest.Tester
39+ }
3740
38- // bootstrapConfig builds a bootstrap Config whose allowed_grpc_services is set
39- // to the provided JSON (a map from target URI to allowed service config).
40- func bootstrapConfig (t * testing.T , allowed string ) * bootstrap.Config {
41- t .Helper ()
42- contents , err := bootstrap .NewContentsForTesting (bootstrap.ConfigOptionsForTesting {
43- Servers : json .RawMessage (`[{"server_uri":"td.googleapis.com:443","channel_creds":[{"type":"insecure"}]}]` ),
44- Node : json .RawMessage (`{}` ),
45- AllowedGRPCServices : json .RawMessage (allowed ),
46- })
47- if err != nil {
48- t .Fatalf ("NewContentsForTesting() failed: %v" , err )
49- }
50- cfg , err := bootstrap .NewConfigFromContents (contents )
51- if err != nil {
52- t .Fatalf ("NewConfigFromContents() failed: %v" , err )
53- }
54- return cfg
41+ func Test (t * testing.T ) {
42+ grpctest .RunSubTests (t , s {})
5543}
5644
45+ const target = "dns:///my-service:443"
46+
5747func googleGrpcService (target string , channelPlugins []* anypb.Any , timeout * durationpb.Duration ) * v3corepb.GrpcService {
5848 return & v3corepb.GrpcService {
5949 TargetSpecifier : & v3corepb.GrpcService_GoogleGrpc_ {
@@ -66,62 +56,59 @@ func googleGrpcService(target string, channelPlugins []*anypb.Any, timeout *dura
6656 }
6757}
6858
69- func TestParse (t * testing.T ) {
70- // The allowed_grpc_services bootstrap field is parsed only when a
71- // consuming feature is enabled.
72- testutils .SetEnvConfig (t , & envconfig .XDSClientExtProcEnabled , true )
59+ func accessTokenPlugin (t * testing.T , token string ) * anypb.Any {
60+ t .Helper ()
61+ a , err := anypb .New (& accesstokenpb.AccessTokenCredentials {Token : token })
62+ if err != nil {
63+ t .Fatalf ("Failed to marshal AccessTokenCredentials: %v" , err )
64+ }
65+ return a
66+ }
7367
68+ func (s ) TestParse (t * testing.T ) {
7469 insecurePlugin := & anypb.Any {TypeUrl : insecureCredsTypeURL }
75- allowedInsecure := `{"dns:///my-service:443":{"channel_creds":[{"type":"insecure"}]}}`
7670
7771 tests := []struct {
7872 name string
7973 gs * v3corepb.GrpcService
80- trusted bool
81- config * bootstrap.Config
82- want Config
74+ want * Config
8375 wantErr string
8476 }{
8577 {
86- name : "trusted_insecure_channel_creds" ,
87- gs : googleGrpcService (target , []* anypb.Any {insecurePlugin }, nil ),
88- trusted : true ,
89- config : bootstrapConfig (t , "{}" ),
90- want : Config {TargetURI : target , ChannelCredentials : bootstrap.ChannelCreds {Type : "insecure" }},
78+ name : "insecure_channel_creds" ,
79+ gs : googleGrpcService (target , []* anypb.Any {insecurePlugin }, nil ),
80+ want : & Config {TargetURI : target , ChannelCredentials : bootstrap.ChannelCreds {Type : "insecure" }},
9181 },
9282 {
93- name : "untrusted_allowlisted_leaves_creds_empty" ,
94- gs : googleGrpcService (target , nil , nil ),
95- trusted : false ,
96- config : bootstrapConfig (t , allowedInsecure ),
97- want : Config {TargetURI : target },
83+ name : "no_channel_creds_left_empty" ,
84+ gs : googleGrpcService (target , nil , nil ),
85+ want : & Config {TargetURI : target },
9886 },
9987 {
100- name : "untrusted_not_allowlisted" ,
101- gs : googleGrpcService (target , nil , nil ),
102- trusted : false ,
103- config : bootstrapConfig (t , "{}" ),
104- wantErr : "not present in allowed_grpc_services" ,
88+ name : "unsupported_channel_creds_left_empty" ,
89+ gs : googleGrpcService (target , []* anypb.Any {{TypeUrl : "type.googleapis.com/unsupported.Credentials" }}, nil ),
90+ want : & Config {TargetURI : target },
10591 },
10692 {
10793 name : "missing_google_grpc" ,
10894 gs : & v3corepb.GrpcService {},
109- trusted : true ,
110- config : bootstrapConfig (t , "{}" ),
11195 wantErr : "only google_grpc" ,
11296 },
97+ {
98+ name : "empty_target_uri" ,
99+ gs : googleGrpcService ("" , nil , nil ),
100+ wantErr : "target_uri must be non-empty" ,
101+ },
113102 {
114103 name : "zero_timeout_rejected" ,
115104 gs : googleGrpcService (target , []* anypb.Any {insecurePlugin }, durationpb .New (0 )),
116- trusted : true ,
117- config : bootstrapConfig (t , "{}" ),
118105 wantErr : "timeout must be strictly positive" ,
119106 },
120107 }
121108
122109 for _ , test := range tests {
123110 t .Run (test .name , func (t * testing.T ) {
124- got , err := New ( test . config , test . trusted ). Parse (test .gs )
111+ got , err := Parse (test .gs )
125112 if test .wantErr != "" {
126113 if err == nil || ! strings .Contains (err .Error (), test .wantErr ) {
127114 t .Fatalf ("Parse() error = %v, want substring %q" , err , test .wantErr )
@@ -138,13 +125,32 @@ func TestParse(t *testing.T) {
138125 }
139126}
140127
141- func TestParseInitialMetadata (t * testing.T ) {
128+ func (s ) TestParseCallCredentials (t * testing.T ) {
129+ gs := googleGrpcService (target , []* anypb.Any {{TypeUrl : insecureCredsTypeURL }}, nil )
130+ gs .GetGoogleGrpc ().CallCredentialsPlugin = []* anypb.Any {accessTokenPlugin (t , "test-token" )}
131+ got , err := Parse (gs )
132+ if err != nil {
133+ t .Fatalf ("Parse() returned unexpected error: %v" , err )
134+ }
135+ want := []bootstrap.CallCredsConfig {{Type : "access_token" , Config : json .RawMessage (`{"token":"test-token"}` )}}
136+ if diff := cmp .Diff (want , got .CallCredentials ); diff != "" {
137+ t .Errorf ("Parse() CallCredentials mismatch (-want +got):\n %s" , diff )
138+ }
139+
140+ // An empty token must be rejected.
141+ gs .GetGoogleGrpc ().CallCredentialsPlugin = []* anypb.Any {accessTokenPlugin (t , "" )}
142+ if _ , err := Parse (gs ); err == nil || ! strings .Contains (err .Error (), "access token must be non-empty" ) {
143+ t .Fatalf ("Parse() error = %v, want substring %q" , err , "access token must be non-empty" )
144+ }
145+ }
146+
147+ func (s ) TestParseInitialMetadata (t * testing.T ) {
142148 gs := googleGrpcService (target , []* anypb.Any {{TypeUrl : insecureCredsTypeURL }}, nil )
143149 gs .InitialMetadata = []* v3corepb.HeaderValue {
144150 {Key : "key-b" , Value : "b" },
145151 {Key : "key-a" , Value : "legacy" , RawValue : []byte ("raw-a" )},
146152 }
147- got , err := New ( bootstrapConfig ( t , "{}" ), true ). Parse (gs )
153+ got , err := Parse (gs )
148154 if err != nil {
149155 t .Fatalf ("Parse() returned unexpected error: %v" , err )
150156 }
0 commit comments