test(kubelet): add a regression test to verify kubelet would not panic

This commit is contained in:
knight42 2020-08-07 17:41:55 +08:00
parent a471843246
commit ebf60155bf
No known key found for this signature in database
GPG Key ID: 1040B69865E7D86C

View File

@ -23,6 +23,7 @@ import (
"fmt"
"path/filepath"
"strings"
"sync"
"testing"
"time"
@ -51,6 +52,67 @@ func getTestCTX() context.Context {
return context.Background()
}
// TestConcurrentlyCreateAndDeleteContainers is a regression test for #93771, which ensures
// kubelet would not panic on concurrent writes to `dockerService.containerCleanupInfos`.
func TestConcurrentlyCreateAndDeleteContainers(t *testing.T) {
ds, _, _ := newTestDockerService()
podName, namespace := "foo", "bar"
containerName, image := "sidecar", "logger"
const count = 20
configs := make([]*runtimeapi.ContainerConfig, 0, count)
sConfigs := make([]*runtimeapi.PodSandboxConfig, 0, count)
for i := 0; i < count; i++ {
s := makeSandboxConfig(fmt.Sprintf("%s%d", podName, i),
fmt.Sprintf("%s%d", namespace, i), fmt.Sprintf("%d", i), 0)
labels := map[string]string{"concurrent-test": fmt.Sprintf("label%d", i)}
c := makeContainerConfig(s, fmt.Sprintf("%s%d", containerName, i),
fmt.Sprintf("%s:v%d", image, i), uint32(i), labels, nil)
sConfigs = append(sConfigs, s)
configs = append(configs, c)
}
containerIDs := make(chan string, len(configs)) // make channel non-blocking to simulate concurrent containers creation
var (
creationWg sync.WaitGroup
deletionWg sync.WaitGroup
)
creationWg.Add(len(configs))
go func() {
creationWg.Wait()
close(containerIDs)
}()
for i := range configs {
go func(i int) {
defer creationWg.Done()
// We don't care about the sandbox id; pass a bogus one.
sandboxID := fmt.Sprintf("sandboxid%d", i)
req := &runtimeapi.CreateContainerRequest{PodSandboxId: sandboxID, Config: configs[i], SandboxConfig: sConfigs[i]}
createResp, err := ds.CreateContainer(getTestCTX(), req)
if err != nil {
t.Errorf("CreateContainer: %v", err)
return
}
containerIDs <- createResp.ContainerId
}(i)
}
for containerID := range containerIDs {
deletionWg.Add(1)
go func(id string) {
defer deletionWg.Done()
_, err := ds.RemoveContainer(getTestCTX(), &runtimeapi.RemoveContainerRequest{ContainerId: id})
if err != nil {
t.Errorf("RemoveContainer: %v", err)
}
}(containerID)
}
deletionWg.Wait()
}
// TestListContainers creates several containers and then list them to check
// whether the correct metadatas, states, and labels are returned.
func TestListContainers(t *testing.T) {