| // Copyright 2017 Google LLC. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package option |
| |
| import ( |
| "testing" |
| |
| "crypto/tls" |
| "math/big" |
| |
| "github.com/google/go-cmp/cmp" |
| "github.com/google/go-cmp/cmp/cmpopts" |
| "golang.org/x/oauth2/google" |
| "google.golang.org/api/internal" |
| "google.golang.org/grpc" |
| ) |
| |
| // Below is a dummy certificate/key pair taken from |
| // https://golang.org/src/crypto/tls/tls_test.go |
| const certPEM = `-----BEGIN CERTIFICATE----- |
| MIIB0zCCAX2gAwIBAgIJAI/M7BYjwB+uMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV |
| BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX |
| aWRnaXRzIFB0eSBMdGQwHhcNMTIwOTEyMjE1MjAyWhcNMTUwOTEyMjE1MjAyWjBF |
| MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 |
| ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANLJ |
| hPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wok/4xIA+ui35/MmNa |
| rtNuC+BdZ1tMuVCPFZcCAwEAAaNQME4wHQYDVR0OBBYEFJvKs8RfJaXTH08W+SGv |
| zQyKn0H8MB8GA1UdIwQYMBaAFJvKs8RfJaXTH08W+SGvzQyKn0H8MAwGA1UdEwQF |
| MAMBAf8wDQYJKoZIhvcNAQEFBQADQQBJlffJHybjDGxRMqaRmDhX0+6v02TUKZsW |
| r5QuVbpQhH6u+0UgcW0jp9QwpxoPTLTWGXEWBBBurxFwiCBhkQ+V |
| -----END CERTIFICATE----- |
| -----BEGIN PRIVATE KEY----- |
| MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo |
| k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G |
| 6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N |
| MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW |
| SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T |
| xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi |
| D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g== |
| -----END PRIVATE KEY----- |
| ` |
| |
| // Check that the slice passed into WithScopes is copied. |
| func TestCopyScopes(t *testing.T) { |
| o := &internal.DialSettings{} |
| |
| scopes := []string{"a", "b"} |
| WithScopes(scopes...).Apply(o) |
| |
| // Modify after using. |
| scopes[1] = "c" |
| |
| if o.Scopes[0] != "a" || o.Scopes[1] != "b" { |
| t.Errorf("want ['a', 'b'], got %+v", o.Scopes) |
| } |
| } |
| |
| func TestApply(t *testing.T) { |
| conn := &grpc.ClientConn{} |
| opts := []ClientOption{ |
| WithEndpoint("https://example.com:443"), |
| WithScopes("a"), // the next WithScopes should overwrite this one |
| WithScopes("https://example.com/auth/helloworld", "https://example.com/auth/otherthing"), |
| WithGRPCConn(conn), |
| WithUserAgent("ua"), |
| WithCredentialsFile("service-account.json"), |
| WithCredentialsJSON([]byte(`{some: "json"}`)), |
| WithCredentials(&google.DefaultCredentials{ProjectID: "p"}), |
| WithAPIKey("api-key"), |
| WithAudiences("https://example.com/"), |
| WithQuotaProject("user-project"), |
| WithRequestReason("Request Reason"), |
| WithTelemetryDisabled(), |
| } |
| var got internal.DialSettings |
| for _, opt := range opts { |
| opt.Apply(&got) |
| } |
| want := internal.DialSettings{ |
| Scopes: []string{"https://example.com/auth/helloworld", "https://example.com/auth/otherthing"}, |
| UserAgent: "ua", |
| Endpoint: "https://example.com:443", |
| GRPCConn: conn, |
| Credentials: &google.DefaultCredentials{ProjectID: "p"}, |
| CredentialsFile: "service-account.json", |
| CredentialsJSON: []byte(`{some: "json"}`), |
| APIKey: "api-key", |
| Audiences: []string{"https://example.com/"}, |
| QuotaProject: "user-project", |
| RequestReason: "Request Reason", |
| TelemetryDisabled: true, |
| } |
| if !cmp.Equal(got, want, cmpopts.IgnoreUnexported(grpc.ClientConn{})) { |
| t.Errorf(cmp.Diff(got, want, cmpopts.IgnoreUnexported(grpc.ClientConn{}))) |
| } |
| } |
| |
| func mockClientCertSource(info *tls.CertificateRequestInfo) (*tls.Certificate, error) { |
| cert, _ := tls.X509KeyPair([]byte(certPEM), []byte(certPEM)) |
| return &cert, nil |
| } |
| |
| func TestApplyClientCertSource(t *testing.T) { |
| opts := []ClientOption{ |
| WithClientCertSource(mockClientCertSource), |
| } |
| var got internal.DialSettings |
| for _, opt := range opts { |
| opt.Apply(&got) |
| } |
| want := internal.DialSettings{ |
| ClientCertSource: mockClientCertSource, |
| } |
| |
| // Functions cannot be compared in Golang for equality, so we will compare the output of the functions instead. |
| certGot, err := got.ClientCertSource(nil) |
| if err != nil { |
| t.Error(err) |
| } |
| certWant, err := want.ClientCertSource(nil) |
| if err != nil { |
| t.Error(err) |
| } |
| if !cmp.Equal(certGot, certWant, cmpopts.IgnoreUnexported(big.Int{}), cmpopts.IgnoreFields(tls.Certificate{}, "Leaf")) { |
| t.Errorf(cmp.Diff(certGot, certWant, cmpopts.IgnoreUnexported(big.Int{}), cmpopts.IgnoreFields(tls.Certificate{}, "Leaf"))) |
| } |
| } |