mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 12:43:23 +00:00
Merge pull request #48824 from yguo0905/docker-validation
Automatic merge from submit-queue (batch tested with PRs 48082, 48815, 48901, 48824) Add test image name to the OS image field of the perf metrics I'd like to add the resource usage benchmarks for COS m60 (docker 1.13.1) but don't want to remove the existing m59 (docker 1.11.2) [ones](https://github.com/kubernetes/kubernetes/blob/master/test/e2e_node/jenkins/benchmark/benchmark-config.yaml#L51-L71), in order to compare the results between the two docker versions. The `image` reported in the metrics is from `Node.Status.NodeInfo.OSImage`, which is always "Container-Optimized OS from Google" (from `/etc/os-releases`) for COS. So there's no way to differentiate two milestones in the metrics. This PR attaches the [image name](https://github.com/kubernetes/kubernetes/blob/master/test/e2e_node/jenkins/benchmark/benchmark-config.yaml#L52) to the `image` field of the metrics. So it will become "Container-Optimized OS from Google (cos-stable-59-9460-64-0)". See the results of the test run: [performance-memory-containervm-resource1-resource_0.json](https://storage.googleapis.com/ygg-gke-dev-bucket/e2e-node-test/ci-kubernetes-node-kubelet-benchmark/13/artifacts/performance-memory-containervm-resource1-resource_0.json) [performance-memory-coreos-resource1-resource_0.json](https://storage.googleapis.com/ygg-gke-dev-bucket/e2e-node-test/ci-kubernetes-node-kubelet-benchmark/13/artifacts/performance-memory-coreos-resource1-resource_0.json) [performance-memory-gci-resource1-resource_0.json](https://storage.googleapis.com/ygg-gke-dev-bucket/e2e-node-test/ci-kubernetes-node-kubelet-benchmark/13/artifacts/performance-memory-gci-resource1-resource_0.json) **Release note**: ``` None ``` Ref: https://github.com/kubernetes/kubernetes/issues/42926 /sig node /area node-e2e /assign @dchen1107
This commit is contained in:
commit
a14abaabab
@ -335,6 +335,7 @@ http-port
|
|||||||
ignore-daemonsets
|
ignore-daemonsets
|
||||||
ignore-not-found
|
ignore-not-found
|
||||||
image-config-file
|
image-config-file
|
||||||
|
image-description
|
||||||
image-gc-high-threshold
|
image-gc-high-threshold
|
||||||
image-gc-low-threshold
|
image-gc-low-threshold
|
||||||
image-project
|
image-project
|
||||||
|
@ -131,6 +131,8 @@ type NodeTestContextType struct {
|
|||||||
PrepullImages bool
|
PrepullImages bool
|
||||||
// KubeletConfig is the kubelet configuration the test is running against.
|
// KubeletConfig is the kubelet configuration the test is running against.
|
||||||
KubeletConfig componentconfig.KubeletConfiguration
|
KubeletConfig componentconfig.KubeletConfiguration
|
||||||
|
// ImageDescription is the description of the image on which the test is running.
|
||||||
|
ImageDescription string
|
||||||
}
|
}
|
||||||
|
|
||||||
type CloudConfig struct {
|
type CloudConfig struct {
|
||||||
@ -250,6 +252,7 @@ func RegisterNodeFlags() {
|
|||||||
// It is hard and unnecessary to deal with the complexity inside the test suite.
|
// It is hard and unnecessary to deal with the complexity inside the test suite.
|
||||||
flag.BoolVar(&TestContext.NodeConformance, "conformance", false, "If true, the test suite will not start kubelet, and fetch system log (kernel, docker, kubelet log etc.) to the report directory.")
|
flag.BoolVar(&TestContext.NodeConformance, "conformance", false, "If true, the test suite will not start kubelet, and fetch system log (kernel, docker, kubelet log etc.) to the report directory.")
|
||||||
flag.BoolVar(&TestContext.PrepullImages, "prepull-images", true, "If true, prepull images so image pull failures do not cause test failures.")
|
flag.BoolVar(&TestContext.PrepullImages, "prepull-images", true, "If true, prepull images so image pull failures do not cause test failures.")
|
||||||
|
flag.StringVar(&TestContext.ImageDescription, "image-description", "", "The description of the image which the test will be running on.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ViperizeFlags sets up all flag and config processing. Future configuration info should be added to viper, not to flags.
|
// ViperizeFlags sets up all flag and config processing. Future configuration info should be added to viper, not to flags.
|
||||||
|
@ -176,10 +176,14 @@ func getTestNodeInfo(f *framework.Framework, testName, testDesc string) map[stri
|
|||||||
framework.Failf("Fail to fetch Memory capacity value as Int64.")
|
framework.Failf("Fail to fetch Memory capacity value as Int64.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
image := node.Status.NodeInfo.OSImage
|
||||||
|
if framework.TestContext.ImageDescription != "" {
|
||||||
|
image = fmt.Sprintf("%s (%s)", image, framework.TestContext.ImageDescription)
|
||||||
|
}
|
||||||
return map[string]string{
|
return map[string]string{
|
||||||
"node": nodeName,
|
"node": nodeName,
|
||||||
"test": testName,
|
"test": testName,
|
||||||
"image": node.Status.NodeInfo.OSImage,
|
"image": image,
|
||||||
"machine": fmt.Sprintf("cpu:%dcore,memory:%.1fGB", cpuValue, float32(memoryValue)/(1024*1024*1024)),
|
"machine": fmt.Sprintf("cpu:%dcore,memory:%.1fGB", cpuValue, float32(memoryValue)/(1024*1024*1024)),
|
||||||
"desc": testDesc,
|
"desc": testDesc,
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,7 @@ func stopKubelet(host, workspace string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RunTest runs test on the node.
|
// RunTest runs test on the node.
|
||||||
func (c *ConformanceRemote) RunTest(host, workspace, results, junitFilePrefix, testArgs, _ string, timeout time.Duration) (string, error) {
|
func (c *ConformanceRemote) RunTest(host, workspace, results, imageDesc, junitFilePrefix, testArgs, _ string, timeout time.Duration) (string, error) {
|
||||||
// Install the cni plugins and add a basic CNI configuration.
|
// Install the cni plugins and add a basic CNI configuration.
|
||||||
if err := setupCNI(host, workspace); err != nil {
|
if err := setupCNI(host, workspace); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -163,7 +163,7 @@ func updateOSSpecificKubeletFlags(args, host, workspace string) (string, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RunTest runs test on the node.
|
// RunTest runs test on the node.
|
||||||
func (n *NodeE2ERemote) RunTest(host, workspace, results, junitFilePrefix, testArgs, ginkgoArgs string, timeout time.Duration) (string, error) {
|
func (n *NodeE2ERemote) RunTest(host, workspace, results, imageDesc, junitFilePrefix, testArgs, ginkgoArgs string, timeout time.Duration) (string, error) {
|
||||||
// Install the cni plugins and add a basic CNI configuration.
|
// Install the cni plugins and add a basic CNI configuration.
|
||||||
if err := setupCNI(host, workspace); err != nil {
|
if err := setupCNI(host, workspace); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -186,8 +186,8 @@ func (n *NodeE2ERemote) RunTest(host, workspace, results, junitFilePrefix, testA
|
|||||||
glog.V(2).Infof("Starting tests on %q", host)
|
glog.V(2).Infof("Starting tests on %q", host)
|
||||||
cmd := getSSHCommand(" && ",
|
cmd := getSSHCommand(" && ",
|
||||||
fmt.Sprintf("cd %s", workspace),
|
fmt.Sprintf("cd %s", workspace),
|
||||||
fmt.Sprintf("timeout -k 30s %fs ./ginkgo %s ./e2e_node.test -- --logtostderr --v 4 --node-name=%s --report-dir=%s --report-prefix=%s %s",
|
fmt.Sprintf("timeout -k 30s %fs ./ginkgo %s ./e2e_node.test -- --logtostderr --v 4 --node-name=%s --report-dir=%s --report-prefix=%s --image-description=%s %s",
|
||||||
timeout.Seconds(), ginkgoArgs, host, results, junitFilePrefix, testArgs),
|
timeout.Seconds(), ginkgoArgs, host, results, junitFilePrefix, imageDesc, testArgs),
|
||||||
)
|
)
|
||||||
return SSH(host, "sh", "-c", cmd)
|
return SSH(host, "sh", "-c", cmd)
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ func CreateTestArchive(suite TestSuite) (string, error) {
|
|||||||
|
|
||||||
// Returns the command output, whether the exit was ok, and any errors
|
// Returns the command output, whether the exit was ok, and any errors
|
||||||
// TODO(random-liu): junitFilePrefix is not prefix actually, the file name is junit-junitFilePrefix.xml. Change the variable name.
|
// TODO(random-liu): junitFilePrefix is not prefix actually, the file name is junit-junitFilePrefix.xml. Change the variable name.
|
||||||
func RunRemote(suite TestSuite, archive string, host string, cleanup bool, junitFilePrefix string, testArgs string, ginkgoArgs string) (string, bool, error) {
|
func RunRemote(suite TestSuite, archive string, host string, cleanup bool, imageDesc, junitFilePrefix, testArgs, ginkgoArgs string) (string, bool, error) {
|
||||||
// Create the temp staging directory
|
// Create the temp staging directory
|
||||||
glog.V(2).Infof("Staging test binaries on %q", host)
|
glog.V(2).Infof("Staging test binaries on %q", host)
|
||||||
workspace := fmt.Sprintf("/tmp/node-e2e-%s", getTimestamp())
|
workspace := fmt.Sprintf("/tmp/node-e2e-%s", getTimestamp())
|
||||||
@ -108,7 +108,7 @@ func RunRemote(suite TestSuite, archive string, host string, cleanup bool, junit
|
|||||||
}
|
}
|
||||||
|
|
||||||
glog.V(2).Infof("Running test on %q", host)
|
glog.V(2).Infof("Running test on %q", host)
|
||||||
output, err := suite.RunTest(host, workspace, resultDir, junitFilePrefix, testArgs, ginkgoArgs, *testTimeoutSeconds)
|
output, err := suite.RunTest(host, workspace, resultDir, imageDesc, junitFilePrefix, testArgs, ginkgoArgs, *testTimeoutSeconds)
|
||||||
|
|
||||||
aggErrs := []error{}
|
aggErrs := []error{}
|
||||||
// Do not log the output here, let the caller deal with the test output.
|
// Do not log the output here, let the caller deal with the test output.
|
||||||
|
@ -37,9 +37,11 @@ type TestSuite interface {
|
|||||||
// that the test package is unpacked in the workspace before running the test.
|
// that the test package is unpacked in the workspace before running the test.
|
||||||
// * results is the directory the test should write result into. All logs should be
|
// * results is the directory the test should write result into. All logs should be
|
||||||
// saved as *.log, all junit file should start with junit*.
|
// saved as *.log, all junit file should start with junit*.
|
||||||
|
// * imageDesc is the description of the image the test is running on.
|
||||||
|
// It will be used for logging purpose only.
|
||||||
// * junitFilePrefix is the prefix of output junit file.
|
// * junitFilePrefix is the prefix of output junit file.
|
||||||
// * testArgs is the arguments passed to test.
|
// * testArgs is the arguments passed to test.
|
||||||
// * ginkgoArgs is the arguments passed to ginkgo.
|
// * ginkgoArgs is the arguments passed to ginkgo.
|
||||||
// * timeout is the test timeout.
|
// * timeout is the test timeout.
|
||||||
RunTest(host, workspace, results, junitFilePrefix, testArgs, ginkgoArgs string, timeout time.Duration) (string, error)
|
RunTest(host, workspace, results, imageDesc, junitFilePrefix, testArgs, ginkgoArgs string, timeout time.Duration) (string, error)
|
||||||
}
|
}
|
||||||
|
@ -282,7 +282,7 @@ func main() {
|
|||||||
fmt.Printf("Initializing e2e tests using host %s.\n", host)
|
fmt.Printf("Initializing e2e tests using host %s.\n", host)
|
||||||
running++
|
running++
|
||||||
go func(host string, junitFilePrefix string) {
|
go func(host string, junitFilePrefix string) {
|
||||||
results <- testHost(host, *cleanup, junitFilePrefix, *ginkgoFlags)
|
results <- testHost(host, *cleanup, "", junitFilePrefix, *ginkgoFlags)
|
||||||
}(host, host)
|
}(host, host)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -368,7 +368,7 @@ func getImageMetadata(input string) *compute.Metadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run tests in archive against host
|
// Run tests in archive against host
|
||||||
func testHost(host string, deleteFiles bool, junitFilePrefix string, ginkgoFlagsStr string) *TestResult {
|
func testHost(host string, deleteFiles bool, imageDesc, junitFilePrefix, ginkgoFlagsStr string) *TestResult {
|
||||||
instance, err := computeService.Instances.Get(*project, *zone, host).Do()
|
instance, err := computeService.Instances.Get(*project, *zone, host).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &TestResult{
|
return &TestResult{
|
||||||
@ -398,7 +398,7 @@ func testHost(host string, deleteFiles bool, junitFilePrefix string, ginkgoFlags
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
output, exitOk, err := remote.RunRemote(suite, path, host, deleteFiles, junitFilePrefix, *testArgs, ginkgoFlagsStr)
|
output, exitOk, err := remote.RunRemote(suite, path, host, deleteFiles, imageDesc, junitFilePrefix, *testArgs, ginkgoFlagsStr)
|
||||||
return &TestResult{
|
return &TestResult{
|
||||||
output: output,
|
output: output,
|
||||||
err: err,
|
err: err,
|
||||||
@ -484,7 +484,7 @@ func testImage(imageConfig *internalGCEImage, junitFilePrefix string) *TestResul
|
|||||||
// If we are going to delete the instance, don't bother with cleaning up the files
|
// If we are going to delete the instance, don't bother with cleaning up the files
|
||||||
deleteFiles := !*deleteInstances && *cleanup
|
deleteFiles := !*deleteInstances && *cleanup
|
||||||
|
|
||||||
result := testHost(host, deleteFiles, junitFilePrefix, ginkgoFlagsStr)
|
result := testHost(host, deleteFiles, imageConfig.image, junitFilePrefix, ginkgoFlagsStr)
|
||||||
// This is a temporary solution to collect serial node serial log. Only port 1 contains useful information.
|
// This is a temporary solution to collect serial node serial log. Only port 1 contains useful information.
|
||||||
// TODO(random-liu): Extract out and unify log collection logic with cluste e2e.
|
// TODO(random-liu): Extract out and unify log collection logic with cluste e2e.
|
||||||
serialPortOutput, err := computeService.Instances.GetSerialPortOutput(*project, *zone, host).Port(1).Do()
|
serialPortOutput, err := computeService.Instances.GetSerialPortOutput(*project, *zone, host).Port(1).Do()
|
||||||
|
Loading…
Reference in New Issue
Block a user