github.com/aliyun/credentials-go@v1.4.7/credentials/providers/uri_test.go (about)

     1  package providers
     2  
     3  import (
     4  	"errors"
     5  	"os"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	httputil "github.com/aliyun/credentials-go/credentials/internal/http"
    11  	"github.com/aliyun/credentials-go/credentials/internal/utils"
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  func TestNewURLCredentialsProvider(t *testing.T) {
    16  	rollback := utils.Memory("ALIBABA_CLOUD_CREDENTIALS_URI")
    17  	defer func() {
    18  		rollback()
    19  	}()
    20  	// case 1: no credentials provider
    21  	_, err := NewURLCredentialsProviderBuilder().
    22  		Build()
    23  	assert.EqualError(t, err, "the url is empty")
    24  
    25  	// case 2: no role arn
    26  	os.Setenv("ALIBABA_CLOUD_CREDENTIALS_URI", "http://localhost:8080")
    27  	p, err := NewURLCredentialsProviderBuilder().
    28  		Build()
    29  	assert.Nil(t, err)
    30  	assert.True(t, strings.HasPrefix(p.url, "http://localhost:8080"))
    31  
    32  	// case 3: check default role session name
    33  	p, err = NewURLCredentialsProviderBuilder().
    34  		WithUrl("http://localhost:9090").
    35  		Build()
    36  	assert.Nil(t, err)
    37  	assert.True(t, strings.HasPrefix(p.url, "http://localhost:9090"))
    38  }
    39  
    40  func TestURLCredentialsProvider_getCredentials(t *testing.T) {
    41  	originHttpDo := httpDo
    42  	defer func() { httpDo = originHttpDo }()
    43  	p, err := NewURLCredentialsProviderBuilder().
    44  		WithUrl("http://localhost:8080").
    45  		Build()
    46  	assert.Nil(t, err)
    47  
    48  	// case 1: server error
    49  	httpDo = func(req *httputil.Request) (res *httputil.Response, err error) {
    50  		err = errors.New("mock server error")
    51  		return
    52  	}
    53  	_, err = p.getCredentials()
    54  	assert.NotNil(t, err)
    55  	assert.Equal(t, "mock server error", err.Error())
    56  
    57  	// case 2: 4xx error
    58  	httpDo = func(req *httputil.Request) (res *httputil.Response, err error) {
    59  		res = &httputil.Response{
    60  			StatusCode: 400,
    61  			Body:       []byte("4xx error"),
    62  		}
    63  		return
    64  	}
    65  
    66  	_, err = p.getCredentials()
    67  	assert.NotNil(t, err)
    68  	assert.Equal(t, "get credentials from GET http://localhost:8080 failed: 4xx error", err.Error())
    69  
    70  	// case 3: invalid json
    71  	httpDo = func(req *httputil.Request) (res *httputil.Response, err error) {
    72  		res = &httputil.Response{
    73  			StatusCode: 200,
    74  			Body:       []byte("invalid json"),
    75  		}
    76  		return
    77  	}
    78  	_, err = p.getCredentials()
    79  	assert.NotNil(t, err)
    80  	assert.Equal(t, "get credentials from GET http://localhost:8080 failed with error, json unmarshal fail: invalid character 'i' looking for beginning of value", err.Error())
    81  
    82  	// case 4: empty response json
    83  	httpDo = func(req *httputil.Request) (res *httputil.Response, err error) {
    84  		res = &httputil.Response{
    85  			StatusCode: 200,
    86  			Body:       []byte("null"),
    87  		}
    88  		return
    89  	}
    90  	_, err = p.getCredentials()
    91  	assert.NotNil(t, err)
    92  	assert.Equal(t, "refresh credentials from GET http://localhost:8080 failed: null", err.Error())
    93  
    94  	// case 5: empty session ak response json
    95  	httpDo = func(req *httputil.Request) (res *httputil.Response, err error) {
    96  		res = &httputil.Response{
    97  			StatusCode: 200,
    98  			Body:       []byte(`{}`),
    99  		}
   100  		return
   101  	}
   102  	_, err = p.getCredentials()
   103  	assert.NotNil(t, err)
   104  	assert.Equal(t, "refresh credentials from GET http://localhost:8080 failed: {}", err.Error())
   105  
   106  	// case 6: mock ok value
   107  	httpDo = func(req *httputil.Request) (res *httputil.Response, err error) {
   108  		res = &httputil.Response{
   109  			StatusCode: 200,
   110  			Body:       []byte(`{"AccessKeyId":"saki","AccessKeySecret":"saks","Expiration":"2021-10-20T04:27:09Z","SecurityToken":"token"}`),
   111  		}
   112  		return
   113  	}
   114  	creds, err := p.getCredentials()
   115  	assert.Nil(t, err)
   116  	assert.Equal(t, "saki", creds.AccessKeyId)
   117  	assert.Equal(t, "saks", creds.AccessKeySecret)
   118  	assert.Equal(t, "token", creds.SecurityToken)
   119  	assert.Equal(t, "2021-10-20T04:27:09Z", creds.Expiration)
   120  
   121  	// needUpdateCredential
   122  	assert.True(t, p.needUpdateCredential())
   123  	p.expirationTimestamp = time.Now().Unix()
   124  	assert.True(t, p.needUpdateCredential())
   125  
   126  	p.expirationTimestamp = time.Now().Unix() + 300
   127  	assert.False(t, p.needUpdateCredential())
   128  }
   129  
   130  func TestURLCredentialsProvider_GetCredentials(t *testing.T) {
   131  	originHttpDo := httpDo
   132  	defer func() { httpDo = originHttpDo }()
   133  
   134  	// case 0: get previous credentials failed
   135  	p, err := NewURLCredentialsProviderBuilder().
   136  		WithUrl("http://localhost:8080").
   137  		Build()
   138  	assert.Nil(t, err)
   139  
   140  	// case 1: get credentials failed
   141  	httpDo = func(req *httputil.Request) (res *httputil.Response, err error) {
   142  		err = errors.New("mock server error")
   143  		return
   144  	}
   145  	_, err = p.GetCredentials()
   146  	assert.NotNil(t, err)
   147  	assert.Equal(t, "mock server error", err.Error())
   148  
   149  	// case 2: get invalid expiration
   150  	httpDo = func(req *httputil.Request) (res *httputil.Response, err error) {
   151  		res = &httputil.Response{
   152  			StatusCode: 200,
   153  			Body:       []byte(`{"AccessKeyId":"akid","AccessKeySecret":"aksecret","Expiration":"invalidexpiration","SecurityToken":"ststoken"}`),
   154  		}
   155  		return
   156  	}
   157  	_, err = p.GetCredentials()
   158  	assert.NotNil(t, err)
   159  	assert.Equal(t, "parsing time \"invalidexpiration\" as \"2006-01-02T15:04:05Z\": cannot parse \"invalidexpiration\" as \"2006\"", err.Error())
   160  
   161  	// case 3: happy result
   162  	httpDo = func(req *httputil.Request) (res *httputil.Response, err error) {
   163  		res = &httputil.Response{
   164  			StatusCode: 200,
   165  			Body:       []byte(`{"AccessKeyId":"akid","AccessKeySecret":"aksecret","Expiration":"2021-10-20T04:27:09Z","SecurityToken":"ststoken"}`),
   166  		}
   167  		return
   168  	}
   169  	cc, err := p.GetCredentials()
   170  	assert.Nil(t, err)
   171  	assert.Equal(t, "akid", cc.AccessKeyId)
   172  	assert.Equal(t, "aksecret", cc.AccessKeySecret)
   173  	assert.Equal(t, "ststoken", cc.SecurityToken)
   174  	assert.Equal(t, "credential_uri", cc.ProviderName)
   175  	assert.True(t, p.needUpdateCredential())
   176  	// get credentials again
   177  	cc, err = p.GetCredentials()
   178  	assert.Nil(t, err)
   179  	assert.Equal(t, "akid", cc.AccessKeyId)
   180  	assert.Equal(t, "aksecret", cc.AccessKeySecret)
   181  	assert.Equal(t, "ststoken", cc.SecurityToken)
   182  	assert.Equal(t, "credential_uri", cc.ProviderName)
   183  	assert.True(t, p.needUpdateCredential())
   184  }
   185  
   186  func TestURLCredentialsProviderWithHttpOptions(t *testing.T) {
   187  	p, err := NewURLCredentialsProviderBuilder().
   188  		WithUrl("http://localhost:8080").
   189  		WithHttpOptions(&HttpOptions{
   190  			ConnectTimeout: 1000,
   191  			ReadTimeout:    1000,
   192  			Proxy:          "localhost:3999",
   193  		}).
   194  		Build()
   195  	assert.Nil(t, err)
   196  	_, err = p.GetCredentials()
   197  	assert.NotNil(t, err)
   198  	assert.Contains(t, err.Error(), "proxyconnect tcp:")
   199  }