Skip to content

Commit

Permalink
internal/civisibility: ensure tag propagation to subtests and add mor…
Browse files Browse the repository at this point in the history
…e checks to the test suite.
  • Loading branch information
tonyredondo committed Oct 9, 2024
1 parent c902705 commit 59f69df
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 3 deletions.
20 changes: 19 additions & 1 deletion internal/civisibility/integrations/gotesting/instrumentation.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,13 @@ func createTestMetadata(tb testing.TB) *testExecutionMetadata {

// getTestMetadata retrieves the CI visibility test metadata associated with a given *testing.T, *testing.B, *testing.common
func getTestMetadata(tb testing.TB) *testExecutionMetadata {
return getTestMetadataFromPointer(reflect.ValueOf(tb).UnsafePointer())
}

// getTestMetadataFromPointer retrieves the CI visibility test metadata associated with a given *testing.T, *testing.B, *testing.common using a pointer
func getTestMetadataFromPointer(ptr unsafe.Pointer) *testExecutionMetadata {
ciVisibilityTestMetadataMutex.RLock()
defer ciVisibilityTestMetadataMutex.RUnlock()
ptr := reflect.ValueOf(tb).UnsafePointer()
if v, ok := ciVisibilityTestMetadata[ptr]; ok {
return v
}
Expand Down Expand Up @@ -223,6 +227,20 @@ func instrumentTestingTFunc(f func(*testing.T)) func(*testing.T) {
defer deleteTestMetadata(t)
}

// Because this is a subtest let's propagate some execution metadata from the parent test
testPrivateFields := getTestPrivateFields(t)
if testPrivateFields.parent != nil {
parentExecMeta := getTestMetadataFromPointer(*testPrivateFields.parent)
if parentExecMeta != nil {
if parentExecMeta.isANewTest {
execMeta.isANewTest = true
}
if parentExecMeta.isARetry {
execMeta.isARetry = true
}
}
}

// Set the CI visibility test.
execMeta.test = test

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ func runFlakyTestRetriesTests(m *testing.M) {
// 1 TestNormalPassingAfterRetryAlwaysFail
// 1 TestEarlyFlakeDetection
// 2 normal spans from testing_test.go

// check spans by resource name
checkSpansByResourceName(finishedSpans, "gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/integrations/gotesting", 1)
checkSpansByResourceName(finishedSpans, "reflections_test.go", 1)
checkSpansByResourceName(finishedSpans, "testing_test.go", 1)
Expand All @@ -126,6 +128,10 @@ func runFlakyTestRetriesTests(m *testing.M) {
checkSpansByResourceName(finishedSpans, "testing_test.go.TestNormalPassingAfterRetryAlwaysFail", 1)
checkSpansByResourceName(finishedSpans, "testing_test.go.TestEarlyFlakeDetection", 1)

// check spans by tag
checkSpansByTagName(finishedSpans, constants.TestIsRetry, 16)

// check spans by type
checkSpansByType(finishedSpans,
44,
1,
Expand Down Expand Up @@ -183,6 +189,8 @@ func runEarlyFlakyTestDetectionTests(m *testing.M) {
// 11 TestNormalPassingAfterRetryAlwaysFail
// 11 TestEarlyFlakeDetection
// 22 normal spans from testing_test.go

// check spans by resource name
checkSpansByResourceName(finishedSpans, "gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/integrations/gotesting", 1)
checkSpansByResourceName(finishedSpans, "reflections_test.go", 1)
checkSpansByResourceName(finishedSpans, "testing_test.go", 1)
Expand All @@ -204,6 +212,11 @@ func runEarlyFlakyTestDetectionTests(m *testing.M) {
checkSpansByResourceName(finishedSpans, "testing_test.go.TestNormalPassingAfterRetryAlwaysFail", 11)
checkSpansByResourceName(finishedSpans, "testing_test.go.TestEarlyFlakeDetection", 11)

// check spans by tag
checkSpansByTagName(finishedSpans, constants.TestIsNew, 187)
checkSpansByTagName(finishedSpans, constants.TestIsRetry, 170)

// check spans by type
checkSpansByType(finishedSpans,
218,
1,
Expand Down Expand Up @@ -275,6 +288,8 @@ func runFlakyTestRetriesWithEarlyFlakyTestDetectionTests(m *testing.M) {
// 1 TestNormalPassingAfterRetryAlwaysFail
// 11 TestEarlyFlakeDetection + 10 retries
// 2 normal spans from testing_test.go

// check spans by resource name
checkSpansByResourceName(finishedSpans, "gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/integrations/gotesting", 1)
checkSpansByResourceName(finishedSpans, "reflections_test.go", 1)
checkSpansByResourceName(finishedSpans, "testing_test.go", 1)
Expand All @@ -296,6 +311,11 @@ func runFlakyTestRetriesWithEarlyFlakyTestDetectionTests(m *testing.M) {
checkSpansByResourceName(finishedSpans, "testing_test.go.TestNormalPassingAfterRetryAlwaysFail", 1)
checkSpansByResourceName(finishedSpans, "testing_test.go.TestEarlyFlakeDetection", 21)

// check spans by tag
checkSpansByTagName(finishedSpans, constants.TestIsNew, 21)
checkSpansByTagName(finishedSpans, constants.TestIsRetry, 36)

// check spans by type
checkSpansByType(finishedSpans,
64,
1,
Expand Down Expand Up @@ -357,11 +377,24 @@ func checkSpansByType(finishedSpans []mocktracer.Span,
}
}

func checkSpansByResourceName(finishedSpans []mocktracer.Span, resourceName string, count int) {
numOfSpans := len(getSpansWithResourceName(finishedSpans, resourceName))
func checkSpansByResourceName(finishedSpans []mocktracer.Span, resourceName string, count int) []mocktracer.Span {
spans := getSpansWithResourceName(finishedSpans, resourceName)
numOfSpans := len(spans)
if numOfSpans != count {
panic(fmt.Sprintf("expected exactly %d spans with resource name: %s, got %d", count, resourceName, numOfSpans))
}

return spans
}

func checkSpansByTagName(finishedSpans []mocktracer.Span, tagName string, count int) []mocktracer.Span {
spans := getSpansWithTagName(finishedSpans, tagName)
numOfSpans := len(spans)
if numOfSpans != count {
panic(fmt.Sprintf("expected exactly %d spans with tag name: %s, got %d", count, tagName, numOfSpans))
}

return spans
}

func setUpHttpServer(flakyRetriesEnabled bool, earlyFlakyDetectionEnabled bool, earlyFlakyDetectionData *net.EfdResponseData) *httptest.Server {
Expand Down Expand Up @@ -444,6 +477,17 @@ func getSpansWithResourceName(spans []mocktracer.Span, resourceName string) []mo
return result
}

func getSpansWithTagName(spans []mocktracer.Span, tag string) []mocktracer.Span {
var result []mocktracer.Span
for _, span := range spans {
if span.Tag(tag) != nil {
result = append(result, span)
}
}

return result
}

func showResourcesNameFromSpans(spans []mocktracer.Span) {
for i, span := range spans {
fmt.Printf(" [%d] = %v\n", i, span.Tag(ext.ResourceName))
Expand Down

0 comments on commit 59f69df

Please sign in to comment.