mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-06 18:54:06 +00:00
e2e test to execute 1000 times in a container
with concurrency 10 Change-Id: Idf9aa8e22e62e718993ea82b23e1818e34556315
This commit is contained in:
parent
d9c54f69d4
commit
f81cce61e6
@ -51,6 +51,10 @@ type ExecOptions struct {
|
||||
// returning stdout, stderr and error. `options` allowed for
|
||||
// additional parameters to be passed.
|
||||
func ExecWithOptions(f *framework.Framework, options ExecOptions) (string, string, error) {
|
||||
return ExecWithOptionsContext(context.Background(), f, options)
|
||||
}
|
||||
|
||||
func ExecWithOptionsContext(ctx context.Context, f *framework.Framework, options ExecOptions) (string, string, error) {
|
||||
if !options.Quiet {
|
||||
framework.Logf("ExecWithOptions %+v", options)
|
||||
}
|
||||
@ -77,7 +81,8 @@ func ExecWithOptions(f *framework.Framework, options ExecOptions) (string, strin
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
framework.Logf("ExecWithOptions: execute(POST %s)", req.URL())
|
||||
err = execute("POST", req.URL(), config, options.Stdin, &stdout, &stderr, tty)
|
||||
err = execute(ctx, "POST", req.URL(), config, options.Stdin, &stdout, &stderr, tty)
|
||||
|
||||
if options.PreserveWhitespace {
|
||||
return stdout.String(), stderr.String(), err
|
||||
}
|
||||
@ -139,12 +144,12 @@ func ExecShellInPodWithFullOutput(ctx context.Context, f *framework.Framework, p
|
||||
return execCommandInPodWithFullOutput(ctx, f, podName, "/bin/sh", "-c", cmd)
|
||||
}
|
||||
|
||||
func execute(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error {
|
||||
func execute(ctx context.Context, method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error {
|
||||
exec, err := remotecommand.NewSPDYExecutor(config, method, url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{
|
||||
return exec.StreamWithContext(ctx, remotecommand.StreamOptions{
|
||||
Stdin: stdin,
|
||||
Stdout: stdout,
|
||||
Stderr: stderr,
|
||||
|
95
test/e2e/kubectl/exec.go
Normal file
95
test/e2e/kubectl/exec.go
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
Copyright 2024 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// OWNER = sig/cli
|
||||
|
||||
package kubectl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/onsi/ginkgo/v2"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/kubernetes/test/e2e/framework"
|
||||
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
||||
admissionapi "k8s.io/pod-security-admission/api"
|
||||
)
|
||||
|
||||
func worker(f *framework.Framework, pod *v1.Pod, id int, jobs <-chan int, results chan<- error) {
|
||||
for j := range jobs {
|
||||
framework.Logf("Worker: %d Job: %d", id, j)
|
||||
func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
stdout, stderr, err := e2epod.ExecWithOptionsContext(ctx, f, e2epod.ExecOptions{
|
||||
Command: []string{"date"},
|
||||
Namespace: f.Namespace.Name,
|
||||
PodName: pod.Name,
|
||||
ContainerName: pod.Spec.Containers[0].Name,
|
||||
Stdin: nil,
|
||||
CaptureStdout: true,
|
||||
CaptureStderr: true,
|
||||
PreserveWhitespace: false,
|
||||
})
|
||||
if err != nil {
|
||||
framework.Logf("Try: %d Error: %v stdout: %s stderr: %s", j, err, stdout, stderr)
|
||||
}
|
||||
results <- err
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
var _ = SIGDescribe("Kubectl exec", func() {
|
||||
f := framework.NewDefaultFramework("exec")
|
||||
|
||||
f.NamespacePodSecurityLevel = admissionapi.LevelBaseline
|
||||
f.It("should be able to execute 1000 times in a container", func(ctx context.Context) {
|
||||
const size = 1000
|
||||
ns := f.Namespace.Name
|
||||
podName := "test-exec-pod"
|
||||
jobs := make(chan int, size)
|
||||
results := make(chan error, size)
|
||||
|
||||
pod := e2epod.NewAgnhostPod(ns, podName, nil, nil, nil)
|
||||
pod = e2epod.NewPodClient(f).CreateSync(ctx, pod)
|
||||
|
||||
// 10 workers for 1000 executions
|
||||
ginkgo.By("Starting workers to exec on pod")
|
||||
for w := 0; w < 10; w++ {
|
||||
framework.Logf("Starting worker %d", w)
|
||||
go worker(f, pod, w, jobs, results)
|
||||
}
|
||||
for i := 0; i < size; i++ {
|
||||
framework.Logf("Sending job %d", i)
|
||||
jobs <- i
|
||||
}
|
||||
ginkgo.By("All jobs processed")
|
||||
close(jobs)
|
||||
|
||||
errors := []error{}
|
||||
for c := 0; c < size; c++ {
|
||||
framework.Logf("Getting results %d", c)
|
||||
err := <-results
|
||||
if err != nil {
|
||||
errors = append(errors, err)
|
||||
}
|
||||
}
|
||||
if len(errors) > 0 {
|
||||
framework.Failf("Exec failed %d times with following errors : %v", len(errors), errors)
|
||||
}
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue
Block a user