Add test cases to reproduce issues with concurrent `helm repo add` commands

Signed-off-by: 's avatarPatrick Decat <pdecat@gmail.com>
parent b4ff4d2f
...@@ -17,13 +17,18 @@ limitations under the License. ...@@ -17,13 +17,18 @@ limitations under the License.
package main package main
import ( import (
"fmt"
"io" "io"
"os" "os"
"os/exec"
"strings"
"sync"
"testing" "testing"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/helm/pkg/helm" "k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/helm/helmpath"
"k8s.io/helm/pkg/repo" "k8s.io/helm/pkg/repo"
"k8s.io/helm/pkg/repo/repotest" "k8s.io/helm/pkg/repo/repotest"
) )
...@@ -101,3 +106,111 @@ func TestRepoAdd(t *testing.T) { ...@@ -101,3 +106,111 @@ func TestRepoAdd(t *testing.T) {
t.Errorf("Duplicate repository name was added") t.Errorf("Duplicate repository name was added")
} }
} }
func TestRepoAddConcurrentGoRoutines(t *testing.T) {
ts, thome, err := repotest.NewTempServer("testdata/testserver/*.*")
if err != nil {
t.Fatal(err)
}
cleanup := resetEnv()
defer func() {
ts.Stop()
os.RemoveAll(thome.String())
cleanup()
}()
settings.Home = thome
if err := ensureTestHome(settings.Home, t); err != nil {
t.Fatal(err)
}
var wg sync.WaitGroup
wg.Add(3)
for i := 0; i < 3; i++ {
go func(name string) {
defer wg.Done()
if err := addRepository(name, ts.URL(), "", "", settings.Home, "", "", "", true); err != nil {
t.Error(err)
}
}(fmt.Sprintf("%s-%d", testName, i))
}
wg.Wait()
f, err := repo.LoadRepositoriesFile(settings.Home.RepositoryFile())
if err != nil {
t.Error(err)
}
var name string
for i := 0; i < 3; i++ {
name = fmt.Sprintf("%s-%d", testName, i)
if !f.Has(name) {
t.Errorf("%s was not successfully inserted into %s", name, settings.Home.RepositoryFile())
}
}
}
// Same as TestRepoAddConcurrentGoRoutines but with repository additions in sub-processes
func TestRepoAddConcurrentSubProcesses(t *testing.T) {
goWantHelperProcess := os.Getenv("GO_WANT_HELPER_PROCESS")
if goWantHelperProcess == "" {
// parent
ts, thome, err := repotest.NewTempServer("testdata/testserver/*.*")
if err != nil {
t.Fatal(err)
}
settings.Home = thome
cleanup := resetEnv()
defer func() {
ts.Stop()
os.RemoveAll(thome.String())
cleanup()
}()
if err := ensureTestHome(settings.Home, t); err != nil {
t.Fatal(err)
}
var wg sync.WaitGroup
wg.Add(3)
for i := 0; i < 3; i++ {
go func(name string) {
defer wg.Done()
cmd := exec.Command(os.Args[0], "-test.run=^TestRepoAddConcurrentSubProcesses$")
cmd.Env = append(os.Environ(), fmt.Sprintf("GO_WANT_HELPER_PROCESS=%s,%s", name, ts.URL()), fmt.Sprintf("HELM_HOME=%s", settings.Home))
out, err := cmd.CombinedOutput()
if len(out) > 0 || err != nil {
t.Fatalf("child process: %q, %v", out, err)
}
}(fmt.Sprintf("%s-%d", testName, i))
}
wg.Wait()
f, err := repo.LoadRepositoriesFile(settings.Home.RepositoryFile())
if err != nil {
t.Error(err)
}
var name string
for i := 0; i < 3; i++ {
name = fmt.Sprintf("%s-%d", testName, i)
if !f.Has(name) {
t.Errorf("%s was not successfully inserted into %s", name, settings.Home.RepositoryFile())
}
}
} else {
// child
s := strings.Split(goWantHelperProcess, ",")
settings.Home = helmpath.Home(os.Getenv("HELM_HOME"))
repoName := s[0]
tsURL := s[1]
if err := addRepository(repoName, tsURL, "", "", settings.Home, "", "", "", true); err != nil {
t.Fatal(err)
}
os.Exit(0)
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment