Skip to content

Commit

Permalink
Fix bug that can occur when starting multiple test environments in pa…
Browse files Browse the repository at this point in the history
…rallel

When starting a single test environment [1], the control plane start-up
logic [2] launches an etcd and kube-apiserver process. The start-up
logic needs to bind these processes to multiple ports, and when none are
configured in advance, the logic looks for unused ports, and then
creates files in the user cache directory to reserve them (for example,
[3]).

However, the same logic used to reserve ports  also has logic that
deletes files corresponding to "outdated" ports [4].

Therefore, if there are multiple processes/threads starting a test
environment, they may sometimes end up trying to delete the same file
which causes a "file not found" error.

This commit adds logic so that trying to start multiple test
environments does not fail if more than one tries to delete the same
file corresponding to an outdated port.

[1] https://github.com/kubernetes-sigs/controller-runtime/blob/7fb8534b80339a5b8158cee3dc9e5f9439d679dc/pkg/envtest/server.go#L197
[2] https://github.com/kubernetes-sigs/controller-runtime/blob/7fb8534b80339a5b8158cee3dc9e5f9439d679dc/pkg/internal/testing/controlplane/plane.go#L49
[3] https://github.com/kubernetes-sigs/controller-runtime/blob/7fb8534b80339a5b8158cee3dc9e5f9439d679dc/pkg/internal/testing/controlplane/etcd.go#L120
[4] https://github.com/kubernetes-sigs/controller-runtime/blob/7fb8534b80339a5b8158cee3dc9e5f9439d679dc/pkg/internal/testing/addr/manager.go#L64
  • Loading branch information
jcanseco committed May 18, 2022
1 parent 7fb8534 commit 2bf4851
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions pkg/internal/testing/addr/manager.go
Expand Up @@ -71,10 +71,20 @@ func (c *portCache) add(port int) (bool, error) {
}
info, err := d.Info()
if err != nil {
// No-op if file no longer exists; may have been deleted by another
// process/thread trying to allocate ports.
if errors.Is(err, fs.ErrNotExist) {
return nil
}
return err
}
if time.Since(info.ModTime()) > portReserveTime {
if err := os.Remove(filepath.Join(cacheDir, path)); err != nil {
// No-op if file no longer exists; may have been deleted by another
// process/thread trying to allocate ports.
if os.IsNotExist(err) {
return nil
}
return err
}
}
Expand Down

0 comments on commit 2bf4851

Please sign in to comment.