gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/grpc/credentials/tls/certprovider/distributor_test.go (about) 1 /* 2 * 3 * Copyright 2020 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package certprovider 20 21 import ( 22 "context" 23 "errors" 24 "testing" 25 "time" 26 ) 27 28 var errProviderTestInternal = errors.New("provider internal error") 29 30 // TestDistributorEmpty tries to read key material from an empty distributor and 31 // expects the call to timeout. 32 func (s) TestDistributorEmpty(t *testing.T) { 33 dist := NewDistributor() 34 35 // This call to KeyMaterial() should timeout because no key material has 36 // been set on the distributor as yet. 37 ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) 38 defer cancel() 39 if err := readAndVerifyKeyMaterial(ctx, dist, nil); !errors.Is(err, context.DeadlineExceeded) { 40 t.Fatal(err) 41 } 42 } 43 44 // TestDistributor invokes the different methods on the Distributor type and 45 // verifies the results. 46 func (s) TestDistributor(t *testing.T) { 47 dist := NewDistributor() 48 49 // Read cert/key files from testdata. 50 km1 := loadKeyMaterials(t, "x509/server1_cert.pem", "x509/server1_key.pem", "x509/client_ca_cert.pem") 51 km2 := loadKeyMaterials(t, "x509/server2_cert.pem", "x509/server2_key.pem", "x509/client_ca_cert.pem") 52 53 // Push key material into the distributor and make sure that a call to 54 // KeyMaterial() returns the expected key material, with both the local 55 // certs and root certs. 56 dist.Set(km1, nil) 57 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 58 defer cancel() 59 if err := readAndVerifyKeyMaterial(ctx, dist, km1); err != nil { 60 t.Fatal(err) 61 } 62 63 // Push new key material into the distributor and make sure that a call to 64 // KeyMaterial() returns the expected key material, with only root certs. 65 dist.Set(km2, nil) 66 if err := readAndVerifyKeyMaterial(ctx, dist, km2); err != nil { 67 t.Fatal(err) 68 } 69 70 // Push an error into the distributor and make sure that a call to 71 // KeyMaterial() returns that error and nil keyMaterial. 72 dist.Set(km2, errProviderTestInternal) 73 if gotKM, err := dist.KeyMaterial(ctx); gotKM != nil || !errors.Is(err, errProviderTestInternal) { 74 t.Fatalf("KeyMaterial() = {%v, %v}, want {nil, %v}", gotKM, err, errProviderTestInternal) 75 } 76 77 // Stop the distributor and KeyMaterial() should return errProviderClosed. 78 dist.Stop() 79 if km, err := dist.KeyMaterial(ctx); !errors.Is(err, errProviderClosed) { 80 t.Fatalf("KeyMaterial() = {%v, %v}, want {nil, %v}", km, err, errProviderClosed) 81 } 82 } 83 84 // TestDistributorConcurrency invokes methods on the distributor in parallel. It 85 // exercises that the scenario where a distributor's KeyMaterial() method is 86 // blocked waiting for keyMaterial, while the Set() method is called from 87 // another goroutine. It verifies that the KeyMaterial() method eventually 88 // returns with expected keyMaterial. 89 func (s) TestDistributorConcurrency(t *testing.T) { 90 dist := NewDistributor() 91 92 // Read cert/key files from testdata. 93 km := loadKeyMaterials(t, "x509/server1_cert.pem", "x509/server1_key.pem", "x509/client_ca_cert.pem") 94 95 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 96 defer cancel() 97 98 // Push key material into the distributor from a goroutine and read from 99 // here to verify that the distributor returns the expected keyMaterial. 100 go func() { 101 // Add a small sleep here to make sure that the call to KeyMaterial() 102 // happens before the call to Set(), thereby the former is blocked till 103 // the latter happens. 104 time.Sleep(100 * time.Microsecond) 105 dist.Set(km, nil) 106 }() 107 if err := readAndVerifyKeyMaterial(ctx, dist, km); err != nil { 108 t.Fatal(err) 109 } 110 }