Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: add barebone e2e tests with basic awslogs scenario #66

Merged
merged 1 commit into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 43 additions & 8 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,23 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version-file: go.mod
go-version: 'stable'
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
# Pin the version in case all the builds start to fail at the same time.
# There may not be an automatic way (e.g., dependabot) to update a specific parameter of a GitHub Action,
# so we will just update it manually whenever it makes sense (e.g., a feature that we want is added).
version: v1.54.0
args: --fix=false --timeout=5m
build:
args: --fix=false --timeout=5m --out-format=colored-line-number
unit-tests:
strategy:
fail-fast: false
matrix:
go: [ '1.17', '1.18', '1.19', '1.20', '1.21' ]
os: [ 'ubuntu-22.04', 'windows-2022' ]
go: [ '1.20', '1.21' ]
os: [ ubuntu-latest, windows-latest ]

name: ${{ matrix.os }} / Go ${{ matrix.go }}
name: Unit Tests / ${{ matrix.os }} / Go ${{ matrix.go }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
Expand All @@ -43,8 +43,43 @@ jobs:
cache: false
- name: build
run: make build
- name: test
run: make test
- name: test-unit
run: make test-unit
e2e-tests-for-awslogs:
strategy:
fail-fast: false
matrix:
go: [ '1.20', '1.21' ]
os: [ ubuntu-latest ] # TODO: Add Windows e2e tests: https://github.com/aws/shim-loggers-for-containerd/issues/68
name: E2E tests / awslogs / ${{ matrix.os }} / Go ${{ matrix.go }}
runs-on: ${{ matrix.os }}
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go }}
cache: false
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.ROLE }}
aws-region: ${{ secrets.REGION }}
- name: install and start containerd
shell: bash
run: sudo scripts/install-containerd
- name: start ecs local endpoint
shell: bash
run: scripts/start-ecs-local-endpoint
- name: ip forwarding # awslogs driver hardcodes "169.254.170.2" as the aws credential endpoint ip so need to forward to local endpoint
shell: bash
run: sudo scripts/ip-forwarding
- name: build
run: sudo make build
- name: test-e2e
run: sudo -E make test-e2e-for-awslogs # containerd interaction requires sudo and aws cloudwatch interaction requires passing env vars
go-mod-tidy-check:
runs-on: ubuntu-latest
steps:
Expand Down
15 changes: 12 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,21 @@ build: $(AWS_CONTAINERD_LOGGERS_BINARY)
$(AWS_CONTAINERD_LOGGERS_BINARY):
go build -o $(AWS_CONTAINERD_LOGGERS_BINARY) $(AWS_CONTAINERD_LOGGERS_DIR)

test: $(SOURCES)
go test -tags unit -race -timeout 30s -cover $(shell go list ./...) --count=1
.PHONY: test-unit
test-unit: $(SOURCES)
go test -tags unit -race -timeout 30s -cover $(shell go list ./... | grep -v e2e) --count=1

.PHONY: test-e2e
test-e2e:
go test -timeout 30m ./e2e -test.v -ginkgo.v --binary "$(AWS_CONTAINERD_LOGGERS_BINARY)"

.PHONY: test-e2e-for-awslogs
test-e2e:
go test -timeout 30m ./e2e -test.v -ginkgo.v --binary "$(AWS_CONTAINERD_LOGGERS_BINARY)" --log-driver "awslogs"
Comment on lines +30 to +36

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these rules are duplicate, did you mean for the second to bee test-e2e-awslogs?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah will fix in a separated PR.


.PHONY: coverage
coverage:
go test -tags unit $(shell go list ./...) -coverprofile=test-coverage.out
go test -tags unit $(shell go list ./... | grep -v e2e) -coverprofile=test-coverage.out
go tool cover -html=test-coverage.out

.PHONY: lint
Expand Down
107 changes: 107 additions & 0 deletions e2e/awslogs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package e2e

import (
"context"
"fmt"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs"
"github.com/containerd/containerd"
"github.com/containerd/containerd/cio"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/oci"
"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
)

const (
awslogsCredentialsEndpointKey = "--awslogs-credentials-endpoint"
awslogsRegionKey = "--awslogs-region"
awslogsStreamKey = "--awslogs-stream"
awslogsGroupKey = "--awslogs-group"
testEcsLocalEndpointPort = "51679"
testAwslogsCredentialEndpoint = ":" + testEcsLocalEndpointPort + "/creds"
testAwslogsRegion = "us-west-2"
testAwsLogsStream = "test-stream"
testAwsLogsGroup = "test-shim-logger"
testAwsLogsMessage = "test-e2e-log"
)

var testAwslogs = func() {
// These tests are run in serial because we only define one log driver instance.
ginkgo.Describe("awslogs shim logger", ginkgo.Serial, func() { //nolint:typecheck
var cwClient *cloudwatchlogs.Client
ginkgo.BeforeEach(func() {
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(testAwslogsRegion))
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
cwClient = cloudwatchlogs.NewFromConfig(cfg)
_, err = cwClient.DeleteLogStream(context.TODO(), &cloudwatchlogs.DeleteLogStreamInput{
LogStreamName: aws.String(testAwsLogsStream),
LogGroupName: aws.String(testAwsLogsGroup),
})
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
})
ginkgo.AfterEach(func() {
_, err := cwClient.DeleteLogStream(context.TODO(), &cloudwatchlogs.DeleteLogStreamInput{
LogStreamName: aws.String(testAwsLogsStream),
LogGroupName: aws.String(testAwsLogsGroup),
})
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
})
ginkgo.It("should send logs to awslogs log driver", func() { //nolint:typecheck
args := map[string]string{
logDriverTypeKey: awslogsDriverName,
containerIdKey: testContainerId,
containerNameKey: testContainerName,
awslogsCredentialsEndpointKey: testAwslogsCredentialEndpoint,
awslogsRegionKey: testAwslogsRegion,
awslogsGroupKey: testAwsLogsGroup,
awslogsStreamKey: testAwsLogsStream,
}
creator := cio.BinaryIO(*Binary, args)
// Create a new client connected to the containerd daemon
client, err := containerd.New(containerdAddress)
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
defer client.Close()
// Create a new context with a customized namespace
ctx := namespaces.WithNamespace(context.Background(), "testAwslogs")
// Pull an image
image, err := client.Pull(ctx, testImage, containerd.WithPullUnpack)
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
// Create a new container with the pulled image
container, err := client.NewContainer(ctx, testContainerId, containerd.WithImage(image),
containerd.WithNewSnapshot("test-snapshot", image), containerd.WithNewSpec(oci.WithImageConfig(image),
oci.WithProcessArgs("/bin/sh", "-c", fmt.Sprintf("echo '%s'", testAwsLogsMessage))))
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
defer container.Delete(ctx, containerd.WithSnapshotCleanup) //nolint:errcheck // testing only
// Create a new task from the container and start it
task, err := container.NewTask(ctx, creator)
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
defer task.Delete(ctx) //nolint:errcheck // testing only

err = task.Start(ctx)
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())

statusC, err := task.Wait(ctx)
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
// Waiting for the task to finish
status := <-statusC
code, _, err := status.Result()
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
gomega.Expect(code).Should(gomega.Equal(uint32(0)))

// Validating in AWS logs
cwOutput, err := cwClient.GetLogEvents(context.TODO(), &cloudwatchlogs.GetLogEventsInput{
LogStreamName: aws.String(testAwsLogsStream),
LogGroupName: aws.String(testAwsLogsGroup),
Limit: aws.Int32(1),
})
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
gomega.Expect(*cwOutput.Events[0].Message).Should(gomega.Equal(testAwsLogsMessage))
})
})
}
43 changes: 43 additions & 0 deletions e2e/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package e2e

import (
"flag"
"testing"

"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
)

const (
// LogDriver options
logDriverTypeKey = "--log-driver"
awslogsDriverName = "awslogs"
containerIdKey = "--container-id"
containerNameKey = "--container-name"
testContainerId = "test-container-id"
testContainerName = "test-container-name"
containerdAddress = "/run/containerd/containerd.sock"
testImage = "public.ecr.aws/docker/library/ubuntu:latest"
)

var (
// Binary is the path the binary of the shim loggers for containerd
Binary = flag.String("binary", "", "the binary of shim loggers for containerd")
LogDriver = flag.String("log-driver", "", "the log driver to test")
)

func TestShimLoggers(t *testing.T) {
const description = "Shim loggers for containerd E2E Tests"

ginkgo.Describe("", func() {
if *LogDriver == awslogsDriverName || *LogDriver == "" {
testAwslogs()
}
})

gomega.RegisterFailHandler(ginkgo.Fail)
ginkgo.RunSpecs(t, description)
}
84 changes: 60 additions & 24 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,71 +1,107 @@
module github.com/aws/shim-loggers-for-containerd

require (
github.com/aws/aws-sdk-go-v2 v1.21.0
github.com/aws/aws-sdk-go-v2/config v1.18.39
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.23.5
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575
github.com/containerd/containerd v1.5.18
github.com/containerd/containerd v1.6.18
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e
github.com/docker/docker v20.10.13+incompatible
github.com/docker/go-units v0.4.0
github.com/golang/mock v1.6.0
github.com/onsi/ginkgo/v2 v2.11.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.4.0
github.com/stretchr/testify v1.8.1
golang.org/x/sync v0.1.0
golang.org/x/sync v0.2.0
gotest.tools v2.2.0+incompatible
)

require (
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/aws/aws-sdk-go v1.34.0 // indirect
github.com/Microsoft/hcsshim v0.9.6 // indirect
github.com/aws/aws-sdk-go v1.45.9 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.13.37 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.11 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.41 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.35 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.42 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.35 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.13.6 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.6 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.21.5 // indirect
github.com/aws/smithy-go v1.14.2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/containerd/cgroups v1.0.4 // indirect
github.com/containerd/continuity v0.3.0 // indirect
github.com/containerd/fifo v1.0.0 // indirect
github.com/containerd/ttrpc v1.1.0 // indirect
github.com/containerd/typeurl v1.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/fluent/fluent-logger-golang v1.9.0 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/gogo/googleapis v1.4.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jmespath/go-jmespath v0.3.0 // indirect
github.com/kr/pretty v0.2.1 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/klauspost/compress v1.11.13 // indirect
github.com/magiconair/properties v1.8.0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mitchellh/mapstructure v1.1.2 // indirect
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/sys/mountinfo v0.5.0 // indirect
github.com/moby/sys/signal v0.6.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/pelletier/go-toml v1.8.1 // indirect
github.com/philhofer/fwd v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
github.com/opencontainers/runc v1.1.2 // indirect
github.com/opencontainers/runtime-spec v1.1.0 // indirect
github.com/opencontainers/selinux v1.10.1 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.11.1 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.26.0 // indirect
github.com/prometheus/procfs v0.6.0 // indirect
github.com/prometheus/common v0.30.0 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/spf13/afero v1.9.2 // indirect
github.com/spf13/cast v1.3.0 // indirect
github.com/spf13/jwalterweatherman v1.0.0 // indirect
github.com/tinylib/msgp v1.1.1 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/time v0.1.0 // indirect
golang.org/x/tools v0.9.3 // indirect
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
google.golang.org/grpc v1.53.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

require (
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/fluent/fluent-logger-golang v1.9.0 // indirect
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/onsi/gomega v1.27.8
github.com/philhofer/fwd v1.0.0 // indirect
github.com/prometheus/client_golang v1.11.1 // indirect
github.com/tinylib/msgp v1.1.1 // indirect
google.golang.org/grpc v1.53.0 // indirect
)

replace github.com/docker/docker v20.10.13+incompatible => github.com/dharmadheeraj/moby v20.10.14-0.20220615184823-6b50baca60ea+incompatible

go 1.17
go 1.21
Loading
Loading