From 0a86c6402ef12a15a9d435e8e4d88420a4d1e333 Mon Sep 17 00:00:00 2001 From: Nikita Vaniasin Date: Thu, 27 Apr 2023 16:19:20 +0200 Subject: [PATCH 1/4] Use Go 1.20.3 for testing. Add govulncheck to pipeline - golangci-lint version updated - enable test for VST: chunk_test.go fixed --- .golangci.yaml | 2 +- .travis.yml | 8 +- CHANGELOG.md | 1 + Makefile | 16 ++-- vst/protocol/chunk_test.go | 150 +++++++++++++++++++++++-------------- 5 files changed, 110 insertions(+), 67 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 6854ac3f..dc477092 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -42,7 +42,7 @@ linters: - gocognit - gofumpt - gocyclo - + - musttag # seems to be broken linters-settings: gci: sections: diff --git a/.travis.yml b/.travis.yml index 8ac0db0d..8a99ede1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,12 +27,12 @@ services: language: go go: - - 1.19.4 + - 1.20.3 env: global: - - GOIMAGE=gcr.io/gcr-for-testing/golang:1.19.4 - - ALPINE_IMAGE=gcr.io/gcr-for-testing/alpine:3.4 + - GOIMAGE=gcr.io/gcr-for-testing/golang:1.20.3 + - ALPINE_IMAGE=gcr.io/gcr-for-testing/alpine:3.17 - STARTER=gcr.io/gcr-for-testing/arangodb/arangodb-starter:0.15.7 jobs: - TEST_SUITE=run-unit-tests ALWAYS=1 @@ -52,7 +52,7 @@ before_script: - | if [ "$TRAVIS_PULL_REQUEST" != "false" ] || [ ! -z "$ALWAYS" ]; then make tools - make linter + make linter vulncheck fi script: diff --git a/CHANGELOG.md b/CHANGELOG.md index 03cb2eca..58d700c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - [V2] Fix: Plain Connection doesn't work with JWT authentication - Support for new error codes if write concern is not fulfilled - Support for geo_s2 analyzers +- Use Go 1.20.3 for testing. Add govulncheck to pipeline ## [1.5.2](https://github.com/arangodb/go-driver/tree/v1.5.2) (2023-03-01) - Bump `DRIVER_VERSION` diff --git a/Makefile b/Makefile index ee1d32d8..2f003734 100644 --- a/Makefile +++ b/Makefile @@ -6,10 +6,10 @@ SCRIPTDIR := $(shell pwd) CURR=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) ROOTDIR:=$(CURR) -GOVERSION ?= 1.19.4 +GOVERSION ?= 1.20.3 GOIMAGE ?= golang:$(GOVERSION) GOV2IMAGE ?= $(GOIMAGE) -ALPINE_IMAGE ?= alpine:3.14 +ALPINE_IMAGE ?= alpine:3.17 TMPDIR := ${SCRIPTDIR}/.tmp DOCKER_CMD:=docker run @@ -138,7 +138,7 @@ else DOCKER_V2_RUN_CMD := $(GOV2IMAGE) go test $(GOBUILDTAGSOPT) $(TESTOPTIONS) $(TESTVERBOSEOPTIONS) ./tests endif -.PHONY: all build clean linter run-tests +.PHONY: all build clean linter run-tests vulncheck all: build @@ -171,7 +171,7 @@ run-unit-tests: run-v2-unit-tests -e CGO_ENABLED=$(CGO_ENABLED) \ -w /usr/code/ \ $(GOIMAGE) \ - go test $(TESTOPTIONS) $(REPOPATH)/http $(REPOPATH)/agency + go test $(TESTOPTIONS) $(REPOPATH)/http $(REPOPATH)/agency $(REPOPATH)/vst/protocol run-v2-unit-tests: @$(DOCKER_CMD) \ @@ -500,11 +500,13 @@ run-benchmarks-single-vpack-no-auth: .PHONY: tools tools: __dir_setup @echo ">> Fetching golangci-lint linter" - @GOBIN=$(TMPDIR)/bin go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.50.1 + @GOBIN=$(TMPDIR)/bin go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.52.2 @echo ">> Fetching goimports" @GOBIN=$(TMPDIR)/bin go install golang.org/x/tools/cmd/goimports@v0.1.12 @echo ">> Fetching license check" @GOBIN=$(TMPDIR)/bin go install github.com/google/addlicense@v1.0.0 + @echo ">> Fetching govulncheck" + @GOBIN=$(TMPDIR)/bin go install golang.org/x/vuln/cmd/govulncheck@v0.1.0 .PHONY: license license: @@ -530,6 +532,10 @@ fmt-verify: license-verify linter: fmt-verify @$(TMPDIR)/bin/golangci-lint run ./... +.PHONY: vulncheck +vulncheck: + $(GOPATH)/bin/govulncheck ./... + # V2 v2-%: diff --git a/vst/protocol/chunk_test.go b/vst/protocol/chunk_test.go index 1bb833ce..3d3f3207 100644 --- a/vst/protocol/chunk_test.go +++ b/vst/protocol/chunk_test.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2017 ArangoDB GmbH, Cologne, Germany +// Copyright 2017-2023 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,19 +17,19 @@ // // Copyright holder is ArangoDB GmbH, Cologne, Germany // -// Author Ewout Prangsma -// package protocol import ( "bytes" "encoding/hex" + "fmt" + "io" "reflect" "testing" ) -type readChunksTest struct { +type readChunksSample struct { ChunkHex string MessageID uint64 MessageLength uint64 @@ -40,8 +40,8 @@ type readChunksTest struct { } func TestReadChunk(t *testing.T) { - tests := []readChunksTest{ - { + chunkSamples := map[Version]readChunksSample{ + Version1_0: { ChunkHex: "1b0000000900000037020000000000000c00000000000000010203", MessageID: 567, MessageLength: 12, @@ -50,7 +50,7 @@ func TestReadChunk(t *testing.T) { NumberOfChunks: 4, Data: []byte{1, 2, 3}, }, - { + Version1_1: { ChunkHex: "1b0000000200000037020000000000000c00000000000000040506", MessageID: 567, MessageLength: 12, @@ -60,41 +60,64 @@ func TestReadChunk(t *testing.T) { Data: []byte{4, 5, 6}, }, } + testCases := map[string]struct { + version Version + readChunk func(r io.Reader) (chunk, error) + }{ + "1.0_reads_1.0": { + version: Version1_0, + readChunk: readChunkVST1_0, + }, + "1.1_reads_1.0": { + version: Version1_0, + readChunk: readChunkVST1_1, + }, + "1.1_reads_1.1": { + version: Version1_1, + readChunk: readChunkVST1_1, + }, + } - for _, test := range tests { - raw, err := hex.DecodeString(test.ChunkHex) - if err != nil { - t.Fatalf("Hex decode failed: %#v", err) - } - r := bytes.NewReader(raw) - var c chunk - //nolint:typecheck - c, err = readChunk(r) - if err != nil { - t.Errorf("ReadChunk for '%s' failed: %#v", test.ChunkHex, err) - } - if c.IsFirst() != test.IsFirst { - t.Errorf("IsFirst for '%s' is invalid. \nGot '%v'\nExpected '%v'", test.ChunkHex, c.IsFirst(), test.IsFirst) - } - if c.Index() != test.Index { - t.Errorf("Index for '%s' is invalid. \nGot '%v'\nExpected '%v'", test.ChunkHex, c.Index(), test.Index) - } - if c.NumberOfChunks() != test.NumberOfChunks { - t.Errorf("NumberOfChunks for '%s' is invalid. \nGot '%v'\nExpected '%v'", test.ChunkHex, c.NumberOfChunks(), test.NumberOfChunks) - } - if c.MessageID != test.MessageID { - t.Errorf("MessageID for '%s' is invalid. \nGot '%v'\nExpected '%v'", test.ChunkHex, c.MessageID, test.MessageID) - } - if c.MessageLength != test.MessageLength { - t.Errorf("MessageLength for '%s' is invalid. \nGot '%v'\nExpected '%v'", test.ChunkHex, c.MessageLength, test.MessageLength) - } - if !reflect.DeepEqual(c.Data, test.Data) { - t.Errorf("Data for '%s' is invalid. \nGot '%v'\nExpected '%v'", test.ChunkHex, c.Data, test.Data) - } + for testName, testCase := range testCases { + t.Run(testName, func(t *testing.T) { + test, ok := chunkSamples[testCase.version] + if !ok { + t.Fatalf("not found chunk sample for version %d", testCase.version) + } + raw, err := hex.DecodeString(test.ChunkHex) + if err != nil { + t.Fatalf("Hex decode failed: %#v", err) + } + r := bytes.NewReader(raw) + var c chunk + c, err = testCase.readChunk(r) + if err != nil { + t.Errorf("ReadChunk for '%s' failed: %#v", test.ChunkHex, err) + } + if c.IsFirst() != test.IsFirst { + t.Errorf("IsFirst for '%s' is invalid. \nGot '%v'\nExpected '%v'", test.ChunkHex, c.IsFirst(), test.IsFirst) + } + if c.Index() != test.Index { + t.Errorf("Index for '%s' is invalid. \nGot '%v'\nExpected '%v'", test.ChunkHex, c.Index(), test.Index) + } + if c.NumberOfChunks() != test.NumberOfChunks { + t.Errorf("NumberOfChunks for '%s' is invalid. \nGot '%v'\nExpected '%v'", test.ChunkHex, c.NumberOfChunks(), test.NumberOfChunks) + } + if c.MessageID != test.MessageID { + t.Errorf("MessageID for '%s' is invalid. \nGot '%v'\nExpected '%v'", test.ChunkHex, c.MessageID, test.MessageID) + } + if c.MessageLength != test.MessageLength { + t.Errorf("MessageLength for '%s' is invalid. \nGot '%v'\nExpected '%v'", test.ChunkHex, c.MessageLength, test.MessageLength) + } + if !reflect.DeepEqual(c.Data, test.Data) { + t.Errorf("Data for '%s' is invalid. \nGot '%v'\nExpected '%v'", test.ChunkHex, c.Data, test.Data) + } + }) } } type buildChunksTest struct { + VSTVersion Version MessageID uint64 MaxChunkSize uint32 MessageParts [][]byte @@ -103,7 +126,9 @@ type buildChunksTest struct { func TestBuildChunks(t *testing.T) { tests := []buildChunksTest{ + // Note: there are no tests for 1.0 version { + VSTVersion: Version1_1, MessageID: 567, MaxChunkSize: 24 + 3, MessageParts: [][]byte{ @@ -119,6 +144,7 @@ func TestBuildChunks(t *testing.T) { }, }, { + VSTVersion: Version1_1, MessageID: 567, MaxChunkSize: 24 + 6, MessageParts: [][]byte{ @@ -134,28 +160,38 @@ func TestBuildChunks(t *testing.T) { }, } - for _, test := range tests { - chunks, err := buildChunks(test.MessageID, test.MaxChunkSize, test.MessageParts...) - if err != nil { - t.Fatalf("BuildChunks failed: %#v", err) - } - - if len(chunks) != len(test.ExpectedChunksHex) { - t.Errorf("Expected %d chunks, got %d", len(test.ExpectedChunksHex), len(chunks)) - } - for i, expected := range test.ExpectedChunksHex { - if i >= len(chunks) { - continue + for i, test := range tests { + t.Run(fmt.Sprintf("test_%d", i), func(t *testing.T) { + chunks, err := buildChunks(test.MessageID, test.MaxChunkSize, test.MessageParts...) + if err != nil { + t.Fatalf("BuildChunks failed: %#v", err) } - var buf bytes.Buffer - //nolint:typecheck - if _, err := chunks[i].WriteTo(&buf); err != nil { - t.Errorf("Failed to write chunk %d: %#v", i, err) + if len(chunks) != len(test.ExpectedChunksHex) { + t.Errorf("Expected %d chunks, got %d", len(test.ExpectedChunksHex), len(chunks)) } - actual := hex.EncodeToString(buf.Bytes()) - if expected != actual { - t.Errorf("Chunk %d is invalid. \nGot '%s'\nExpected '%s'", i, actual, expected) + for i, expected := range test.ExpectedChunksHex { + if i >= len(chunks) { + continue + } + var buf bytes.Buffer + var err error + switch test.VSTVersion { + case Version1_0: + _, err = chunks[i].WriteToVST1_0(&buf) + case Version1_1: + _, err = chunks[i].WriteToVST1_1(&buf) + default: + t.Fatalf("vst version %s not supported", test.VSTVersion) + return + } + if err != nil { + t.Errorf("Failed to write chunk %d: %#v", i, err) + } + actual := hex.EncodeToString(buf.Bytes()) + if expected != actual { + t.Errorf("Chunk %d is invalid. \nGot '%s'\nExpected '%s'", i, actual, expected) + } } - } + }) } } From c90bbe2a2d4bf5e28bded18a579461abc3e256c7 Mon Sep 17 00:00:00 2001 From: Nikita Vaniasin Date: Thu, 27 Apr 2023 16:36:39 +0200 Subject: [PATCH 2/4] Fix vulncheck path --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2f003734..57c6e5a3 100644 --- a/Makefile +++ b/Makefile @@ -534,7 +534,7 @@ linter: fmt-verify .PHONY: vulncheck vulncheck: - $(GOPATH)/bin/govulncheck ./... + $(TMPDIR)/bin/govulncheck ./... # V2 From cbb913d24f9645b3996c65fd2513317c510dabc4 Mon Sep 17 00:00:00 2001 From: Nikita Vaniasin Date: Thu, 27 Apr 2023 17:25:36 +0200 Subject: [PATCH 3/4] Fix format for Fatalf in test --- vst/protocol/chunk_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vst/protocol/chunk_test.go b/vst/protocol/chunk_test.go index 3d3f3207..f8bcbcdb 100644 --- a/vst/protocol/chunk_test.go +++ b/vst/protocol/chunk_test.go @@ -181,7 +181,7 @@ func TestBuildChunks(t *testing.T) { case Version1_1: _, err = chunks[i].WriteToVST1_1(&buf) default: - t.Fatalf("vst version %s not supported", test.VSTVersion) + t.Fatalf("vst version %d not supported", test.VSTVersion) return } if err != nil { From 229adece79e500b99a0e9f9cf9ba85f0719b0515 Mon Sep 17 00:00:00 2001 From: Nikita Vaniasin Date: Wed, 10 May 2023 19:10:17 +0200 Subject: [PATCH 4/4] Remove vulncheck from travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8a99ede1..9e680394 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,7 +52,7 @@ before_script: - | if [ "$TRAVIS_PULL_REQUEST" != "false" ] || [ ! -z "$ALWAYS" ]; then make tools - make linter vulncheck + make linter fi script: