Skip to content

Commit 8435fde

Browse files
Add pkg/cli/alpha/internal/update/prepare_test.go
1 parent 83597e1 commit 8435fde

File tree

4 files changed

+194
-1
lines changed

4 files changed

+194
-1
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.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func (opts *Update) defineFromVersion(config store.Store) (string, error) {
7575

7676
func (opts *Update) defineToVersion() string {
7777
if len(opts.ToVersion) != 0 {
78-
if !strings.HasPrefix(opts.FromVersion, "v") {
78+
if !strings.HasPrefix(opts.ToVersion, "v") {
7979
return "v" + opts.ToVersion
8080
}
8181
return opts.ToVersion
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
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+
"sigs.k8s.io/kubebuilder/v4/pkg/cli/alpha/internal/common"
28+
"sigs.k8s.io/kubebuilder/v4/pkg/config"
29+
"sigs.k8s.io/kubebuilder/v4/pkg/config/store/yaml"
30+
v3 "sigs.k8s.io/kubebuilder/v4/pkg/config/v3"
31+
)
32+
33+
func TestCommand(t *testing.T) {
34+
RegisterFailHandler(Fail)
35+
RunSpecs(t, "update")
36+
}
37+
38+
var _ = Describe("Prepare for internal update", func() {
39+
var (
40+
tmpDir string
41+
workDir string
42+
projectFile string
43+
)
44+
45+
BeforeEach(func() {
46+
tmpDir, _ = os.MkdirTemp("", "kubebuilder-prepare-test")
47+
workDir, _ = os.Getwd()
48+
os.Chdir(tmpDir)
49+
projectFile = filepath.Join(tmpDir, yaml.DefaultPath)
50+
51+
config.Register(config.Version{Number: 3}, func() config.Config {
52+
return &v3.Cfg{Version: config.Version{Number: 3}, CliVersion: "1.0.0"}
53+
})
54+
55+
gock.New("https://api.github.com").
56+
Get("/repos/kubernetes-sigs/kubebuilder/releases/latest").
57+
Reply(200).
58+
JSON(map[string]string{
59+
"tag_name": "v1.1.0",
60+
})
61+
})
62+
63+
AfterEach(func() {
64+
os.Chdir(workDir)
65+
os.RemoveAll(tmpDir)
66+
defer gock.Off()
67+
})
68+
69+
Context("Prepare", func() {
70+
DescribeTable("should succeed for valid options",
71+
func(options *Update) {
72+
73+
const version = `version: "3"`
74+
Expect(os.WriteFile(projectFile, []byte(version), 0o644)).To(Succeed())
75+
76+
result := options.Prepare()
77+
Expect(result).To(BeNil())
78+
Expect(options.Prepare()).To(Succeed())
79+
Expect(options.FromVersion).To(Equal("v1.0.0"))
80+
Expect(options.ToVersion).To(Equal("v1.1.0"))
81+
},
82+
Entry("options", &Update{FromVersion: "v1.0.0", ToVersion: "v1.1.0", FromBranch: "test"}),
83+
Entry("options", &Update{FromVersion: "1.0.0", ToVersion: "1.1.0", FromBranch: "test"}),
84+
Entry("options", &Update{FromVersion: "v1.0.0", ToVersion: "v1.1.0"}),
85+
Entry("options", &Update{FromVersion: "1.0.0"}),
86+
Entry("options", &Update{ToVersion: "1.1.0"}),
87+
Entry("options", &Update{}),
88+
)
89+
90+
DescribeTable("Should fail to prepare if project path is undetermined",
91+
func(options *Update) {
92+
result := options.Prepare()
93+
Expect(result).NotTo(BeNil())
94+
Expect(result.Error()).Should(ContainSubstring("failed to determine project path"))
95+
},
96+
Entry("options", &Update{FromVersion: "v1.0.0", ToVersion: "v1.1.0", FromBranch: "test"}),
97+
)
98+
99+
DescribeTable("Should fail if PROJECT config could not be loaded",
100+
func(options *Update) {
101+
const version = ""
102+
Expect(os.WriteFile(projectFile, []byte(version), 0o644)).To(Succeed())
103+
104+
result := options.Prepare()
105+
Expect(result).NotTo(BeNil())
106+
Expect(result.Error()).Should(ContainSubstring("failed to load PROJECT config"))
107+
},
108+
Entry("options", &Update{FromVersion: "v1.0.0", ToVersion: "v1.1.0", FromBranch: "test"}),
109+
)
110+
111+
DescribeTable("Should fail if FromVersion cannot be determined",
112+
func(options *Update) {
113+
114+
config.Register(config.Version{Number: 3}, func() config.Config {
115+
return &v3.Cfg{Version: config.Version{Number: 3}}
116+
})
117+
118+
const version = `version: "3"`
119+
Expect(os.WriteFile(projectFile, []byte(version), 0o644)).To(Succeed())
120+
121+
// TODO: Update test. err is Nil as default branch in Prepare() is being hardcoded to "main".
122+
// Hence, the defineFromVersion condition will never fail.
123+
// result := options.Prepare()
124+
// Expect(result).NotTo(BeNil())
125+
// Expect(result.Error()).Should(ContainSubstring("failed to determine the version"))
126+
Expect(options.FromVersion).To(BeEquivalentTo(""))
127+
},
128+
Entry("options", &Update{}),
129+
)
130+
})
131+
132+
Context("DefineFromVersion", func() {
133+
134+
DescribeTable("Should succeed when branch or CliVersion in Project config is present",
135+
func(options *Update) {
136+
137+
const version = `version: "3"`
138+
Expect(os.WriteFile(projectFile, []byte(version), 0o644)).To(Succeed())
139+
140+
config, err := common.LoadProjectConfig(tmpDir)
141+
Expect(err).NotTo(HaveOccurred())
142+
fromVersion, err := options.defineFromVersion(config)
143+
Expect(err).To(BeNil())
144+
Expect(fromVersion).To(BeEquivalentTo("v1.0.0"))
145+
},
146+
Entry("options", &Update{FromVersion: ""}),
147+
Entry("options", &Update{FromBranch: "test"}),
148+
Entry("options", &Update{FromVersion: "1.0.0", FromBranch: "test"}),
149+
)
150+
DescribeTable("Should fail when branch and CliVersion in Project config are absent",
151+
func(options *Update) {
152+
153+
config.Register(config.Version{Number: 3}, func() config.Config {
154+
return &v3.Cfg{Version: config.Version{Number: 3}}
155+
})
156+
157+
const version = `version: "3"`
158+
Expect(os.WriteFile(projectFile, []byte(version), 0o644)).To(Succeed())
159+
160+
config, err := common.LoadProjectConfig(tmpDir)
161+
Expect(err).NotTo(HaveOccurred())
162+
fromVersion, err := options.defineFromVersion(config)
163+
Expect(err).To(HaveOccurred())
164+
Expect(err.Error()).To(ContainSubstring("no version specified in PROJECT file"))
165+
Expect(fromVersion).To(Equal(""))
166+
},
167+
Entry("options", &Update{FromVersion: ""}),
168+
Entry("options", &Update{FromVersion: "v1.0.0"}),
169+
)
170+
})
171+
172+
Context("DefineToVersion", func() {
173+
174+
DescribeTable("Should succeed.",
175+
func(options *Update) {
176+
toVersion := options.defineToVersion()
177+
Expect(toVersion).To(BeEquivalentTo("v1.1.0"))
178+
},
179+
Entry("options", &Update{ToVersion: "1.1.0"}),
180+
Entry("options", &Update{ToVersion: "v1.1.0"}),
181+
Entry("options", &Update{}),
182+
)
183+
184+
})
185+
186+
})

0 commit comments

Comments
 (0)