Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions pkg/envtest/envtest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -963,4 +963,56 @@ var _ = Describe("Test", func() {
Expect(env.WebhookInstallOptions.LocalServingCertDir).ShouldNot(BeADirectory())
})
})

Describe("Binary Path Handling", func() {
It("should respect pre-configured binary paths when not downloading", func() {
// Setup custom paths
customAPIServerPath := "/custom/path/to/kube-apiserver"
customEtcdPath := "/custom/path/to/etcd"
customKubectlPath := "/custom/path/to/kubectl"

// Create an environment with pre-configured paths
testEnv := &Environment{}
testEnv.ControlPlane.GetAPIServer().Path = customAPIServerPath
testEnv.ControlPlane.Etcd = &Etcd{}
testEnv.ControlPlane.Etcd.Path = customEtcdPath
testEnv.ControlPlane.KubectlPath = customKubectlPath

// Set BinaryAssetsDirectory to ensure it's not using defaults
testEnv.BinaryAssetsDirectory = "/should/not/be/used"
testEnv.DownloadBinaryAssets = false

// Call configureBinaryPaths to test the path configuration logic
err := testEnv.configureBinaryPaths()
Expect(err).NotTo(HaveOccurred())

// Verify paths were preserved (not overwritten)
apiServer := testEnv.ControlPlane.GetAPIServer()
Expect(apiServer.Path).To(Equal(customAPIServerPath))
Expect(testEnv.ControlPlane.Etcd.Path).To(Equal(customEtcdPath))
Expect(testEnv.ControlPlane.KubectlPath).To(Equal(customKubectlPath))
})

It("should auto-configure binary paths when not pre-configured", func() {
// Create an environment without pre-configured paths
testEnv := &Environment{}
testEnv.BinaryAssetsDirectory = "/test/assets"
testEnv.DownloadBinaryAssets = false

// Call configureBinaryPaths
err := testEnv.configureBinaryPaths()
Expect(err).NotTo(HaveOccurred())

// Verify paths were set using BinPathFinder
apiServer := testEnv.ControlPlane.GetAPIServer()
Expect(apiServer.Path).NotTo(BeEmpty())
Expect(testEnv.ControlPlane.Etcd.Path).NotTo(BeEmpty())
Expect(testEnv.ControlPlane.KubectlPath).NotTo(BeEmpty())

// Verify the paths contain the binary names
Expect(apiServer.Path).To(ContainSubstring("kube-apiserver"))
Expect(testEnv.ControlPlane.Etcd.Path).To(ContainSubstring("etcd"))
Expect(testEnv.ControlPlane.KubectlPath).To(ContainSubstring("kubectl"))
})
})
})
63 changes: 44 additions & 19 deletions pkg/envtest/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ var (
// Environment creates a Kubernetes test environment that will start / stop the Kubernetes control plane and
// install extension APIs.
type Environment struct {
// ControlPlane is the ControlPlane including the apiserver and etcd
// ControlPlane is the ControlPlane including the apiserver and etcd.
// Binary paths (APIServer.Path, Etcd.Path, KubectlPath) can be pre-configured in ControlPlane.
// If DownloadBinaryAssets is true, the downloaded paths will always be used.
// If DownloadBinaryAssets is false and paths are not pre-configured (default is empty), they will be
// automatically resolved using BinaryAssetsDirectory.
ControlPlane controlplane.ControlPlane

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

// configureBinaryPaths configures the binary paths for the API server, etcd, and kubectl.
// If DownloadBinaryAssets is true, it downloads and uses those paths.
// If DownloadBinaryAssets is false, it only sets paths that are not already configured (empty).
func (te *Environment) configureBinaryPaths() error {
apiServer := te.ControlPlane.GetAPIServer()

if te.ControlPlane.Etcd == nil {
te.ControlPlane.Etcd = &controlplane.Etcd{}
}

if te.DownloadBinaryAssets {
apiServerPath, etcdPath, kubectlPath, err := downloadBinaryAssets(context.TODO(),
te.BinaryAssetsDirectory, te.DownloadBinaryAssetsVersion, te.DownloadBinaryAssetsIndexURL)
if err != nil {
return err
}

apiServer.Path = apiServerPath
te.ControlPlane.Etcd.Path = etcdPath
te.ControlPlane.KubectlPath = kubectlPath
} else {
if apiServer.Path == "" {
apiServer.Path = process.BinPathFinder("kube-apiserver", te.BinaryAssetsDirectory)
}
if te.ControlPlane.Etcd.Path == "" {
te.ControlPlane.Etcd.Path = process.BinPathFinder("etcd", te.BinaryAssetsDirectory)
}
if te.ControlPlane.KubectlPath == "" {
te.ControlPlane.KubectlPath = process.BinPathFinder("kubectl", te.BinaryAssetsDirectory)
}
}
return nil
}

// Start starts a local Kubernetes server and updates te.ApiserverPort with the port it is listening on.
func (te *Environment) Start() (*rest.Config, error) {
if te.useExistingCluster() {
Expand All @@ -229,10 +267,6 @@ func (te *Environment) Start() (*rest.Config, error) {
} else {
apiServer := te.ControlPlane.GetAPIServer()

if te.ControlPlane.Etcd == nil {
te.ControlPlane.Etcd = &controlplane.Etcd{}
}

if os.Getenv(envAttachOutput) == "true" {
te.AttachControlPlaneOutput = true
}
Expand All @@ -243,6 +277,9 @@ func (te *Environment) Start() (*rest.Config, error) {
if apiServer.Err == nil {
apiServer.Err = os.Stderr
}
if te.ControlPlane.Etcd == nil {
te.ControlPlane.Etcd = &controlplane.Etcd{}
}
if te.ControlPlane.Etcd.Out == nil {
te.ControlPlane.Etcd.Out = os.Stdout
}
Expand All @@ -251,20 +288,8 @@ func (te *Environment) Start() (*rest.Config, error) {
}
}

if te.DownloadBinaryAssets {
apiServerPath, etcdPath, kubectlPath, err := downloadBinaryAssets(context.TODO(),
te.BinaryAssetsDirectory, te.DownloadBinaryAssetsVersion, te.DownloadBinaryAssetsIndexURL)
if err != nil {
return nil, err
}

apiServer.Path = apiServerPath
te.ControlPlane.Etcd.Path = etcdPath
te.ControlPlane.KubectlPath = kubectlPath
} else {
apiServer.Path = process.BinPathFinder("kube-apiserver", te.BinaryAssetsDirectory)
te.ControlPlane.Etcd.Path = process.BinPathFinder("etcd", te.BinaryAssetsDirectory)
te.ControlPlane.KubectlPath = process.BinPathFinder("kubectl", te.BinaryAssetsDirectory)
if err := te.configureBinaryPaths(); err != nil {
return nil, fmt.Errorf("failed to configure binary paths: %w", err)
}

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