Skip to content

Commit

Permalink
fix(deps): upgrade to Go to 1.22, upgrade golanglintci to 1.56
Browse files Browse the repository at this point in the history
This PR builds sdk-test-harness with Go 1.22, up from Go 1.18. 

Additionally, golanglintci is upgraded to 1.56 and newly failing lints are fixed.
  • Loading branch information
cwaldren-ld authored Feb 21, 2024
1 parent 5dae36b commit 4159378
Show file tree
Hide file tree
Showing 18 changed files with 53 additions and 54 deletions.
2 changes: 1 addition & 1 deletion .github/actions/ci/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ runs:
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: 1.18
go-version: 1.22
- name: Run tests
shell: bash
run: make test
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
name: Publish Release

on:
workflow_call:
inputs:
Expand Down
10 changes: 2 additions & 8 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ run:
linters:
enable:
- bodyclose
- deadcode
- depguard
- dupl
- errcheck
- gochecknoglobals
Expand All @@ -24,18 +22,14 @@ linters:
- megacheck
- misspell
- nakedret
#- nolintlint
# nolintlint is currently disabled because some linters don't yet work with Go 1.18, but we may have nolint
# directives that would be needed to suppress those linters if they did work.
- nolintlint
- prealloc
- staticcheck
- structcheck
- stylecheck
- typecheck
- unconvert
- unparam
- unused
- varcheck
- whitespace
fast: false

Expand All @@ -44,7 +38,7 @@ linters-settings:
simplify: false
goimports:
local-prefixes: gopkg.in/launchdarkly,github.com/launchdarkly

issues:
exclude-use-default: false
max-same-issues: 1000
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This page is for people doing development of the SDK test harness itself. See al

## Tools used

To build and test the tool locally, you will need Go 1.18 or higher.
To build and test the tool locally, you will need Go 1.22 or higher.

You do not need to install any other development tools used for the SDKs in order to build the test harness. Generally, each SDK project will include a corresponding test service which will be built using the same tools as that SDK.

Expand Down
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

GORELEASER_VERSION=v1.7.0
GORELEASER_DOWNLOAD_URL=https://github.com/goreleaser/goreleaser/releases/download/v1.7.0/goreleaser_$(shell uname)_$(shell uname -m).tar.gz
GORELEASER_VERSION=v1.24.0
GORELEASER_DOWNLOAD_URL=https://github.com/goreleaser/goreleaser/releases/download/v1.24.0/goreleaser_$(shell uname)_$(shell uname -m).tar.gz
GORELEASER=./bin/goreleaser/goreleaser

GOLANGCI_LINT_VERSION=v1.45.2
GOLANGCI_LINT_VERSION=v1.56.2

LINTER=./bin/golangci-lint
LINTER_VERSION_FILE=./bin/.golangci-lint-version-$(GOLANGCI_LINT_VERSION)
Expand Down
20 changes: 10 additions & 10 deletions data/context_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,11 @@ func (f *ContextFactory) SetKeyDisambiguatorValueSameAs(f1 *ContextFactory) {
// Each will have an appropriate Description, so the logic for running a test against each one can look
// like this:
//
// for _, contexts := range data.NewContextFactoriesForSingleAndMultiKind("NameOfTest") {
// t.Run(contexts.Description(), func(t *testing.T) {
// context := contexts.NextUniqueContext() // do something with this
// })
// }
// for _, contexts := range data.NewContextFactoriesForSingleAndMultiKind("NameOfTest") {
// t.Run(contexts.Description(), func(t *testing.T) {
// context := contexts.NextUniqueContext() // do something with this
// })
// }
func NewContextFactoriesForSingleAndMultiKind(
prefix string, builderActions ...func(*ldcontext.Builder),
) []*ContextFactory {
Expand All @@ -130,11 +130,11 @@ func NewContextFactoriesForSingleAndMultiKind(
// Each will have an appropriate Description, so the logic for running a test against each one can look
// like this:
//
// for _, contexts := range data.NewContextFactoriesForExercisingAllAttributes("NameOfTest") {
// t.Run(contexts.Description(), func(t *testing.T) {
// context := contexts.NextUniqueContext() // do something with this
// })
// }
// for _, contexts := range data.NewContextFactoriesForExercisingAllAttributes("NameOfTest") {
// t.Run(contexts.Description(), func(t *testing.T) {
// context := contexts.NextUniqueContext() // do something with this
// })
// }
func NewContextFactoriesForExercisingAllAttributes(
prefix string,
) []*ContextFactory {
Expand Down
1 change: 1 addition & 0 deletions framework/harness/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ func startServer(port int, handler http.Handler) error {
}
handler.ServeHTTP(w, r)
}),
ReadHeaderTimeout: 10 * time.Second, // arbitrary but non-infinite timeout to avoid Slowloris Attack
}
go func() {
if err := server.ListenAndServe(); err != nil {
Expand Down
11 changes: 6 additions & 5 deletions framework/helpers/assertions.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import (
"time"
)

// Calls testFn repeatedly at intervals until the expected value is seen or the timeout elapses.
// PollForSpecificResultValue calls testFn repeatedly at intervals until the expected value is seen or the timeout
// elapses.
// Returns true if the value was matched, false if timed out.
func PollForSpecificResultValue[V comparable](
testFn func() V,
Expand All @@ -28,7 +29,7 @@ func PollForSpecificResultValue[V comparable](
}
}

// Equivalent to assert.Eventually from stretchr/testify/assert, except that it does not use a
// AssertEventually is equivalent to assert.Eventually from stretchr/testify/assert, except that it does not use a
// separate goroutine so it does not cause problems with our test framework. It calls testFn
// repeatedly at intervals until it gets a true value; if the timeout elapses, the test fails.
func AssertEventually(
Expand All @@ -46,7 +47,7 @@ func AssertEventually(
return false
}

// Equivalent to require.Eventually from stretchr/testify/assert, except that it does not use a
// RequireEventually is equivalent to require.Eventually from stretchr/testify/assert, except that it does not use a
// separate goroutine so it does not cause problems with our test framework. It calls testFn
// repeatedly at intervals until it gets a true value; if the timeout elapses, the test fails
// and immediately exits.
Expand All @@ -63,7 +64,7 @@ func RequireEventually(
}
}

// Equivalent to assert.Never from stretchr/testify/assert, except that it does not use a
// AssertNever is equivalent to assert.Never from stretchr/testify/assert, except that it does not use a
// separate goroutine so it does not cause problems with our test framework. It calls testFn
// repeatedly at intervals until either the timeout elapses or it receives a true value; if
// it receives a true value, the test fails.
Expand All @@ -82,7 +83,7 @@ func AssertNever(
return true
}

// Equivalent to require.Never from stretchr/testify/assert, except that it does not use a
// RequireNever is equivalent to require.Never from stretchr/testify/assert, except that it does not use a
// separate goroutine so it does not cause problems with our test framework. It calls testFn
// repeatedly at intervals until either the timeout elapses or it receives a true value; if
// it receives a true value, the test fails and exits immediately
Expand Down
2 changes: 2 additions & 0 deletions framework/helpers/package_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package helpers contains various utilities for writing tests.
package helpers
3 changes: 1 addition & 2 deletions framework/opt/maybe.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ func (m Maybe[V]) OrElse(valueIfUndefined V) V {
// result of fmt.Sprintf with "%v".
func (m Maybe[V]) String() string {
if m.defined {
var v interface{}
v = m.value
v := interface{}(m.value)
if s, ok := v.(fmt.Stringer); ok {
return s.String()
}
Expand Down
2 changes: 1 addition & 1 deletion mockld/streaming_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func (s *StreamingService) makePutEvent() eventsource.Event {
}
}

// Sends an SSE event to all clients that are currently connected to the stream-- or, if no client
// PushEvent sends an SSE event to all clients that are currently connected to the stream-- or, if no client
// has connected yet, queues the event so that it will be sent (after the initial data) to the
// first client that connects. (The latter is necessary to avoid race conditions, since even after
// a connection is received on the stream endpoint, it is hard for the test logic to know when the
Expand Down
8 changes: 4 additions & 4 deletions sdktests/client_side_auto_env_attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,23 +88,23 @@ func doClientSideAutoEnvAttributesEventsNoCollisionsTests(t *ldtest.T) {
client.FlushEvents(t)
payload := events.ExpectAnalyticsEvents(t, defaultEventTimeout)

context_matchers := []m.Matcher{
contextMatchers := []m.Matcher{
m.JSONOptProperty("ld_application").Should(m.BeNil()),
m.JSONOptProperty("ld_device").Should(m.BeNil()),
}

if context.Multiple() {
for _, c := range context.GetAllIndividualContexts(nil) {
context_matchers = append(context_matchers, m.JSONProperty(string(c.Kind())).Should(m.Not(m.BeNil())))
contextMatchers = append(contextMatchers, m.JSONProperty(string(c.Kind())).Should(m.Not(m.BeNil())))
}
} else {
context_matchers = append(context_matchers, m.JSONProperty("kind").Should(m.Equal(string(context.Kind()))))
contextMatchers = append(contextMatchers, m.JSONProperty("kind").Should(m.Equal(string(context.Kind()))))
}

m.In(t).Assert(payload, m.Items(
append(
[]m.Matcher{IsIdentifyEvent()},
m.JSONProperty("context").Should(m.AllOf(context_matchers...)),
m.JSONProperty("context").Should(m.AllOf(contextMatchers...)),
)...,
))
})
Expand Down
4 changes: 4 additions & 0 deletions sdktests/common_tests_events_base.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func NewCommonEventTests(t *ldtest.T, testName string, baseSDKConfigurers ...SDK
return CommonEventTests{newCommonTestsBase(t, testName, baseSDKConfigurers...)}
}

//nolint:unused // May not be used now, but could be helpful in new tests.
func (c CommonEventTests) discardIdentifyEventIfClientSide(t *ldtest.T, client *SDKClient, events *SDKEventSink) {
if c.isClientSide {
client.FlushEvents(t)
Expand All @@ -36,6 +37,7 @@ func (c CommonEventTests) initialEventPayloadExpectations() []m.Matcher {
return []m.Matcher{IsIdentifyEvent()}
}

//nolint:unused // May not be used now, but could be helpful in new tests.
func (c CommonEventTests) eventsWithIndexEventIfAppropriate(matchers ...m.Matcher) []m.Matcher {
// Server-side SDKs (excluding PHP) send an index event for each never-before-seen user. Client-side
// SDKs and the PHP SDK do not.
Expand All @@ -45,12 +47,14 @@ func (c CommonEventTests) eventsWithIndexEventIfAppropriate(matchers ...m.Matche
return append([]m.Matcher{IsIndexEvent()}, matchers...)
}

//nolint:unused // May not be used now, but could be helpful in new tests.
func (c CommonEventTests) eventsWithIndexEventAndSummaryEventIfAppropriate(matchers ...m.Matcher) []m.Matcher {
return c.eventsWithSummaryEventIfAppropriate(
c.eventsWithIndexEventIfAppropriate(matchers...)...,
)
}

//nolint:unused // May not be used now, but could be helpful in new tests.
func (c CommonEventTests) eventsWithSummaryEventIfAppropriate(matchers ...m.Matcher) []m.Matcher {
// The PHP SDK is the only one that never sends a summary event.
if c.isPHP {
Expand Down
4 changes: 2 additions & 2 deletions sdktests/common_tests_events_contexts.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ func (c CommonEventTests) EventContexts(t *ldtest.T) {

if user := representContextAsOldUser(t, context); user != nil {
t.Run("with old user", func(t *ldtest.T) {
_ = basicEvaluateFlagWithOldUser(t, client, flagKey, user, defaultValue)
basicEvaluateFlagWithOldUser(t, client, flagKey, user, defaultValue)
verifyResult(t)
})
}
Expand Down Expand Up @@ -263,7 +263,7 @@ func (c CommonEventTests) EventContexts(t *ldtest.T) {
if c.isClientSide {
client.SendIdentifyEventWithOldUser(t, user)
}
_ = basicEvaluateFlagWithOldUser(t, client, debuggedFlagKey, user, defaultValue)
basicEvaluateFlagWithOldUser(t, client, debuggedFlagKey, user, defaultValue)
client.FlushEvents(t)
payload := events.ExpectAnalyticsEvents(t, defaultEventTimeout)
eventMatchers := []m.Matcher{debugEventMatcher, IsSummaryEvent()}
Expand Down
5 changes: 2 additions & 3 deletions sdktests/common_tests_tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"time"

"github.com/launchdarkly/sdk-test-harness/v2/framework/harness"
"github.com/launchdarkly/sdk-test-harness/v2/framework/helpers"
h "github.com/launchdarkly/sdk-test-harness/v2/framework/helpers"
"github.com/launchdarkly/sdk-test-harness/v2/framework/ldtest"
o "github.com/launchdarkly/sdk-test-harness/v2/framework/opt"
Expand Down Expand Up @@ -48,7 +47,7 @@ func (c CommonTagsTests) Run(t *ldtest.T) {
}

withTagsConfig := func(tags servicedef.SDKConfigTagsParams) SDKConfigurer {
return helpers.ConfigOptionFunc[servicedef.SDKConfigParams](func(config *servicedef.SDKConfigParams) error {
return h.ConfigOptionFunc[servicedef.SDKConfigParams](func(config *servicedef.SDKConfigParams) error {
config.Tags = o.Some(tags)
return nil
})
Expand Down Expand Up @@ -171,7 +170,7 @@ func (c CommonTagsTests) Run(t *ldtest.T) {

makeStringOfLength := func(n int) string {
// makes nice strings that look like "12345678901234" etc. so it's easier to see when one is longer than another
b := make([]byte, n, n)
b := make([]byte, n)
for i := 0; i < n; i++ {
b[i] = byte('0' + ((i + 1) % 10))
}
Expand Down
5 changes: 2 additions & 3 deletions sdktests/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,13 @@ func basicEvaluateFlagWithOldUser(
flagKey string,
user json.RawMessage,
defaultValue ldvalue.Value,
) ldvalue.Value {
result := client.EvaluateFlag(t, servicedef.EvaluateFlagParams{
) {
client.EvaluateFlag(t, servicedef.EvaluateFlagParams{
FlagKey: flagKey,
User: user,
ValueType: servicedef.ValueTypeAny,
DefaultValue: defaultValue,
})
return result.Value
}

// computeExpectedBucketValue implements the bucketing hash value calculation as per the evaluation spec,
Expand Down
6 changes: 2 additions & 4 deletions sdktests/php_events_eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,7 @@ func doPHPFeatureEventTests(t *ldtest.T) {
withDebug: false,
malformed: false,
}].ReuseFlagForValueType(valueType)
var expectedValue ldvalue.Value
expectedValue = flagValues(valueType)
expectedValue := flagValues(valueType)
context := anonymousFactory.NextUniqueContext()
resp := client.EvaluateFlag(t, servicedef.EvaluateFlagParams{
FlagKey: flag.Key,
Expand Down Expand Up @@ -227,8 +226,7 @@ func doPHPFeatureEventTests(t *ldtest.T) {
withDebug: false,
malformed: false,
}].ReuseFlagForValueType(valueType)
var expectedValue ldvalue.Value
expectedValue = flagValues(valueType)
expectedValue := flagValues(valueType)
resp := client.EvaluateFlag(t, servicedef.EvaluateFlagParams{
FlagKey: flag.Key,
Context: o.Some(multiContext),
Expand Down
14 changes: 7 additions & 7 deletions sdktests/server_side_migrations.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// nolint:lll,dupl
//nolint:lll,dupl
package sdktests

import (
Expand Down Expand Up @@ -139,11 +139,11 @@ func executesOriginsInCorrectOrder(t *ldtest.T) {
t.DebugLogger(),
func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("old read")) // nolint:errcheck,gosec
_, _ = w.Write([]byte("old read"))
},
func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("new read")) // nolint:errcheck,gosec
_, _ = w.Write([]byte("new read"))
},
)
t.Defer(service.Close)
Expand Down Expand Up @@ -208,11 +208,11 @@ func executesReads(t *ldtest.T) {
t.DebugLogger(),
func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("old read")) // nolint:errcheck,gosec
_, _ = w.Write([]byte("old read"))
},
func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("new read")) // nolint:errcheck,gosec
_, _ = w.Write([]byte("new read"))
},
)
t.Defer(service.Close)
Expand Down Expand Up @@ -428,7 +428,7 @@ func tracksInvoked(t *ldtest.T, order ldmigration.ExecutionOrder) {
}
}

// nolint:dupl // Invokes and latency happen to share the same setup, but should be tested independently.
//nolint:dupl // Invokes and latency happen to share the same setup, but should be tested independently.
func tracksLatency(t *ldtest.T, order ldmigration.ExecutionOrder) {
onlyOld := []m.Matcher{m.JSONOptProperty("old").Should(m.Not(m.BeNil())), m.JSONOptProperty("new").Should(m.BeNil())}
both := []m.Matcher{m.JSONOptProperty("old").Should(m.Not(m.BeNil())), m.JSONOptProperty("new").Should(m.Not(m.BeNil()))}
Expand Down Expand Up @@ -936,7 +936,7 @@ func tracksConsistencyCorrectlyBasedOnStage(t *ldtest.T, order ldmigration.Execu
handler := func(response string) func(w http.ResponseWriter, req *http.Request) {
return func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(response)) // nolint:errcheck,gosec
_, _ = w.Write([]byte(response))
}
}
ld := handler("LaunchDarkly")
Expand Down

0 comments on commit 4159378

Please sign in to comment.