Skip to content

Commit b99b269

Browse files
authored
Merge pull request #3372 from mzhaom/fix/envtest-respect-custom-binary-paths
✨ envtest: respect pre-configured binary paths in ControlPlane
2 parents d37116b + b4232f0 commit b99b269

File tree

2 files changed

+96
-19
lines changed

2 files changed

+96
-19
lines changed

pkg/envtest/envtest_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,4 +963,56 @@ var _ = Describe("Test", func() {
963963
Expect(env.WebhookInstallOptions.LocalServingCertDir).ShouldNot(BeADirectory())
964964
})
965965
})
966+
967+
Describe("Binary Path Handling", func() {
968+
It("should respect pre-configured binary paths when not downloading", func() {
969+
// Setup custom paths
970+
customAPIServerPath := "/custom/path/to/kube-apiserver"
971+
customEtcdPath := "/custom/path/to/etcd"
972+
customKubectlPath := "/custom/path/to/kubectl"
973+
974+
// Create an environment with pre-configured paths
975+
testEnv := &Environment{}
976+
testEnv.ControlPlane.GetAPIServer().Path = customAPIServerPath
977+
testEnv.ControlPlane.Etcd = &Etcd{}
978+
testEnv.ControlPlane.Etcd.Path = customEtcdPath
979+
testEnv.ControlPlane.KubectlPath = customKubectlPath
980+
981+
// Set BinaryAssetsDirectory to ensure it's not using defaults
982+
testEnv.BinaryAssetsDirectory = "/should/not/be/used"
983+
testEnv.DownloadBinaryAssets = false
984+
985+
// Call configureBinaryPaths to test the path configuration logic
986+
err := testEnv.configureBinaryPaths()
987+
Expect(err).NotTo(HaveOccurred())
988+
989+
// Verify paths were preserved (not overwritten)
990+
apiServer := testEnv.ControlPlane.GetAPIServer()
991+
Expect(apiServer.Path).To(Equal(customAPIServerPath))
992+
Expect(testEnv.ControlPlane.Etcd.Path).To(Equal(customEtcdPath))
993+
Expect(testEnv.ControlPlane.KubectlPath).To(Equal(customKubectlPath))
994+
})
995+
996+
It("should auto-configure binary paths when not pre-configured", func() {
997+
// Create an environment without pre-configured paths
998+
testEnv := &Environment{}
999+
testEnv.BinaryAssetsDirectory = "/test/assets"
1000+
testEnv.DownloadBinaryAssets = false
1001+
1002+
// Call configureBinaryPaths
1003+
err := testEnv.configureBinaryPaths()
1004+
Expect(err).NotTo(HaveOccurred())
1005+
1006+
// Verify paths were set using BinPathFinder
1007+
apiServer := testEnv.ControlPlane.GetAPIServer()
1008+
Expect(apiServer.Path).NotTo(BeEmpty())
1009+
Expect(testEnv.ControlPlane.Etcd.Path).NotTo(BeEmpty())
1010+
Expect(testEnv.ControlPlane.KubectlPath).NotTo(BeEmpty())
1011+
1012+
// Verify the paths contain the binary names
1013+
Expect(apiServer.Path).To(ContainSubstring("kube-apiserver"))
1014+
Expect(testEnv.ControlPlane.Etcd.Path).To(ContainSubstring("etcd"))
1015+
Expect(testEnv.ControlPlane.KubectlPath).To(ContainSubstring("kubectl"))
1016+
})
1017+
})
9661018
})

pkg/envtest/server.go

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,11 @@ var (
109109
// Environment creates a Kubernetes test environment that will start / stop the Kubernetes control plane and
110110
// install extension APIs.
111111
type Environment struct {
112-
// ControlPlane is the ControlPlane including the apiserver and etcd
112+
// ControlPlane is the ControlPlane including the apiserver and etcd.
113+
// Binary paths (APIServer.Path, Etcd.Path, KubectlPath) can be pre-configured in ControlPlane.
114+
// If DownloadBinaryAssets is true, the downloaded paths will always be used.
115+
// If DownloadBinaryAssets is false and paths are not pre-configured (default is empty), they will be
116+
// automatically resolved using BinaryAssetsDirectory.
113117
ControlPlane controlplane.ControlPlane
114118

115119
// Scheme is used to determine if conversion webhooks should be enabled
@@ -211,6 +215,40 @@ func (te *Environment) Stop() error {
211215
return te.ControlPlane.Stop()
212216
}
213217

218+
// configureBinaryPaths configures the binary paths for the API server, etcd, and kubectl.
219+
// If DownloadBinaryAssets is true, it downloads and uses those paths.
220+
// If DownloadBinaryAssets is false, it only sets paths that are not already configured (empty).
221+
func (te *Environment) configureBinaryPaths() error {
222+
apiServer := te.ControlPlane.GetAPIServer()
223+
224+
if te.ControlPlane.Etcd == nil {
225+
te.ControlPlane.Etcd = &controlplane.Etcd{}
226+
}
227+
228+
if te.DownloadBinaryAssets {
229+
apiServerPath, etcdPath, kubectlPath, err := downloadBinaryAssets(context.TODO(),
230+
te.BinaryAssetsDirectory, te.DownloadBinaryAssetsVersion, te.DownloadBinaryAssetsIndexURL)
231+
if err != nil {
232+
return err
233+
}
234+
235+
apiServer.Path = apiServerPath
236+
te.ControlPlane.Etcd.Path = etcdPath
237+
te.ControlPlane.KubectlPath = kubectlPath
238+
} else {
239+
if apiServer.Path == "" {
240+
apiServer.Path = process.BinPathFinder("kube-apiserver", te.BinaryAssetsDirectory)
241+
}
242+
if te.ControlPlane.Etcd.Path == "" {
243+
te.ControlPlane.Etcd.Path = process.BinPathFinder("etcd", te.BinaryAssetsDirectory)
244+
}
245+
if te.ControlPlane.KubectlPath == "" {
246+
te.ControlPlane.KubectlPath = process.BinPathFinder("kubectl", te.BinaryAssetsDirectory)
247+
}
248+
}
249+
return nil
250+
}
251+
214252
// Start starts a local Kubernetes server and updates te.ApiserverPort with the port it is listening on.
215253
func (te *Environment) Start() (*rest.Config, error) {
216254
if te.useExistingCluster() {
@@ -229,10 +267,6 @@ func (te *Environment) Start() (*rest.Config, error) {
229267
} else {
230268
apiServer := te.ControlPlane.GetAPIServer()
231269

232-
if te.ControlPlane.Etcd == nil {
233-
te.ControlPlane.Etcd = &controlplane.Etcd{}
234-
}
235-
236270
if os.Getenv(envAttachOutput) == "true" {
237271
te.AttachControlPlaneOutput = true
238272
}
@@ -243,6 +277,9 @@ func (te *Environment) Start() (*rest.Config, error) {
243277
if apiServer.Err == nil {
244278
apiServer.Err = os.Stderr
245279
}
280+
if te.ControlPlane.Etcd == nil {
281+
te.ControlPlane.Etcd = &controlplane.Etcd{}
282+
}
246283
if te.ControlPlane.Etcd.Out == nil {
247284
te.ControlPlane.Etcd.Out = os.Stdout
248285
}
@@ -251,20 +288,8 @@ func (te *Environment) Start() (*rest.Config, error) {
251288
}
252289
}
253290

254-
if te.DownloadBinaryAssets {
255-
apiServerPath, etcdPath, kubectlPath, err := downloadBinaryAssets(context.TODO(),
256-
te.BinaryAssetsDirectory, te.DownloadBinaryAssetsVersion, te.DownloadBinaryAssetsIndexURL)
257-
if err != nil {
258-
return nil, err
259-
}
260-
261-
apiServer.Path = apiServerPath
262-
te.ControlPlane.Etcd.Path = etcdPath
263-
te.ControlPlane.KubectlPath = kubectlPath
264-
} else {
265-
apiServer.Path = process.BinPathFinder("kube-apiserver", te.BinaryAssetsDirectory)
266-
te.ControlPlane.Etcd.Path = process.BinPathFinder("etcd", te.BinaryAssetsDirectory)
267-
te.ControlPlane.KubectlPath = process.BinPathFinder("kubectl", te.BinaryAssetsDirectory)
291+
if err := te.configureBinaryPaths(); err != nil {
292+
return nil, fmt.Errorf("failed to configure binary paths: %w", err)
268293
}
269294

270295
if err := te.defaultTimeouts(); err != nil {

0 commit comments

Comments
 (0)