From 2b1a9025469fc5a9915d22bae0c3c886f946737f Mon Sep 17 00:00:00 2001 From: jmontesi Date: Fri, 27 Oct 2023 12:12:05 +0200 Subject: [PATCH] performance: avoid failing test case if a process cannot be found It applies to rt-apps-no-exec-probes. The reason a process cannot be found after it has been properly retrieved previously could be that the process has finished. So, in this case it seems more adequate to just ignore it than to produce an error. If the error is of another kind the container is added to the non compliant list but the processing for that container continues instead of breaking, to have more info on the processes. The commit also changes the verification order in that test case, making the faster check of exec probes at the beginning, skipping the slower part in which the processes are list. Finally, the compliant containers are added to its list with the reason for compliance. --- cnf-certification-test/performance/suite.go | 25 +++++++++++++++++++-- pkg/scheduling/scheduling.go | 3 ++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/cnf-certification-test/performance/suite.go b/cnf-certification-test/performance/suite.go index bef86ab94..792307a84 100644 --- a/cnf-certification-test/performance/suite.go +++ b/cnf-certification-test/performance/suite.go @@ -19,6 +19,7 @@ package performance import ( "fmt" "strconv" + "strings" "github.com/onsi/ginkgo/v2" "github.com/sirupsen/logrus" @@ -232,30 +233,50 @@ func testSchedulingPolicyInCPUPool(env *provider.TestEnvironment, testhelper.AddTestResultReason(compliantContainersPids, nonCompliantContainersPids, tnf.ClaimFilePrintf, ginkgo.Fail) } +const noProcessFoundErrMsg = "No such process" + func testRtAppsNoExecProbes(env *provider.TestEnvironment, cuts []*provider.Container) { var compliantObjects []*testhelper.ReportObject var nonCompliantObjects []*testhelper.ReportObject for _, cut := range cuts { + if !cut.HasExecProbes() { + compliantObjects = append(compliantObjects, testhelper.NewContainerReportObject(cut.Namespace, cut.Podname, cut.Name, "Container does not define exec probes", true)) + continue + } + processes, err := crclient.GetContainerProcesses(cut, env) if err != nil { tnf.ClaimFilePrintf("Could not determine the processes pids for container %s, err: %v", cut, err) nonCompliantObjects = append(nonCompliantObjects, testhelper.NewContainerReportObject(cut.Namespace, cut.Podname, cut.Name, "Could not determine the processes pids for container", false)) break } + + allProcessesCompliant := true for _, p := range processes { schedPolicy, _, err := scheduling.GetProcessCPUScheduling(p.Pid, cut) if err != nil { + // If the process does not exist anymore it means that it has finished since the time the process list + // was retrieved. In this case, just ignore the error and continue processing the rest of the processes. + if strings.Contains(err.Error(), noProcessFoundErrMsg) { + continue + } tnf.ClaimFilePrintf("Could not determine the scheduling policy for container %s (pid=%v), err: %v", cut, p.Pid, err) nonCompliantObjects = append(nonCompliantObjects, testhelper.NewContainerReportObject(cut.Namespace, cut.Podname, cut.Name, "Could not determine the scheduling policy for container", false). AddField(testhelper.ProcessID, strconv.Itoa(p.Pid))) - break + allProcessesCompliant = false + continue } - if scheduling.PolicyIsRT(schedPolicy) && cut.HasExecProbes() { + if scheduling.PolicyIsRT(schedPolicy) { tnf.ClaimFilePrintf("Pod %s/Container %s defines exec probes while having a RT scheduling policy for pid %d", cut.Podname, cut, p.Pid) nonCompliantObjects = append(nonCompliantObjects, testhelper.NewContainerReportObject(cut.Namespace, cut.Podname, cut.Name, "Container defines exec probes while having a RT scheduling policy", false). AddField(testhelper.ProcessID, strconv.Itoa(p.Pid))) + allProcessesCompliant = false } } + + if allProcessesCompliant { + compliantObjects = append(compliantObjects, testhelper.NewContainerReportObject(cut.Namespace, cut.Podname, cut.Name, "Container defines exec probes but does not have a RT scheduling policy", true)) + } } testhelper.AddTestResultReason(compliantObjects, nonCompliantObjects, tnf.ClaimFilePrintf, ginkgo.Fail) } diff --git a/pkg/scheduling/scheduling.go b/pkg/scheduling/scheduling.go index bf7ae338b..1e09eab8d 100644 --- a/pkg/scheduling/scheduling.go +++ b/pkg/scheduling/scheduling.go @@ -132,7 +132,8 @@ func GetProcessCPUScheduling(pid int, testContainer *provider.Container) (schedu stdout, stderr, err := ch.ExecCommandContainer(ctx, command) if err != nil || stderr != "" { - return schedulePolicy, InvalidPriority, fmt.Errorf("command %q failed to run in debug pod %s (node %s): %v", command, ctx.GetPodName(), testContainer.NodeName, err) + return schedulePolicy, InvalidPriority, fmt.Errorf("command %q failed to run in debug pod %s (node %s): %v (stderr: %v)", + command, ctx.GetPodName(), testContainer.NodeName, err, stderr) } schedulePolicy, schedulePriority, err = parseSchedulingPolicyAndPriority(stdout)