diff --git a/.golangci.yaml b/.golangci.yaml index a983c508..50740ea3 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -18,6 +18,7 @@ linters: - ireturn - perfsprint - gocritic + - paralleltest linters-settings: errcheck: check-type-assertions: true diff --git a/internal/mux/response_test.go b/internal/mux/response_test.go index 2ec907d9..e70dbc9d 100644 --- a/internal/mux/response_test.go +++ b/internal/mux/response_test.go @@ -9,6 +9,8 @@ import ( ) func TestResponseWriter(t *testing.T) { + t.Parallel() + var rw http.ResponseWriter = &response{} _, ok := rw.(io.ReaderFrom) require.True(t, ok) diff --git a/pkg/oci/containerd_test.go b/pkg/oci/containerd_test.go index 5ac8b393..d89b06d7 100644 --- a/pkg/oci/containerd_test.go +++ b/pkg/oci/containerd_test.go @@ -13,6 +13,8 @@ import ( ) func TestVerifyStatusResponse(t *testing.T) { + t.Parallel() + tests := []struct { name string configPath string @@ -57,6 +59,8 @@ func TestVerifyStatusResponse(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Parallel() + resp := &runtimeapi.StatusResponse{ Info: map[string]string{ "config": fmt.Sprintf(`{"registry": {"configPath": %q}, "containerd": {"runtimes":{"discardUnpackedLayers": %v}}}`, tt.configPath, tt.discardUnpackedLayers), @@ -73,6 +77,8 @@ func TestVerifyStatusResponse(t *testing.T) { } func TestCreateFilter(t *testing.T) { + t.Parallel() + tests := []struct { name string expectedListFilter string @@ -95,6 +101,8 @@ func TestCreateFilter(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Parallel() + listFilter, eventFilter := createFilters(stringListToUrlList(t, tt.registries)) require.Equal(t, tt.expectedListFilter, listFilter) require.Equal(t, tt.expectedEventFilter, eventFilter) @@ -103,6 +111,8 @@ func TestCreateFilter(t *testing.T) { } func TestMirrorConfiguration(t *testing.T) { + t.Parallel() + registryConfigPath := "/etc/containerd/certs.d" tests := []struct { @@ -307,6 +317,8 @@ capabilities = ['pull', 'resolve'] } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Parallel() + fs := afero.NewMemMapFs() if tt.createConfigPathDir { err := fs.Mkdir(registryConfigPath, 0o755) @@ -340,6 +352,8 @@ capabilities = ['pull', 'resolve'] } func TestMirrorConfigurationInvalidMirrorURL(t *testing.T) { + t.Parallel() + fs := afero.NewMemMapFs() mirrors := stringListToUrlList(t, []string{"http://127.0.0.1:5000"}) diff --git a/pkg/oci/image_test.go b/pkg/oci/image_test.go index 635a1178..e88a1cd1 100644 --- a/pkg/oci/image_test.go +++ b/pkg/oci/image_test.go @@ -9,6 +9,8 @@ import ( ) func TestParseImage(t *testing.T) { + t.Parallel() + tests := []struct { name string image string @@ -54,6 +56,8 @@ func TestParseImage(t *testing.T) { for _, registry := range registries { for _, tt := range tests { t.Run(fmt.Sprintf("%s_%s", tt.name, registry), func(t *testing.T) { + t.Parallel() + for _, extraDgst := range []string{tt.expectedDigest.String(), ""} { img, err := Parse(fmt.Sprintf("%s/%s", registry, tt.image), digest.Digest(extraDgst)) if !tt.digestInImage && extraDgst == "" { @@ -73,11 +77,15 @@ func TestParseImage(t *testing.T) { } func TestParseImageDigestDoesNotMatch(t *testing.T) { + t.Parallel() + _, err := Parse("quay.io/jetstack/cert-manager-webhook@sha256:13fd9eaadb4e491ef0e1d82de60cb199f5ad2ea5a3f8e0c19fdf31d91175b9cb", digest.Digest("sha256:ec4306b243d98cce7c3b1f994f2dae660059ef521b2b24588cfdc950bd816d4c")) require.EqualError(t, err, "invalid digest set does not match parsed digest: quay.io/jetstack/cert-manager-webhook@sha256:13fd9eaadb4e491ef0e1d82de60cb199f5ad2ea5a3f8e0c19fdf31d91175b9cb sha256:13fd9eaadb4e491ef0e1d82de60cb199f5ad2ea5a3f8e0c19fdf31d91175b9cb") } func TestParseImageNoTagOrDigest(t *testing.T) { + t.Parallel() + _, err := Parse("ghcr.io/spegel-org/spegel", digest.Digest("")) require.EqualError(t, err, "image needs to contain a digest") } diff --git a/pkg/oci/oci_test.go b/pkg/oci/oci_test.go index 8be912b2..305c0ad9 100644 --- a/pkg/oci/oci_test.go +++ b/pkg/oci/oci_test.go @@ -22,6 +22,8 @@ import ( ) func TestOCIClient(t *testing.T) { + t.Parallel() + b, err := os.ReadFile("./testdata/images.json") require.NoError(t, err) imgs := []map[string]string{} @@ -84,6 +86,8 @@ func TestOCIClient(t *testing.T) { for _, ociClient := range []Client{remoteContainerd, localContainerd} { t.Run(ociClient.Name(), func(t *testing.T) { + t.Parallel() + imgs, err := ociClient.ListImages(ctx) require.NoError(t, err) require.Len(t, imgs, 5) @@ -130,6 +134,8 @@ func TestOCIClient(t *testing.T) { } for _, tt := range contentTests { t.Run(tt.mediaType, func(t *testing.T) { + t.Parallel() + size, err := ociClient.Size(ctx, tt.dgst) require.NoError(t, err) require.Equal(t, tt.size, size) @@ -249,6 +255,8 @@ func TestOCIClient(t *testing.T) { } for _, tt := range identifiersTests { t.Run(tt.imageName, func(t *testing.T) { + t.Parallel() + img, err := Parse(tt.imageName, digest.Digest(tt.imageDigest)) require.NoError(t, err) keys, err := ociClient.AllIdentifiers(ctx, img) diff --git a/pkg/registry/distribution_test.go b/pkg/registry/distribution_test.go index 474277ee..b932f9ab 100644 --- a/pkg/registry/distribution_test.go +++ b/pkg/registry/distribution_test.go @@ -8,6 +8,8 @@ import ( ) func TestParsePathComponents(t *testing.T) { + t.Parallel() + tests := []struct { name string registry string @@ -35,6 +37,8 @@ func TestParsePathComponents(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Parallel() + ref, err := parsePathComponents(tt.registry, tt.path) require.NoError(t, err) require.Equal(t, tt.expectedName, ref.name) @@ -45,11 +49,15 @@ func TestParsePathComponents(t *testing.T) { } func TestParsePathComponentsInvalidPath(t *testing.T) { + t.Parallel() + _, err := parsePathComponents("example.com", "/v2/spegel-org/spegel/v0.0.1") require.EqualError(t, err, "distribution path could not be parsed") } func TestParsePathComponentsMissingRegistry(t *testing.T) { + t.Parallel() + _, err := parsePathComponents("", "/v2/spegel-org/spegel/manifests/v0.0.1") require.EqualError(t, err, "registry parameter needs to be set for tag references") } diff --git a/pkg/registry/registry_test.go b/pkg/registry/registry_test.go index 119ccf92..6c645049 100644 --- a/pkg/registry/registry_test.go +++ b/pkg/registry/registry_test.go @@ -15,6 +15,8 @@ import ( ) func TestMirrorHandler(t *testing.T) { + t.Parallel() + badSvr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) w.Header().Set("foo", "bar") @@ -23,7 +25,9 @@ func TestMirrorHandler(t *testing.T) { w.Write([]byte("hello world")) } })) - defer badSvr.Close() + t.Cleanup(func() { + badSvr.Close() + }) badAddrPort := netip.MustParseAddrPort(badSvr.Listener.Addr().String()) goodSvr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("foo", "bar") @@ -32,7 +36,9 @@ func TestMirrorHandler(t *testing.T) { w.Write([]byte("hello world")) } })) - defer goodSvr.Close() + t.Cleanup(func() { + goodSvr.Close() + }) goodAddrPort := netip.MustParseAddrPort(goodSvr.Listener.Addr().String()) unreachableAddrPort := netip.MustParseAddrPort("127.0.0.1:0") @@ -91,6 +97,8 @@ func TestMirrorHandler(t *testing.T) { for _, tt := range tests { for _, method := range []string{http.MethodGet, http.MethodHead} { t.Run(fmt.Sprintf("%s-%s", method, tt.name), func(t *testing.T) { + t.Parallel() + target := fmt.Sprintf("http://example.com/v2/foo/bar/blobs/%s", tt.key) rw := httptest.NewRecorder() req := httptest.NewRequest(method, target, nil) @@ -122,6 +130,8 @@ func TestMirrorHandler(t *testing.T) { } func TestGetClientIP(t *testing.T) { + t.Parallel() + tests := []struct { name string request *http.Request @@ -155,6 +165,8 @@ func TestGetClientIP(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Parallel() + ip := getClientIP(tt.request) require.Equal(t, tt.expected, ip) }) diff --git a/pkg/routing/bootstrap_test.go b/pkg/routing/bootstrap_test.go index 06b522d5..207f21fb 100644 --- a/pkg/routing/bootstrap_test.go +++ b/pkg/routing/bootstrap_test.go @@ -10,6 +10,8 @@ import ( ) func TestHTTPBootstrap(t *testing.T) { + t.Parallel() + ctx, cancel := context.WithCancel(context.TODO()) defer cancel() diff --git a/pkg/routing/p2p_test.go b/pkg/routing/p2p_test.go index 10993d59..7e99c9a9 100644 --- a/pkg/routing/p2p_test.go +++ b/pkg/routing/p2p_test.go @@ -9,6 +9,8 @@ import ( ) func TestListenMultiaddrs(t *testing.T) { + t.Parallel() + tests := []struct { name string addr string @@ -32,6 +34,8 @@ func TestListenMultiaddrs(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Parallel() + multiAddrs, err := listenMultiaddrs(tt.addr) require.NoError(t, err) require.Equal(t, len(tt.expected), len(multiAddrs)) @@ -43,6 +47,8 @@ func TestListenMultiaddrs(t *testing.T) { } func TestIPInMultiaddr(t *testing.T) { + t.Parallel() + tests := []struct { ma string expected netip.Addr @@ -61,6 +67,8 @@ func TestIPInMultiaddr(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Parallel() + multiAddr, err := ma.NewMultiaddr(tt.ma) require.NoError(t, err) v, err := ipInMultiaddr(multiAddr) @@ -71,6 +79,8 @@ func TestIPInMultiaddr(t *testing.T) { } func TestIsIp6(t *testing.T) { + t.Parallel() + m, err := ma.NewMultiaddr("/ip6/::") require.NoError(t, err) require.True(t, isIp6(m)) diff --git a/pkg/state/state_test.go b/pkg/state/state_test.go index b2a4d02d..57bb80c6 100644 --- a/pkg/state/state_test.go +++ b/pkg/state/state_test.go @@ -13,6 +13,8 @@ import ( ) func TestBasic(t *testing.T) { + t.Parallel() + tests := []struct { name string resolveLatestTag bool @@ -35,6 +37,8 @@ func TestBasic(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + t.Parallel() + imgs := []oci.Image{} for _, imageStr := range imgRefs { img, err := oci.Parse(imageStr, "") diff --git a/pkg/throttle/byterate_test.go b/pkg/throttle/byterate_test.go index cd858f8f..d9b17532 100644 --- a/pkg/throttle/byterate_test.go +++ b/pkg/throttle/byterate_test.go @@ -8,6 +8,8 @@ import ( ) func TestByterateUnmarshalValid(t *testing.T) { + t.Parallel() + tests := []struct { input string expected Byterate @@ -35,6 +37,8 @@ func TestByterateUnmarshalValid(t *testing.T) { } for _, tt := range tests { t.Run(tt.input, func(t *testing.T) { + t.Parallel() + var br Byterate err := br.UnmarshalText([]byte(tt.input)) require.NoError(t, err) @@ -44,6 +48,8 @@ func TestByterateUnmarshalValid(t *testing.T) { } func TestByterateUnmarshalInvalid(t *testing.T) { + t.Parallel() + tests := []struct { input string }{ @@ -59,6 +65,8 @@ func TestByterateUnmarshalInvalid(t *testing.T) { } for _, tt := range tests { t.Run(tt.input, func(t *testing.T) { + t.Parallel() + var br Byterate err := br.UnmarshalText([]byte(tt.input)) require.EqualError(t, err, fmt.Sprintf("invalid byterate format %s should be n Bps, n KBps, n MBps, n GBps, or n TBps", tt.input)) diff --git a/pkg/throttle/throttle_test.go b/pkg/throttle/throttle_test.go index e90ccb14..5aaf4d97 100644 --- a/pkg/throttle/throttle_test.go +++ b/pkg/throttle/throttle_test.go @@ -9,6 +9,8 @@ import ( ) func TestThrottler(t *testing.T) { + t.Parallel() + br := 500 * Bps throttler := NewThrottler(br) w := throttler.Writer(bytes.NewBuffer([]byte{}))