Skip to content

Commit

Permalink
fix(tests): update imagetrust tests to use mock service
Browse files Browse the repository at this point in the history
- use secretsManagerMock and secretsManagerCacheMock to avoid failing
because of "already exists" error when running multiple times
image_trust_test on the same localstack instance

Signed-off-by: Andreea-Lupu <[email protected]>
  • Loading branch information
Andreea-Lupu committed Oct 13, 2023
1 parent fc2380b commit 7f4a609
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 80 deletions.
7 changes: 4 additions & 3 deletions pkg/extensions/imagetrust/cosign.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"io"
"os"
"path"
"strings"

"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
"github.com/aws/aws-sdk-go-v2/service/secretsmanager/types"
Expand Down Expand Up @@ -256,11 +257,11 @@ func (cloud *PublicKeyAWSStorage) StorePublicKey(name godigest.Digest, publicKey
}

_, err := cloud.secretsManagerClient.CreateSecret(context.Background(), secretInputParam)
if err != nil {
return err
if err != nil && strings.Contains(err.Error(), "already exists") {
return nil
}

return nil
return err
}

func validatePublicKey(publicKeyContent []byte) (bool, error) {
Expand Down
186 changes: 110 additions & 76 deletions pkg/extensions/imagetrust/image_trust_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ import (
)

var (
errExpiryError = errors.New("expiry err")
errUnexpectedError = errors.New("unexpected err")
errExpiryError = errors.New("expiry err")
errUnexpectedError = errors.New("unexpected err")
errAlreadyExistsError = errors.New("the secret trustpolicy already exists")
)

func TestInitCosignAndNotationDirs(t *testing.T) {
Expand Down Expand Up @@ -661,30 +662,13 @@ func TestLocalTrustStore(t *testing.T) {
func TestAWSTrustStore(t *testing.T) {
tskip.SkipDynamo(t)

trustpolicy := "trustpolicy"

Convey("NewAWSImageTrustStore error", t, func() {
_, err := imagetrust.NewAWSImageTrustStore("us-east-2", "wrong;endpoint")
So(err, ShouldNotBeNil)
})

Convey("InitTrustpolicy retry", t, func() {
smanager, err := imagetrust.GetSecretsManagerClient("us-east-2", os.Getenv("DYNAMODBMOCK_ENDPOINT"))
So(err, ShouldBeNil)

smCache := imagetrust.GetSecretsManagerRetrieval("us-east-2", os.Getenv("DYNAMODBMOCK_ENDPOINT"))

description := "notation trustpolicy file"
content := "trustpolicy content"

_, err = smanager.CreateSecret(context.Background(),
&secretsmanager.CreateSecretInput{
Name: &trustpolicy,
Description: &description,
SecretString: &content,
})
So(err, ShouldBeNil)

secretsManagerMock := mocks.SecretsManagerMock{
DeleteSecretFn: func(ctx context.Context, params *secretsmanager.DeleteSecretInput,
optFns ...func(*secretsmanager.Options),
Expand All @@ -694,20 +678,25 @@ func TestAWSTrustStore(t *testing.T) {
CreateSecretFn: func(ctx context.Context, params *secretsmanager.CreateSecretInput,
optFns ...func(*secretsmanager.Options),
) (*secretsmanager.CreateSecretOutput, error) {
return smanager.CreateSecret(ctx, params, optFns...)
return &secretsmanager.CreateSecretOutput{}, errAlreadyExistsError
},
}

secretsManagerCacheMock := mocks.SecretsManagerCacheMock{
GetSecretStringFn: func(secretID string) (string, error) {
return "", errUnexpectedError
},
}

_, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, secretsManagerCacheMock)
_, err := imagetrust.NewCertificateAWSStorage(secretsManagerMock, secretsManagerCacheMock)
So(err, ShouldNotBeNil)

_, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, smCache)
secretsManagerCacheMock = mocks.SecretsManagerCacheMock{
GetSecretStringFn: func(secretID string) (string, error) {
return content, nil
},
}

_, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, secretsManagerCacheMock)
So(err, ShouldNotBeNil)

secretsManagerMock = mocks.SecretsManagerMock{
Expand All @@ -719,43 +708,77 @@ func TestAWSTrustStore(t *testing.T) {
CreateSecretFn: func(ctx context.Context, params *secretsmanager.CreateSecretInput,
optFns ...func(*secretsmanager.Options),
) (*secretsmanager.CreateSecretOutput, error) {
return smanager.CreateSecret(ctx, params, optFns...)
return &secretsmanager.CreateSecretOutput{}, errUnexpectedError
},
}

_, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, smCache)
_, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, secretsManagerCacheMock)
So(err, ShouldNotBeNil)

errVal := make(chan bool)

secretsManagerMock = mocks.SecretsManagerMock{
DeleteSecretFn: func(ctx context.Context, params *secretsmanager.DeleteSecretInput,
optFns ...func(*secretsmanager.Options),
) (*secretsmanager.DeleteSecretOutput, error) {
go func() {
time.Sleep(3 * time.Second)

smanager.DeleteSecret(ctx, params, optFns...) //nolint:errcheck
errVal <- true
}()

return &secretsmanager.DeleteSecretOutput{}, nil
},
CreateSecretFn: func(ctx context.Context, params *secretsmanager.CreateSecretInput,
optFns ...func(*secretsmanager.Options),
) (*secretsmanager.CreateSecretOutput, error) {
return smanager.CreateSecret(ctx, params, optFns...)
select {
case <-errVal:
return &secretsmanager.CreateSecretOutput{}, nil
default:
return &secretsmanager.CreateSecretOutput{}, errAlreadyExistsError
}
},
}

_, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, smCache)
_, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, secretsManagerCacheMock)
So(err, ShouldBeNil)
})

Convey("GetCertificates errors", t, func() {
smanager, err := imagetrust.GetSecretsManagerClient("us-east-2", os.Getenv("DYNAMODBMOCK_ENDPOINT"))
So(err, ShouldBeNil)
name := "ca/test/digest"
content := "invalid certificate content"

secretsManagerMock := mocks.SecretsManagerMock{
DeleteSecretFn: func(ctx context.Context, params *secretsmanager.DeleteSecretInput,
optFns ...func(*secretsmanager.Options),
) (*secretsmanager.DeleteSecretOutput, error) {
return &secretsmanager.DeleteSecretOutput{}, nil
},
CreateSecretFn: func(ctx context.Context, params *secretsmanager.CreateSecretInput,
optFns ...func(*secretsmanager.Options),
) (*secretsmanager.CreateSecretOutput, error) {
if *params.Name == "trustpolicy" {
return &secretsmanager.CreateSecretOutput{}, nil
}

smCache := imagetrust.GetSecretsManagerRetrieval("us-east-2", os.Getenv("DYNAMODBMOCK_ENDPOINT"))
return &secretsmanager.CreateSecretOutput{}, errUnexpectedError
},
ListSecretsFn: func(ctx context.Context, params *secretsmanager.ListSecretsInput,
optFns ...func(*secretsmanager.Options),
) (*secretsmanager.ListSecretsOutput, error) {
return &secretsmanager.ListSecretsOutput{
SecretList: []types.SecretListEntry{{Name: &name}},
}, nil
},
}
secretsManagerCacheMock := mocks.SecretsManagerCacheMock{
GetSecretStringFn: func(secretID string) (string, error) {
return content, nil
},
}

notationStorage, err := imagetrust.NewCertificateAWSStorage(smanager, smCache)
notationStorage, err := imagetrust.NewCertificateAWSStorage(secretsManagerMock, secretsManagerCacheMock)
So(err, ShouldBeNil)

_, err = notationStorage.GetCertificates(context.Background(), "wrongType", "")
Expand All @@ -766,44 +789,56 @@ func TestAWSTrustStore(t *testing.T) {
So(err, ShouldNotBeNil)
So(err, ShouldEqual, zerr.ErrInvalidTruststoreName)

name := "ca/test/digest"
description := "notation certificate"
content := "invalid certificate content"

_, err = smanager.CreateSecret(context.Background(),
&secretsmanager.CreateSecretInput{
Name: &name,
Description: &description,
SecretString: &content,
})
So(err, ShouldBeNil)

_, err = notationStorage.GetCertificates(context.Background(), "ca", "test")
So(err, ShouldNotBeNil)

newName := "ca/newtest/digest"
newSecret := base64.StdEncoding.EncodeToString([]byte(content))

_, err = smanager.CreateSecret(context.Background(),
&secretsmanager.CreateSecretInput{
Name: &newName,
Description: &description,
SecretString: &newSecret,
})
secretsManagerMock = mocks.SecretsManagerMock{
DeleteSecretFn: func(ctx context.Context, params *secretsmanager.DeleteSecretInput,
optFns ...func(*secretsmanager.Options),
) (*secretsmanager.DeleteSecretOutput, error) {
return &secretsmanager.DeleteSecretOutput{}, nil
},
CreateSecretFn: func(ctx context.Context, params *secretsmanager.CreateSecretInput,
optFns ...func(*secretsmanager.Options),
) (*secretsmanager.CreateSecretOutput, error) {
if *params.Name == "trustpolicy" {
return &secretsmanager.CreateSecretOutput{}, nil
}

return &secretsmanager.CreateSecretOutput{}, errUnexpectedError
},
ListSecretsFn: func(ctx context.Context, params *secretsmanager.ListSecretsInput,
optFns ...func(*secretsmanager.Options),
) (*secretsmanager.ListSecretsOutput, error) {
return &secretsmanager.ListSecretsOutput{
SecretList: []types.SecretListEntry{{Name: &newName}},
}, nil
},
}
secretsManagerCacheMock = mocks.SecretsManagerCacheMock{
GetSecretStringFn: func(secretID string) (string, error) {
return newSecret, nil
},
}

notationStorage, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, secretsManagerCacheMock)
So(err, ShouldBeNil)

_, err = notationStorage.GetCertificates(context.Background(), "ca", "newtest")
So(err, ShouldNotBeNil)

secretsManagerMock := mocks.SecretsManagerMock{
secretsManagerMock = mocks.SecretsManagerMock{
ListSecretsFn: func(ctx context.Context, params *secretsmanager.ListSecretsInput,
optFns ...func(*secretsmanager.Options),
) (*secretsmanager.ListSecretsOutput, error) {
return &secretsmanager.ListSecretsOutput{}, errUnexpectedError
},
}

notationStorage, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, smCache)
notationStorage, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, secretsManagerCacheMock)
So(err, ShouldBeNil)

_, err = notationStorage.GetCertificates(context.Background(), "ca", "newtest")
Expand All @@ -817,7 +852,7 @@ func TestAWSTrustStore(t *testing.T) {
},
}

secretsManagerCacheMock := mocks.SecretsManagerCacheMock{
secretsManagerCacheMock = mocks.SecretsManagerCacheMock{
GetSecretStringFn: func(secretID string) (string, error) {
return "", errUnexpectedError
},
Expand All @@ -831,42 +866,41 @@ func TestAWSTrustStore(t *testing.T) {
})

Convey("GetPublicKeyVerifier errors", t, func() {
smanager, err := imagetrust.GetSecretsManagerClient("us-east-2", os.Getenv("DYNAMODBMOCK_ENDPOINT"))
So(err, ShouldBeNil)

smCache := imagetrust.GetSecretsManagerRetrieval("us-east-2", os.Getenv("DYNAMODBMOCK_ENDPOINT"))
secretsManagerMock := mocks.SecretsManagerMock{}
secretsManagerCacheMock := mocks.SecretsManagerCacheMock{
GetSecretStringFn: func(secretID string) (string, error) {
return "", errUnexpectedError
},
}

cosignStorage := imagetrust.NewPublicKeyAWSStorage(smanager, smCache)
cosignStorage := imagetrust.NewPublicKeyAWSStorage(secretsManagerMock, secretsManagerCacheMock)

_, _, err = cosignStorage.GetPublicKeyVerifier("badsecret")
_, _, err := cosignStorage.GetPublicKeyVerifier("badsecret")
So(err, ShouldNotBeNil)

secretName := "digest"
description := "cosign public key"
secret := "invalid public key content"

_, err = smanager.CreateSecret(context.Background(),
&secretsmanager.CreateSecretInput{
Name: &secretName,
Description: &description,
SecretString: &secret,
})
So(err, ShouldBeNil)
secretsManagerCacheMock = mocks.SecretsManagerCacheMock{
GetSecretStringFn: func(secretID string) (string, error) {
return secret, nil
},
}

cosignStorage = imagetrust.NewPublicKeyAWSStorage(secretsManagerMock, secretsManagerCacheMock)

_, _, err = cosignStorage.GetPublicKeyVerifier(secretName)
So(err, ShouldNotBeNil)

secretName = "newdigest"

newSecret := base64.StdEncoding.EncodeToString([]byte(secret))

_, err = smanager.CreateSecret(context.Background(),
&secretsmanager.CreateSecretInput{
Name: &secretName,
Description: &description,
SecretString: &newSecret,
})
So(err, ShouldBeNil)
secretsManagerCacheMock = mocks.SecretsManagerCacheMock{
GetSecretStringFn: func(secretID string) (string, error) {
return newSecret, nil
},
}

cosignStorage = imagetrust.NewPublicKeyAWSStorage(secretsManagerMock, secretsManagerCacheMock)

_, _, err = cosignStorage.GetPublicKeyVerifier(secretName)
So(err, ShouldNotBeNil)
Expand Down
6 changes: 5 additions & 1 deletion pkg/extensions/imagetrust/notation.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func (cloud *CertificateAWSStorage) InitTrustpolicy(trustpolicy []byte) error {
}

_, err := cloud.secretsManagerClient.CreateSecret(context.Background(), secretInputParam)
if err != nil && strings.Contains(err.Error(), "the secret trustpolicy already exists.") {
if err != nil && strings.Contains(err.Error(), "the secret trustpolicy already exists") {
trustpolicyContent, err := cloud.secretsManagerCache.GetSecretString(name)
if err != nil {
return err
Expand Down Expand Up @@ -495,6 +495,10 @@ func (cloud *CertificateAWSStorage) StoreCertificate(

_, err := cloud.secretsManagerClient.CreateSecret(context.Background(), secretInputParam)

if err != nil && strings.Contains(err.Error(), "already exists") {
return nil
}

return err
}

Expand Down

0 comments on commit 7f4a609

Please sign in to comment.