Skip to content

Commit

Permalink
internal/civisibility: fix subtest unique naming on retries.
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyredondo committed Oct 8, 2024
1 parent d661852 commit c902705
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,9 @@ func applyAdditionalFeaturesToTestFunc(f func(*testing.T), testInfo *commonInfo)
originalExecMeta := getTestMetadata(t)

for {
// let's clear the matcher subnames map before any execution to avoid subname tests to be called "parent/subname#NN" due the retries
getTestContextMatcherPrivateFields(t).ClearSubNames()

// increment execution index
executionIndex++

Expand Down Expand Up @@ -683,6 +686,9 @@ func applyAdditionalFeaturesToTestFunc(f func(*testing.T), testInfo *commonInfo)
var suite integrations.DdTestSuite

for {
// let's clear the matcher subnames map before any execution to avoid subname tests to be called "parent/subname#NN" due the retries
getTestContextMatcherPrivateFields(t).ClearSubNames()

// increment execution index
executionIndex++

Expand Down
39 changes: 39 additions & 0 deletions internal/civisibility/integrations/gotesting/reflections.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,45 @@ func getTestParentPrivateFields(t *testing.T) *commonPrivateFields {
return nil
}

// contextMatcher is collection of required private fields from testing.context.match
type contextMatcher struct {
mu *sync.RWMutex
subNames *map[string]int32
}

// ClearSubNames clears the subname map used for creating unique names for subtests
func (c *contextMatcher) ClearSubNames() {
c.mu.Lock()
defer c.mu.Unlock()
*c.subNames = map[string]int32{}
}

// getTestContextMatcherPrivateFields is a method to retrieve all required privates field from
// testing.T.context.match, returning a contextMatcher instance
func getTestContextMatcherPrivateFields(t *testing.T) *contextMatcher {
indirectValue := reflect.Indirect(reflect.ValueOf(t))
contextMember := indirectValue.FieldByName("context")
if !contextMember.IsValid() {
return nil
}
contextMember = contextMember.Elem()
matchMember := contextMember.FieldByName("match")
if !matchMember.IsValid() {
return nil
}
matchMember = matchMember.Elem()

fields := &contextMatcher{}
if ptr, err := getFieldPointerFromValue(matchMember, "mu"); err == nil {
fields.mu = (*sync.RWMutex)(ptr)
}
if ptr, err := getFieldPointerFromValue(matchMember, "subNames"); err == nil {
fields.subNames = (*map[string]int32)(ptr)
}

return fields
}

// copyTestWithoutParent tries to copy all private fields except the t.parent from a *testing.T to another
func copyTestWithoutParent(source *testing.T, target *testing.T) {
// Copy important field values
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,15 +188,15 @@ func runEarlyFlakyTestDetectionTests(m *testing.M) {
checkSpansByResourceName(finishedSpans, "testing_test.go", 1)
checkSpansByResourceName(finishedSpans, "testing_test.go.TestMyTest01", 11)
checkSpansByResourceName(finishedSpans, "testing_test.go.TestMyTest02", 11)
// checkSpansByResourceName(finishedSpans, "testing_test.go.TestMyTest02/sub01", 11)
// checkSpansByResourceName(finishedSpans, "testing_test.go.TestMyTest02/sub01/sub03", 11)
checkSpansByResourceName(finishedSpans, "testing_test.go.TestMyTest02/sub01", 11)
checkSpansByResourceName(finishedSpans, "testing_test.go.TestMyTest02/sub01/sub03", 11)
checkSpansByResourceName(finishedSpans, "testing_test.go.Test_Foo", 11)
// checkSpansByResourceName(finishedSpans, "testing_test.go.Test_Foo/yellow_should_return_color", 11)
// checkSpansByResourceName(finishedSpans, "testing_test.go.Test_Foo/banana_should_return_fruit", 11)
// checkSpansByResourceName(finishedSpans, "testing_test.go.Test_Foo/duck_should_return_animal", 11)
checkSpansByResourceName(finishedSpans, "testing_test.go.Test_Foo/yellow_should_return_color", 11)
checkSpansByResourceName(finishedSpans, "testing_test.go.Test_Foo/banana_should_return_fruit", 11)
checkSpansByResourceName(finishedSpans, "testing_test.go.Test_Foo/duck_should_return_animal", 11)
checkSpansByResourceName(finishedSpans, "testing_test.go.TestWithExternalCalls", 11)
// checkSpansByResourceName(finishedSpans, "testing_test.go.TestWithExternalCalls/default", 11)
// checkSpansByResourceName(finishedSpans, "testing_test.go.TestWithExternalCalls/custom-name", 11)
checkSpansByResourceName(finishedSpans, "testing_test.go.TestWithExternalCalls/default", 11)
checkSpansByResourceName(finishedSpans, "testing_test.go.TestWithExternalCalls/custom-name", 11)
checkSpansByResourceName(finishedSpans, "testing_test.go.TestSkip", 11)
checkSpansByResourceName(finishedSpans, "testing_test.go.TestRetryWithPanic", 11)
checkSpansByResourceName(finishedSpans, "testing_test.go.TestRetryWithFail", 11)
Expand Down

0 comments on commit c902705

Please sign in to comment.