From d8759cccde426a19e973d48ec756fad30251b129 Mon Sep 17 00:00:00 2001 From: Zhiwei Liang <121905282+zliang-akamai@users.noreply.github.com> Date: Mon, 26 Feb 2024 11:48:35 -0500 Subject: [PATCH] Standardize Linode DX Makefile; cleanup duplicated integration tests (#196) --- .golangci.yml | 2 +- Makefile | 58 +++++--- builder/linode/builder_acc_test.go | 4 +- test/integration/e2e_test.go | 135 ------------------ .../template/test_image_template.json | 19 --- 5 files changed, 45 insertions(+), 173 deletions(-) delete mode 100644 test/integration/e2e_test.go delete mode 100644 test/integration/template/test_image_template.json diff --git a/.golangci.yml b/.golangci.yml index 89ed0b44..8759f21b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -44,7 +44,7 @@ run: concurrency: 4 # timeout for analysis, e.g. 30s, 5m, default is 1m - timeout: 10m + timeout: 15m # exit code when at least one issue was found, default is 1 issues-exit-code: 1 diff --git a/Makefile b/Makefile index 9f2443d1..5d2a272d 100644 --- a/Makefile +++ b/Makefile @@ -1,34 +1,48 @@ NAME=linode BINARY=packer-plugin-${NAME} -GOFMT_FILES?=$$(find . -name '*.go') COUNT?=1 -TEST?=$(shell go list ./builder/...) +UNIT_TEST_TARGET?=$(shell go list ./builder/...) HASHICORP_PACKER_PLUGIN_SDK_VERSION?=$(shell go list -m github.com/hashicorp/packer-plugin-sdk | cut -d " " -f2) +PACKER_SDC_REPO ?= github.com/hashicorp/packer-plugin-sdk/cmd/packer-sdc +.DEFAULT_GOAL = dev -.PHONY: dev - -build: fmtcheck - @go build -o ${BINARY} +# install is an alias of dev +.PHONY: install +install: dev +.PHONY: dev dev: build @mkdir -p ~/.packer.d/plugins/ @mv ${BINARY} ~/.packer.d/plugins/${BINARY} -test: dev fmtcheck - @PACKER_ACC=1 go test -count $(COUNT) ./... -v -timeout=100m +.PHONY: build +build: fmtcheck + @go build -o ${BINARY} + +.PHONY: test +test: dev fmtcheck acctest +.PHONY: install-packer-sdc install-packer-sdc: ## Install packer sofware development command - @go install github.com/hashicorp/packer-plugin-sdk/cmd/packer-sdc@${HASHICORP_PACKER_PLUGIN_SDK_VERSION} + @go install ${PACKER_SDC_REPO}@${HASHICORP_PACKER_PLUGIN_SDK_VERSION} +.PHONY: plugin-check plugin-check: install-packer-sdc build @packer-sdc plugin-check ${BINARY} +.PHONY: unit-test unit-test: dev - go test -count $(COUNT) -v $(TEST) -timeout=10m + @go test -count $(COUNT) -v $(UNIT_TEST_TARGET) -timeout=10m -int-test: dev - @go test -v test/integration/e2e_test.go +# int-test is an alias of acctest +.PHONY: int-test +int-test: acctest + +.PHONY: acctest +acctest: dev + @PACKER_ACC=1 go test -count $(COUNT) ./... -v -timeout=100m +.PHONY: generate generate: install-packer-sdc @go generate ./... @rm -rf .docs @@ -36,12 +50,24 @@ generate: install-packer-sdc @./.web-docs/scripts/compile-to-webdocs.sh "." ".docs" ".web-docs" "linode" @rm -r ".docs" +.PHONY: fmtcheck fmtcheck: @sh -c "'$(CURDIR)/scripts/gofmtcheck.sh'" +.PHONY: lint lint: fmtcheck - golangci-lint run --timeout 15m0s + @golangci-lint run -fmt: - gofmt -w $(GOFMT_FILES) - gofumpt -w . +.PHONY: format +format: + @gofumpt -w . + +.PHONY: deps +deps: install-packer-sdc + @go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest + @go install mvdan.cc/gofumpt@latest + +.PHONY: clean +clean: + @rm -rf .docs + @rm -rf ./packer-plugin-linode diff --git a/builder/linode/builder_acc_test.go b/builder/linode/builder_acc_test.go index e61b5406..3264f7a9 100644 --- a/builder/linode/builder_acc_test.go +++ b/builder/linode/builder_acc_test.go @@ -36,9 +36,9 @@ const testBuilderAccBasic = ` { "builders": [{ "type": "linode", - "region": "us-ord", + "region": "us-mia", "instance_type": "g6-nanode-1", - "image": "linode/debian11", + "image": "linode/debian12", "ssh_username": "root", "cloud_init": true }] diff --git a/test/integration/e2e_test.go b/test/integration/e2e_test.go deleted file mode 100644 index b9a5ded8..00000000 --- a/test/integration/e2e_test.go +++ /dev/null @@ -1,135 +0,0 @@ -package integration - -import ( - "context" - "fmt" - "net/http" - "os" - "os/exec" - "strconv" - "strings" - "testing" - "time" - - "github.com/linode/linodego" - "github.com/stretchr/testify/assert" - "golang.org/x/oauth2" -) - -const ( - packerTemplate = "template/test_image_template.json" -) - -func TestBuildPackerImage(t *testing.T) { - linodeToken := os.Getenv("LINODE_TOKEN") - - if linodeToken == "" { - t.Fatal("Linode token is not set. Please set LINODE_TOKEN as environment variable.") - } - - linodeImageLabel := generateImageLabel() - err := os.Setenv("LINODE_IMAGE_LABEL", linodeImageLabel) - if err != nil { - fmt.Printf("Error setting LINODE_IMAGE_LABEL: %v\n", err) - return - } - - // Run the Packer build command from terminal - cmd := exec.Command("packer", "build", packerTemplate) - - output, err := cmd.CombinedOutput() - - defer func() { - if err := teardown(linodeImageLabel); err != nil { - fmt.Printf("Error during deleting image after test execution: %v\n", err) - } - }() - - // Check if the Packer build was successful - if err != nil { - t.Fatalf("Error building Packer image: %v\nOutput:\n%s", err, output) - } - - // Assert the output contains expected strings - expectedSubstring := "Builds finished. The artifacts of successful builds" - assert.True(t, strings.Contains(string(output), expectedSubstring), "Expected successful build output to contain: %s", expectedSubstring) - - // Assert other fields - err = assertLinodeImage(linodeImageLabel, t) - - if err != nil { - t.Fatalf("Error asserting Linode builder image: %v", err) - } -} - -func assertLinodeImage(imageLabel string, t *testing.T) error { - client := getLinodegoClient() - - images, err := client.ListImages(context.Background(), nil) - if err != nil { - return fmt.Errorf("error listing Linode images: %v", err) - } - - // Find the desired image by label prefix - var targetImage *linodego.Image - for _, image := range images { - if image.Label != "" && strings.HasPrefix(image.Label, imageLabel) { - targetImage = &image - break - } - } - - if targetImage == nil { - return fmt.Errorf("image with label '%s' not found", imageLabel) - } - - assert.Equal(t, "manual", targetImage.Type, "unexpected instance type") - expectedInstanceIDFormat := "private/" - assert.True(t, strings.HasPrefix(targetImage.ID, expectedInstanceIDFormat), "unexpected instance ID prefix") - expectedInstanceLabel := "test-image-" - assert.True(t, strings.HasPrefix(targetImage.Label, expectedInstanceLabel), "unexpected instance label prefix") - expectedImageDescription := "My Test Image Description" - assert.Equal(t, expectedImageDescription, targetImage.Description, "unexpected image description") - - return nil -} - -func teardown(imageLabel string) error { - client := getLinodegoClient() - images, err := client.ListImages(context.Background(), nil) - if err != nil { - return fmt.Errorf("error listing Linode images: %v", err) - } - - for _, image := range images { - if image.Label != "" && strings.HasPrefix(image.Label, imageLabel) { - err = client.DeleteImage(context.Background(), image.ID) - if err != nil { - return fmt.Errorf("error during Linode image deletion: %v", err) - } - } - } - - return nil -} - -func getLinodegoClient() linodego.Client { - linodeToken := os.Getenv("LINODE_TOKEN") - - tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: linodeToken}) - oauth2Client := &http.Client{ - Transport: &oauth2.Transport{ - Source: tokenSource, - }, - } - linodeClient := linodego.NewClient(oauth2Client) - - return linodeClient -} - -func generateImageLabel() string { - timestamp := strconv.FormatInt(time.Now().UnixNano(), 10) // Shortened format without dashes - instanceLabel := fmt.Sprintf("test-image-%s", timestamp) - - return instanceLabel -} diff --git a/test/integration/template/test_image_template.json b/test/integration/template/test_image_template.json deleted file mode 100644 index 7808bf31..00000000 --- a/test/integration/template/test_image_template.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "variables": { - "linode_token": "{{env `LINODE_TOKEN`}}", - "instance_image_label": "{{env `LINODE_IMAGE_LABEL`}}" - }, - "builders": [{ - "type": "linode", - "linode_token": "{{ user `linode_token` }}", - "image": "linode/debian9", - "region": "us-east", - "instance_type": "g6-nanode-1", - "instance_label": "test-instance-{{timestamp}}", - - "image_label": "{{ user `instance_image_label` }}", - "image_description": "My Test Image Description", - - "ssh_username": "root" - }] -} \ No newline at end of file