...

Source file src/github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api/client_test.go

Documentation: github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api

     1  // Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"). You may
     4  // not use this file except in compliance with the License. A copy of the
     5  // License is located at
     6  //
     7  //	http://aws.amazon.com/apache2.0/
     8  //
     9  // or in the "license" file accompanying this file. This file is distributed
    10  // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
    11  // express or implied. See the License for the specific language governing
    12  // permissions and limitations under the License.
    13  
    14  package api
    15  
    16  import (
    17  	"encoding/base64"
    18  	"errors"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/aws/aws-sdk-go-v2/aws"
    23  	"github.com/aws/aws-sdk-go-v2/service/ecr"
    24  	ecrtypes "github.com/aws/aws-sdk-go-v2/service/ecr/types"
    25  	"github.com/aws/aws-sdk-go-v2/service/ecrpublic"
    26  	ecrpublictypes "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types"
    27  	mock_api "github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api/mocks"
    28  	"github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cache"
    29  	mock_cache "github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cache/mocks"
    30  	"github.com/stretchr/testify/assert"
    31  )
    32  
    33  const (
    34  	registryID       = "123456789012"
    35  	proxyEndpoint    = "123456789012.dkr.ecr.us-east-1.amazonaws.com"
    36  	expectedUsername = "username"
    37  	expectedPassword = "password"
    38  )
    39  
    40  func TestExtractRegistry(t *testing.T) {
    41  	testCases := []struct {
    42  		serverURL string
    43  		registry  *Registry
    44  		hasError  bool
    45  	}{{
    46  		serverURL: "https://123456789012.dkr.ecr.us-east-1.amazonaws.com/v2/blah/blah",
    47  		registry: &Registry{
    48  			ID:      "123456789012",
    49  			FIPS:    false,
    50  			Region:  "us-east-1",
    51  			Service: ServiceECR,
    52  		},
    53  		hasError: false,
    54  	}, {
    55  		serverURL: "123456789012.dkr.ecr.us-west-2.amazonaws.com",
    56  		registry: &Registry{
    57  			ID:      "123456789012",
    58  			FIPS:    false,
    59  			Region:  "us-west-2",
    60  			Service: ServiceECR,
    61  		},
    62  		hasError: false,
    63  	}, {
    64  		serverURL: "210987654321.dkr.ecr.cn-north-1.amazonaws.com.cn/foo",
    65  		registry: &Registry{
    66  			ID:      "210987654321",
    67  			FIPS:    false,
    68  			Region:  "cn-north-1",
    69  			Service: ServiceECR,
    70  		},
    71  		hasError: false,
    72  	}, {
    73  		serverURL: "123456789012.dkr.ecr-fips.us-gov-west-1.amazonaws.com",
    74  		registry: &Registry{
    75  			ID:      "123456789012",
    76  			FIPS:    true,
    77  			Region:  "us-gov-west-1",
    78  			Service: ServiceECR,
    79  		},
    80  		hasError: false,
    81  	}, {
    82  		serverURL: "https://public.ecr.aws",
    83  		registry: &Registry{
    84  			Service: ServiceECRPublic,
    85  		},
    86  	}, {
    87  		serverURL: "public.ecr.aws",
    88  		registry: &Registry{
    89  			Service: ServiceECRPublic,
    90  		},
    91  	}, {
    92  		serverURL: "https://public.ecr.aws/amazonlinux",
    93  		registry: &Registry{
    94  			Service: ServiceECRPublic,
    95  		},
    96  	}, {
    97  		serverURL: ".dkr.ecr.not-real.amazonaws.com",
    98  		hasError:  true,
    99  	}, {
   100  		serverURL: "not.ecr.io",
   101  		hasError:  true,
   102  	}, {
   103  		serverURL: "https://123456789012.dkr.ecr.us-west-2.amazonaws.com.fake.example.com/image:latest",
   104  		hasError:  true,
   105  	}, {
   106  		serverURL: "123456789012.dkr.ecr.us-west-2.amazonaws.com.fake.example.com",
   107  		hasError:  true,
   108  	}, {
   109  		serverURL: "123456789012.dkr.ecr-fips.us-gov-west-1.amazonaws.com.fake.example.com",
   110  		hasError:  true,
   111  	}, {
   112  		serverURL: "210987654321.dkr.ecr.cn-north-1.amazonaws.com.cn.fake.example.com.cn",
   113  		hasError:  true,
   114  	}, {
   115  		serverURL: "https://public.ecr.aws.fake.example.com",
   116  		hasError:  true,
   117  	}, {
   118  		serverURL: "public.ecr.aws.fake.example.com",
   119  		hasError:  true,
   120  	}}
   121  	for _, tc := range testCases {
   122  		t.Run(tc.serverURL, func(t *testing.T) {
   123  			registry, err := ExtractRegistry(tc.serverURL)
   124  			if !tc.hasError {
   125  				assert.NoError(t, err, "No error expected")
   126  				assert.EqualValues(t, tc.registry, registry, "Registry should be equal")
   127  			} else {
   128  				assert.Error(t, err, "Expected error")
   129  			}
   130  		})
   131  	}
   132  }
   133  
   134  func TestGetAuthConfigSuccess(t *testing.T) {
   135  	ecrClient := &mock_api.MockECRAPI{}
   136  	credentialCache := &mock_cache.MockCredentialsCache{}
   137  
   138  	client := &defaultClient{
   139  		ecrClient:       ecrClient,
   140  		credentialCache: credentialCache,
   141  	}
   142  
   143  	testProxyEndpoint := proxyEndpointScheme + proxyEndpoint
   144  	authorizationToken := base64.StdEncoding.EncodeToString([]byte(expectedUsername + ":" + expectedPassword))
   145  	expiresAt := time.Now().Add(12 * time.Hour)
   146  
   147  	ecrClient.GetAuthorizationTokenFn = func(input *ecr.GetAuthorizationTokenInput) (*ecr.GetAuthorizationTokenOutput, error) {
   148  		assert.NotNil(t, input, "GetAuthorizationToken input")
   149  		assert.Len(t, input.RegistryIds, 1, "GetAuthorizationToken registry IDs len")
   150  		return &ecr.GetAuthorizationTokenOutput{
   151  			AuthorizationData: []ecrtypes.AuthorizationData{{
   152  				ProxyEndpoint:      aws.String(testProxyEndpoint),
   153  				ExpiresAt:          aws.Time(expiresAt),
   154  				AuthorizationToken: aws.String(authorizationToken),
   155  			}},
   156  		}, nil
   157  	}
   158  
   159  	authEntry := &cache.AuthEntry{
   160  		ProxyEndpoint:      testProxyEndpoint,
   161  		RequestedAt:        time.Now(),
   162  		ExpiresAt:          expiresAt,
   163  		AuthorizationToken: authorizationToken,
   164  	}
   165  
   166  	credentialCache.GetFn = func(_ string) *cache.AuthEntry { return nil }
   167  	credentialCache.SetFn = func(_ string, actual *cache.AuthEntry) {
   168  		compareAuthEntry(t, actual, authEntry)
   169  	}
   170  
   171  	auth, err := client.GetCredentials(proxyEndpoint)
   172  	assert.Nil(t, err)
   173  	assert.Equal(t, auth.Username, expectedUsername)
   174  	assert.Equal(t, auth.Password, expectedPassword)
   175  	assert.Equal(t, auth.ProxyEndpoint, testProxyEndpoint)
   176  }
   177  
   178  func TestGetAuthConfigNoMatchAuthorizationToken(t *testing.T) {
   179  	ecrClient := &mock_api.MockECRAPI{}
   180  	credentialCache := &mock_cache.MockCredentialsCache{}
   181  
   182  	client := &defaultClient{
   183  		ecrClient:       ecrClient,
   184  		credentialCache: credentialCache,
   185  	}
   186  
   187  	ecrClient.GetAuthorizationTokenFn = func(input *ecr.GetAuthorizationTokenInput) (*ecr.GetAuthorizationTokenOutput, error) {
   188  		assert.NotNil(t, input, "GetAuthorizationToken input")
   189  		assert.Len(t, input.RegistryIds, 1, "GetAuthorizationToken registry IDs len")
   190  		return &ecr.GetAuthorizationTokenOutput{
   191  			AuthorizationData: []ecrtypes.AuthorizationData{{
   192  				ProxyEndpoint:      aws.String(proxyEndpointScheme + "notproxy"),
   193  				AuthorizationToken: aws.String(base64.StdEncoding.EncodeToString([]byte(expectedUsername + ":" + expectedPassword))),
   194  			}},
   195  		}, nil
   196  	}
   197  
   198  	credentialCache.GetFn = func(_ string) *cache.AuthEntry { return nil }
   199  
   200  	auth, err := client.GetCredentials(proxyEndpoint)
   201  	assert.NotNil(t, err)
   202  	assert.Nil(t, auth)
   203  }
   204  
   205  func TestGetAuthConfigGetCacheSuccess(t *testing.T) {
   206  	ecrClient := &mock_api.MockECRAPI{}
   207  	credentialCache := &mock_cache.MockCredentialsCache{}
   208  
   209  	client := &defaultClient{
   210  		ecrClient:       ecrClient,
   211  		credentialCache: credentialCache,
   212  	}
   213  
   214  	testProxyEndpoint := proxyEndpointScheme + proxyEndpoint
   215  	authorizationToken := base64.StdEncoding.EncodeToString([]byte(expectedUsername + ":" + expectedPassword))
   216  	expiresAt := time.Now().Add(12 * time.Hour)
   217  
   218  	authEntry := &cache.AuthEntry{
   219  		ProxyEndpoint:      testProxyEndpoint,
   220  		ExpiresAt:          expiresAt,
   221  		RequestedAt:        time.Now(),
   222  		AuthorizationToken: authorizationToken,
   223  	}
   224  	credentialCache.GetFn = func(r string) *cache.AuthEntry {
   225  		assert.Equal(t, registryID, r, "get from cache")
   226  		return authEntry
   227  	}
   228  
   229  	auth, err := client.GetCredentials(proxyEndpoint)
   230  	assert.Nil(t, err)
   231  	assert.Equal(t, auth.Username, expectedUsername)
   232  	assert.Equal(t, auth.Password, expectedPassword)
   233  	assert.Equal(t, auth.ProxyEndpoint, testProxyEndpoint)
   234  }
   235  
   236  func TestGetAuthConfigSuccessInvalidCacheHit(t *testing.T) {
   237  	ecrClient := &mock_api.MockECRAPI{}
   238  	credentialCache := &mock_cache.MockCredentialsCache{}
   239  
   240  	client := &defaultClient{
   241  		ecrClient:       ecrClient,
   242  		credentialCache: credentialCache,
   243  	}
   244  
   245  	testProxyEndpoint := proxyEndpointScheme + proxyEndpoint
   246  	authorizationToken := base64.StdEncoding.EncodeToString([]byte(expectedUsername + ":" + expectedPassword))
   247  	expiresAt := time.Now().Add(12 * time.Hour)
   248  
   249  	ecrClient.GetAuthorizationTokenFn = func(input *ecr.GetAuthorizationTokenInput) (*ecr.GetAuthorizationTokenOutput, error) {
   250  		assert.NotNil(t, input, "GetAuthorizationToken input")
   251  		assert.Len(t, input.RegistryIds, 1, "GetAuthorizationToken registry IDs len")
   252  		return &ecr.GetAuthorizationTokenOutput{
   253  			AuthorizationData: []ecrtypes.AuthorizationData{{
   254  				ProxyEndpoint:      aws.String(testProxyEndpoint),
   255  				ExpiresAt:          aws.Time(expiresAt),
   256  				AuthorizationToken: aws.String(authorizationToken),
   257  			}},
   258  		}, nil
   259  	}
   260  
   261  	expiredAuthEntry := &cache.AuthEntry{
   262  		ProxyEndpoint:      testProxyEndpoint,
   263  		RequestedAt:        time.Now().Add(-12 * time.Hour),
   264  		ExpiresAt:          time.Now().Add(-6 * time.Hour),
   265  		AuthorizationToken: authorizationToken,
   266  	}
   267  
   268  	authEntry := &cache.AuthEntry{
   269  		ProxyEndpoint:      testProxyEndpoint,
   270  		RequestedAt:        time.Now(),
   271  		ExpiresAt:          expiresAt,
   272  		AuthorizationToken: authorizationToken,
   273  	}
   274  
   275  	credentialCache.GetFn = func(r string) *cache.AuthEntry {
   276  		assert.Equal(t, registryID, r, "get from cache")
   277  		return expiredAuthEntry
   278  	}
   279  	credentialCache.SetFn = func(_ string, actual *cache.AuthEntry) {
   280  		compareAuthEntry(t, actual, authEntry)
   281  	}
   282  
   283  	auth, err := client.GetCredentials(proxyEndpoint)
   284  	assert.Nil(t, err)
   285  	assert.Equal(t, auth.Username, expectedUsername)
   286  	assert.Equal(t, auth.Password, expectedPassword)
   287  	assert.Equal(t, auth.ProxyEndpoint, testProxyEndpoint)
   288  }
   289  
   290  func TestGetAuthConfigBadBase64(t *testing.T) {
   291  	ecrClient := &mock_api.MockECRAPI{}
   292  	credentialCache := &mock_cache.MockCredentialsCache{}
   293  
   294  	client := &defaultClient{
   295  		ecrClient:       ecrClient,
   296  		credentialCache: credentialCache,
   297  	}
   298  
   299  	ecrClient.GetAuthorizationTokenFn = func(input *ecr.GetAuthorizationTokenInput) (*ecr.GetAuthorizationTokenOutput, error) {
   300  		assert.NotNil(t, input, "GetAuthorizationToken input")
   301  		assert.Len(t, input.RegistryIds, 1, "GetAuthorizationToken registry IDs len")
   302  		return &ecr.GetAuthorizationTokenOutput{
   303  			AuthorizationData: []ecrtypes.AuthorizationData{{
   304  				ProxyEndpoint:      aws.String(proxyEndpointScheme + proxyEndpoint),
   305  				AuthorizationToken: aws.String(expectedUsername + ":" + expectedPassword),
   306  			}},
   307  		}, nil
   308  	}
   309  
   310  	credentialCache.GetFn = func(_ string) *cache.AuthEntry { return nil }
   311  
   312  	auth, err := client.GetCredentials(proxyEndpoint)
   313  	assert.NotNil(t, err)
   314  	t.Log(err)
   315  	assert.Nil(t, auth)
   316  }
   317  
   318  func TestGetAuthConfigMissingResponse(t *testing.T) {
   319  	ecrClient := &mock_api.MockECRAPI{}
   320  	credentialCache := &mock_cache.MockCredentialsCache{}
   321  
   322  	client := &defaultClient{
   323  		ecrClient:       ecrClient,
   324  		credentialCache: credentialCache,
   325  	}
   326  
   327  	ecrClient.GetAuthorizationTokenFn = func(input *ecr.GetAuthorizationTokenInput) (*ecr.GetAuthorizationTokenOutput, error) {
   328  		assert.NotNil(t, input, "GetAuthorizationToken input")
   329  		assert.Len(t, input.RegistryIds, 1, "GetAuthorizationToken registry IDs len")
   330  		return nil, nil
   331  	}
   332  
   333  	credentialCache.GetFn = func(_ string) *cache.AuthEntry { return nil }
   334  
   335  	auth, err := client.GetCredentials(proxyEndpoint)
   336  	assert.NotNil(t, err)
   337  	t.Log(err)
   338  	assert.Nil(t, auth)
   339  }
   340  
   341  func TestGetAuthConfigECRError(t *testing.T) {
   342  	ecrClient := &mock_api.MockECRAPI{}
   343  	credentialCache := &mock_cache.MockCredentialsCache{}
   344  
   345  	client := &defaultClient{
   346  		ecrClient:       ecrClient,
   347  		credentialCache: credentialCache,
   348  	}
   349  
   350  	ecrClient.GetAuthorizationTokenFn = func(input *ecr.GetAuthorizationTokenInput) (*ecr.GetAuthorizationTokenOutput, error) {
   351  		assert.NotNil(t, input, "GetAuthorizationToken input")
   352  		assert.Len(t, input.RegistryIds, 1, "GetAuthorizationToken registry IDs len")
   353  		return nil, errors.New("test error")
   354  	}
   355  
   356  	credentialCache.GetFn = func(_ string) *cache.AuthEntry { return nil }
   357  
   358  	auth, err := client.GetCredentials(proxyEndpoint)
   359  	assert.NotNil(t, err)
   360  	t.Log(err)
   361  	assert.Nil(t, auth)
   362  }
   363  
   364  func TestGetAuthConfigSuccessInvalidCacheHitFallback(t *testing.T) {
   365  	ecrClient := &mock_api.MockECRAPI{}
   366  	credentialCache := &mock_cache.MockCredentialsCache{}
   367  
   368  	client := &defaultClient{
   369  		ecrClient:       ecrClient,
   370  		credentialCache: credentialCache,
   371  	}
   372  
   373  	testProxyEndpoint := proxyEndpointScheme + proxyEndpoint
   374  	authorizationToken := base64.StdEncoding.EncodeToString([]byte(expectedUsername + ":" + expectedPassword))
   375  
   376  	ecrClient.GetAuthorizationTokenFn = func(input *ecr.GetAuthorizationTokenInput) (*ecr.GetAuthorizationTokenOutput, error) {
   377  		assert.NotNil(t, input, "GetAuthorizationToken input")
   378  		assert.Len(t, input.RegistryIds, 1, "GetAuthorizationToken registry IDs len")
   379  		return nil, errors.New("service error")
   380  	}
   381  
   382  	expiredAuthEntry := &cache.AuthEntry{
   383  		ProxyEndpoint:      testProxyEndpoint,
   384  		RequestedAt:        time.Now().Add(-12 * time.Hour),
   385  		ExpiresAt:          time.Now().Add(-6 * time.Hour),
   386  		AuthorizationToken: authorizationToken,
   387  	}
   388  
   389  	credentialCache.GetFn = func(r string) *cache.AuthEntry {
   390  		assert.Equal(t, registryID, r, "get from cache")
   391  		return expiredAuthEntry
   392  	}
   393  
   394  	auth, err := client.GetCredentials(proxyEndpoint)
   395  	assert.Nil(t, err)
   396  	assert.Equal(t, auth.Username, expectedUsername)
   397  	assert.Equal(t, auth.Password, expectedPassword)
   398  	assert.Equal(t, auth.ProxyEndpoint, testProxyEndpoint)
   399  }
   400  
   401  func TestListCredentialsSuccess(t *testing.T) {
   402  	ecrClient := &mock_api.MockECRAPI{}
   403  	ecrPublicClient := &mock_api.MockECRPublicAPI{}
   404  	credentialCache := &mock_cache.MockCredentialsCache{}
   405  
   406  	client := &defaultClient{
   407  		credentialCache: credentialCache,
   408  		ecrClient:       ecrClient,
   409  		ecrPublicClient: ecrPublicClient,
   410  	}
   411  
   412  	testProxyEndpoint := proxyEndpointScheme + proxyEndpoint
   413  	authorizationToken := base64.StdEncoding.EncodeToString([]byte(expectedUsername + ":" + expectedPassword))
   414  	expiresAt := time.Now().Add(12 * time.Hour)
   415  
   416  	authEntry := &cache.AuthEntry{
   417  		ProxyEndpoint:      testProxyEndpoint,
   418  		RequestedAt:        time.Now(),
   419  		ExpiresAt:          expiresAt,
   420  		AuthorizationToken: authorizationToken,
   421  	}
   422  	authEntries := []*cache.AuthEntry{authEntry}
   423  
   424  	ecrClient.GetAuthorizationTokenFn = func(_ *ecr.GetAuthorizationTokenInput) (*ecr.GetAuthorizationTokenOutput, error) {
   425  		return nil, errors.New("test error")
   426  	}
   427  	ecrPublicClient.GetAuthorizationTokenFn = func(_ *ecrpublic.GetAuthorizationTokenInput) (*ecrpublic.GetAuthorizationTokenOutput, error) {
   428  		return nil, errors.New("test error")
   429  	}
   430  	credentialCache.GetFn = func(_ string) *cache.AuthEntry { return nil }
   431  	credentialCache.GetPublicFn = func() *cache.AuthEntry { return nil }
   432  	credentialCache.ListFn = func() []*cache.AuthEntry { return authEntries }
   433  
   434  	auths, err := client.ListCredentials()
   435  	assert.NoError(t, err)
   436  	assert.NotNil(t, auths)
   437  	assert.Len(t, auths, 1)
   438  
   439  	auth := auths[0]
   440  	assert.Equal(t, auth.Username, expectedUsername)
   441  	assert.Equal(t, auth.Password, expectedPassword)
   442  	assert.Equal(t, auth.ProxyEndpoint, testProxyEndpoint)
   443  }
   444  
   445  func TestListCredentialsCached(t *testing.T) {
   446  	credentialCache := &mock_cache.MockCredentialsCache{}
   447  
   448  	client := &defaultClient{
   449  		credentialCache: credentialCache,
   450  	}
   451  
   452  	testProxyEndpoint := proxyEndpointScheme + proxyEndpoint
   453  	authorizationToken := base64.StdEncoding.EncodeToString([]byte(expectedUsername + ":" + expectedPassword))
   454  	expiresAt := time.Now().Add(12 * time.Hour)
   455  
   456  	authEntry1 := &cache.AuthEntry{
   457  		ProxyEndpoint:      testProxyEndpoint,
   458  		RequestedAt:        time.Now(),
   459  		ExpiresAt:          expiresAt,
   460  		AuthorizationToken: authorizationToken,
   461  		Service:            cache.ServiceECR,
   462  	}
   463  	authEntry2 := &cache.AuthEntry{
   464  		ProxyEndpoint:      testProxyEndpoint,
   465  		RequestedAt:        time.Now(),
   466  		ExpiresAt:          expiresAt,
   467  		AuthorizationToken: authorizationToken,
   468  		Service:            cache.ServiceECRPublic,
   469  	}
   470  	authEntries := []*cache.AuthEntry{authEntry1, authEntry2}
   471  
   472  	credentialCache.GetFn = func(_ string) *cache.AuthEntry { return authEntry1 }
   473  	credentialCache.GetPublicFn = func() *cache.AuthEntry { return authEntry2 }
   474  	credentialCache.ListFn = func() []*cache.AuthEntry { return authEntries }
   475  
   476  	auths, err := client.ListCredentials()
   477  	assert.NoError(t, err)
   478  	assert.NotNil(t, auths)
   479  	assert.Len(t, auths, 2)
   480  
   481  	assert.Equal(t, auths[0].Username, expectedUsername)
   482  	assert.Equal(t, auths[0].Password, expectedPassword)
   483  	assert.Equal(t, auths[0].ProxyEndpoint, testProxyEndpoint)
   484  	assert.Equal(t, auths[1].Username, expectedUsername)
   485  	assert.Equal(t, auths[1].Password, expectedPassword)
   486  	assert.Equal(t, auths[1].ProxyEndpoint, testProxyEndpoint)
   487  }
   488  
   489  func TestListCredentialsEmpty(t *testing.T) {
   490  	ecrClient := &mock_api.MockECRAPI{}
   491  	ecrPublicClient := &mock_api.MockECRPublicAPI{}
   492  	credentialCache := &mock_cache.MockCredentialsCache{}
   493  
   494  	client := &defaultClient{
   495  		credentialCache: credentialCache,
   496  		ecrClient:       ecrClient,
   497  		ecrPublicClient: ecrPublicClient,
   498  	}
   499  
   500  	testProxyEndpoint := proxyEndpointScheme + proxyEndpoint
   501  	authorizationToken := base64.StdEncoding.EncodeToString([]byte(expectedUsername + ":" + expectedPassword))
   502  	expiresAt := time.Now().Add(12 * time.Hour)
   503  
   504  	authEntry1 := &cache.AuthEntry{
   505  		ProxyEndpoint:      testProxyEndpoint,
   506  		RequestedAt:        time.Now(),
   507  		ExpiresAt:          expiresAt,
   508  		AuthorizationToken: authorizationToken,
   509  		Service:            cache.ServiceECR,
   510  	}
   511  	authEntry2 := &cache.AuthEntry{
   512  		ProxyEndpoint:      ecrPublicEndpoint,
   513  		RequestedAt:        time.Now(),
   514  		ExpiresAt:          expiresAt,
   515  		AuthorizationToken: authorizationToken,
   516  		Service:            cache.ServiceECRPublic,
   517  	}
   518  	authEntries := []*cache.AuthEntry{authEntry1, authEntry2}
   519  
   520  	ecrClient.GetAuthorizationTokenFn = func(input *ecr.GetAuthorizationTokenInput) (*ecr.GetAuthorizationTokenOutput, error) {
   521  		assert.NotNil(t, input, "GetAuthorizationToken input")
   522  		assert.Len(t, input.RegistryIds, 0, "GetAuthorizationToken registry IDs len")
   523  		return &ecr.GetAuthorizationTokenOutput{
   524  			AuthorizationData: []ecrtypes.AuthorizationData{{
   525  				ProxyEndpoint:      aws.String(testProxyEndpoint),
   526  				ExpiresAt:          aws.Time(expiresAt),
   527  				AuthorizationToken: aws.String(authorizationToken),
   528  			}},
   529  		}, nil
   530  	}
   531  	ecrPublicClient.GetAuthorizationTokenFn = func(*ecrpublic.GetAuthorizationTokenInput) (*ecrpublic.GetAuthorizationTokenOutput, error) {
   532  		return &ecrpublic.GetAuthorizationTokenOutput{
   533  			AuthorizationData: &ecrpublictypes.AuthorizationData{
   534  				ExpiresAt:          aws.Time(expiresAt),
   535  				AuthorizationToken: aws.String(authorizationToken),
   536  			},
   537  		}, nil
   538  	}
   539  	credentialCache.GetFn = func(_ string) *cache.AuthEntry { return nil }
   540  	credentialCache.GetPublicFn = func() *cache.AuthEntry { return nil }
   541  	credentialCache.ListFn = func() []*cache.AuthEntry { return authEntries }
   542  	setCallCount := 0
   543  	credentialCache.SetFn = func(_ string, _ *cache.AuthEntry) {
   544  		setCallCount++
   545  	}
   546  
   547  	auths, err := client.ListCredentials()
   548  	assert.NoError(t, err)
   549  	assert.NotNil(t, auths)
   550  	assert.Len(t, auths, 2)
   551  	assert.Equal(t, 2, setCallCount)
   552  
   553  	assert.Equal(t, auths[0].Username, expectedUsername)
   554  	assert.Equal(t, auths[0].Password, expectedPassword)
   555  	assert.Equal(t, auths[0].ProxyEndpoint, testProxyEndpoint)
   556  	assert.Equal(t, auths[1].Username, expectedUsername)
   557  	assert.Equal(t, auths[1].Password, expectedPassword)
   558  	assert.Equal(t, auths[1].ProxyEndpoint, ecrPublicEndpoint)
   559  }
   560  
   561  func TestListCredentialsBadBase64AuthToken(t *testing.T) {
   562  	ecrClient := &mock_api.MockECRAPI{}
   563  	ecrPublicClient := &mock_api.MockECRPublicAPI{}
   564  	credentialCache := &mock_cache.MockCredentialsCache{}
   565  
   566  	client := &defaultClient{
   567  		credentialCache: credentialCache,
   568  		ecrClient:       ecrClient,
   569  		ecrPublicClient: ecrPublicClient,
   570  	}
   571  
   572  	testProxyEndpoint := proxyEndpointScheme + proxyEndpoint
   573  	expiresAt := time.Now().Add(12 * time.Hour)
   574  
   575  	emptyCache := []*cache.AuthEntry{}
   576  	credentialCache.ListFn = func() []*cache.AuthEntry { return emptyCache }
   577  	credentialCache.GetFn = func(_ string) *cache.AuthEntry { return nil }
   578  	credentialCache.GetPublicFn = func() *cache.AuthEntry { return nil }
   579  
   580  	ecrClient.GetAuthorizationTokenFn = func(input *ecr.GetAuthorizationTokenInput) (*ecr.GetAuthorizationTokenOutput, error) {
   581  		assert.NotNil(t, input, "GetAuthorizationToken input")
   582  		assert.Len(t, input.RegistryIds, 0, "GetAuthorizationToken registry IDs len")
   583  		return &ecr.GetAuthorizationTokenOutput{
   584  			AuthorizationData: []ecrtypes.AuthorizationData{{
   585  				ProxyEndpoint:      aws.String(testProxyEndpoint),
   586  				ExpiresAt:          aws.Time(expiresAt),
   587  				AuthorizationToken: aws.String("invalid:token"),
   588  			}},
   589  		}, nil
   590  	}
   591  	ecrPublicClient.GetAuthorizationTokenFn = func(_ *ecrpublic.GetAuthorizationTokenInput) (*ecrpublic.GetAuthorizationTokenOutput, error) {
   592  		return nil, errors.New("test error")
   593  	}
   594  
   595  	auths, err := client.ListCredentials()
   596  	assert.NoError(t, err)
   597  	assert.NotNil(t, auths)
   598  	assert.Empty(t, auths)
   599  }
   600  
   601  func TestListCredentialsInvalidAuthToken(t *testing.T) {
   602  	ecrClient := &mock_api.MockECRAPI{}
   603  	ecrPublicClient := &mock_api.MockECRPublicAPI{}
   604  	credentialCache := &mock_cache.MockCredentialsCache{}
   605  
   606  	client := &defaultClient{
   607  		credentialCache: credentialCache,
   608  		ecrClient:       ecrClient,
   609  		ecrPublicClient: ecrPublicClient,
   610  	}
   611  
   612  	testProxyEndpoint := proxyEndpointScheme + proxyEndpoint
   613  	expiresAt := time.Now().Add(12 * time.Hour)
   614  
   615  	emptyCache := []*cache.AuthEntry{}
   616  	credentialCache.ListFn = func() []*cache.AuthEntry { return emptyCache }
   617  	credentialCache.GetFn = func(_ string) *cache.AuthEntry { return nil }
   618  	credentialCache.GetPublicFn = func() *cache.AuthEntry { return nil }
   619  
   620  	ecrClient.GetAuthorizationTokenFn = func(input *ecr.GetAuthorizationTokenInput) (*ecr.GetAuthorizationTokenOutput, error) {
   621  		assert.NotNil(t, input, "GetAuthorizationToken input")
   622  		assert.Len(t, input.RegistryIds, 0, "GetAuthorizationToken registry IDs len")
   623  		return &ecr.GetAuthorizationTokenOutput{
   624  			AuthorizationData: []ecrtypes.AuthorizationData{{
   625  				ProxyEndpoint:      aws.String(testProxyEndpoint),
   626  				ExpiresAt:          aws.Time(expiresAt),
   627  				AuthorizationToken: aws.String("invalidtoken"),
   628  			}},
   629  		}, nil
   630  	}
   631  	ecrPublicClient.GetAuthorizationTokenFn = func(_ *ecrpublic.GetAuthorizationTokenInput) (*ecrpublic.GetAuthorizationTokenOutput, error) {
   632  		return nil, errors.New("test error")
   633  	}
   634  
   635  	auths, err := client.ListCredentials()
   636  	assert.NoError(t, err)
   637  	assert.NotNil(t, auths)
   638  	assert.Empty(t, auths)
   639  }
   640  
   641  func compareAuthEntry(t *testing.T, actual *cache.AuthEntry, expected *cache.AuthEntry) {
   642  	assert.NotNil(t, actual)
   643  	assert.Equal(t, expected.AuthorizationToken, actual.AuthorizationToken)
   644  	assert.Equal(t, expected.ProxyEndpoint, actual.ProxyEndpoint)
   645  	assert.Equal(t, expected.ExpiresAt, actual.ExpiresAt)
   646  	assert.WithinDuration(t, expected.RequestedAt, actual.RequestedAt, 5*time.Second)
   647  }
   648  

View as plain text