From 45bc8758b665fa89550abc0f273e25d3318970e5 Mon Sep 17 00:00:00 2001 From: Anurag Mittal Date: Thu, 12 Sep 2024 02:10:37 +0200 Subject: [PATCH] Add CI workflows for testing and building COSI - Update GO version to 1.23.2 - Added Dockerfile, Makefile and CI workflows - Added tests for DriverInfo in identity server using Ginkgo Issue: S3C-9222 --- .github/workflows/ci.yml | 40 +++++++++++++++ .github/workflows/release.yml | 32 ++++++++++++ .gitignore | 1 + Dockerfile | 18 +++++++ Makefile | 19 +++++++ go.mod | 17 +++++-- go.sum | 19 +++++++ pkg/driver/driver_suite_test.go | 13 +++++ pkg/driver/identity_test.go | 90 +++++++++++++++++++++++++++++++++ 9 files changed, 244 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml create mode 100644 Dockerfile create mode 100644 Makefile create mode 100644 pkg/driver/driver_suite_test.go create mode 100644 pkg/driver/identity_test.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f85ee5d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,40 @@ +name: CI + +on: + push: + branches: + - '**' + +jobs: + test: + name: Run Tests + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: 1.23.2 + + # Install Ginkgo CLI + - name: Install Ginkgo CLI + run: go install github.com/onsi/ginkgo/v2/ginkgo@latest + + - name: Install dependencies + run: go mod tidy + + - name: Run tests + run: make test + + dev-container-build: + permissions: + contents: read + packages: write + uses: scality/workflows/.github/workflows/docker-build.yaml@v2 + with: + name: cosi + namespace: ${{ github.repository_owner }} + tag: ${{ github.sha }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..0792869 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,32 @@ +name: Release + +on: + workflow_dispatch: + inputs: + tag: + description: "Tag to be released (e.g., v1.0.0)" + required: true +jobs: + prod-container-build: + permissions: + contents: read + packages: write + uses: scality/workflows/.github/workflows/docker-build.yaml@v2 + with: + name: cosi + namespace: ${{ github.repository_owner }} + tag: ${{ inputs.tag }} + + create-github-release: + runs-on: ubuntu-latest + needs: prod-container-build + steps: + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + target_commitish: ${{ github.sha }} + tag_name: ${{ inputs.tag }} + name: Release ${{ inputs.tag }} + generate_release_notes: true diff --git a/.gitignore b/.gitignore index 87dc371..72f9910 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ release-tools bin .idea vendor +coverage.txt diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2702cb6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +FROM golang:1.23.2 AS builder + +WORKDIR /app + +ENV CGO_ENABLED=0 \ + GOOS=linux \ + GOARCH=amd64 + +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . + +RUN go build -o scality-cosi-driver ./cmd/scality-cosi-driver + +FROM gcr.io/distroless/static:latest +COPY --from=builder /app/scality-cosi-driver /scality-cosi-driver +ENTRYPOINT ["/scality-cosi-driver"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..613ec5c --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +APP_NAME = scality-cosi-driver +BIN_DIR = ./bin + +.PHONY: all build test clean + +all: test build + +build: + @echo "Building $(APP_NAME)..." + go build -o $(BIN_DIR)/$(APP_NAME) ./cmd/$(APP_NAME) + +test: + @echo "Running Ginkgo tests..." + # Running Ginkgo tests recursively (-r) with verbose output (-v) + ginkgo -r -v --cover --coverprofile=coverage.txt + +clean: + @echo "Cleaning up..." + rm -rf $(BIN_DIR) diff --git a/go.mod b/go.mod index 592be53..7f989a4 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/scality/cosi go 1.22.6 require ( + github.com/stretchr/testify v1.9.0 google.golang.org/grpc v1.66.0 k8s.io/client-go v0.31.0 k8s.io/klog/v2 v2.130.1 @@ -19,11 +20,13 @@ require ( github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.4 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect github.com/google/uuid v1.6.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -31,16 +34,20 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/onsi/ginkgo/v2 v2.20.2 // indirect + github.com/onsi/gomega v1.34.2 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/x448/float16 v0.8.4 // indirect - golang.org/x/net v0.28.0 // indirect + golang.org/x/net v0.30.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/term v0.25.0 // indirect + golang.org/x/text v0.19.0 // indirect golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.24.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 9ca1b0d..bd47bff 100644 --- a/go.sum +++ b/go.sum @@ -34,6 +34,8 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA= +github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -64,8 +66,13 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/ginkgo/v2 v2.20.1 h1:YlVIbqct+ZmnEph770q9Q7NVAz4wwIiVNahee6JyUzo= +github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= +github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= +github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -99,6 +106,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -109,12 +118,18 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -123,6 +138,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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= @@ -133,6 +150,8 @@ google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/pkg/driver/driver_suite_test.go b/pkg/driver/driver_suite_test.go new file mode 100644 index 0000000..14c035f --- /dev/null +++ b/pkg/driver/driver_suite_test.go @@ -0,0 +1,13 @@ +package driver_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestCosiDev(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Driver Suite") +} diff --git a/pkg/driver/identity_test.go b/pkg/driver/identity_test.go new file mode 100644 index 0000000..ee219f1 --- /dev/null +++ b/pkg/driver/identity_test.go @@ -0,0 +1,90 @@ +package driver_test + +import ( + "context" + "strings" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/scality/cosi/pkg/driver" + + cosiapi "sigs.k8s.io/container-object-storage-interface-spec" +) + +var _ = Describe("Identity Server DriverGetInfo", func() { + Context("with valid provisioner names", func() { + var ( + request *cosiapi.DriverGetInfoRequest + server cosiapi.IdentityServer + err error + ) + + // Helper function to initialize the server with the given provisioner and perform DriverGetInfo + initAndGetInfo := func(provisionerName string) (*cosiapi.DriverGetInfoResponse, error) { + server, err = driver.InitIdentityServer(provisionerName) + Expect(err).ToNot(HaveOccurred()) + return server.DriverGetInfo(context.Background(), request) + } + + BeforeEach(func() { + request = &cosiapi.DriverGetInfoRequest{} + }) + + It("should return default driver name info", func() { + provisionerName := "scality-cosi-driver" + resp, err := initAndGetInfo(provisionerName) + Expect(err).ToNot(HaveOccurred()) + Expect(resp).ToNot(BeNil()) + Expect(resp.Name).To(Equal(provisionerName)) + }) + + It("should return a long driver name info", func() { + provisionerName := "scality-cosi-driver" + strings.Repeat("x", 1000) + resp, err := initAndGetInfo(provisionerName) + Expect(err).ToNot(HaveOccurred()) + Expect(resp).ToNot(BeNil()) + Expect(resp.Name).To(Equal(provisionerName)) + }) + + It("should return driver name info containing special characters", func() { + provisionerName := "scality-cosi-driver-ß∂ƒ©" + resp, err := initAndGetInfo(provisionerName) + Expect(err).ToNot(HaveOccurred()) + Expect(resp).ToNot(BeNil()) + Expect(resp.Name).To(Equal(provisionerName)) + }) + }) + + Context("with invalid provisioner names", func() { + var ( + err error + ) + + It("should return an error for empty driver name", func() { + _, err = driver.InitIdentityServer("") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("driver name must not be empty")) + }) + }) + + // For now no use of request object in DriverInfo + // Test to ensure intentional changes in the future + Context("with nil request object", func() { + var ( + server cosiapi.IdentityServer + err error + ) + + BeforeEach(func() { + server, err = driver.InitIdentityServer("scality-cosi-driver") + Expect(err).ToNot(HaveOccurred()) + }) + + It("should handle nil request gracefully", func() { + resp, err := server.DriverGetInfo(context.Background(), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(resp).ToNot(BeNil()) + Expect(resp.Name).To(Equal("scality-cosi-driver")) + }) + }) +})