Skip to content

Commit

Permalink
Add start time timestamps to <testcase>/Run data in JUnit XML outpu…
Browse files Browse the repository at this point in the history
…t from `terraform test` (#36295)

* Record metadata about the start timestamp for a Run/test case

* Add RFC3339 format timestamp attributes to `<testcase>` elements in JUnit XML output

* Ensure timestamps are saved as and rendered as UTC timestamps
  • Loading branch information
SarahFrench authored Jan 10, 2025
1 parent b827ca4 commit 43f31c4
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 2 deletions.
3 changes: 2 additions & 1 deletion internal/backend/local/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ func (runner *TestFileRunner) Test(file *moduletest.File) {
}
}

startTime := time.Now()
startTime := time.Now().UTC()
state, updatedState := runner.run(run, file, runner.RelevantStates[key].State, config)
runDuration := time.Since(startTime)
if updatedState {
Expand All @@ -370,6 +370,7 @@ func (runner *TestFileRunner) Test(file *moduletest.File) {
// If we got far enough to actually execute the run then we'll give
// the view some additional metadata about the execution.
run.ExecutionMeta = &moduletest.RunExecutionMeta{
Start: startTime,
Duration: runDuration,
}
runner.Suite.View.Run(run, file, moduletest.Complete, 0)
Expand Down
4 changes: 3 additions & 1 deletion internal/command/views/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,8 @@ func junitXMLTestReport(suite *moduletest.Suite) ([]byte, error) {
// "not known", and thus omit that case. (In practice many
// JUnit XML consumers treat the absense of this attribute
// as zero anyway.)
RunTime float64 `xml:"time,attr,omitempty"`
RunTime float64 `xml:"time,attr,omitempty"`
Timestamp string `xml:"timestamp,attr,omitempty"`
}

testCase := TestCase{
Expand All @@ -913,6 +914,7 @@ func junitXMLTestReport(suite *moduletest.Suite) ([]byte, error) {
}
if execMeta := run.ExecutionMeta; execMeta != nil {
testCase.RunTime = execMeta.Duration.Seconds()
testCase.Timestamp = execMeta.StartTimestamp()
}
switch run.Status {
case moduletest.Skip:
Expand Down
11 changes: 11 additions & 0 deletions internal/moduletest/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,20 @@ type Run struct {
}

type RunExecutionMeta struct {
Start time.Time
Duration time.Duration
}

// StartTimestamp returns the start time metadata as a timestamp formatted as YYYY-MM-DDTHH:MM:SSZ.
// Times are converted to UTC, if they aren't already.
// If the start time is unset an empty string is returned.
func (m *RunExecutionMeta) StartTimestamp() string {
if m.Start.IsZero() {
return ""
}
return m.Start.UTC().Format(time.RFC3339)
}

// Verbose is a utility struct that holds all the information required for a run
// to render the results verbosely.
//
Expand Down

0 comments on commit 43f31c4

Please sign in to comment.