Skip to content

Commit c9b50e1

Browse files
authored
Merge pull request #4931 from cmallikarjunah/issue-4925-add-UTs
🌱 Add unit tests for alpha/internal/update
2 parents 869ca6b + 15b7a1b commit c9b50e1

File tree

8 files changed

+763
-4
lines changed

8 files changed

+763
-4
lines changed

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ require (
2323
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
2424
github.com/google/go-cmp v0.7.0 // indirect
2525
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
26+
github.com/h2non/gock v1.2.0 // indirect
27+
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
2628
github.com/inconshreveable/mousetrap v1.1.0 // indirect
2729
github.com/kr/pretty v0.3.1 // indirect
2830
github.com/pkg/errors v0.9.1 // indirect

go.sum

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
1818
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
1919
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
2020
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
21+
github.com/h2non/gock v1.2.0 h1:K6ol8rfrRkUOefooBC8elXoaNGYkpp7y2qcxGG6BzUE=
22+
github.com/h2non/gock v1.2.0/go.mod h1:tNhoxHYW2W42cYkYb1WqzdbYIieALC99kpYr7rH/BQk=
23+
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
24+
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
2125
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
2226
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
2327
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
@@ -27,6 +31,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
2731
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
2832
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
2933
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
34+
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
3035
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
3136
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
3237
github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY=

pkg/cli/alpha/internal/update/prepare.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func (opts *Update) Prepare() error {
5959

6060
// defineFromVersion will return the CLI version to be used for the update with the v prefix.
6161
func (opts *Update) defineFromVersion(config store.Store) (string, error) {
62-
if len(opts.FromBranch) == 0 && len(config.Config().GetCliVersion()) == 0 {
62+
if len(opts.FromVersion) == 0 && len(config.Config().GetCliVersion()) == 0 {
6363
return "", fmt.Errorf("no version specified in PROJECT file. " +
6464
"Please use --from-version flag to specify the version to update from")
6565
}
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package update
18+
19+
import (
20+
"os"
21+
"path/filepath"
22+
"testing"
23+
24+
"github.com/h2non/gock"
25+
. "github.com/onsi/ginkgo/v2"
26+
. "github.com/onsi/gomega"
27+
28+
"sigs.k8s.io/kubebuilder/v4/pkg/cli/alpha/internal/common"
29+
"sigs.k8s.io/kubebuilder/v4/pkg/config"
30+
"sigs.k8s.io/kubebuilder/v4/pkg/config/store/yaml"
31+
v3 "sigs.k8s.io/kubebuilder/v4/pkg/config/v3"
32+
)
33+
34+
func TestCommand(t *testing.T) {
35+
RegisterFailHandler(Fail)
36+
RunSpecs(t, "update")
37+
}
38+
39+
var _ = Describe("Prepare for internal update", func() {
40+
var (
41+
tmpDir string
42+
workDir string
43+
projectFile string
44+
err error
45+
)
46+
47+
BeforeEach(func() {
48+
workDir, err = os.Getwd()
49+
Expect(err).ToNot(HaveOccurred())
50+
51+
tmpDir, err = os.MkdirTemp("", "kubebuilder-prepare-test")
52+
Expect(err).ToNot(HaveOccurred())
53+
err = os.Chdir(tmpDir)
54+
Expect(err).ToNot(HaveOccurred())
55+
56+
projectFile = filepath.Join(tmpDir, yaml.DefaultPath)
57+
58+
config.Register(config.Version{Number: 3}, func() config.Config {
59+
return &v3.Cfg{Version: config.Version{Number: 3}, CliVersion: "1.0.0"}
60+
})
61+
62+
gock.New("https://api.github.com").
63+
Get("/repos/kubernetes-sigs/kubebuilder/releases/latest").
64+
Reply(200).
65+
JSON(map[string]string{
66+
"tag_name": "v1.1.0",
67+
})
68+
})
69+
70+
AfterEach(func() {
71+
err = os.Chdir(workDir)
72+
Expect(err).ToNot(HaveOccurred())
73+
74+
err = os.RemoveAll(tmpDir)
75+
Expect(err).ToNot(HaveOccurred())
76+
defer gock.Off()
77+
})
78+
79+
Context("Prepare", func() {
80+
DescribeTable("should succeed for valid options",
81+
func(options *Update) {
82+
const version = `version: "3"`
83+
Expect(os.WriteFile(projectFile, []byte(version), 0o644)).To(Succeed())
84+
85+
result := options.Prepare()
86+
Expect(result).ToNot(HaveOccurred())
87+
Expect(options.Prepare()).To(Succeed())
88+
Expect(options.FromVersion).To(Equal("v1.0.0"))
89+
Expect(options.ToVersion).To(Equal("v1.1.0"))
90+
},
91+
Entry("options", &Update{FromVersion: "v1.0.0", ToVersion: "v1.1.0", FromBranch: "test"}),
92+
Entry("options", &Update{FromVersion: "1.0.0", ToVersion: "1.1.0", FromBranch: "test"}),
93+
Entry("options", &Update{FromVersion: "v1.0.0", ToVersion: "v1.1.0"}),
94+
Entry("options", &Update{}),
95+
)
96+
97+
DescribeTable("Should fail to prepare if project path is undetermined",
98+
func(options *Update) {
99+
err = options.Prepare()
100+
Expect(err).To(HaveOccurred())
101+
Expect(err.Error()).Should(ContainSubstring("failed to determine project path"))
102+
},
103+
Entry("options", &Update{FromVersion: "v1.0.0", ToVersion: "v1.1.0", FromBranch: "test"}),
104+
)
105+
106+
DescribeTable("Should fail if PROJECT config could not be loaded",
107+
func(options *Update) {
108+
const version = ""
109+
Expect(os.WriteFile(projectFile, []byte(version), 0o644)).To(Succeed())
110+
111+
err := options.Prepare()
112+
Expect(err).To(HaveOccurred())
113+
Expect(err.Error()).Should(ContainSubstring("failed to load PROJECT config"))
114+
},
115+
Entry("options", &Update{FromVersion: "v1.0.0", ToVersion: "v1.1.0", FromBranch: "test"}),
116+
)
117+
118+
DescribeTable("Should fail if FromVersion cannot be determined",
119+
func(options *Update) {
120+
config.Register(config.Version{Number: 3}, func() config.Config {
121+
return &v3.Cfg{Version: config.Version{Number: 3}}
122+
})
123+
124+
const version = `version: "3"`
125+
Expect(os.WriteFile(projectFile, []byte(version), 0o644)).To(Succeed())
126+
Expect(options.FromVersion).To(BeEquivalentTo(""))
127+
},
128+
Entry("options", &Update{}),
129+
)
130+
})
131+
132+
Context("DefineFromVersion", func() {
133+
DescribeTable("Should succeed when --from-version or CliVersion in Project config is present",
134+
func(options *Update) {
135+
const version = `version: "3"`
136+
Expect(os.WriteFile(projectFile, []byte(version), 0o644)).To(Succeed())
137+
138+
config, err := common.LoadProjectConfig(tmpDir)
139+
Expect(err).ToNot(HaveOccurred())
140+
fromVersion, err := options.defineFromVersion(config)
141+
Expect(err).ToNot(HaveOccurred())
142+
Expect(fromVersion).To(BeEquivalentTo("v1.0.0"))
143+
},
144+
Entry("options", &Update{FromVersion: ""}),
145+
Entry("options", &Update{FromVersion: "1.0.0"}),
146+
)
147+
DescribeTable("Should fail when --from-version and CliVersion in Project config both are absent",
148+
func(options *Update) {
149+
config.Register(config.Version{Number: 3}, func() config.Config {
150+
return &v3.Cfg{Version: config.Version{Number: 3}}
151+
})
152+
153+
const version = `version: "3"`
154+
Expect(os.WriteFile(projectFile, []byte(version), 0o644)).To(Succeed())
155+
156+
config, err := common.LoadProjectConfig(tmpDir)
157+
Expect(err).NotTo(HaveOccurred())
158+
fromVersion, err := options.defineFromVersion(config)
159+
Expect(err).To(HaveOccurred())
160+
Expect(err.Error()).To(ContainSubstring("no version specified in PROJECT file"))
161+
Expect(fromVersion).To(Equal(""))
162+
},
163+
Entry("options", &Update{FromVersion: ""}),
164+
)
165+
})
166+
167+
Context("DefineToVersion", func() {
168+
DescribeTable("Should succeed.",
169+
func(options *Update) {
170+
toVersion := options.defineToVersion()
171+
Expect(toVersion).To(BeEquivalentTo("v1.1.0"))
172+
},
173+
Entry("options", &Update{ToVersion: "1.1.0"}),
174+
Entry("options", &Update{ToVersion: "v1.1.0"}),
175+
Entry("options", &Update{}),
176+
)
177+
})
178+
})

pkg/cli/alpha/internal/update/update.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ func (opts *Update) prepareAncestorBranch() error {
142142
if err := gitCmd.Run(); err != nil {
143143
return fmt.Errorf("failed to stage changes in %s: %w", opts.AncestorBranch, err)
144144
}
145-
commitMessage := "Clean scaffold from release version:" + opts.FromVersion
145+
commitMessage := "Clean scaffolding from release version: " + opts.FromVersion
146146
_ = exec.Command("git", "commit", "-m", commitMessage).Run()
147147
return nil
148148
}
@@ -252,7 +252,7 @@ func runAlphaGenerate(tempDir, version string) error {
252252
if err := cmd.Run(); err != nil {
253253
return fmt.Errorf("failed to run alpha generate: %w", err)
254254
}
255-
log.Info("Successfully ran alpha generate", version)
255+
log.Info("Successfully ran alpha generate ", version)
256256

257257
// TODO: Analyse if this command is still needed in the future.
258258
// It was added because the alpha generate command in versions prior to v4.7.0 does
@@ -314,7 +314,7 @@ func (opts *Update) prepareUpgradeBranch() error {
314314
return fmt.Errorf("failed to stage changes in %s: %w", opts.UpgradeBranch, err)
315315
}
316316

317-
_ = exec.Command("git", "commit", "-m", "Clean scaffolding from version "+opts.ToVersion).Run()
317+
_ = exec.Command("git", "commit", "-m", "Clean scaffolding from release version: "+opts.ToVersion).Run()
318318
return nil
319319
}
320320

0 commit comments

Comments
 (0)