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  }