second first commit
This commit is contained in:
@@ -0,0 +1,311 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"math/big"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"floci-sdk-test-go/internal/testutil"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/service/acm"
|
||||
acmtypes "github.com/aws/aws-sdk-go-v2/service/acm/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// generateSelfSignedCert creates a self-signed certificate and private key in PEM format.
|
||||
func generateSelfSignedCert() (certPEM, keyPEM []byte) {
|
||||
key, _ := rsa.GenerateKey(rand.Reader, 2048)
|
||||
tmpl := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{CommonName: "test.example.com"},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(365 * 24 * time.Hour),
|
||||
}
|
||||
certDER, _ := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &key.PublicKey, key)
|
||||
certPEM = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
|
||||
keyPEM = pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)})
|
||||
return
|
||||
}
|
||||
|
||||
func TestACM(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
svc := testutil.ACMClient()
|
||||
var certARN string
|
||||
|
||||
t.Run("RequestCertificate", func(t *testing.T) {
|
||||
r, err := svc.RequestCertificate(ctx, &acm.RequestCertificateInput{
|
||||
DomainName: aws.String("go-test.example.com"),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
certARN = aws.ToString(r.CertificateArn)
|
||||
assert.NotEmpty(t, certARN)
|
||||
assert.True(t, strings.HasPrefix(certARN, "arn:aws:acm:"), "ARN should match arn:aws:acm pattern, got: %s", certARN)
|
||||
})
|
||||
|
||||
t.Run("DescribeCertificate", func(t *testing.T) {
|
||||
if certARN == "" {
|
||||
t.Skip("No certificate ARN from RequestCertificate")
|
||||
}
|
||||
r, err := svc.DescribeCertificate(ctx, &acm.DescribeCertificateInput{
|
||||
CertificateArn: aws.String(certARN),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "go-test.example.com", aws.ToString(r.Certificate.DomainName))
|
||||
assert.Equal(t, acmtypes.CertificateStatusIssued, r.Certificate.Status)
|
||||
})
|
||||
|
||||
t.Run("GetCertificate", func(t *testing.T) {
|
||||
if certARN == "" {
|
||||
t.Skip("No certificate ARN from RequestCertificate")
|
||||
}
|
||||
r, err := svc.GetCertificate(ctx, &acm.GetCertificateInput{
|
||||
CertificateArn: aws.String(certARN),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, aws.ToString(r.Certificate))
|
||||
})
|
||||
|
||||
t.Run("ListCertificates", func(t *testing.T) {
|
||||
if certARN == "" {
|
||||
t.Skip("No certificate ARN from RequestCertificate")
|
||||
}
|
||||
r, err := svc.ListCertificates(ctx, &acm.ListCertificatesInput{})
|
||||
require.NoError(t, err)
|
||||
|
||||
found := false
|
||||
for _, c := range r.CertificateSummaryList {
|
||||
if aws.ToString(c.CertificateArn) == certARN {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
assert.True(t, found, "Certificate %s should appear in list", certARN)
|
||||
})
|
||||
|
||||
t.Run("AddTagsToCertificate", func(t *testing.T) {
|
||||
if certARN == "" {
|
||||
t.Skip("No certificate ARN from RequestCertificate")
|
||||
}
|
||||
_, err := svc.AddTagsToCertificate(ctx, &acm.AddTagsToCertificateInput{
|
||||
CertificateArn: aws.String(certARN),
|
||||
Tags: []acmtypes.Tag{
|
||||
{Key: aws.String("Env"), Value: aws.String("test")},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
r, err := svc.ListTagsForCertificate(ctx, &acm.ListTagsForCertificateInput{
|
||||
CertificateArn: aws.String(certARN),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
found := false
|
||||
for _, tag := range r.Tags {
|
||||
if aws.ToString(tag.Key) == "Env" && aws.ToString(tag.Value) == "test" {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
assert.True(t, found, "Tag Env=test should be present")
|
||||
})
|
||||
|
||||
t.Run("ListTagsForCertificate", func(t *testing.T) {
|
||||
if certARN == "" {
|
||||
t.Skip("No certificate ARN from RequestCertificate")
|
||||
}
|
||||
r, err := svc.ListTagsForCertificate(ctx, &acm.ListTagsForCertificateInput{
|
||||
CertificateArn: aws.String(certARN),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
found := false
|
||||
for _, tag := range r.Tags {
|
||||
if aws.ToString(tag.Key) == "Env" && aws.ToString(tag.Value) == "test" {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
assert.True(t, found, "Tag Env=test should still be present")
|
||||
})
|
||||
|
||||
t.Run("RemoveTagsFromCertificate", func(t *testing.T) {
|
||||
if certARN == "" {
|
||||
t.Skip("No certificate ARN from RequestCertificate")
|
||||
}
|
||||
_, err := svc.RemoveTagsFromCertificate(ctx, &acm.RemoveTagsFromCertificateInput{
|
||||
CertificateArn: aws.String(certARN),
|
||||
Tags: []acmtypes.Tag{
|
||||
{Key: aws.String("Env"), Value: aws.String("test")},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
r, err := svc.ListTagsForCertificate(ctx, &acm.ListTagsForCertificateInput{
|
||||
CertificateArn: aws.String(certARN),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, tag := range r.Tags {
|
||||
assert.NotEqual(t, "Env", aws.ToString(tag.Key), "Tag Env should have been removed")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("DeleteCertificate", func(t *testing.T) {
|
||||
if certARN == "" {
|
||||
t.Skip("No certificate ARN from RequestCertificate")
|
||||
}
|
||||
_, err := svc.DeleteCertificate(ctx, &acm.DeleteCertificateInput{
|
||||
CertificateArn: aws.String(certARN),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = svc.DescribeCertificate(ctx, &acm.DescribeCertificateInput{
|
||||
CertificateArn: aws.String(certARN),
|
||||
})
|
||||
assert.Error(t, err, "DescribeCertificate should fail after deletion")
|
||||
})
|
||||
}
|
||||
|
||||
func TestACMImportExport(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
svc := testutil.ACMClient()
|
||||
certPEM, keyPEM := generateSelfSignedCert()
|
||||
var importedARN string
|
||||
|
||||
t.Cleanup(func() {
|
||||
if importedARN != "" {
|
||||
svc.DeleteCertificate(ctx, &acm.DeleteCertificateInput{
|
||||
CertificateArn: aws.String(importedARN),
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ImportCertificate", func(t *testing.T) {
|
||||
r, err := svc.ImportCertificate(ctx, &acm.ImportCertificateInput{
|
||||
Certificate: certPEM,
|
||||
PrivateKey: keyPEM,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
importedARN = aws.ToString(r.CertificateArn)
|
||||
assert.NotEmpty(t, importedARN)
|
||||
assert.True(t, strings.HasPrefix(importedARN, "arn:aws:acm:"), "ARN should match arn:aws:acm pattern, got: %s", importedARN)
|
||||
})
|
||||
|
||||
t.Run("GetImportedCertificate", func(t *testing.T) {
|
||||
if importedARN == "" {
|
||||
t.Skip("No imported certificate ARN")
|
||||
}
|
||||
r, err := svc.GetCertificate(ctx, &acm.GetCertificateInput{
|
||||
CertificateArn: aws.String(importedARN),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, aws.ToString(r.Certificate))
|
||||
})
|
||||
|
||||
t.Run("ExportCertificate", func(t *testing.T) {
|
||||
if importedARN == "" {
|
||||
t.Skip("No imported certificate ARN")
|
||||
}
|
||||
r, err := svc.ExportCertificate(ctx, &acm.ExportCertificateInput{
|
||||
CertificateArn: aws.String(importedARN),
|
||||
Passphrase: []byte("test-passphrase"),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, aws.ToString(r.Certificate), "Exported certificate body should not be empty")
|
||||
assert.NotEmpty(t, aws.ToString(r.PrivateKey), "Exported private key should not be empty")
|
||||
})
|
||||
|
||||
t.Run("ExportRequestedCertificateFails", func(t *testing.T) {
|
||||
// Request a certificate (not imported) - export should fail
|
||||
reqResult, err := svc.RequestCertificate(ctx, &acm.RequestCertificateInput{
|
||||
DomainName: aws.String("go-export-fail.example.com"),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
requestedARN := aws.ToString(reqResult.CertificateArn)
|
||||
|
||||
t.Cleanup(func() {
|
||||
svc.DeleteCertificate(ctx, &acm.DeleteCertificateInput{
|
||||
CertificateArn: aws.String(requestedARN),
|
||||
})
|
||||
})
|
||||
|
||||
_, err = svc.ExportCertificate(ctx, &acm.ExportCertificateInput{
|
||||
CertificateArn: aws.String(requestedARN),
|
||||
Passphrase: []byte("test-passphrase"),
|
||||
})
|
||||
assert.Error(t, err, "ExportCertificate should fail for a requested (non-imported) certificate")
|
||||
})
|
||||
}
|
||||
|
||||
func TestACMAccountConfiguration(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
svc := testutil.ACMClient()
|
||||
|
||||
_, err := svc.PutAccountConfiguration(ctx, &acm.PutAccountConfigurationInput{
|
||||
ExpiryEvents: &acmtypes.ExpiryEventsConfiguration{
|
||||
DaysBeforeExpiry: aws.Int32(45),
|
||||
},
|
||||
IdempotencyToken: aws.String("go-test-idempotency-token"),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
r, err := svc.GetAccountConfiguration(ctx, &acm.GetAccountConfigurationInput{})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, r.ExpiryEvents)
|
||||
assert.Equal(t, int32(45), aws.ToInt32(r.ExpiryEvents.DaysBeforeExpiry))
|
||||
}
|
||||
|
||||
func TestACMErrorHandling(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
svc := testutil.ACMClient()
|
||||
|
||||
t.Run("DescribeNonExistent", func(t *testing.T) {
|
||||
_, err := svc.DescribeCertificate(ctx, &acm.DescribeCertificateInput{
|
||||
CertificateArn: aws.String("arn:aws:acm:us-east-1:000000000000:certificate/00000000-0000-0000-0000-000000000000"),
|
||||
})
|
||||
assert.Error(t, err, "DescribeCertificate should fail for non-existent ARN")
|
||||
})
|
||||
|
||||
t.Run("RequestWithSANs", func(t *testing.T) {
|
||||
r, err := svc.RequestCertificate(ctx, &acm.RequestCertificateInput{
|
||||
DomainName: aws.String("go-san-test.example.com"),
|
||||
SubjectAlternativeNames: []string{
|
||||
"go-san-test.example.com",
|
||||
"www.go-san-test.example.com",
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
sanARN := aws.ToString(r.CertificateArn)
|
||||
assert.NotEmpty(t, sanARN)
|
||||
|
||||
t.Cleanup(func() {
|
||||
svc.DeleteCertificate(ctx, &acm.DeleteCertificateInput{
|
||||
CertificateArn: aws.String(sanARN),
|
||||
})
|
||||
})
|
||||
|
||||
desc, err := svc.DescribeCertificate(ctx, &acm.DescribeCertificateInput{
|
||||
CertificateArn: aws.String(sanARN),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, desc.Certificate.SubjectAlternativeNames, "go-san-test.example.com")
|
||||
assert.Contains(t, desc.Certificate.SubjectAlternativeNames, "www.go-san-test.example.com")
|
||||
})
|
||||
|
||||
t.Run("ImportInvalidPEM", func(t *testing.T) {
|
||||
_, err := svc.ImportCertificate(ctx, &acm.ImportCertificateInput{
|
||||
Certificate: []byte("not-valid-pem-data"),
|
||||
PrivateKey: []byte("not-valid-key-data"),
|
||||
})
|
||||
assert.Error(t, err, "ImportCertificate should fail with invalid PEM data")
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user