mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-13 22:05:59 +00:00
e2e framework: list specs and labels
-list-tests is a more concise alternative for `ginkgo --dry-run` with one line per test. In contrast to `--dry-run`, it really lists all tests. `--dry-run` without additional parameters uses the default skip expression from the E2E context, which filters out flaky and feature-gated tests. The output includes the source code location where each test is defined. It is sorted by test name (not source code location) because that order is independent of reorganizing the source code and ordering by location can be achieved with "sort". -list-labels has no corresponding feature in Ginkgo. One possible usage is to figure out what values might make sense for -focus/skip/label-filter. Unit tests will follow in a future commit.
This commit is contained in:
parent
aa4d2fc5ed
commit
3afdcc03ea
@ -23,9 +23,11 @@ import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
@ -36,6 +38,7 @@ import (
|
||||
"github.com/onsi/gomega"
|
||||
gomegaformat "github.com/onsi/gomega/format"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
cliflag "k8s.io/component-base/cli/flag"
|
||||
@ -53,6 +56,12 @@ const (
|
||||
DefaultNumNodes = -1
|
||||
)
|
||||
|
||||
var (
|
||||
// Output is used for output when not running tests, for example in -list-tests.
|
||||
// Test output should go to ginkgo.GinkgoWriter.
|
||||
Output io.Writer = os.Stdout
|
||||
)
|
||||
|
||||
// TestContextType contains test settings and global state. Due to
|
||||
// historic reasons, it is a mixture of items managed by the test
|
||||
// framework itself, cloud providers and individual tests.
|
||||
@ -94,6 +103,8 @@ type TestContextType struct {
|
||||
// ListImages will list off all images that are used then quit
|
||||
ListImages bool
|
||||
|
||||
listTests, listLabels bool
|
||||
|
||||
// ListConformanceTests will list off all conformance tests that are available then quit
|
||||
ListConformanceTests bool
|
||||
|
||||
@ -356,6 +367,8 @@ func RegisterCommonFlags(flags *flag.FlagSet) {
|
||||
flags.StringVar(&TestContext.NonblockingTaints, "non-blocking-taints", `node-role.kubernetes.io/control-plane`, "Nodes with taints in this comma-delimited list will not block the test framework from starting tests.")
|
||||
|
||||
flags.BoolVar(&TestContext.ListImages, "list-images", false, "If true, will show list of images used for running tests.")
|
||||
flags.BoolVar(&TestContext.listLabels, "list-labels", false, "If true, will show the list of labels that can be used to select tests via -ginkgo.label-filter.")
|
||||
flags.BoolVar(&TestContext.listTests, "list-tests", false, "If true, will show the full names of all tests (aka specs) that can be used to select test via -ginkgo.focus/skip.")
|
||||
flags.StringVar(&TestContext.KubectlPath, "kubectl-path", "kubectl", "The kubectl binary to use. For development, you might use 'cluster/kubectl.sh' here.")
|
||||
|
||||
flags.StringVar(&TestContext.ProgressReportURL, "progress-report-url", "", "The URL to POST progress updates to as the suite runs to assist in aiding integrations. If empty, no messages sent.")
|
||||
@ -494,6 +507,11 @@ func AfterReadingAllFlags(t *TestContextType) {
|
||||
gomega.SetDefaultEventuallyTimeout(t.timeouts.PodStart)
|
||||
gomega.SetDefaultConsistentlyDuration(t.timeouts.PodStartShort)
|
||||
|
||||
if t.listLabels || t.listTests {
|
||||
listTestInformation(ginkgo.PreviewSpecs("Kubernetes e2e test statistics"))
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// Only set a default host if one won't be supplied via kubeconfig
|
||||
if len(t.Host) == 0 && len(t.KubeConfig) == 0 {
|
||||
// Check if we can use the in-cluster config
|
||||
@ -600,3 +618,47 @@ func AfterReadingAllFlags(t *TestContextType) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func listTestInformation(report ginkgo.Report) {
|
||||
indent := strings.Repeat(" ", 4)
|
||||
|
||||
if TestContext.listLabels {
|
||||
labels := sets.New[string]()
|
||||
for _, spec := range report.SpecReports {
|
||||
if spec.LeafNodeType == types.NodeTypeIt {
|
||||
labels.Insert(spec.Labels()...)
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(Output, "The following labels can be used with 'gingko run --label-filter':\n%s%s\n\n", indent, strings.Join(sets.List(labels), "\n"+indent))
|
||||
}
|
||||
if TestContext.listTests {
|
||||
leafs := make([][]string, 0, len(report.SpecReports))
|
||||
wd, _ := os.Getwd()
|
||||
for _, spec := range report.SpecReports {
|
||||
if spec.LeafNodeType == types.NodeTypeIt {
|
||||
leafs = append(leafs, []string{fmt.Sprintf("%s:%d: ", relativePath(wd, spec.LeafNodeLocation.FileName), spec.LeafNodeLocation.LineNumber), spec.FullText()})
|
||||
}
|
||||
}
|
||||
// Sort by test name, not the source code location, because the test
|
||||
// name is more stable across code refactoring.
|
||||
sort.Slice(leafs, func(i, j int) bool {
|
||||
return leafs[i][1] < leafs[j][1]
|
||||
})
|
||||
fmt.Fprint(Output, "The following spec names can be used with 'ginkgo run --focus/skip':\n")
|
||||
for _, leaf := range leafs {
|
||||
fmt.Fprintf(Output, "%s%s%s\n", indent, leaf[0], leaf[1])
|
||||
}
|
||||
fmt.Fprint(Output, "\n")
|
||||
}
|
||||
}
|
||||
|
||||
func relativePath(wd, path string) string {
|
||||
if wd == "" {
|
||||
return path
|
||||
}
|
||||
relpath, err := filepath.Rel(wd, path)
|
||||
if err != nil {
|
||||
return path
|
||||
}
|
||||
return relpath
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user