diff --git a/pkg/plugins/golang/go_version_test.go b/pkg/plugins/golang/go_version_test.go index f19d8304bb6..4153dded316 100644 --- a/pkg/plugins/golang/go_version_test.go +++ b/pkg/plugins/golang/go_version_test.go @@ -17,6 +17,7 @@ limitations under the License. package golang import ( + "errors" "sort" . "github.com/onsi/ginkgo/v2" @@ -24,6 +25,34 @@ import ( ) var _ = Describe("GoVersion", func() { + Context("String", func() { + It("patch is not empty", func() { + v := GoVersion{major: 1, minor: 1, patch: 1} + Expect(v.String()).To(Equal("go1.1.1")) + }) + It("preRelease is not empty", func() { + v := GoVersion{major: 1, minor: 1, prerelease: "-alpha"} + Expect(v.String()).To(Equal("go1.1-alpha")) + }) + It("default", func() { + v := GoVersion{major: 1, minor: 1} + Expect(v.String()).To(Equal("go1.1")) + }) + }) + + Context("MustParse", func() { + It("succeeds", func() { + v := GoVersion{major: 1, minor: 1, patch: 1} + Expect(MustParse("go1.1.1")).To(Equal(v)) + }) + It("panics", func() { + triggerPanic := func() { + MustParse("go1.a") + } + Expect(triggerPanic).To(PanicWith(errors.New("invalid version string"))) + }) + }) + Context("parse", func() { var v GoVersion @@ -129,6 +158,24 @@ var _ = Describe("GoVersion", func() { }) }) +var _ = Describe("ValidateGoVersion", func() { + DescribeTable("should return no error for valid/supported go versions", func(minVersion, maxVersion GoVersion) { + Expect(ValidateGoVersion(minVersion, maxVersion)).To(Succeed()) + }, + Entry("for minVersion: 1.1.1 and maxVersion: 2000.1.1", GoVersion{major: 1, minor: 1, patch: 1}, + GoVersion{major: 2000, minor: 1, patch: 1}), + Entry("for minVersion: 1.1.1 and maxVersion: 1.2000.2000", GoVersion{major: 1, minor: 1, patch: 1}, + GoVersion{major: 1, minor: 2000, patch: 1}), + ) + + DescribeTable("should return error for invalid/unsupported go versions", func(minVersion, maxVersion GoVersion) { + Expect(ValidateGoVersion(minVersion, maxVersion)).NotTo(Succeed()) + }, + Entry("for invalid min and maxVersions", GoVersion{major: 2, minor: 2, patch: 2}, + GoVersion{major: 1, minor: 1, patch: 1}), + ) +}) + var _ = Describe("checkGoVersion", func() { var ( goVerMin GoVersion diff --git a/pkg/plugins/golang/options_test.go b/pkg/plugins/golang/options_test.go index 8d7c5ad34bf..49f6fc43daa 100644 --- a/pkg/plugins/golang/options_test.go +++ b/pkg/plugins/golang/options_test.go @@ -82,6 +82,8 @@ var _ = Describe("Options", func() { } else { Expect(res.Path).To(Equal(path.Join(cfg.GetRepository(), "api", gvk.Version))) } + } else if len(options.ExternalAPIPath) > 0 { + Expect(res.Path).To(Equal("testPath")) } else { // Core-resources have a path despite not having an API/Webhook but they are not tested here Expect(res.Path).To(Equal("")) @@ -104,6 +106,12 @@ var _ = Describe("Options", func() { } else { Expect(res.Webhooks.IsEmpty()).To(BeTrue()) } + + if len(options.ExternalAPIPath) > 0 { + Expect(res.External).To(BeTrue()) + Expect(res.Domain).To(Equal("test.io")) + } + Expect(res.QualifiedGroup()).To(Equal(gvk.Group + "." + gvk.Domain)) Expect(res.PackageName()).To(Equal(gvk.Group)) Expect(res.ImportAlias()).To(Equal(gvk.Group + gvk.Version)) @@ -112,6 +120,9 @@ var _ = Describe("Options", func() { Entry("when updating nothing", Options{}), Entry("when updating the plural", Options{Plural: "mates"}), Entry("when updating the Controller", Options{DoController: true}), + Entry("when updating with External API Path", Options{ExternalAPIPath: "testPath", ExternalAPIDomain: "test.io"}), + Entry("when updating the API with setting webhooks params", + Options{DoAPI: true, DoDefaulting: true, DoValidation: true, DoConversion: true}), ) DescribeTable("should use core apis", diff --git a/pkg/plugins/golang/repository_test.go b/pkg/plugins/golang/repository_test.go new file mode 100644 index 00000000000..ee86a29a12d --- /dev/null +++ b/pkg/plugins/golang/repository_test.go @@ -0,0 +1,111 @@ +/* +Copyright 2025 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package golang + +import ( + "os" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("golang:repository", func() { + var ( + tmpDir string + oldDir string + ) + + BeforeEach(func() { + var err error + tmpDir, err = os.MkdirTemp("", "repo-test") + Expect(err).NotTo(HaveOccurred()) + oldDir, err = os.Getwd() + Expect(err).NotTo(HaveOccurred()) + Expect(os.Chdir(tmpDir)).To(Succeed()) + }) + + AfterEach(func() { + Expect(os.Chdir(oldDir)).To(Succeed()) + Expect(os.RemoveAll(tmpDir)).To(Succeed()) + }) + + When("go.mod exists", func() { + BeforeEach(func() { + // Simulate `go mod edit -json` output by writing a go.mod file and using go commands + Expect(os.WriteFile("go.mod", []byte("module github.com/example/repo\n"), 0o644)).To(Succeed()) + }) + + It("findGoModulePath returns the module path", func() { + path, err := findGoModulePath() + Expect(err).NotTo(HaveOccurred()) + Expect(path).To(Equal("github.com/example/repo")) + }) + + It("FindCurrentRepo returns the module path", func() { + path, err := FindCurrentRepo() + Expect(err).NotTo(HaveOccurred()) + Expect(path).To(Equal("github.com/example/repo")) + }) + }) + + When("go.mod does not exist", func() { + It("findGoModulePath returns error", func() { + got, err := findGoModulePath() + Expect(err).To(HaveOccurred()) + Expect(got).To(Equal("")) + }) + + It("FindCurrentRepo tries to init a module and returns the path or a helpful error", func() { + path, err := FindCurrentRepo() + if err != nil { + Expect(path).To(Equal("")) + Expect(err.Error()).To(ContainSubstring("could not determine repository path")) + } else { + Expect(path).NotTo(BeEmpty()) + } + }) + }) + + When("go mod command fails with exec.ExitError", func() { + var origPath string + + BeforeEach(func() { + // Move go binary out of PATH to force exec error + origPath = os.Getenv("PATH") + // Set PATH to empty so "go" cannot be found + Expect(os.Setenv("PATH", "")).To(Succeed()) + }) + + AfterEach(func() { + Expect(os.Setenv("PATH", origPath)).To(Succeed()) + }) + + It("findGoModulePath returns error with stderr message", func() { + got, err := findGoModulePath() + Expect(err).To(HaveOccurred()) + Expect(err.Error()).NotTo(BeEmpty()) + Expect(got).To(Equal("")) + }) + + It("FindCurrentRepo returns error with stderr message", func() { + got, err := FindCurrentRepo() + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("could not determine repository path")) + Expect(got).To(Equal("")) + }) + }) +})