Skip to content

Commit 61526d2

Browse files
moving teamcitytestscripts again so they are provider generated (#14748) (#23890)
[upstream:884aa539cdbf2c55efcf1def253aea8f1f13c662] Signed-off-by: Modular Magician <[email protected]>
1 parent 1f1c839 commit 61526d2

File tree

2 files changed

+276
-0
lines changed

2 files changed

+276
-0
lines changed

scripts/teamcitytestscripts/main.go

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
// ----------------------------------------------------------------------------
2+
//
3+
// *** AUTO GENERATED CODE *** Type: Handwritten ***
4+
//
5+
// ----------------------------------------------------------------------------
6+
//
7+
// This code is generated by Magic Modules using the following:
8+
//
9+
// Source file: https://github.com/GoogleCloudPlatform/magic-modules/tree/main/mmv1/third_party/terraform/scripts/teamcitytestscripts/main.go
10+
//
11+
// DO NOT EDIT this file directly. Any changes made to this file will be
12+
// overwritten during the next generation cycle.
13+
//
14+
// ----------------------------------------------------------------------------
15+
package main
16+
17+
import (
18+
"bufio"
19+
"bytes"
20+
"flag"
21+
"fmt"
22+
"io"
23+
"os"
24+
"os/exec"
25+
"strings"
26+
"time"
27+
)
28+
29+
func usage() string {
30+
return `Usage:
31+
teamcity-go-test -test <binary> [-parallelism n] [-timeout t]
32+
33+
Test names must be listed one per line on stdin.
34+
`
35+
}
36+
37+
func main() {
38+
testBinary := flag.String("test", "", "executable containing the tests to run")
39+
parallelism := flag.Int("parallelism", 1, "number of tests to execute in parallel")
40+
timeout := flag.String("timeout", "", "an optional per-test timeout")
41+
flag.Parse()
42+
43+
if testBinary == nil || *testBinary == "" {
44+
fmt.Fprint(os.Stderr, usage())
45+
os.Exit(1)
46+
}
47+
48+
if _, err := os.Stat(*testBinary); err != nil {
49+
fmt.Fprintf(os.Stderr, "Cannot find binary: %s\n", *testBinary)
50+
os.Exit(1)
51+
}
52+
53+
testNames := make([]string, 0, 0)
54+
stdInReader := bufio.NewReader(os.Stdin)
55+
56+
for {
57+
line, err := stdInReader.ReadString('\n')
58+
if err != nil {
59+
if err == io.EOF {
60+
if strings.TrimSpace(line) != "" {
61+
testNames = append(testNames, line)
62+
}
63+
break
64+
}
65+
fmt.Fprintf(os.Stderr, "error reading stdin: %s", err)
66+
os.Exit(1)
67+
}
68+
69+
if strings.TrimSpace(line) != "" {
70+
testNames = append(testNames, line)
71+
}
72+
}
73+
74+
testQueue := make(chan string)
75+
messages := make(chan string)
76+
completed := make(chan struct{})
77+
78+
for i := 0; i < *parallelism; i++ {
79+
go runWorker(testQueue, messages, completed, *testBinary, *timeout)
80+
}
81+
82+
go func() {
83+
for _, testName := range testNames {
84+
testQueue <- strings.TrimSpace(testName)
85+
}
86+
}()
87+
88+
resultsCount := 0
89+
for {
90+
select {
91+
case message := <-messages:
92+
fmt.Printf("%s", message)
93+
case <-completed:
94+
resultsCount++
95+
}
96+
97+
if resultsCount == len(testNames) {
98+
break
99+
}
100+
}
101+
}
102+
103+
func runWorker(inputQueue <-chan string, messages chan<- string, done chan<- struct{}, binaryName, timeout string) {
104+
for {
105+
select {
106+
case testName := <-inputQueue:
107+
test := NewTeamCityTest(testName)
108+
//messages <- fmt.Sprintf("%s", test.FormatStartNotice())
109+
runTest(test, binaryName, timeout)
110+
messages <- test.FormatTestOutput()
111+
done <- struct{}{}
112+
}
113+
}
114+
}
115+
116+
func runTest(test *TeamCityTest, binaryName, timeout string) {
117+
var out bytes.Buffer
118+
var errOut bytes.Buffer
119+
120+
test.Started = time.Now()
121+
122+
args := []string{
123+
"-test.v",
124+
"-test.run",
125+
fmt.Sprintf("^%s$", test.Name),
126+
}
127+
if timeout != "" {
128+
args = append(args, "-test.timeout")
129+
args = append(args, timeout)
130+
}
131+
132+
cmd := exec.Command(binaryName, args...)
133+
cmd.Stdout = &out
134+
cmd.Stderr = &errOut
135+
// Not sure what to do with errors here other than report them out to the runner.
136+
cmd.Run()
137+
138+
test.ParseTestRunnerOutput(out.String(), errOut.String())
139+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// ----------------------------------------------------------------------------
2+
//
3+
// *** AUTO GENERATED CODE *** Type: Handwritten ***
4+
//
5+
// ----------------------------------------------------------------------------
6+
//
7+
// This code is generated by Magic Modules using the following:
8+
//
9+
// Source file: https://github.com/GoogleCloudPlatform/magic-modules/tree/main/mmv1/third_party/terraform/scripts/teamcitytestscripts/teamcity.go
10+
//
11+
// DO NOT EDIT this file directly. Any changes made to this file will be
12+
// overwritten during the next generation cycle.
13+
//
14+
// ----------------------------------------------------------------------------
15+
package main
16+
17+
import (
18+
"bytes"
19+
"fmt"
20+
"regexp"
21+
"strings"
22+
"time"
23+
)
24+
25+
const (
26+
TeamCityTimestampFormat = "2006-01-02T15:04:05.000"
27+
TeamCityTestStarted = "##teamcity[testStarted timestamp='%s' name='%s']\n"
28+
TeamCityTestFailed = "##teamcity[testFailed timestamp='%s' name='%s']\n"
29+
TeamCityTestFinished = "##teamcity[testFinished timestamp='%s' name='%s']\n"
30+
TeamCityTestFailedRace = "##teamcity[testFailed timestamp='%s' name='%s' message='Race detected!']\n"
31+
TeamCityTestIgnored = "##teamcity[testIgnored timestamp='%s' name='%s']\n"
32+
TeamCityTestFailedPanic = "##teamcity[testFailed timestamp='%s' name='%s' message='Test ended in panic.']\n"
33+
TeamCityTestDiffFailed = "##teamcity[testDiffFailed timestamp='%s' name='%s']\n"
34+
TeamCityTestStdOut = "##teamcity[testStdOut name='%s' out='%s']\n"
35+
TeamCityTestStdErr = "##teamcity[testStdErr name='%s' out='%s']\n"
36+
)
37+
38+
var (
39+
end = regexp.MustCompile(`--- (PASS|SKIP|FAIL):\s+([a-zA-Z_]\S*) \(([\.\d]+)\)`)
40+
diff = regexp.MustCompile(`\[Diff\] (.*)`)
41+
paniced = regexp.MustCompile(`panic:\s+(.*)\s+\[recovered\]\n`)
42+
//suite = regexp.MustCompile("^(ok|FAIL)\\s+([^\\s]+)\\s+([\\.\\d]+)s")
43+
race = regexp.MustCompile("^WARNING: DATA RACE")
44+
)
45+
46+
type TeamCityTest struct {
47+
Name, Output, ErrOutput, Duration string
48+
Race, Fail, Skip, Pass, Diff bool
49+
Started time.Time
50+
}
51+
52+
func NewTeamCityTest(testName string) *TeamCityTest {
53+
return &TeamCityTest{
54+
Name: testName,
55+
}
56+
}
57+
58+
func (test *TeamCityTest) ParseTestRunnerOutput(testOutput string, errOutput string) {
59+
hasDataRace := race.MatchString(testOutput)
60+
test.Race = hasDataRace
61+
62+
resultDiff := diff.FindStringSubmatch(testOutput)
63+
if resultDiff != nil {
64+
test.Diff = true
65+
} else {
66+
resultLines := end.FindStringSubmatch(testOutput)
67+
if resultLines != nil {
68+
switch resultLines[1] {
69+
case "PASS":
70+
test.Pass = true
71+
case "SKIP":
72+
test.Skip = true
73+
case "FAIL":
74+
test.Fail = true
75+
}
76+
test.Duration = resultLines[3]
77+
}
78+
}
79+
test.Output = testOutput
80+
test.ErrOutput = errOutput
81+
}
82+
83+
func (test *TeamCityTest) FormatTestOutput() string {
84+
now := time.Now().Format(TeamCityTimestampFormat)
85+
86+
var output bytes.Buffer
87+
88+
output.WriteString(fmt.Sprintf(TeamCityTestStarted, test.Started.Format(TeamCityTimestampFormat), test.Name))
89+
90+
output.WriteString(fmt.Sprintf(TeamCityTestStdOut, test.Name, escapeOutput(test.Output)))
91+
output.WriteString(fmt.Sprintf(TeamCityTestStdErr, test.Name, escapeOutput(test.ErrOutput)))
92+
93+
if test.Diff {
94+
output.WriteString(fmt.Sprintf(TeamCityTestDiffFailed, now, test.Name))
95+
// have to fail so that teamcity catches failure correctly
96+
output.WriteString(fmt.Sprintf(TeamCityTestFailedPanic, now, test.Name))
97+
output.WriteString(fmt.Sprintf(TeamCityTestFinished, now, test.Name))
98+
return output.String()
99+
100+
}
101+
102+
if test.Fail {
103+
output.WriteString(fmt.Sprintf(TeamCityTestFailed, now, test.Name))
104+
output.WriteString(fmt.Sprintf(TeamCityTestFinished, now, test.Name))
105+
return output.String()
106+
}
107+
108+
if test.Race {
109+
output.WriteString(fmt.Sprintf(TeamCityTestFailedRace, now, test.Name))
110+
output.WriteString(fmt.Sprintf(TeamCityTestFinished, now, test.Name))
111+
return output.String()
112+
}
113+
114+
if test.Skip {
115+
output.WriteString(fmt.Sprintf(TeamCityTestIgnored, now, test.Name))
116+
return output.String()
117+
}
118+
119+
if test.Pass {
120+
output.WriteString(fmt.Sprintf(TeamCityTestFinished, now, test.Name))
121+
return output.String()
122+
}
123+
124+
// test passes if no diff, even if failure (failure artifacts will be in regular_failure_file.log)
125+
output.WriteString(fmt.Sprintf(TeamCityTestFinished, now, test.Name))
126+
127+
return output.String()
128+
}
129+
130+
func escapeOutput(outputLines string) string {
131+
newOutput := strings.Replace(outputLines, "|", "||", -1)
132+
newOutput = strings.Replace(newOutput, "\n", "|n", -1)
133+
newOutput = strings.Replace(newOutput, "'", "|'", -1)
134+
newOutput = strings.Replace(newOutput, "]", "|]", -1)
135+
newOutput = strings.Replace(newOutput, "[", "|[", -1)
136+
return newOutput
137+
}

0 commit comments

Comments
 (0)