mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
Generate conformance test spec with offset
decorator
`FullStackTrace` is not available in v2 if no exception found with test execution. The change is needed for conformance test's spec validation. pls see: https://github.com/onsi/ginkgo/issues/960 for details. Signed-off-by: Dave Chen <dave.chen@arm.com>
This commit is contained in:
parent
dd58016484
commit
20498fd65d
@ -28,7 +28,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
@ -70,8 +69,6 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type frame struct {
|
type frame struct {
|
||||||
Function string
|
|
||||||
|
|
||||||
// File and Line are the file name and line number of the
|
// File and Line are the file name and line number of the
|
||||||
// location in this frame. For non-leaf frames, this will be
|
// location in this frame. For non-leaf frames, this will be
|
||||||
// the location of a call. These may be the empty string and
|
// the location of a call. These may be the empty string and
|
||||||
@ -97,7 +94,7 @@ func main() {
|
|||||||
dec := json.NewDecoder(f)
|
dec := json.NewDecoder(f)
|
||||||
testInfos := []*ConformanceData{}
|
testInfos := []*ConformanceData{}
|
||||||
for {
|
for {
|
||||||
var spec *types.SpecSummary
|
var spec *types.SpecReport
|
||||||
if err := dec.Decode(&spec); err == io.EOF {
|
if err := dec.Decode(&spec); err == io.EOF {
|
||||||
break
|
break
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
@ -119,39 +116,35 @@ func main() {
|
|||||||
saveAllTestInfo(testInfos)
|
saveAllTestInfo(testInfos)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isConformance(spec *types.SpecSummary) bool {
|
func isConformance(spec *types.SpecReport) bool {
|
||||||
return strings.Contains(getTestName(spec), "[Conformance]")
|
return strings.Contains(getTestName(spec), "[Conformance]")
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTestInfo(spec *types.SpecSummary) *ConformanceData {
|
func getTestInfo(spec *types.SpecReport) *ConformanceData {
|
||||||
var c *ConformanceData
|
var c *ConformanceData
|
||||||
var err error
|
var err error
|
||||||
// The key to this working is that we don't need to parse every file or walk
|
// The key to this working is that we don't need to parse every file or walk
|
||||||
// every componentCodeLocation. The last componentCodeLocation is going to typically start
|
// every types.CodeLocation. The LeafNodeLocation is going to be file:line which
|
||||||
// with the ConformanceIt(...) call and the next call in that callstack will be the
|
// attached to the comment that we want.
|
||||||
// ast.Node which is attached to the comment that we want.
|
leafNodeLocation := spec.LeafNodeLocation
|
||||||
for i := len(spec.ComponentCodeLocations) - 1; i > 0; i-- {
|
frame := frame{
|
||||||
fullstacktrace := spec.ComponentCodeLocations[i].FullStackTrace
|
File: leafNodeLocation.FileName,
|
||||||
c, err = getConformanceDataFromStackTrace(fullstacktrace)
|
Line: leafNodeLocation.LineNumber,
|
||||||
if err != nil {
|
}
|
||||||
log.Printf("Error looking for conformance data: %v", err)
|
c, err = getConformanceData(frame)
|
||||||
}
|
if err != nil {
|
||||||
if c != nil {
|
log.Printf("Error looking for conformance data: %v", err)
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if c == nil {
|
if c == nil {
|
||||||
log.Printf("Did not find test info for spec: %#v\n", getTestName(spec))
|
log.Printf("Did not find test info for spec: %#v\n", getTestName(spec))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
c.CodeName = getTestName(spec)
|
c.CodeName = getTestName(spec)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTestName(spec *types.SpecSummary) string {
|
func getTestName(spec *types.SpecReport) string {
|
||||||
return strings.Join(spec.ComponentTexts[1:], " ")
|
return strings.Join(spec.ContainerHierarchyTexts[0:], " ") + " " + spec.LeafNodeText
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveAllTestInfo(dataSet []*ConformanceData) {
|
func saveAllTestInfo(dataSet []*ConformanceData) {
|
||||||
@ -185,56 +178,27 @@ func saveAllTestInfo(dataSet []*ConformanceData) {
|
|||||||
fmt.Println(string(b))
|
fmt.Println(string(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
func getConformanceDataFromStackTrace(fullstackstrace string) (*ConformanceData, error) {
|
func getConformanceData(targetFrame frame) (*ConformanceData, error) {
|
||||||
// The full stacktrace to parse from ginkgo is of the form:
|
|
||||||
// k8s.io/kubernetes/test/e2e/storage/utils.SIGDescribe(0x51f4c4f, 0xf, 0x53a0dd8, 0xc000ab6e01)\n\ttest/e2e/storage/utils/framework.go:23 +0x75\n ... ...
|
|
||||||
// So we need to split it into lines, remove whitespace, and then grab the files/lines.
|
|
||||||
stack := strings.Replace(fullstackstrace, "\t", "", -1)
|
|
||||||
calls := strings.Split(stack, "\n")
|
|
||||||
frames := []frame{}
|
|
||||||
i := 0
|
|
||||||
for i < len(calls) {
|
|
||||||
fileLine := strings.Split(calls[i+1], " ")
|
|
||||||
lineinfo := strings.Split(fileLine[0], ":")
|
|
||||||
line, err := strconv.Atoi(lineinfo[1])
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
frames = append(frames, frame{
|
|
||||||
Function: calls[i],
|
|
||||||
File: lineinfo[0],
|
|
||||||
Line: line,
|
|
||||||
})
|
|
||||||
i += 2
|
|
||||||
}
|
|
||||||
|
|
||||||
// filenames are in one of two special GOPATHs depending on if they were
|
// filenames are in one of two special GOPATHs depending on if they were
|
||||||
// built dockerized or with the host go
|
// built dockerized or with the host go
|
||||||
// we want to trim this prefix to produce portable relative paths
|
// we want to trim this prefix to produce portable relative paths
|
||||||
k8sSRC := *k8sPath + "/_output/local/go/src/k8s.io/kubernetes/"
|
k8sSRC := *k8sPath + "/_output/local/go/src/k8s.io/kubernetes/"
|
||||||
for i := range frames {
|
trimmedFile := strings.TrimPrefix(targetFrame.File, k8sSRC)
|
||||||
trimmedFile := strings.TrimPrefix(frames[i].File, k8sSRC)
|
trimmedFile = strings.TrimPrefix(trimmedFile, "/go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/")
|
||||||
trimmedFile = strings.TrimPrefix(trimmedFile, "/go/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/")
|
targetFrame.File = trimmedFile
|
||||||
frames[i].File = trimmedFile
|
|
||||||
|
freader, err := os.Open(targetFrame.File)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer freader.Close()
|
||||||
|
|
||||||
for _, curFrame := range frames {
|
cd, err := scanFileForFrame(targetFrame.File, freader, targetFrame)
|
||||||
if _, seen := seenLines[fmt.Sprintf("%v:%v", curFrame.File, curFrame.Line)]; seen {
|
if err != nil {
|
||||||
continue
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if cd != nil {
|
||||||
freader, err := os.Open(curFrame.File)
|
return cd, nil
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer freader.Close()
|
|
||||||
cd, err := scanFileForFrame(curFrame.File, freader, curFrame)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if cd != nil {
|
|
||||||
return cd, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -644,7 +644,7 @@ func (kc *KubeConfig) FindCluster(name string) *KubeCluster {
|
|||||||
|
|
||||||
// ConformanceIt is wrapper function for ginkgo It. Adds "[Conformance]" tag and makes static analysis easier.
|
// ConformanceIt is wrapper function for ginkgo It. Adds "[Conformance]" tag and makes static analysis easier.
|
||||||
func ConformanceIt(text string, body interface{}) bool {
|
func ConformanceIt(text string, body interface{}) bool {
|
||||||
return ginkgo.It(text+" [Conformance]", body)
|
return ginkgo.It(text+" [Conformance]", ginkgo.Offset(1), body)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PodStateVerification represents a verification of pod state.
|
// PodStateVerification represents a verification of pod state.
|
||||||
|
Loading…
Reference in New Issue
Block a user