diff --git a/.github/workflows/makefile.yml b/.github/workflows/makefile.yml index e345d182a..e23beba81 100644 --- a/.github/workflows/makefile.yml +++ b/.github/workflows/makefile.yml @@ -21,7 +21,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 # Upgraded with: - go-version: '1.24.13' + go-version: '1.25.8' cache: true # Built-in caching for faster runs - name: Install dependencies @@ -39,4 +39,4 @@ jobs: COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | go install github.com/mattn/goveralls@latest - $(go env GOPATH)/bin/goveralls -coverprofile=profile.cov -service=github \ No newline at end of file + $(go env GOPATH)/bin/goveralls -coverprofile=profile.cov -service=github diff --git a/Dockerfile b/Dockerfile index c1d36b44b..8f8412ea6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ ARG CI_IMAGE_REGISTRY -FROM golang:1.24.13 as builder +FROM golang:1.25.8 as builder ARG COMPONENT diff --git a/Dockerfile_arm_all b/Dockerfile_arm_all index 955e8e508..20244c93e 100644 --- a/Dockerfile_arm_all +++ b/Dockerfile_arm_all @@ -1,6 +1,6 @@ ARG CI_IMAGE_REGISTRY -FROM golang:1.24.13 as builder +FROM golang:1.25.8 as builder ARG COMPONENT diff --git a/go.mod b/go.mod index b741e40be..a362bbb92 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/oracle/oci-cloud-controller-manager -go 1.24.13 +go 1.25.0 replace ( github.com/docker/distribution => github.com/docker/distribution v2.8.3+incompatible diff --git a/pkg/csi/driver/bv_controller_test.go b/pkg/csi/driver/bv_controller_test.go index 865712141..f66b8d92f 100644 --- a/pkg/csi/driver/bv_controller_test.go +++ b/pkg/csi/driver/bv_controller_test.go @@ -21,6 +21,7 @@ import ( "reflect" "strings" "testing" + "testing/synctest" "time" "github.com/container-storage-interface/spec/lib/go/csi" @@ -1235,27 +1236,29 @@ func TestControllerDriver_CreateVolume(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), testTimeout) - defer cancel() - d := &BlockVolumeControllerDriver{ControllerDriver{ - KubeClient: nil, - logger: zap.S(), - config: &providercfg.Config{CompartmentID: ""}, - client: NewClientProvisioner(nil, &MockBlockStorageClient{}, nil), - util: &csi_util.Util{Logger: logging.Logger().Sugar()}, - }} - got, err := d.CreateVolume(ctx, tt.args.req) - if tt.wantErr == nil && err != nil { - t.Errorf("got error %q, want none", err) - } - if tt.wantErr != nil && err == nil { - t.Errorf("want error %q, got none", tt.wantErr) - } else if tt.wantErr != nil && !strings.Contains(err.Error(), tt.wantErr.Error()) { - t.Errorf("want error %q to include %q", err, tt.wantErr) - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ControllerDriver.CreateVolume() = %v, want %v", got, tt.want) - } + synctest.Test(t, func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), testTimeout) + defer cancel() + d := &BlockVolumeControllerDriver{ControllerDriver{ + KubeClient: nil, + logger: zap.S(), + config: &providercfg.Config{CompartmentID: ""}, + client: NewClientProvisioner(nil, &MockBlockStorageClient{}, nil), + util: &csi_util.Util{Logger: logging.Logger().Sugar()}, + }} + got, err := d.CreateVolume(ctx, tt.args.req) + if tt.wantErr == nil && err != nil { + t.Errorf("got error %q, want none", err) + } + if tt.wantErr != nil && err == nil { + t.Errorf("want error %q, got none", tt.wantErr) + } else if tt.wantErr != nil && !strings.Contains(err.Error(), tt.wantErr.Error()) { + t.Errorf("want error %q to include %q", err, tt.wantErr) + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ControllerDriver.CreateVolume() = %v, want %v", got, tt.want) + } + }) }) } } @@ -1405,29 +1408,31 @@ func TestControllerDriver_ControllerPublishVolume(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), testTimeout) - defer cancel() - d := &BlockVolumeControllerDriver{ControllerDriver{ - KubeClient: &util.MockKubeClient{ - CoreClient: &util.MockCoreClient{}, - }, - logger: zap.S(), - config: &providercfg.Config{CompartmentID: ""}, - client: NewClientProvisioner(nil, &MockBlockStorageClient{}, nil), - util: &csi_util.Util{Logger: logging.Logger().Sugar()}, - }} - got, err := d.ControllerPublishVolume(ctx, tt.args.req) - if tt.wantErr == nil && err != nil { - t.Errorf("got error %q, want none", err) - } - if tt.wantErr != nil && err == nil { - t.Errorf("want error %q, got none", tt.wantErr) - } else if tt.wantErr != nil && !strings.Contains(err.Error(), tt.wantErr.Error()) { - t.Errorf("want error %q to include %q", err, tt.wantErr) - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ControllerDriver.ControllerPublish() = %v, want %v", got, tt.want) - } + synctest.Test(t, func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), testTimeout) + defer cancel() + d := &BlockVolumeControllerDriver{ControllerDriver{ + KubeClient: &util.MockKubeClient{ + CoreClient: &util.MockCoreClient{}, + }, + logger: zap.S(), + config: &providercfg.Config{CompartmentID: ""}, + client: NewClientProvisioner(nil, &MockBlockStorageClient{}, nil), + util: &csi_util.Util{Logger: logging.Logger().Sugar()}, + }} + got, err := d.ControllerPublishVolume(ctx, tt.args.req) + if tt.wantErr == nil && err != nil { + t.Errorf("got error %q, want none", err) + } + if tt.wantErr != nil && err == nil { + t.Errorf("want error %q, got none", tt.wantErr) + } else if tt.wantErr != nil && !strings.Contains(err.Error(), tt.wantErr.Error()) { + t.Errorf("want error %q to include %q", err, tt.wantErr) + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ControllerDriver.ControllerPublish() = %v, want %v", got, tt.want) + } + }) }) } } @@ -1479,29 +1484,31 @@ func TestControllerDriver_ControllerUnpublishVolume(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), testTimeout) - defer cancel() - d := &BlockVolumeControllerDriver{ControllerDriver{ - KubeClient: &util.MockKubeClient{ - CoreClient: &util.MockCoreClient{}, - }, - logger: zap.S(), - config: &providercfg.Config{CompartmentID: ""}, - client: NewClientProvisioner(nil, &MockBlockStorageClient{}, nil), - util: &csi_util.Util{Logger: logging.Logger().Sugar()}, - }} - got, err := d.ControllerUnpublishVolume(ctx, tt.args.req) - if tt.wantErr == nil && err != nil { - t.Errorf("got error %q, want none", err) - } - if tt.wantErr != nil && err == nil { - t.Errorf("want error %q, got none", tt.wantErr) - } else if tt.wantErr != nil && !strings.Contains(err.Error(), tt.wantErr.Error()) { - t.Errorf("want error %q to include %q", err, tt.wantErr) - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ControllerDriver.ControllerUnpublish() = %v, want %v", got, tt.want) - } + synctest.Test(t, func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), testTimeout) + defer cancel() + d := &BlockVolumeControllerDriver{ControllerDriver{ + KubeClient: &util.MockKubeClient{ + CoreClient: &util.MockCoreClient{}, + }, + logger: zap.S(), + config: &providercfg.Config{CompartmentID: ""}, + client: NewClientProvisioner(nil, &MockBlockStorageClient{}, nil), + util: &csi_util.Util{Logger: logging.Logger().Sugar()}, + }} + got, err := d.ControllerUnpublishVolume(ctx, tt.args.req) + if tt.wantErr == nil && err != nil { + t.Errorf("got error %q, want none", err) + } + if tt.wantErr != nil && err == nil { + t.Errorf("want error %q, got none", tt.wantErr) + } else if tt.wantErr != nil && !strings.Contains(err.Error(), tt.wantErr.Error()) { + t.Errorf("want error %q to include %q", err, tt.wantErr) + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ControllerDriver.ControllerUnpublish() = %v, want %v", got, tt.want) + } + }) }) } } diff --git a/pkg/csi/driver/fss_controller_test.go b/pkg/csi/driver/fss_controller_test.go index 0c0411bfc..a03fbb64e 100644 --- a/pkg/csi/driver/fss_controller_test.go +++ b/pkg/csi/driver/fss_controller_test.go @@ -21,6 +21,7 @@ import ( "reflect" "strings" "testing" + "testing/synctest" "time" "github.com/container-storage-interface/spec/lib/go/csi" @@ -751,28 +752,30 @@ func TestFSSControllerDriver_CreateVolume(t *testing.T) { }, } for _, tt := range tests { - ctx, cancel := context.WithTimeout(context.Background(), testTimeout) - defer cancel() t.Run(tt.name, func(t *testing.T) { - d := &FSSControllerDriver{ControllerDriver: ControllerDriver{ - KubeClient: nil, - logger: zap.S(), - config: &providercfg.Config{CompartmentID: "", Auth: config.AuthConfig{TenancyID: tt.args.tenancyId}}, - client: NewClientProvisioner(nil, nil, &MockFileStorageClient{}), - util: &csi_util.Util{}, - }} - got, err := d.CreateVolume(ctx, tt.args.req) - if tt.wantErr == nil && err != nil { - t.Errorf("got error %q, want none", err) - } - if tt.wantErr != nil && err == nil { - t.Errorf("want error %q, got none", tt.wantErr) - } else if tt.wantErr != nil && !strings.Contains(err.Error(), tt.wantErr.Error()) { - t.Errorf("want error %q to include %q", err, tt.wantErr) - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ControllerDriver.CreateVolume() = %v, want %v", got, tt.want) - } + synctest.Test(t, func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), testTimeout) + defer cancel() + d := &FSSControllerDriver{ControllerDriver: ControllerDriver{ + KubeClient: nil, + logger: zap.S(), + config: &providercfg.Config{CompartmentID: "", Auth: config.AuthConfig{TenancyID: tt.args.tenancyId}}, + client: NewClientProvisioner(nil, nil, &MockFileStorageClient{}), + util: &csi_util.Util{}, + }} + got, err := d.CreateVolume(ctx, tt.args.req) + if tt.wantErr == nil && err != nil { + t.Errorf("got error %q, want none", err) + } + if tt.wantErr != nil && err == nil { + t.Errorf("want error %q, got none", tt.wantErr) + } else if tt.wantErr != nil && !strings.Contains(err.Error(), tt.wantErr.Error()) { + t.Errorf("want error %q to include %q", err, tt.wantErr) + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ControllerDriver.CreateVolume() = %v, want %v", got, tt.want) + } + }) }) } } diff --git a/pkg/util/mock_oci_clients.go b/pkg/util/mock_oci_clients.go index 8e4a1cd92..106426dc0 100644 --- a/pkg/util/mock_oci_clients.go +++ b/pkg/util/mock_oci_clients.go @@ -2,6 +2,7 @@ package util import ( "context" + "time" "github.com/oracle/oci-go-sdk/v65/common" "github.com/oracle/oci-go-sdk/v65/core" @@ -9,6 +10,12 @@ import ( lustre "github.com/oracle/oci-go-sdk/v65/lustrefilestorage" ) +// mockPollInterval is the fake-time interval used by pagination mocks that +// simulate an infinite page stream until context cancellation. It must be +// smaller than testTimeout so the context expires after a few iterations when +// running inside a testing/synctest bubble. +const mockPollInterval = 5 * time.Second + type MockOCIBlockStorageClient struct { client core.BlockstorageClient } @@ -28,10 +35,9 @@ type MockOCILustreFileStorageClient struct { func (c MockOCIFileStorageClient) ListMountTargets(ctx context.Context, request filestorage.ListMountTargetsRequest) (response filestorage.ListMountTargetsResponse, err error) { if *request.DisplayName == "mount-target-idempotency-check-timeout-volume" { select { - // from retry.go case <-ctx.Done(): return response, ctx.Err() - default: + case <-time.After(mockPollInterval): return filestorage.ListMountTargetsResponse{ Items: []filestorage.MountTargetSummary{ { @@ -48,10 +54,9 @@ func (c MockOCIFileStorageClient) ListMountTargets(ctx context.Context, request func (c MockOCIFileStorageClient) ListFileSystems(ctx context.Context, request filestorage.ListFileSystemsRequest) (response filestorage.ListFileSystemsResponse, err error) { if *request.DisplayName == "file-system-idempotency-check-timeout-volume" { select { - // from retry.go case <-ctx.Done(): return response, ctx.Err() - default: + case <-time.After(mockPollInterval): return filestorage.ListFileSystemsResponse{ Items: []filestorage.FileSystemSummary{ { @@ -68,10 +73,9 @@ func (c MockOCIFileStorageClient) ListFileSystems(ctx context.Context, request f func (c MockOCIFileStorageClient) ListExports(ctx context.Context, request filestorage.ListExportsRequest) (response filestorage.ListExportsResponse, err error) { if *request.FileSystemId == "export-idempotency-check-timeout" { select { - // from retry.go case <-ctx.Done(): return response, ctx.Err() - default: + case <-time.After(mockPollInterval): return filestorage.ListExportsResponse{ Items: []filestorage.ExportSummary{}, OpcNextPage: common.String("a"), @@ -84,10 +88,9 @@ func (c MockOCIFileStorageClient) ListExports(ctx context.Context, request files func (c MockOCIComputeClient) ListVolumeAttachments(ctx context.Context, request core.ListVolumeAttachmentsRequest) (response core.ListVolumeAttachmentsResponse, err error) { if *request.VolumeId == "find-active-volume-attachment-timeout-volume" || *request.VolumeId == "find-volume-attachment-timeout" { select { - // from retry.go case <-ctx.Done(): return response, ctx.Err() - default: + case <-time.After(mockPollInterval): return core.ListVolumeAttachmentsResponse{ Items: []core.VolumeAttachment{ core.IScsiVolumeAttachment{ @@ -122,10 +125,9 @@ func (c MockOCIComputeClient) GetVolumeAttachment(ctx context.Context, request c func (c *MockOCIBlockStorageClient) ListVolumes(ctx context.Context, request core.ListVolumesRequest) (response core.ListVolumesResponse, err error) { if *request.DisplayName == "get-volumes-by-name-timeout-volume" { select { - // from retry.go case <-ctx.Done(): return response, ctx.Err() - default: + case <-time.After(mockPollInterval): return core.ListVolumesResponse{ Items: []core.Volume{ {