1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2024 Datadog, Inc.
package integrations
import (
"context"
"fmt"
"strings"
"time"
"ci-visibility-test-github/main/civisibility/constants"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
)
// Test Module
// Ensures that tslvTestModule implements the DdTestModule interface.
var _ DdTestModule = (*tslvTestModule)(nil)
// tslvTestModule implements the DdTestModule interface and represents a module within a test session.
type tslvTestModule struct {
ciVisibilityCommon
session *tslvTestSession
moduleID uint64
name string
framework string
suites map[string]DdTestSuite
}
// createTestModule initializes a new test module within a given session.
func createTestModule(session *tslvTestSession, name string, framework string, frameworkVersion string, startTime time.Time) DdTestModule {
// Ensure CI visibility is properly configured.
EnsureCiVisibilityInitialization()
operationName := "test_module"
if framework != "" {
operationName = fmt.Sprintf("%s.%s", strings.ToLower(framework), operationName)
}
resourceName := name
var sessionTags []tracer.StartSpanOption
if session != nil {
sessionTags = session.tags
}
// Module tags should include session tags so the backend can calculate the session fingerprint from the module.
moduleTags := append(sessionTags, []tracer.StartSpanOption{
tracer.Tag(constants.TestType, constants.TestTypeTest),
tracer.Tag(constants.TestModule, name),
tracer.Tag(constants.TestFramework, framework),
tracer.Tag(constants.TestFrameworkVersion, frameworkVersion),
}...)
testOpts := append(fillCommonTags([]tracer.StartSpanOption{
tracer.ResourceName(resourceName),
tracer.SpanType(constants.SpanTypeTestModule),
tracer.StartTime(startTime),
}), moduleTags...)
span, ctx := tracer.StartSpanFromContext(context.Background(), operationName, testOpts...)
moduleID := span.Context().SpanID()
if session != nil {
span.SetTag(constants.TestSessionIDTag, fmt.Sprint(session.sessionID))
}
span.SetTag(constants.TestModuleIDTag, fmt.Sprint(moduleID))
module := &tslvTestModule{
session: session,
moduleID: moduleID,
name: name,
framework: framework,
suites: map[string]DdTestSuite{},
ciVisibilityCommon: ciVisibilityCommon{
startTime: startTime,
tags: moduleTags,
span: span,
ctx: ctx,
},
}
// Ensure to close everything before CI visibility exits. In CI visibility mode, we try to never lose data.
PushCiVisibilityCloseAction(func() { module.Close() })
return module
}
// Name returns the name of the test module.
func (t *tslvTestModule) Name() string { return t.name }
// Framework returns the testing framework used by the test module.
func (t *tslvTestModule) Framework() string { return t.framework }
// Session returns the test session to which the test module belongs.
func (t *tslvTestModule) Session() DdTestSession { return t.session }
// Close closes the test module and sets the finish time to the current time.
func (t *tslvTestModule) Close() { t.CloseWithFinishTime(time.Now()) }
// CloseWithFinishTime closes the test module with the given finish time.
func (t *tslvTestModule) CloseWithFinishTime(finishTime time.Time) {
t.mutex.Lock()
defer t.mutex.Unlock()
if t.closed {
return
}
for _, suite := range t.suites {
suite.Close()
}
t.suites = map[string]DdTestSuite{}
t.span.Finish(tracer.FinishTime(finishTime))
t.closed = true
}
// GetOrCreateSuite returns an existing suite or creates a new one with the given name.
func (t *tslvTestModule) GetOrCreateSuite(name string) DdTestSuite {
return t.GetOrCreateSuiteWithStartTime(name, time.Now())
}
// GetOrCreateSuiteWithStartTime returns an existing suite or creates a new one with the given name and start time.
func (t *tslvTestModule) GetOrCreateSuiteWithStartTime(name string, startTime time.Time) DdTestSuite {
t.mutex.Lock()
defer t.mutex.Unlock()
var suite DdTestSuite
if v, ok := t.suites[name]; ok {
suite = v
} else {
suite = createTestSuite(t, name, startTime)
t.suites[name] = suite
}
return suite
}
|