github.com/opentelekomcloud/gophertelekomcloud@v0.9.3/acceptance/openstack/client_test.go (about) 1 package openstack 2 3 import ( 4 "fmt" 5 "net/http" 6 "os" 7 "sync" 8 "testing" 9 "time" 10 11 "github.com/opentelekomcloud/gophertelekomcloud" 12 "github.com/opentelekomcloud/gophertelekomcloud/acceptance/clients" 13 "github.com/opentelekomcloud/gophertelekomcloud/acceptance/tools" 14 "github.com/opentelekomcloud/gophertelekomcloud/openstack" 15 th "github.com/opentelekomcloud/gophertelekomcloud/testhelper" 16 fake "github.com/opentelekomcloud/gophertelekomcloud/testhelper/client" 17 ) 18 19 func TestAuthenticatedClient(t *testing.T) { 20 cc, err := clients.CloudAndClient() 21 th.AssertNoErr(t, err) 22 23 if cc.TokenID == "" { 24 t.Errorf("No token ID assigned to the client") 25 } 26 27 if cc.ProjectID == "" { 28 t.Errorf("Project ID is not set for the client") 29 } 30 if cc.UserID == "" { 31 t.Errorf("User ID is not set for the client") 32 } 33 if cc.DomainID == "" { 34 t.Errorf("Domain ID is not set for the client") 35 } 36 if cc.RegionID == "" { 37 t.Errorf("Region ID is not set for the client") 38 } 39 40 // Find the storage service in the service catalog. 41 storage, err := openstack.NewComputeV2(cc.ProviderClient, golangsdk.EndpointOpts{ 42 Region: cc.RegionName, 43 }) 44 th.AssertNoErr(t, err) 45 t.Logf("Located a compute service at endpoint: [%s]", storage.Endpoint) 46 } 47 48 func TestAuthTokenNoRegion(t *testing.T) { 49 cc, err := clients.CloudAndClient() 50 th.AssertNoErr(t, err) 51 52 envPrefix := tools.RandomString("", 5) 53 th.AssertNoErr(t, os.Setenv(envPrefix+"_TOKEN", cc.TokenID)) 54 th.AssertNoErr(t, os.Setenv(envPrefix+"_AUTH_URL", cc.IdentityEndpoint)) 55 56 env := openstack.NewEnv(envPrefix) 57 client, err := env.AuthenticatedClient() 58 th.AssertNoErr(t, err) 59 _, err = openstack.NewComputeV2(client, golangsdk.EndpointOpts{}) 60 th.AssertNoErr(t, err) 61 } 62 63 func TestReAuth(t *testing.T) { 64 cloud, err := clients.CloudAndClient() 65 th.AssertNoErr(t, err) 66 67 opts, err := openstack.AuthOptionsFromInfo(&cloud.AuthInfo, cloud.AuthType) 68 th.AssertNoErr(t, err) 69 70 ao := opts.(golangsdk.AuthOptions) 71 ao.AllowReauth = true 72 73 scl, err := openstack.AuthenticatedClient(ao) 74 th.AssertNoErr(t, err) 75 76 t.Logf("Creating a compute client") 77 _, err = openstack.NewComputeV2(scl, golangsdk.EndpointOpts{ 78 Region: cloud.RegionName, 79 }) 80 th.AssertNoErr(t, err) 81 82 t.Logf("Sleeping for 1 second") 83 time.Sleep(1 * time.Second) 84 t.Logf("Attempting to reauthenticate") 85 86 th.AssertNoErr(t, scl.ReauthFunc()) 87 88 t.Logf("Creating a compute client") 89 _, err = openstack.NewComputeV2(scl, golangsdk.EndpointOpts{ 90 Region: cloud.RegionName, 91 }) 92 th.AssertNoErr(t, err) 93 } 94 95 type failHandler struct { 96 ExpectedFailures int 97 ErrorCode int 98 FailCount int 99 mut *sync.RWMutex 100 } 101 102 func (f *failHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 103 if f.mut == nil { 104 f.mut = new(sync.RWMutex) 105 } 106 107 defer func() { _ = r.Body.Close() }() 108 if f.FailCount < f.ExpectedFailures { 109 f.mut.Lock() 110 f.FailCount += 1 111 f.mut.Unlock() 112 w.WriteHeader(f.ErrorCode) 113 } else { 114 w.WriteHeader(200) 115 } 116 } 117 118 func TestGatewayRetry(t *testing.T) { 119 th.SetupHTTP() 120 defer th.TeardownHTTP() 121 122 for _, code := range []int{http.StatusBadGateway, http.StatusGatewayTimeout} { 123 124 failHandler := &failHandler{ExpectedFailures: 1, ErrorCode: code} 125 th.Mux.Handle(fmt.Sprintf("/%d", code), failHandler) 126 127 codeURL := fmt.Sprintf("%d", code) 128 t.Run(codeURL, func(sub *testing.T) { 129 client := fake.ServiceClient() 130 _, err := client.Delete(client.ServiceURL(codeURL), &golangsdk.RequestOpts{ 131 OkCodes: []int{200}, 132 }) 133 th.AssertNoErr(sub, err) 134 th.AssertEquals(sub, failHandler.ExpectedFailures, failHandler.FailCount) 135 }) 136 } 137 } 138 139 func TestTooManyRequestsRetry(t *testing.T) { 140 th.SetupHTTP() 141 defer th.TeardownHTTP() 142 143 code := http.StatusTooManyRequests 144 retries := 2 145 timeout := 20 * time.Second 146 failHandler := &failHandler{ExpectedFailures: 1, ErrorCode: code} 147 th.Mux.Handle(fmt.Sprintf("/%d", code), failHandler) 148 149 codeURL := fmt.Sprintf("%d", code) 150 t.Run(codeURL, func(sub *testing.T) { 151 client := fake.ServiceClient() 152 client.MaxBackoffRetries = &retries 153 client.BackoffRetryTimeout = &timeout 154 155 _, err := client.Delete(client.ServiceURL(codeURL), &golangsdk.RequestOpts{ 156 OkCodes: []int{200}, 157 }) 158 th.AssertNoErr(sub, err) 159 th.AssertEquals(sub, failHandler.ExpectedFailures, failHandler.FailCount) 160 }) 161 } 162 163 func TestAuthTempAKSK(t *testing.T) { 164 securityToken := os.Getenv("OS_SECURITY_TOKEN") 165 if securityToken == "" { 166 t.Skip("OS_SECURITY_TOKEN env var is missing but client_test requires") 167 } 168 cc, err := clients.CloudAndClient() 169 th.AssertNoErr(t, err) 170 171 if cc.ProjectID == "" { 172 t.Errorf("Project ID is not set for the client") 173 } 174 if cc.AuthInfo.AuthURL == "" { 175 t.Errorf("Auth URL is not set for the client") 176 } 177 if cc.AKSKAuthOptions.AccessKey == "" { 178 t.Errorf("Access Key is not set for the client") 179 } 180 if cc.AKSKAuthOptions.SecretKey == "" { 181 t.Errorf("Secret Key is not set for the client") 182 } 183 if cc.AKSKAuthOptions.SecurityToken == "" { 184 t.Errorf("Security Token is not set for the client") 185 } 186 187 // Find several services in the service catalog. 188 storage, err := openstack.NewComputeV2(cc.ProviderClient, golangsdk.EndpointOpts{ 189 Region: cc.RegionName, 190 }) 191 th.AssertNoErr(t, err) 192 t.Logf("Located a storage service at endpoint: [%s]", storage.Endpoint) 193 194 compute, err := openstack.NewComputeV2(cc.ProviderClient, golangsdk.EndpointOpts{ 195 Region: cc.RegionName, 196 }) 197 th.AssertNoErr(t, err) 198 t.Logf("Located a compute service at endpoint: [%s]", compute.Endpoint) 199 }