Skip to content

Commit a309f35

Browse files
committed
new fields modified unit tests
1 parent 27efa26 commit a309f35

File tree

4 files changed

+161
-66
lines changed

4 files changed

+161
-66
lines changed

pkg/cmd/roachtest/datadog/datadog.go

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,17 @@ const (
6666
logFileTagName = "log_file"
6767

6868
// Datadog Log Entry User Defined Attribute Names
69-
timestampAttributeName = "timestamp"
70-
clusterAttributeName = "cluster"
71-
buildNumberAttributeName = "build_number"
72-
resultAttributeName = "result"
69+
timestampAttributeName = "timestamp"
70+
clusterAttributeName = "cluster"
71+
buildNumberAttributeName = "build_number"
72+
buildConfigurationAttributeName = "build_configuration"
73+
resultAttributeName = "result"
74+
durationAttributeName = "duration"
7375

7476
// Datadog Log Entry Static Values for roachtest test.log
7577
defaultEnv = "ci"
7678
defaultDDSource = "teamcity"
7779
defaultService = "roachtest"
78-
logName = "test.log"
7980
)
8081

8182
// LogMetadata contains the test metadata that will be associated with each log
@@ -86,6 +87,7 @@ const (
8687
type LogMetadata struct {
8788
TestName string
8889
Result string // PASS or FAIL
90+
Duration string // Duration of the test in seconds
8991
Owner string
9092
Cloud string
9193
Platform string // e.g., linux-amd64, linux-arm64
@@ -94,6 +96,7 @@ type LogMetadata struct {
9496
TCHost string // Teamcity Agent Name e.g., gce-agent-nightlies-roachtest-20240520-no-preempt-43
9597
TCBuildConfName string // TeamCity Build Configuration name e.g. Roachtest Nightly - GCE (Bazel)
9698
TCBuildNumber string // TeamCity Build Configuration execution instance
99+
LogName string // e.g. test.log
97100
Tags map[string]string
98101
}
99102

@@ -124,17 +127,17 @@ func formatTags(tags map[string]string) string {
124127
return result
125128
}
126129

127-
// makeTags constructs a string representation of tags to be added to Datadog
128-
// log entries. Empty tag values do not cause errors
130+
// makeTags makes a map of tag names and values to be added to Datadog log
131+
// entries. Empty tag values do not cause errors.
129132
func (m LogMetadata) makeTags() map[string]string {
130133
tagMap := map[string]string{
131134
envTagName: defaultEnv,
132-
versionTagName: m.Version,
133-
platformTagName: m.Platform,
134-
cloudTagName: m.Cloud,
135135
testNameTagName: m.TestName,
136136
ownerTagName: m.Owner,
137-
logFileTagName: logName,
137+
cloudTagName: m.Cloud,
138+
platformTagName: m.Platform,
139+
versionTagName: m.Version,
140+
logFileTagName: m.LogName,
138141
}
139142
return tagMap
140143
}
@@ -144,20 +147,24 @@ func NewLogMetadata(
144147
l *logger.Logger,
145148
spec *registry.TestSpec,
146149
result bool,
150+
duration string,
147151
cloud spec.Cloud,
148152
osName string,
149153
arch vm.CPUArch,
150154
clusterName string,
155+
logName string,
151156
) LogMetadata {
152157

153158
m := LogMetadata{
154159
TestName: spec.Name,
155160
Result: makeResult(result),
161+
Duration: duration,
156162
Owner: string(spec.Owner),
157163
Cloud: cloud.String(),
158164
Platform: makePlatform(osName, arch),
159165
Cluster: clusterName,
160166
Version: os.Getenv(envTCBuildBranch),
167+
LogName: logName,
161168
}
162169

163170
// Teamcity System Properties are available in the build properties file
@@ -420,10 +427,12 @@ func parseLogLine(line string, logMeta LogMetadata) (*datadogV2.HTTPLogItem, err
420427
entry.SetDdtags(formatTags(logMeta.Tags))
421428
entry.SetHostname(logMeta.TCHost)
422429
entry.AdditionalProperties = map[string]string{
423-
timestampAttributeName: timestamp,
424-
clusterAttributeName: logMeta.Cluster,
425-
buildNumberAttributeName: logMeta.TCBuildNumber,
426-
resultAttributeName: logMeta.Result,
430+
timestampAttributeName: timestamp,
431+
clusterAttributeName: logMeta.Cluster,
432+
buildNumberAttributeName: logMeta.TCBuildNumber,
433+
buildConfigurationAttributeName: logMeta.TCBuildConfName,
434+
resultAttributeName: logMeta.Result,
435+
durationAttributeName: logMeta.Duration,
427436
}
428437
// Duplicate tags into attributes for an improved UI experience
429438
for k, v := range logMeta.Tags {

pkg/cmd/roachtest/datadog/datadog_test.go

Lines changed: 129 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"context"
1111
"os"
1212
"path/filepath"
13+
"strings"
1314
"testing"
1415

1516
"github.com/DataDog/datadog-api-client-go/v2/api/datadog"
@@ -20,6 +21,22 @@ import (
2021
"github.com/stretchr/testify/require"
2122
)
2223

24+
// To be used throughout unit tests
25+
var unittestLogMetadata = LogMetadata{
26+
TestName: "acceptance/event-log",
27+
Result: "PASS",
28+
Duration: "6.67s",
29+
Owner: "test-eng",
30+
Cloud: "gce",
31+
Platform: "linux-amd64",
32+
Version: "master",
33+
Cluster: "test-cluster",
34+
TCHost: "test-host",
35+
TCBuildConfName: "Roachtest Nightly - GCE (Bazel)",
36+
TCBuildNumber: "12345",
37+
LogName: "test.log",
38+
}
39+
2340
func TestParseTimestamp(t *testing.T) {
2441
tests := []struct {
2542
name string
@@ -72,7 +89,7 @@ func TestParseTimestamp(t *testing.T) {
7289
}
7390
}
7491

75-
func TestBuildPlatformField(t *testing.T) {
92+
func TestMakePlatform(t *testing.T) {
7693
tests := []struct {
7794
name string
7895
os string
@@ -107,24 +124,23 @@ func TestBuildPlatformField(t *testing.T) {
107124
}
108125
}
109126

127+
func TestMakeResult(t *testing.T) {
128+
require.Equal(t, testResultPass, makeResult(true))
129+
require.Equal(t, testResultFail, makeResult(false))
130+
}
131+
110132
func TestParseLogFile(t *testing.T) {
133+
originalLogMetadata := unittestLogMetadata
134+
defer func() {
135+
unittestLogMetadata = originalLogMetadata
136+
unittestLogMetadata.Tags = map[string]string{} // reset tags explicitly because the above is a shallow copy
137+
}()
111138
// Dummy logger for parseLogFile
112139
l, err := logger.RootLogger(os.DevNull, logger.NoTee)
113140
require.NoError(t, err)
114141
defer l.Close()
115142

116-
logMetadata := LogMetadata{
117-
TestName: "acceptance/event-log",
118-
Result: "PASS",
119-
Owner: "test-eng",
120-
Cloud: "gce",
121-
Platform: "linux-amd64",
122-
TCHost: "test-host",
123-
Version: "master",
124-
TCBuildNumber: "12345",
125-
Cluster: "test-cluster",
126-
}
127-
logMetadata.Tags = logMetadata.makeTags()
143+
unittestLogMetadata.Tags = unittestLogMetadata.makeTags()
128144

129145
testLogPath := filepath.Join("testdata", "test_log_example")
130146
file, err := os.Open(testLogPath)
@@ -136,7 +152,7 @@ func TestParseLogFile(t *testing.T) {
136152
skippedEntries := make([]string, 0)
137153
for scanner.Scan() {
138154
line := scanner.Text()
139-
entry, err := parseLogLine(line, logMetadata)
155+
entry, err := parseLogLine(line, unittestLogMetadata)
140156
if err != nil {
141157
skippedEntries = append(skippedEntries, line)
142158
} else {
@@ -155,16 +171,16 @@ func TestParseLogFile(t *testing.T) {
155171
// Check that entry fields are set correctly
156172
require.Equal(t, defaultDDSource, *validEntries[0].Ddsource)
157173
require.Equal(t, defaultService, *validEntries[0].Service)
158-
require.Equal(t, logMetadata.TCHost, *validEntries[0].Hostname)
174+
require.Equal(t, unittestLogMetadata.TCHost, *validEntries[0].Hostname)
159175

160176
// Verify ddtags contains all expected tags
161177
ddTags := validEntries[0].Ddtags
162178
require.Contains(t, *ddTags, "env:"+defaultEnv)
163-
require.Contains(t, *ddTags, "version:"+logMetadata.Version)
164-
require.Contains(t, *ddTags, "platform:"+logMetadata.Platform)
165-
require.Contains(t, *ddTags, "cloud:"+logMetadata.Cloud)
166-
require.Contains(t, *ddTags, "name:"+logMetadata.TestName)
167-
require.Contains(t, *ddTags, "owner:"+logMetadata.Owner)
179+
require.Contains(t, *ddTags, "version:"+unittestLogMetadata.Version)
180+
require.Contains(t, *ddTags, "platform:"+unittestLogMetadata.Platform)
181+
require.Contains(t, *ddTags, "cloud:"+unittestLogMetadata.Cloud)
182+
require.Contains(t, *ddTags, "name:"+unittestLogMetadata.TestName)
183+
require.Contains(t, *ddTags, "owner:"+unittestLogMetadata.Owner)
168184

169185
// Verify timestamp is set in AdditionalProperties
170186
require.NotNil(t, validEntries[0].AdditionalProperties)
@@ -173,16 +189,82 @@ func TestParseLogFile(t *testing.T) {
173189
require.Equal(t, "2025-11-12T07:19:40Z", timestamp)
174190
}
175191

192+
func TestMakeTags(t *testing.T) {
193+
tags := unittestLogMetadata.makeTags()
194+
require.Equal(t, defaultEnv, tags[envTagName])
195+
require.Equal(t, unittestLogMetadata.TestName, tags[testNameTagName])
196+
require.Equal(t, unittestLogMetadata.Owner, tags[ownerTagName])
197+
require.Equal(t, unittestLogMetadata.Cloud, tags[cloudTagName])
198+
require.Equal(t, unittestLogMetadata.Platform, tags[platformTagName])
199+
require.Equal(t, unittestLogMetadata.Version, tags[versionTagName])
200+
require.Equal(t, unittestLogMetadata.LogName, tags[logFileTagName])
201+
}
202+
203+
func TestFormatTags(t *testing.T) {
204+
tests := []struct {
205+
name string
206+
tags map[string]string
207+
checkContains []string
208+
}{
209+
{
210+
name: "empty map",
211+
tags: map[string]string{},
212+
checkContains: []string{},
213+
},
214+
{
215+
name: "single tag",
216+
tags: map[string]string{"env": "test"},
217+
checkContains: []string{"env:test"},
218+
},
219+
{
220+
name: "multiple tags",
221+
tags: map[string]string{
222+
"env": "ci",
223+
"version": "master",
224+
"cloud": "gce",
225+
},
226+
checkContains: []string{"env:ci", "version:master", "cloud:gce"},
227+
},
228+
{
229+
name: "tag with empty value",
230+
tags: map[string]string{
231+
"env": "test",
232+
"empty": "",
233+
},
234+
checkContains: []string{"env:test", "empty:"},
235+
},
236+
}
237+
238+
for _, tt := range tests {
239+
t.Run(tt.name, func(t *testing.T) {
240+
result := formatTags(tt.tags)
241+
if len(tt.tags) == 0 {
242+
require.Equal(t, "", result) // edge case
243+
} else {
244+
// Check that all expected tags are present
245+
for _, part := range tt.checkContains {
246+
require.Contains(t, result, part)
247+
}
248+
// Verify tag string format
249+
expectedCommas := len(tt.tags) - 1
250+
actualCommas := strings.Count(result, ",")
251+
require.Equal(t, expectedCommas, actualCommas, "should have correct number of commas")
252+
require.Len(t, strings.Split(result, ","), len(tt.tags))
253+
}
254+
})
255+
}
256+
}
257+
176258
func TestNewDatadogContextMissingCredentials(t *testing.T) {
177259
// Save and restore env vars
178-
originalAPIKey := os.Getenv("DD_API_KEY")
179-
originalDatadogSite := os.Getenv("DD_SITE")
260+
originalAPIKey := os.Getenv(envDatadogAPIKey)
261+
originalDatadogSite := os.Getenv(envDatadogSite)
180262
defer func() {
181-
_ = os.Setenv("DD_API_KEY", originalAPIKey)
182-
_ = os.Setenv("DD_SITE", originalDatadogSite)
263+
_ = os.Setenv(envDatadogAPIKey, originalAPIKey)
264+
_ = os.Setenv(envDatadogSite, originalDatadogSite)
183265
}()
184-
_ = os.Unsetenv("DD_API_KEY")
185-
_ = os.Unsetenv("DD_SITE")
266+
_ = os.Unsetenv(envDatadogAPIKey)
267+
_ = os.Unsetenv(envDatadogSite)
186268

187269
ctx := context.Background()
188270
_, err := newDatadogContext(ctx)
@@ -191,14 +273,14 @@ func TestNewDatadogContextMissingCredentials(t *testing.T) {
191273

192274
func TestNewDatadogContextDDKeySet(t *testing.T) {
193275
// Save and restore env vars
194-
originalAPIKey := os.Getenv("DD_API_KEY")
195-
originalDatadogSite := os.Getenv("DD_SITE")
276+
originalAPIKey := os.Getenv(envDatadogAPIKey)
277+
originalDatadogSite := os.Getenv(envDatadogSite)
196278
defer func() {
197-
_ = os.Setenv("DD_API_KEY", originalAPIKey)
198-
_ = os.Setenv("DD_SITE", originalDatadogSite)
279+
_ = os.Setenv(envDatadogAPIKey, originalAPIKey)
280+
_ = os.Setenv(envDatadogSite, originalDatadogSite)
199281
}()
200-
_ = os.Setenv("DD_API_KEY", "1234")
201-
_ = os.Unsetenv("DD_SITE")
282+
_ = os.Setenv(envDatadogAPIKey, "1234")
283+
_ = os.Unsetenv(envDatadogSite)
202284
ctx := context.Background()
203285
datadogCtx, err := newDatadogContext(ctx)
204286
require.NoError(t, err)
@@ -209,16 +291,16 @@ func TestNewDatadogContextDDKeySet(t *testing.T) {
209291

210292
func TestNewDatadogContextDatadogFlagSet(t *testing.T) {
211293
// Save and restore env vars
212-
originalAPIKey := os.Getenv("DD_API_KEY")
213-
originalDatadogSite := os.Getenv("DD_SITE")
294+
originalAPIKey := os.Getenv(envDatadogAPIKey)
295+
originalDatadogSite := os.Getenv(envDatadogSite)
214296
originalFlag := roachtestflags.DatadogAPIKey
215297
defer func() {
216-
_ = os.Setenv("DD_API_KEY", originalAPIKey)
217-
_ = os.Setenv("DD_SITE", originalDatadogSite)
298+
_ = os.Setenv(envDatadogAPIKey, originalAPIKey)
299+
_ = os.Setenv(envDatadogSite, originalDatadogSite)
218300
roachtestflags.DatadogAPIKey = originalFlag
219301
}()
220-
_ = os.Unsetenv("DD_API_KEY")
221-
_ = os.Unsetenv("DD_SITE")
302+
_ = os.Unsetenv(envDatadogAPIKey)
303+
_ = os.Unsetenv(envDatadogSite)
222304
roachtestflags.DatadogAPIKey = "1234"
223305
ctx := context.Background()
224306
datadogCtx, err := newDatadogContext(ctx)
@@ -230,14 +312,14 @@ func TestNewDatadogContextDatadogFlagSet(t *testing.T) {
230312

231313
func TestNewDatadogContextDatadogSiteSet(t *testing.T) {
232314
// Save and restore env vars
233-
originalAPIKey := os.Getenv("DD_API_KEY")
234-
originalDatadogSite := os.Getenv("DD_SITE")
315+
originalAPIKey := os.Getenv(envDatadogAPIKey)
316+
originalDatadogSite := os.Getenv(envDatadogSite)
235317
defer func() {
236-
_ = os.Setenv("DD_API_KEY", originalAPIKey)
237-
_ = os.Setenv("DD_SITE", originalDatadogSite)
318+
_ = os.Setenv(envDatadogAPIKey, originalAPIKey)
319+
_ = os.Setenv(envDatadogSite, originalDatadogSite)
238320
}()
239-
_ = os.Setenv("DD_API_KEY", "1234")
240-
_ = os.Setenv("DD_SITE", "test-site")
321+
_ = os.Setenv(envDatadogAPIKey, "1234")
322+
_ = os.Setenv(envDatadogSite, "test-site")
241323
ctx := context.Background()
242324
datadogCtx, err := newDatadogContext(ctx)
243325
require.NoError(t, err)
@@ -251,10 +333,10 @@ func TestNewDatadogContextDatadogSiteSet(t *testing.T) {
251333

252334
func TestShouldUploadLogs(t *testing.T) {
253335
// Save and restore env var and flag
254-
originalBranch := os.Getenv("TC_BUILD_BRANCH")
336+
originalBranch := os.Getenv(envTCBuildBranch)
255337
originalFlag := roachtestflags.DatadogAlwaysUpload
256338
defer func() {
257-
_ = os.Setenv("TC_BUILD_BRANCH", originalBranch)
339+
_ = os.Setenv(envTCBuildBranch, originalBranch)
258340
roachtestflags.DatadogAlwaysUpload = originalFlag
259341
}()
260342

@@ -292,7 +374,7 @@ func TestShouldUploadLogs(t *testing.T) {
292374

293375
for _, tt := range tests {
294376
t.Run(tt.name, func(t *testing.T) {
295-
_ = os.Setenv("TC_BUILD_BRANCH", tt.branch)
377+
_ = os.Setenv(envTCBuildBranch, tt.branch)
296378
roachtestflags.DatadogAlwaysUpload = tt.datadogAlwaysUpload
297379

298380
result := ShouldUploadLogs()

pkg/cmd/roachtest/test_impl.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,10 @@ func (t *testImpl) duration() time.Duration {
542542
return t.end.Sub(t.start)
543543
}
544544

545+
func (t *testImpl) formattedDuration() string {
546+
return fmt.Sprintf("%.2fs", t.duration().Seconds())
547+
}
548+
545549
func (t *testImpl) Failed() bool {
546550
t.mu.RLock()
547551
defer t.mu.RUnlock()

0 commit comments

Comments
 (0)