Skip to content

Commit 55470cf

Browse files
authored
Merge pull request bitrise-steplib#13 from bitrise-steplib/export-test-results-test-addon
Export test results test addon
2 parents d2fd457 + 33bd06d commit 55470cf

File tree

4 files changed

+174
-5
lines changed

4 files changed

+174
-5
lines changed

bitrise.yml

+36
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ workflows:
1717
- test-in-src-dir
1818
- test-in-root-tmp-dir
1919
- check-artifacts
20+
- check-testaddon-export
2021

2122
test-in-src-dir:
2223
title: Test android project & mono repo projects in source dir
@@ -102,6 +103,41 @@ workflows:
102103
exit 1
103104
fi
104105
106+
check-testaddon-export:
107+
steps:
108+
- script:
109+
title: purge previous build artifacts
110+
inputs:
111+
- content: ./gradlew clean
112+
- script:
113+
title: purge test deploy dir (will always cause ignorable cli error)
114+
inputs:
115+
- content: rm -rf $BITRISE_TEST_DEPLOY_DIR/*
116+
- path::./:
117+
title: run step with predefined inputs
118+
inputs:
119+
- module: app
120+
- variant: Debug
121+
- script:
122+
title: check exported arftifacts
123+
is_always_run: true
124+
inputs:
125+
- content: |-
126+
#!/usr/bin/env bash
127+
set -ex
128+
129+
# check directory and test-info.json existense
130+
if [ $(find ${BITRISE_TEST_DEPLOY_DIR} -regex ".*/app-debug/test-info.json" | grep -c .) -eq 0 ]; then
131+
echo "ERROR: ${BITRISE_TEST_DEPLOY_DIR} does not contain app-debug/test-info.json."
132+
exit 1
133+
fi
134+
135+
# check result xml existense
136+
if [ ! $(find ${BITRISE_TEST_DEPLOY_DIR} -regex ".*/app-debug/TEST.*.xml" | grep -c .) -eq 2 ]; then
137+
echo "ERROR: ${BITRISE_TEST_RESULT_DIR}/app-debug does not contain all test result XMLs."
138+
exit 1
139+
fi
140+
105141
go-tests:
106142
steps:
107143
- go-list:

main.go

+36-5
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@ import (
1111
"github.com/bitrise-io/go-utils/pathutil"
1212
"github.com/bitrise-io/go-utils/sliceutil"
1313
"github.com/bitrise-steplib/bitrise-step-android-unit-test/cache"
14+
"github.com/bitrise-steplib/bitrise-step-android-unit-test/testaddon"
1415
"github.com/bitrise-tools/go-android/gradle"
1516
"github.com/bitrise-tools/go-steputils/stepconf"
1617
shellquote "github.com/kballard/go-shellquote"
1718
)
1819

20+
const resultArtifactPathPattern = "*TEST*.xml"
21+
1922
// Configs ...
2023
type Configs struct {
2124
ProjectLocation string `env:"project_location,dir"`
@@ -32,9 +35,13 @@ func failf(f string, args ...interface{}) {
3235
os.Exit(1)
3336
}
3437

35-
func getArtifacts(gradleProject gradle.Project, started time.Time, pattern string) (artifacts []gradle.Artifact, err error) {
38+
func getArtifacts(gradleProject gradle.Project, started time.Time, pattern string, includeModuleName bool, isDirectoryMode bool) (artifacts []gradle.Artifact, err error) {
3639
for _, t := range []time.Time{started, time.Time{}} {
37-
artifacts, err = gradleProject.FindDirs(t, pattern, true)
40+
if isDirectoryMode {
41+
artifacts, err = gradleProject.FindDirs(t, pattern, includeModuleName)
42+
} else {
43+
artifacts, err = gradleProject.FindArtifacts(t, pattern, includeModuleName)
44+
}
3845
if err != nil {
3946
return
4047
}
@@ -173,7 +180,7 @@ func main() {
173180
log.Infof("Export reports:")
174181
fmt.Println()
175182

176-
reports, err := getArtifacts(gradleProject, started, config.ReportPathPattern)
183+
reports, err := getArtifacts(gradleProject, started, config.ReportPathPattern, true, true)
177184
if err != nil {
178185
failf("Failed to find reports, error: %v", err)
179186
}
@@ -187,7 +194,7 @@ func main() {
187194
log.Infof("Export results:")
188195
fmt.Println()
189196

190-
results, err := getArtifacts(gradleProject, started, config.ResultPathPattern)
197+
results, err := getArtifacts(gradleProject, started, config.ResultPathPattern, true, true)
191198
if err != nil {
192199
failf("Failed to find results, error: %v", err)
193200
}
@@ -196,6 +203,30 @@ func main() {
196203
failf("Failed to export results, error: %v", err)
197204
}
198205

206+
log.Infof("Export test results for test addon:")
207+
fmt.Println()
208+
209+
resultXMLs, err := getArtifacts(gradleProject, started, resultArtifactPathPattern, false, false)
210+
if err != nil {
211+
log.Warnf("Failed to find test result XMLs, error: %s", err)
212+
} else {
213+
if baseDir := os.Getenv("BITRISE_TEST_RESULT_DIR"); baseDir != "" {
214+
for _, artifact := range resultXMLs {
215+
uniqueDir, err := getUniqueDir(artifact.Path)
216+
if err != nil {
217+
log.Warnf("Failed to export test results for test addon: cannot get export directory for artifact (%s): %s", err)
218+
continue
219+
}
220+
221+
if err := testaddon.ExportArtifact(artifact.Path, baseDir, uniqueDir); err != nil {
222+
log.Warnf("Failed to export test results for test addon: %s", err)
223+
}
224+
}
225+
log.Printf(" Exporting test results to test addon successful [ %s ] ", baseDir)
226+
}
227+
}
228+
229+
199230
if testErr != nil {
200231
os.Exit(1)
201232
}
@@ -206,4 +237,4 @@ func main() {
206237
log.Warnf("%s", warning)
207238
}
208239
log.Donef(" Done")
209-
}
240+
}

testaddon.go

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
"unicode"
7+
)
8+
9+
// getUniqueDir returns the unique subdirectory inside the test addon export diroctory for a given artifact.
10+
func getUniqueDir(path string) (string, error) {
11+
parts := strings.Split(path, "/")
12+
i := len(parts) - 1
13+
for i > 0 && parts[i] != "test-results" {
14+
i--
15+
}
16+
17+
if i == 0 {
18+
return "", fmt.Errorf("path (%s) does not contain 'test-results' folder", path)
19+
}
20+
21+
if i+1 > len(parts) {
22+
return "", fmt.Errorf("get variant name: out of index error")
23+
}
24+
25+
variant := parts[i+1]
26+
variant = strings.TrimPrefix(variant, "test")
27+
variant = strings.TrimSuffix(variant, "UnitTest")
28+
29+
runes := []rune(variant)
30+
runes[0] = unicode.ToLower(runes[0])
31+
variant = string(runes)
32+
33+
if i < 2 {
34+
return "", fmt.Errorf("get module name: out of index error")
35+
}
36+
module := parts[i-2]
37+
38+
return module + "-" + variant, nil
39+
}

testaddon/testaddon.go

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package testaddon
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
9+
"github.com/bitrise-io/go-utils/command"
10+
)
11+
12+
const (
13+
// ResultDescriptorFileName is the name of the test result descriptor file.
14+
ResultDescriptorFileName = "test-info.json"
15+
)
16+
17+
func generateTestInfoFile(dir string, data []byte) error {
18+
f, err := os.Create(filepath.Join(dir, ResultDescriptorFileName))
19+
if err != nil {
20+
return err
21+
}
22+
23+
if _, err := f.Write(data); err != nil {
24+
return err
25+
}
26+
27+
if err := f.Sync(); err != nil {
28+
return err
29+
}
30+
31+
if err := f.Close(); err != nil {
32+
return err
33+
}
34+
35+
return nil
36+
}
37+
38+
// ExportArtifact exports artifact found at path in directory uniqueDir,
39+
// rooted at baseDir.
40+
func ExportArtifact(path, baseDir, uniqueDir string) error {
41+
exportDir := filepath.Join(baseDir, uniqueDir)
42+
43+
if err := os.MkdirAll(exportDir, os.ModePerm); err != nil {
44+
return fmt.Errorf("skipping artifact (%s): could not ensure unique export dir (%s): %s", path, exportDir, err)
45+
}
46+
47+
if _, err := os.Stat(filepath.Join(exportDir, ResultDescriptorFileName)); os.IsNotExist(err) {
48+
m := map[string]string{"test-name": uniqueDir}
49+
data, err := json.Marshal(m)
50+
if err != nil {
51+
return fmt.Errorf("create test info descriptor: json marshal data (%s): %s", m, err)
52+
}
53+
if err := generateTestInfoFile(exportDir, data); err != nil {
54+
return fmt.Errorf("create test info descriptor: generate file: %s", err)
55+
}
56+
}
57+
58+
name := filepath.Base(path)
59+
if err := command.CopyFile(path, filepath.Join(exportDir, name)); err != nil {
60+
return fmt.Errorf("failed to export artifact (%s), error: %v", name, err)
61+
}
62+
return nil
63+
}

0 commit comments

Comments
 (0)