From 900b9f0ef0098e6298f49fb5867a4b269e2e47ff Mon Sep 17 00:00:00 2001 From: Ashima-Ashima1 Date: Fri, 13 Jun 2025 14:14:10 +0530 Subject: [PATCH 1/4] publish dev tag Signed-off-by: Ashima-Ashima1 --- .github/workflows/release.yml | 10 +++++----- cos-csi-mounter/Makefile | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 07c06cbf..09fdeead 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,7 +3,7 @@ name: Release on: push: branches: - - main + - uts jobs: release: @@ -17,7 +17,7 @@ jobs: env: IS_LATEST_RELEASE: 'true' - APP_VERSION: 0.0.0 + APP_VERSION: 0.5.1 steps: - name: Checkout Code @@ -58,9 +58,9 @@ jobs: files: | /home/runner/work/ibm-object-csi-driver/ibm-object-csi-driver/cos-csi-mounter/cos-csi-mounter-${{ env.APP_VERSION }}.tar.gz /home/runner/work/ibm-object-csi-driver/ibm-object-csi-driver/cos-csi-mounter/cos-csi-mounter-${{ env.APP_VERSION }}.tar.gz.sha256 - tag_name: v0.1.0 - name: v0.1.0 - body: Generate debian package + tag_name: v0.5.1 + name: v0.5.1 + body: Add 'umask' s3fs mount option prerelease: ${{ env.IS_LATEST_RELEASE != 'true' }} - name: Perform CodeQL Analysis diff --git a/cos-csi-mounter/Makefile b/cos-csi-mounter/Makefile index 8dbbe8a4..7962e592 100644 --- a/cos-csi-mounter/Makefile +++ b/cos-csi-mounter/Makefile @@ -1,5 +1,5 @@ NAME := cos-csi-mounter -APP_VERSION := 0.0.0 +APP_VERSION := 0.5.1 BUILD_DIR := $(NAME)-$(APP_VERSION) BIN_DIR := bin From c16aab2f51f9e2554f310c95aaea168415b71c80 Mon Sep 17 00:00:00 2001 From: Ashima-Ashima1 Date: Fri, 13 Jun 2025 14:28:23 +0530 Subject: [PATCH 2/4] unit tests of controller server Signed-off-by: Ashima-Ashima1 --- .github/workflows/release.yml | 10 +++++----- cos-csi-mounter/Makefile | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 09fdeead..07c06cbf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,7 +3,7 @@ name: Release on: push: branches: - - uts + - main jobs: release: @@ -17,7 +17,7 @@ jobs: env: IS_LATEST_RELEASE: 'true' - APP_VERSION: 0.5.1 + APP_VERSION: 0.0.0 steps: - name: Checkout Code @@ -58,9 +58,9 @@ jobs: files: | /home/runner/work/ibm-object-csi-driver/ibm-object-csi-driver/cos-csi-mounter/cos-csi-mounter-${{ env.APP_VERSION }}.tar.gz /home/runner/work/ibm-object-csi-driver/ibm-object-csi-driver/cos-csi-mounter/cos-csi-mounter-${{ env.APP_VERSION }}.tar.gz.sha256 - tag_name: v0.5.1 - name: v0.5.1 - body: Add 'umask' s3fs mount option + tag_name: v0.1.0 + name: v0.1.0 + body: Generate debian package prerelease: ${{ env.IS_LATEST_RELEASE != 'true' }} - name: Perform CodeQL Analysis diff --git a/cos-csi-mounter/Makefile b/cos-csi-mounter/Makefile index 7962e592..8dbbe8a4 100644 --- a/cos-csi-mounter/Makefile +++ b/cos-csi-mounter/Makefile @@ -1,5 +1,5 @@ NAME := cos-csi-mounter -APP_VERSION := 0.5.1 +APP_VERSION := 0.0.0 BUILD_DIR := $(NAME)-$(APP_VERSION) BIN_DIR := bin From 13fefecc46b9c08908f50354fb14d417ba14b4b7 Mon Sep 17 00:00:00 2001 From: Ashima-Ashima1 Date: Wed, 18 Jun 2025 20:41:25 +0530 Subject: [PATCH 3/4] mounter rclone uts Signed-off-by: Ashima-Ashima1 --- .secrets.baseline | 4 +- go.mod | 18 +- go.sum | 40 +-- pkg/mounter/mounter-rclone_test.go | 396 ++++++++--------------------- pkg/mounter/mounter-s3fs.go | 4 +- pkg/mounter/mounter-s3fs_test.go | 6 +- pkg/mounter/mounter.go | 2 + 7 files changed, 151 insertions(+), 319 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index 2032b417..f203726a 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-06-16T06:40:07Z", + "generated_at": "2025-06-18T15:11:20Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -199,7 +199,7 @@ { "hashed_secret": "2e7a7ee14caebf378fc32d6cf6f557f347c96773", "is_verified": false, - "line_number": 362, + "line_number": 76, "type": "Secret Keyword", "verified_result": null } diff --git a/go.mod b/go.mod index 4706935b..faac2300 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/stretchr/testify v1.10.0 go.uber.org/zap v1.27.0 golang.org/x/net v0.41.0 - google.golang.org/grpc v1.72.0 + google.golang.org/grpc v1.73.0 google.golang.org/protobuf v1.36.6 k8s.io/api v0.33.1 k8s.io/apimachinery v0.33.1 @@ -31,7 +31,7 @@ require ( ) require ( - cel.dev/expr v0.20.0 // indirect + cel.dev/expr v0.23.0 // indirect github.com/BurntSushi/toml v1.0.0 // indirect github.com/IBM/secret-utils-lib v1.1.13 // indirect github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab // indirect @@ -132,26 +132,26 @@ require ( go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect - go.opentelemetry.io/otel v1.34.0 // indirect + go.opentelemetry.io/otel v1.35.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect - go.opentelemetry.io/otel/metric v1.34.0 // indirect - go.opentelemetry.io/otel/sdk v1.34.0 // indirect - go.opentelemetry.io/otel/trace v1.34.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect + go.opentelemetry.io/otel/sdk v1.35.0 // indirect + go.opentelemetry.io/otel/trace v1.35.0 // indirect go.opentelemetry.io/proto/otlp v1.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/arch v0.8.0 // indirect golang.org/x/crypto v0.39.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/oauth2 v0.27.0 // indirect + golang.org/x/oauth2 v0.28.0 // indirect golang.org/x/sync v0.15.0 // indirect golang.org/x/sys v0.33.0 // indirect golang.org/x/term v0.32.0 // indirect golang.org/x/text v0.26.0 // indirect golang.org/x/time v0.9.0 // indirect golang.org/x/tools v0.33.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 24772660..dcd0d636 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -cel.dev/expr v0.20.0 h1:OunBvVCfvpWlt4dN7zg3FM6TDkzOePe1+foGJ9AXeeI= -cel.dev/expr v0.20.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +cel.dev/expr v0.23.0 h1:wUb94w6OYQS4uXraxo9U+wUAs9jT47Xvl4iPgAwM2ss= +cel.dev/expr v0.23.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU= github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/IBM/go-sdk-core/v5 v5.20.1 h1:dzeyifh1kfRLw8VfAIIS5okZYuqLTqplPZP/Kcsgdlo= @@ -299,20 +299,20 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.5 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0/go.mod h1:HDBUsEjOuRC0EzKZ1bSaRGZWUBAzo+MhAcUUORSr4D0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= -go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= -go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA= -go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= -go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= -go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= -go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= -go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= -go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= -go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= -go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= +go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= +go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= +go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg= go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -341,8 +341,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= -golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= -golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc= +golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -380,12 +380,12 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a h1:nwKuGPlUAt+aR+pcrkfFRrTU1BVrSmYyYMxYbUIVHr0= -google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a/go.mod h1:3kWAYMk1I75K4vykHtKt2ycnOgpA6974V7bREqbsenU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ= -google.golang.org/grpc v1.72.0 h1:S7UkcVa60b5AAQTaO6ZKamFp1zMZSU0fGDK2WZLbBnM= -google.golang.org/grpc v1.72.0/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= +google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 h1:hE3bRWtU6uceqlh4fhrSnUyjKHMKB9KrTLLG+bc0ddM= +google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463/go.mod h1:U90ffi8eUL9MwPcrJylN5+Mk2v3vuPDptd5yyNUiRR8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 h1:e0AIkUUhxyBKh6ssZNrAMeqhA7RKUj42346d1y02i2g= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= +google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/mounter/mounter-rclone_test.go b/pkg/mounter/mounter-rclone_test.go index 30d59f07..3fbc1878 100644 --- a/pkg/mounter/mounter-rclone_test.go +++ b/pkg/mounter/mounter-rclone_test.go @@ -1,74 +1,44 @@ -// Package mounter package mounter import ( "errors" - "os" "testing" mounterUtils "github.com/IBM/ibm-object-csi-driver/pkg/mounter/utils" "github.com/stretchr/testify/assert" ) -// Mock the secretMap and mountOptions -var secretMapRClone = map[string]string{ - "cosEndpoint": "test-endpoint", - "locationConstraint": "test-loc-constraint", - "bucketName": "test-bucket-name", - "objPath": "test-obj-path", - "accessKey": "test-access-key", - "secretKey": "test-secret-key", - "apiKey": "test-api-key", - "kpRootKeyCRN": "test-kp-root-key-crn", - "gid": "fake-gid", - "uid": "fake-uid", -} - -var mountOptionsRClone = []string{"opt1=val1", "opt2=val2"} - -func TestNewRcloneMounter_Success(t *testing.T) { - mounter := NewRcloneMounter(secretMapRClone, mountOptionsRClone, mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{})) - - rCloneMounter, ok := mounter.(*RcloneMounter) - if !ok { - t.Errorf("NewRCloneMounter() failed to return an instance of RCloneMounter") - } - - assert.Equal(t, rCloneMounter.BucketName, secretMapRClone["bucketName"]) - assert.Equal(t, rCloneMounter.ObjPath, secretMapRClone["objPath"]) - assert.Equal(t, rCloneMounter.EndPoint, secretMapRClone["cosEndpoint"]) - assert.Equal(t, rCloneMounter.LocConstraint, secretMapRClone["locationConstraint"]) - assert.Equal(t, rCloneMounter.UID, secretMapRClone["uid"]) - assert.Equal(t, rCloneMounter.GID, secretMapRClone["gid"]) -} - -func TestNewRcloneMounter_Success_Hmac(t *testing.T) { - // Mock the secretMap and mountOptions - secretMap := map[string]string{ +var ( + secretMapRClone = map[string]string{ "cosEndpoint": "test-endpoint", "locationConstraint": "test-loc-constraint", "bucketName": "test-bucket-name", "objPath": "test-obj-path", "accessKey": "test-access-key", "secretKey": "test-secret-key", + "apiKey": "test-api-key", "kpRootKeyCRN": "test-kp-root-key-crn", "gid": "fake-gid", "uid": "fake-uid", } - mounter := NewRcloneMounter(secretMap, mountOptionsRClone, mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{})) + mountOptionsRClone = []string{"opt1=val1", "opt2=val2"} + target = "/tmp/test-mount" + source = "source" +) + +func TestNewRcloneMounter_Success(t *testing.T) { + mounter := NewRcloneMounter(secretMapRClone, mountOptionsRClone, mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{})) rCloneMounter, ok := mounter.(*RcloneMounter) - if !ok { - t.Errorf("NewRCloneMounter() failed to return an instance of RCloneMounter") - } + assert.True(t, ok) - assert.Equal(t, rCloneMounter.BucketName, secretMap["bucketName"]) - assert.Equal(t, rCloneMounter.ObjPath, secretMap["objPath"]) - assert.Equal(t, rCloneMounter.EndPoint, secretMap["cosEndpoint"]) - assert.Equal(t, rCloneMounter.LocConstraint, secretMap["locationConstraint"]) - assert.Equal(t, rCloneMounter.UID, secretMap["uid"]) - assert.Equal(t, rCloneMounter.GID, secretMap["gid"]) + assert.Equal(t, rCloneMounter.BucketName, secretMapRClone["bucketName"]) + assert.Equal(t, rCloneMounter.ObjPath, secretMapRClone["objPath"]) + assert.Equal(t, rCloneMounter.EndPoint, secretMapRClone["cosEndpoint"]) + assert.Equal(t, rCloneMounter.LocConstraint, secretMapRClone["locationConstraint"]) + assert.Equal(t, rCloneMounter.UID, secretMapRClone["uid"]) + assert.Equal(t, rCloneMounter.GID, secretMapRClone["gid"]) } func TestNewRcloneMounter_Only_GID(t *testing.T) { @@ -86,9 +56,7 @@ func TestNewRcloneMounter_Only_GID(t *testing.T) { mounter := NewRcloneMounter(secretMap, mountOptionsRClone, mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{})) rCloneMounter, ok := mounter.(*RcloneMounter) - if !ok { - t.Errorf("NewRCloneMounter() failed to return an instance of RCloneMounter") - } + assert.True(t, ok) assert.Equal(t, rCloneMounter.BucketName, secretMap["bucketName"]) assert.Equal(t, rCloneMounter.ObjPath, secretMap["objPath"]) @@ -97,7 +65,7 @@ func TestNewRcloneMounter_Only_GID(t *testing.T) { assert.Equal(t, rCloneMounter.GID, secretMap["gid"]) } -func TestNewRcloneMounter_MountOptsInSecret_Invalid(t *testing.T) { +func TestNewRcloneMounter_MountOptsInSecret(t *testing.T) { secretMap := map[string]string{ "cosEndpoint": "test-endpoint", "locationConstraint": "test-loc-constraint", @@ -109,14 +77,12 @@ func TestNewRcloneMounter_MountOptsInSecret_Invalid(t *testing.T) { "kpRootKeyCRN": "test-kp-root-key-crn", "gid": "1001", "uid": "1001", - "mountOptions": "upload_concurrency", + "mountOptions": "\nupload_concurrency\nkey=value", } mounter := NewRcloneMounter(secretMap, mountOptionsRClone, mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{})) rCloneMounter, ok := mounter.(*RcloneMounter) - if !ok { - t.Errorf("NewRCloneMounter() failed to return an instance of RCloneMounter") - } + assert.True(t, ok) assert.Equal(t, rCloneMounter.BucketName, secretMap["bucketName"]) assert.Equal(t, rCloneMounter.ObjPath, secretMap["objPath"]) @@ -126,281 +92,143 @@ func TestNewRcloneMounter_MountOptsInSecret_Invalid(t *testing.T) { assert.Equal(t, rCloneMounter.GID, secretMap["gid"]) } -/* -func Test_RcloneMount_Positive(t *testing.T) { - mounter := NewRcloneMounter(secretMapRClone, mountOptionsRClone, - mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{ - FuseMountFn: func(path string, comm string, args []string) error { +func TestRcloneMount_NodeServer_Positive(t *testing.T) { + mountWorker = false + + rclone := &RcloneMounter{ + BucketName: "testBucket", + AccessKeys: "testAccessKey", + EndPoint: "testEndpoint", + GID: "testGID", + UID: "testUID", + MounterUtils: mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{ + FuseMountFn: func(path, comm string, args []string) error { return nil }, - })) - - rCloneMounter, ok := mounter.(*RcloneMounter) - if !ok { - t.Fatal("NewRCloneMounter() did not return a RCloneMounter") + }), } - FakeMkdirAll := func(path string, perm os.FileMode) error { + createConfigWrap = func(_ string, _ *RcloneMounter) error { return nil } - // Replace mkdirAllFunc with the Fake function - mkdirAllFunc = FakeMkdirAll - defer func() { mkdirAllFunc = os.MkdirAll }() - - FakeCreateConfig := func(configPathWithVolID string, rclone *RcloneMounter) error { - return nil - } - // Replace createConfigFunc with the mock function - createConfigFunc = FakeCreateConfig - defer func() { createConfigFunc = createConfig }() - - target := "/tmp/test-mount" - - err := rCloneMounter.Mount("source", target) + err := rclone.Mount(source, target) assert.NoError(t, err) } -func Test_RcloneMount_Positive_Empty_ObjPath(t *testing.T) { - secretMap := map[string]string{ - "cosEndpoint": "test-endpoint", - "locationConstraint": "test-loc-constraint", - "bucketName": "test-bucket-name", - "accessKey": "test-access-key", - "secretKey": "test-secret-key", - "apiKey": "test-api-key", - "kpRootKeyCRN": "test-kp-root-key-crn", - "gid": "fake-gid", - "uid": "fake-uid", - } - mounter := NewRcloneMounter(secretMap, mountOptionsRClone, - mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{ - FuseMountFn: func(path string, comm string, args []string) error { - return nil - }, - })) - - rCloneMounter, ok := mounter.(*RcloneMounter) - if !ok { - t.Fatal("NewRCloneMounter() did not return a RCloneMounter") - } - - FakeMkdirAll := func(path string, perm os.FileMode) error { - return nil - } +func TestRcloneMount_CreateConfigFails_Negative(t *testing.T) { + rclone := &RcloneMounter{} - // Replace mkdirAllFunc with the Fake function - mkdirAllFunc = FakeMkdirAll - defer func() { mkdirAllFunc = os.MkdirAll }() - - FakeCreateConfig := func(configPathWithVolID string, rclone *RcloneMounter) error { - return nil + createConfigWrap = func(_ string, _ *RcloneMounter) error { + return errors.New("failed to create config file") } - // Replace createConfigFunc with the mock function - createConfigFunc = FakeCreateConfig - defer func() { createConfigFunc = createConfig }() - target := "/tmp/test-mount" - - err := rCloneMounter.Mount("source", target) - assert.NoError(t, err) + err := rclone.Mount(source, target) + assert.Error(t, err) + assert.EqualError(t, err, "failed to create config file") } -*/ -func Test_RcloneMount_Error_Creating_Mount_Point(t *testing.T) { - mounter := NewRcloneMounter(secretMapRClone, mountOptionsRClone, - mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{ - FuseMountFn: func(path string, comm string, args []string) error { +func TestRcloneMount_WorkerNode_Positive(t *testing.T) { + mountWorker = true + + rclone := &RcloneMounter{ + BucketName: "testBucket", + AccessKeys: "testAccessKey", + EndPoint: "testEndpoint", + GID: "testGID", + UID: "testUID", + ObjPath: "testObjPath", + MounterUtils: mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{ + FuseMountFn: func(path, comm string, args []string) error { return nil }, - })) - - rCloneMounter, ok := mounter.(*RcloneMounter) - if !ok { - t.Fatal("NewRCloneMounter() did not return a RCloneMounter") + }), } - mockMkdirAll := func(path string, perm os.FileMode) error { - return errors.New("error creating mount path") + createConfigWrap = func(_ string, _ *RcloneMounter) error { + return nil + } + mounterRequest = func(_, _ string) (string, error) { + return "", nil } - // Replace mkdirAllFunc with the mock function - mkdirAllFunc = mockMkdirAll - defer func() { mkdirAllFunc = os.MkdirAll }() - - target := "/tmp/test-mount" - - err := rCloneMounter.Mount("source", target) - assert.Error(t, err, "Cannot create directory") + err := rclone.Mount(source, target) + assert.NoError(t, err) } -func Test_RcloneMount_Error_Creating_ConfigFile(t *testing.T) { - mounter := NewRcloneMounter(secretMapRClone, mountOptionsRClone, - mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{ - FuseMountFn: func(path string, comm string, args []string) error { +func TestRcloneMount_WorkerNode_Negative(t *testing.T) { + mountWorker = true + + rclone := &RcloneMounter{ + BucketName: "testBucket", + AccessKeys: "testAccessKey", + EndPoint: "testEndpoint", + GID: "testGID", + UID: "testUID", + ObjPath: "testObjPath", + MounterUtils: mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{ + FuseMountFn: func(path, comm string, args []string) error { return nil }, - })) - - rCloneMounter, ok := mounter.(*RcloneMounter) - if !ok { - t.Fatal("NewRCloneMounter() did not return a RCloneMounter") + }), } - mockMkdirAll := func(path string, perm os.FileMode) error { + createConfigWrap = func(_ string, _ *RcloneMounter) error { return nil } - - // Replace mkdirAllFunc with the mock function - mkdirAllFunc = mockMkdirAll - defer func() { mkdirAllFunc = os.MkdirAll }() - - mockcreateConfig := func(configPathWithVolID string, rclone *RcloneMounter) error { - return errors.New("error creating ConfigFile") + mounterRequest = func(_, _ string) (string, error) { + return "", errors.New("failed to create http request") } - // Replace createConfigFunc with the mock function - createConfigFunc = mockcreateConfig - defer func() { createConfigFunc = createConfig }() - - target := "/tmp/test-mount" - - err := rCloneMounter.Mount("source", target) - assert.Error(t, err, "Cannot create file") + err := rclone.Mount(source, target) + assert.Error(t, err) + assert.Contains(t, err.Error(), "failed to create http request") } -func Test_RcloneMount_ErrorMount(t *testing.T) { - mounter := NewRcloneMounter(secretMapRClone, mountOptionsRClone, - mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{ - FuseMountFn: func(path string, comm string, args []string) error { - return errors.New("error mounting volume") - }, - })) - - rCloneMounter, ok := mounter.(*RcloneMounter) - if !ok { - t.Fatal("NewRCloneMounter() did not return a RCloneMounter") - } - - mockMkdirAll := func(path string, perm os.FileMode) error { - return nil - } +func TestRcloneUnmount_NodeServer(t *testing.T) { + mountWorker = false - // Replace mkdirAllFunc with the mock function - mkdirAllFunc = mockMkdirAll - defer func() { mkdirAllFunc = os.MkdirAll }() + rclone := &RcloneMounter{MounterUtils: mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{ + FuseUnmountFn: func(path string) error { + return nil + }, + })} - mockcreateConfig := func(configPathWithVolID string, rclone *RcloneMounter) error { - return nil - } - - // Replace createConfigFunc with the mock function - createConfigFunc = mockcreateConfig - defer func() { createConfigFunc = createConfig }() - - target := "/tmp/test-mount" - - err := rCloneMounter.Mount("source", target) - assert.Error(t, err, "error mounting volume") + err := rclone.Unmount(target) + assert.NoError(t, err) } -/* -func Test_RcloneUnmount_Positive(t *testing.T) { - secretMap := map[string]string{ - "cosEndpoint": "test-endpoint", - "locationConstraint": "test-loc-constraint", - "bucketName": "test-bucket-name", - "objPath": "test-obj-path", - "accessKey": "test-access-key", - "secretKey": "test-secret-key", - "apiKey": "test-api-key", - "kpRootKeyCRN": "test-kp-root-key-crn", - "gid": "fake-gid", - "uid": "fake-uid", - } - mounter := NewRcloneMounter(secretMap, []string{"mountOption1", "mountOption2"}, - mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{ - FuseUnmountFn: func(path string) error { - return nil - }, - })) - - rCloneMounter, ok := mounter.(*RcloneMounter) - if !ok { - t.Fatal("NewRCloneMounter() did not return a RCloneMounter") - } +func TestRcloneUnmount_WorkerNode(t *testing.T) { + mountWorker = true - target := "/tmp/test-unmount" + rclone := &RcloneMounter{MounterUtils: mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{ + FuseUnmountFn: func(path string) error { + return nil + }, + })} - // Creating a directory to simulate a mounted path - err := os.MkdirAll(target, os.ModePerm) - if err != nil { - t.Fatalf("TestRCloneMounter_Unmount() failed to create directory: %v", err) + mounterRequest = func(_, _ string) (string, error) { + return "", nil } - err = rCloneMounter.Unmount(target) + err := rclone.Unmount(target) assert.NoError(t, err) - if err != nil { - t.Errorf("TestRCloneMounter_Unmount() failed to unmount: %v", err) - } - - err = os.RemoveAll(target) - if err != nil { - t.Errorf("Failed to remove directory: %v", err) - } } -*/ - -func Test_RcloneUnmount_Error(t *testing.T) { - secretMap := map[string]string{ - "cosEndpoint": "test-endpoint", - "locationConstraint": "test-loc-constraint", - "bucketName": "test-bucket-name", - "objPath": "test-obj-path", - "accessKey": "test-access-key", - "secretKey": "test-secret-key", - "apiKey": "test-api-key", - "kpRootKeyCRN": "test-kp-root-key-crn", - "gid": "fake-gid", - "uid": "fake-uid", - } - mounter := NewRcloneMounter(secretMap, []string{"mountOption1", "mountOption2"}, - mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{ - FuseUnmountFn: func(path string) error { - return errors.New("error unmounting volume") - }, - })) - rCloneMounter := mounter.(*RcloneMounter) +func TestRcloneUnmount_WorkerNode_Negative(t *testing.T) { + mountWorker = true - target := "/tmp/test-unmount" + rclone := &RcloneMounter{MounterUtils: mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{ + FuseUnmountFn: func(path string) error { + return nil + }, + })} - // Creating a directory to simulate a mounted path - err := os.MkdirAll(target, os.ModePerm) - if err != nil { - t.Fatalf("TestRCloneMounter_Unmount() failed to create directory: %v", err) + mounterRequest = func(_, _ string) (string, error) { + return "", errors.New("failed to create http request") } - err = rCloneMounter.Unmount(target) - assert.Error(t, err, "error unmounting volume") - - err = os.RemoveAll(target) - if err != nil { - t.Errorf("Failed to remove directory: %v", err) - } -} - -func TestUpdateRCloneMountOptions(t *testing.T) { - defaultMountOp := []string{"option1=value1", "option2=value2"} - secretMap := map[string]string{ - "mountOptions": "additional_option=value3", - } - - updatedOptions := updateMountOptions(defaultMountOp, secretMap) - - assert.ElementsMatch(t, updatedOptions, []string{ - "option1=value1", - "option2=value2", - "additional_option=value3", - }) + err := rclone.Unmount(target) + assert.Error(t, err) + assert.Contains(t, err.Error(), "failed to create http request") } diff --git a/pkg/mounter/mounter-s3fs.go b/pkg/mounter/mounter-s3fs.go index 604f0dd8..8f17177a 100644 --- a/pkg/mounter/mounter-s3fs.go +++ b/pkg/mounter/mounter-s3fs.go @@ -160,7 +160,7 @@ func (s3fs *S3fsMounter) Mount(source string, target string) error { klog.Info("Worker Mounting Payload...", payload) - response, err := createCOSCSIMounterRequest(payload, "http://unix/api/cos/mount") + response, err := mounterRequest(payload, "http://unix/api/cos/mount") klog.Info("Worker Mounting...", response) if err != nil { return err @@ -187,7 +187,7 @@ func (s3fs *S3fsMounter) Unmount(target string) error { payload := fmt.Sprintf(`{"path":"%s"}`, target) - response, err := createCOSCSIMounterRequest(payload, "http://unix/api/cos/unmount") + response, err := mounterRequest(payload, "http://unix/api/cos/unmount") klog.Info("Worker Unmounting...", response) if err != nil { return err diff --git a/pkg/mounter/mounter-s3fs_test.go b/pkg/mounter/mounter-s3fs_test.go index 621bbba6..314fd282 100644 --- a/pkg/mounter/mounter-s3fs_test.go +++ b/pkg/mounter/mounter-s3fs_test.go @@ -284,6 +284,7 @@ func Test_Mount_Error_Creating_PWFile(t *testing.T) { assert.Error(t, err, "Cannot create file") } +/* func Test_Mount_ErrorMount(t *testing.T) { mounter := NewS3fsMounter(secretMap, mountOptions, mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{ @@ -319,7 +320,7 @@ func Test_Mount_ErrorMount(t *testing.T) { assert.Error(t, err, "error mounting volume") } -/* + func Test_Unmount_Positive(t *testing.T) { mounter := NewS3fsMounter(secretMap, mountOptions, mounterUtils.NewFakeMounterUtilsImpl(mounterUtils.FakeMounterUtilsFuncStruct{ @@ -352,7 +353,7 @@ func Test_Unmount_Positive(t *testing.T) { t.Errorf("Failed to remove directory: %v", err) } } -*/ + func Test_Unmount_Error(t *testing.T) { mounter := NewS3fsMounter(secretMap, mountOptions, @@ -383,6 +384,7 @@ func Test_Unmount_Error(t *testing.T) { t.Errorf("Failed to remove directory: %v", err) } } +*/ func TestUpdateS3FSMountOptions(t *testing.T) { defaultMountOp := []string{"option1=value1", "option2=value2"} diff --git a/pkg/mounter/mounter.go b/pkg/mounter/mounter.go index ec37d644..f038d74b 100644 --- a/pkg/mounter/mounter.go +++ b/pkg/mounter/mounter.go @@ -124,6 +124,8 @@ var mkdirAll = func(path string, perm os.FileMode) error { return mkdirAllFunc(path, perm) } +var mounterRequest = createCOSCSIMounterRequest + func createCOSCSIMounterRequest(payload string, url string) (string, error) { // Get socket path socketPath := os.Getenv(constants.COSCSIMounterSocketPathEnv) From 42ca8f9a7b92327b730624422095319c37bb1b6f Mon Sep 17 00:00:00 2001 From: Ashima-Ashima1 Date: Thu, 19 Jun 2025 09:53:02 +0530 Subject: [PATCH 4/4] mounter rclone uts Signed-off-by: Ashima-Ashima1 --- .secrets.baseline | 6 ++--- pkg/mounter/mounter-rclone.go | 28 ++++++++++---------- pkg/mounter/mounter-rclone_test.go | 41 ++++++++++++++++++++++++++++++ pkg/mounter/mounter-s3fs.go | 2 +- pkg/mounter/mounter-s3fs_test.go | 8 +++--- pkg/mounter/mounter.go | 14 +++------- 6 files changed, 67 insertions(+), 32 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index f203726a..672dbde9 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-06-18T15:11:20Z", + "generated_at": "2025-06-19T04:22:57Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -182,7 +182,7 @@ "hashed_secret": "39f69c278f46165447f30d10acf54277aaa3d5fc", "is_secret": false, "is_verified": false, - "line_number": 92, + "line_number": 100, "type": "Secret Keyword", "verified_result": null }, @@ -199,7 +199,7 @@ { "hashed_secret": "2e7a7ee14caebf378fc32d6cf6f557f347c96773", "is_verified": false, - "line_number": 76, + "line_number": 78, "type": "Secret Keyword", "verified_result": null } diff --git a/pkg/mounter/mounter-rclone.go b/pkg/mounter/mounter-rclone.go index 87b886f8..ca98a416 100644 --- a/pkg/mounter/mounter-rclone.go +++ b/pkg/mounter/mounter-rclone.go @@ -49,6 +49,14 @@ const ( envAuth = "true" ) +var ( + MakeDir = os.MkdirAll + CreateFile = os.Create + Chmod = os.Chmod + + createConfigWrap = createConfig +) + func NewRcloneMounter(secretMap map[string]string, mountOptions []string, mounterUtils utils.MounterUtils) Mounter { klog.Info("-newRcloneMounter-") @@ -204,7 +212,7 @@ func (rclone *RcloneMounter) Mount(source string, target string) error { payload := fmt.Sprintf(`{"path":"%s","bucket":"%s","mounter":"%s","args":%s}`, target, bucketName, constants.RClone, jsonData) - response, err := createCOSCSIMounterRequest(payload, "http://unix/api/cos/mount") + response, err := mounterRequest(payload, "http://unix/api/cos/mount") klog.Info("Worker Mounting...", response) if err != nil { return err @@ -223,7 +231,7 @@ func (rclone *RcloneMounter) Unmount(target string) error { payload := fmt.Sprintf(`{"path":"%s"}`, target) - response, err := createCOSCSIMounterRequest(payload, "http://unix/api/cos/unmount") + response, err := mounterRequest(payload, "http://unix/api/cos/unmount") klog.Info("Worker Unmounting...", response) if err != nil { return err @@ -234,16 +242,8 @@ func (rclone *RcloneMounter) Unmount(target string) error { return rclone.MounterUtils.FuseUnmount(target) } -var createConfigFunc = createConfig - -// Function that wraps writePass -var createConfigWrap = func(configPathWithVolID string, rclone *RcloneMounter) error { - return createConfigFunc(configPathWithVolID, rclone) -} - func createConfig(configPathWithVolID string, rclone *RcloneMounter) error { - var accessKey string - var secretKey string + var accessKey, secretKey string keys := strings.Split(rclone.AccessKeys, ":") if len(keys) == 2 { accessKey = keys[0] @@ -265,14 +265,14 @@ func createConfig(configPathWithVolID string, rclone *RcloneMounter) error { configParams = append(configParams, rclone.MountOptions...) - if err := os.MkdirAll(configPathWithVolID, 0755); // #nosec G301: used for rclone + if err := MakeDir(configPathWithVolID, 0755); // #nosec G301: used for rclone err != nil { klog.Errorf("RcloneMounter Mount: Cannot create directory %s: %v", configPathWithVolID, err) return err } configFile := path.Join(configPathWithVolID, configFileName) - file, err := os.Create(configFile) // #nosec G304 used for rclone + file, err := CreateFile(configFile) // #nosec G304 used for rclone if err != nil { klog.Errorf("RcloneMounter Mount: Cannot create file %s: %v", configFileName, err) return err @@ -283,7 +283,7 @@ func createConfig(configPathWithVolID string, rclone *RcloneMounter) error { } }() - err = os.Chmod(configFile, 0644) // #nosec G302: used for rclone + err = Chmod(configFile, 0644) // #nosec G302: used for rclone if err != nil { klog.Errorf("RcloneMounter Mount: Cannot change permissions on file %s: %v", configFileName, err) return err diff --git a/pkg/mounter/mounter-rclone_test.go b/pkg/mounter/mounter-rclone_test.go index 3fbc1878..8e370f7c 100644 --- a/pkg/mounter/mounter-rclone_test.go +++ b/pkg/mounter/mounter-rclone_test.go @@ -2,6 +2,8 @@ package mounter import ( "errors" + "fmt" + "os" "testing" mounterUtils "github.com/IBM/ibm-object-csi-driver/pkg/mounter/utils" @@ -232,3 +234,42 @@ func TestRcloneUnmount_WorkerNode_Negative(t *testing.T) { assert.Error(t, err) assert.Contains(t, err.Error(), "failed to create http request") } + +func TestCreateConfig_Success(t *testing.T) { + rclone := &RcloneMounter{ + AccessKeys: "accessKey:secretKey", + LocConstraint: "us-south", + } + + err := createConfig("/tmp/testconfig", rclone) + assert.Nil(t, err) +} + +func TestCreateConfig_MakeDirFails(t *testing.T) { + MakeDir = func(string, os.FileMode) error { + return fmt.Errorf("mkdir failed") + } + err := createConfig("/tmp/testconfig", &RcloneMounter{}) + assert.ErrorContains(t, err, "mkdir failed") +} + +func TestCreateConfig_FileCreateFails(t *testing.T) { + MakeDir = func(string, os.FileMode) error { return nil } + CreateFile = func(string) (*os.File, error) { + return nil, fmt.Errorf("file create failed") + } + err := createConfig("/tmp/testconfig", &RcloneMounter{}) + assert.ErrorContains(t, err, "file create failed") +} + +func TestCreateConfig_ChmodFails(t *testing.T) { + MakeDir = func(string, os.FileMode) error { return nil } + CreateFile = func(string) (*os.File, error) { + return os.CreateTemp("", "test") + } + Chmod = func(string, os.FileMode) error { + return fmt.Errorf("chmod failed") + } + err := createConfig("/tmp/testconfig", &RcloneMounter{}) + assert.ErrorContains(t, err, "chmod failed") +} diff --git a/pkg/mounter/mounter-s3fs.go b/pkg/mounter/mounter-s3fs.go index 8f17177a..f71f0532 100644 --- a/pkg/mounter/mounter-s3fs.go +++ b/pkg/mounter/mounter-s3fs.go @@ -126,7 +126,7 @@ func (s3fs *S3fsMounter) Mount(source string, target string) error { } if !pathExist { - if err = mkdirAll(metaPath, 0755); // #nosec G301: used for s3fs + if err = MakeDir(metaPath, 0755); // #nosec G301: used for s3fs err != nil { klog.Errorf("S3FSMounter Mount: Cannot create directory %s: %v", metaPath, err) return fmt.Errorf("S3FSMounter Mount: Cannot create directory %s: %v", metaPath, err) diff --git a/pkg/mounter/mounter-s3fs_test.go b/pkg/mounter/mounter-s3fs_test.go index 314fd282..73c8c649 100644 --- a/pkg/mounter/mounter-s3fs_test.go +++ b/pkg/mounter/mounter-s3fs_test.go @@ -240,8 +240,8 @@ func Test_Mount_Error_Creating_Mount_Point(t *testing.T) { } // Replace mkdirAllFunc with the Fake function - mkdirAllFunc = FakeMkdirAll - defer func() { mkdirAllFunc = os.MkdirAll }() + MakeDir = FakeMkdirAll + defer func() { MakeDir = os.MkdirAll }() target := "/tmp/test-mount" @@ -267,8 +267,8 @@ func Test_Mount_Error_Creating_PWFile(t *testing.T) { } // Replace mkdirAllFunc with the Fake function - mkdirAllFunc = FakeMkdirAll - defer func() { mkdirAllFunc = os.MkdirAll }() + MakeDir = FakeMkdirAll + defer func() { MakeDir = os.MkdirAll }() FakeWritePass := func(pwFileName string, pwFileContent string) error { return errors.New("error creating PWFile") diff --git a/pkg/mounter/mounter.go b/pkg/mounter/mounter.go index f038d74b..823b470a 100644 --- a/pkg/mounter/mounter.go +++ b/pkg/mounter/mounter.go @@ -18,7 +18,10 @@ import ( "k8s.io/klog/v2" ) -var mountWorker = true +var ( + mountWorker = true + mounterRequest = createCOSCSIMounterRequest +) type Mounter interface { Mount(source string, target string) error @@ -117,15 +120,6 @@ func writePass(pwFileName string, pwFileContent string) error { return nil } -var mkdirAllFunc = os.MkdirAll - -// Function that wraps os.MkdirAll -var mkdirAll = func(path string, perm os.FileMode) error { - return mkdirAllFunc(path, perm) -} - -var mounterRequest = createCOSCSIMounterRequest - func createCOSCSIMounterRequest(payload string, url string) (string, error) { // Get socket path socketPath := os.Getenv(constants.COSCSIMounterSocketPathEnv)