Skip to content

Commit c9a5dde

Browse files
authored
Added support for test report upload (#7)
1 parent 0c3231e commit c9a5dde

36 files changed

Lines changed: 2704 additions & 107 deletions

api/api.go

Lines changed: 116 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -4,99 +4,119 @@ import (
44
"github.com/harness/lite-engine/engine/spec"
55
)
66

7-
type SetupRequest struct {
8-
Envs map[string]string `json:"envs,omitempty"`
9-
Network spec.Network `json:"network"`
10-
Platform spec.Platform `json:"platform,omitempty"`
11-
Volumes []*spec.Volume `json:"volumes,omitempty"`
12-
Secrets []string `json:"secrets,omitempty"`
13-
LogConfig LogConfig `json:"log_config,omitempty"`
14-
TIConfig TIConfig `json:"ti_config,omitempty"`
15-
}
16-
17-
type SetupResponse struct{}
18-
19-
type DestroyRequest struct{}
20-
21-
type DestroyResponse struct{}
22-
23-
type StartStepRequest struct {
24-
ID string `json:"id,omitempty"` // Unique identifier of step
25-
Detach bool `json:"detach,omitempty"`
26-
Envs map[string]string `json:"environment,omitempty"`
27-
Name string `json:"name,omitempty"`
28-
Secrets []string `json:"secrets,omitempty"`
29-
WorkingDir string `json:"working_dir,omitempty"`
30-
Kind StepType `json:"kind,omitempty"`
31-
Run RunConfig `json:"run,omitempty"`
32-
RunTest RunTestConfig `json:"run_test,omitempty"`
33-
34-
LogKey string `json:"log_key,omitempty"`
35-
OutputVars []string `json:"output_var,omitempty"`
36-
Timeout int `json:"timeout,omitempty"` // step timeout in seconds
37-
38-
// Valid only for steps running on docker container
39-
Auth *spec.Auth `json:"auth,omitempty"`
40-
CPUPeriod int64 `json:"cpu_period,omitempty"`
41-
CPUQuota int64 `json:"cpu_quota,omitempty"`
42-
CPUShares int64 `json:"cpu_shares,omitempty"`
43-
CPUSet []string `json:"cpu_set,omitempty"`
44-
Devices []*spec.VolumeDevice `json:"devices,omitempty"`
45-
DNS []string `json:"dns,omitempty"`
46-
DNSSearch []string `json:"dns_search,omitempty"`
47-
ExtraHosts []string `json:"extra_hosts,omitempty"`
48-
IgnoreStdout bool `json:"ignore_stderr,omitempty"`
49-
IgnoreStderr bool `json:"ignore_stdout,omitempty"`
50-
Image string `json:"image,omitempty"`
51-
Labels map[string]string `json:"labels,omitempty"`
52-
MemSwapLimit int64 `json:"memswap_limit,omitempty"`
53-
MemLimit int64 `json:"mem_limit,omitempty"`
54-
Network string `json:"network,omitempty"`
55-
Networks []string `json:"networks,omitempty"`
56-
Privileged bool `json:"privileged,omitempty"`
57-
Pull spec.PullPolicy `json:"pull,omitempty"`
58-
ShmSize int64 `json:"shm_size,omitempty"`
59-
User string `json:"user,omitempty"`
60-
Volumes []*spec.VolumeMount `json:"volumes,omitempty"`
61-
}
62-
63-
type StartStepResponse struct{}
64-
65-
type PollStepRequest struct {
66-
ID string `json:"id,omitempty"`
67-
}
68-
69-
type PollStepResponse struct {
70-
Exited bool `json:"exited,omitempty"`
71-
ExitCode int `json:"exit_code,omitempty"`
72-
OOMKilled bool `json:"oom_killed,omitempty"`
73-
}
74-
75-
type RunConfig struct {
76-
Command []string `json:"commands,omitempty"`
77-
Entrypoint []string `json:"entrypoint,omitempty"`
78-
}
79-
80-
type RunTestConfig struct {
81-
Args string `json:"args,omitempty"`
82-
Entrypoint []string `json:"entrypoint,omitempty"`
83-
PreCommand string `json:"pre_command,omitempty"`
84-
PostCommand string `json:"post_command,omitempty"`
85-
BuildTool string `json:"build_tool,omitempty"`
86-
Language string `json:"language,omitempty"`
87-
Packages string `json:"packages,omitempty"`
88-
RunOnlySelectedTests bool `json:"run_only_selected_tests,omitempty"`
89-
TestAnnotations string `json:"test_annotations,omitempty"`
90-
}
91-
92-
type LogConfig struct {
93-
AccountID string `json:"account_id,omitempty"`
94-
IndirectUpload bool `json:"indirect_upload,omitempty"` // Whether to directly upload via signed link or using log service
95-
URL string `json:"url,omitempty"`
96-
Token string `json:"token,omitempty"`
97-
}
98-
99-
type TIConfig struct {
100-
URL string `json:"url,omitempty"`
101-
Token string `json:"token,omitempty"`
102-
}
7+
type (
8+
SetupRequest struct {
9+
Envs map[string]string `json:"envs,omitempty"`
10+
Network spec.Network `json:"network"`
11+
Platform spec.Platform `json:"platform,omitempty"`
12+
Volumes []*spec.Volume `json:"volumes,omitempty"`
13+
Secrets []string `json:"secrets,omitempty"`
14+
LogConfig LogConfig `json:"log_config,omitempty"`
15+
TIConfig TIConfig `json:"ti_config,omitempty"`
16+
}
17+
18+
SetupResponse struct{}
19+
20+
DestroyRequest struct{}
21+
22+
DestroyResponse struct{}
23+
24+
StartStepRequest struct {
25+
ID string `json:"id,omitempty"` // Unique identifier of step
26+
Detach bool `json:"detach,omitempty"`
27+
Envs map[string]string `json:"environment,omitempty"`
28+
Name string `json:"name,omitempty"`
29+
LogKey string `json:"log_key,omitempty"`
30+
Secrets []string `json:"secrets,omitempty"`
31+
WorkingDir string `json:"working_dir,omitempty"`
32+
Kind StepType `json:"kind,omitempty"`
33+
Run RunConfig `json:"run,omitempty"`
34+
RunTest RunTestConfig `json:"run_test,omitempty"`
35+
36+
OutputVars []string `json:"output_var,omitempty"`
37+
TestReport TestReport `json:"test_report,omitempty"`
38+
Timeout int `json:"timeout,omitempty"` // step timeout in seconds
39+
40+
// Valid only for steps running on docker container
41+
Auth *spec.Auth `json:"auth,omitempty"`
42+
CPUPeriod int64 `json:"cpu_period,omitempty"`
43+
CPUQuota int64 `json:"cpu_quota,omitempty"`
44+
CPUShares int64 `json:"cpu_shares,omitempty"`
45+
CPUSet []string `json:"cpu_set,omitempty"`
46+
Devices []*spec.VolumeDevice `json:"devices,omitempty"`
47+
DNS []string `json:"dns,omitempty"`
48+
DNSSearch []string `json:"dns_search,omitempty"`
49+
ExtraHosts []string `json:"extra_hosts,omitempty"`
50+
IgnoreStdout bool `json:"ignore_stderr,omitempty"`
51+
IgnoreStderr bool `json:"ignore_stdout,omitempty"`
52+
Image string `json:"image,omitempty"`
53+
Labels map[string]string `json:"labels,omitempty"`
54+
MemSwapLimit int64 `json:"memswap_limit,omitempty"`
55+
MemLimit int64 `json:"mem_limit,omitempty"`
56+
Network string `json:"network,omitempty"`
57+
Networks []string `json:"networks,omitempty"`
58+
Privileged bool `json:"privileged,omitempty"`
59+
Pull spec.PullPolicy `json:"pull,omitempty"`
60+
ShmSize int64 `json:"shm_size,omitempty"`
61+
User string `json:"user,omitempty"`
62+
Volumes []*spec.VolumeMount `json:"volumes,omitempty"`
63+
}
64+
65+
StartStepResponse struct{}
66+
67+
PollStepRequest struct {
68+
ID string `json:"id,omitempty"`
69+
}
70+
71+
PollStepResponse struct {
72+
Exited bool `json:"exited,omitempty"`
73+
ExitCode int `json:"exit_code,omitempty"`
74+
OOMKilled bool `json:"oom_killed,omitempty"`
75+
}
76+
77+
RunConfig struct {
78+
Command []string `json:"commands,omitempty"`
79+
Entrypoint []string `json:"entrypoint,omitempty"`
80+
}
81+
82+
RunTestConfig struct {
83+
Args string `json:"args,omitempty"`
84+
Entrypoint []string `json:"entrypoint,omitempty"`
85+
PreCommand string `json:"pre_command,omitempty"`
86+
PostCommand string `json:"post_command,omitempty"`
87+
BuildTool string `json:"build_tool,omitempty"`
88+
Language string `json:"language,omitempty"`
89+
Packages string `json:"packages,omitempty"`
90+
RunOnlySelectedTests bool `json:"run_only_selected_tests,omitempty"`
91+
TestAnnotations string `json:"test_annotations,omitempty"`
92+
}
93+
94+
LogConfig struct {
95+
AccountID string `json:"account_id,omitempty"`
96+
IndirectUpload bool `json:"indirect_upload,omitempty"` // Whether to directly upload via signed link or using log service
97+
URL string `json:"url,omitempty"`
98+
Token string `json:"token,omitempty"`
99+
}
100+
101+
TIConfig struct {
102+
URL string `json:"url,omitempty"`
103+
Token string `json:"token,omitempty"`
104+
AccountID string `json:"account_id,omitempty"`
105+
OrgID string `json:"org_id,omitempty"`
106+
ProjectID string `json:"project_id,omitempty"`
107+
PipelineID string `json:"pipeline_id,omitempty"`
108+
StageID string `json:"stage_id,omitempty"`
109+
BuildID string `json:"build_id,omitempty"`
110+
Repo string `json:"repo,omitempty"`
111+
Sha string `json:"sha,omitempty"`
112+
}
113+
114+
TestReport struct {
115+
Kind ReportType `json:"kind,omitempty"`
116+
Junit JunitReport `json:"junit,omitempty"`
117+
}
118+
119+
JunitReport struct {
120+
Paths []string `json:"paths,omitempty"`
121+
}
122+
)

api/report_type.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package api
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
)
7+
8+
// ReportType defines the step type.
9+
type ReportType int
10+
11+
// ReportType enumeration.
12+
const (
13+
Junit ReportType = iota
14+
)
15+
16+
func (s ReportType) String() string {
17+
return reportTypeID[s]
18+
}
19+
20+
var reportTypeID = map[ReportType]string{
21+
Junit: "Junit",
22+
}
23+
24+
var reportTypeName = map[string]ReportType{
25+
"": Junit,
26+
"Junit": Junit,
27+
}
28+
29+
// MarshalJSON marshals the string representation of the
30+
// report type to JSON.
31+
func (s *ReportType) MarshalJSON() ([]byte, error) {
32+
buffer := bytes.NewBufferString(`"`)
33+
buffer.WriteString(reportTypeID[*s])
34+
buffer.WriteString(`"`)
35+
return buffer.Bytes(), nil
36+
}
37+
38+
// UnmarshalJSON unmarshals the json representation of the
39+
// report type from a string value.
40+
func (s *ReportType) UnmarshalJSON(b []byte) error {
41+
// unmarshal as string
42+
var a string
43+
err := json.Unmarshal(b, &a)
44+
if err != nil {
45+
return err
46+
}
47+
// lookup value
48+
*s = reportTypeName[a]
49+
return nil
50+
}

api/step_type.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ var stepTypeName = map[string]StepType{
3030
}
3131

3232
// MarshalJSON marshals the string representation of the
33-
// pull type to JSON.
33+
// step type to JSON.
3434
func (s *StepType) MarshalJSON() ([]byte, error) {
3535
buffer := bytes.NewBufferString(`"`)
3636
buffer.WriteString(stepTypeID[*s])
@@ -39,7 +39,7 @@ func (s *StepType) MarshalJSON() ([]byte, error) {
3939
}
4040

4141
// UnmarshalJSON unmarshals the json representation of the
42-
// pull type from a string value.
42+
// step type from a string value.
4343
func (s *StepType) UnmarshalJSON(b []byte) error {
4444
// unmarshal as string
4545
var a string

executor/run.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import (
55
"io"
66

77
"github.com/drone/runner-go/pipeline/runtime"
8+
"github.com/sirupsen/logrus"
89

910
"github.com/harness/lite-engine/api"
1011
"github.com/harness/lite-engine/engine"
12+
"github.com/harness/lite-engine/ti/report"
1113
)
1214

1315
func executeRunStep(ctx context.Context, engine *engine.Engine, r *api.StartStepRequest, out io.Writer) (
@@ -16,5 +18,10 @@ func executeRunStep(ctx context.Context, engine *engine.Engine, r *api.StartStep
1618
step.Command = r.Run.Command
1719
step.Entrypoint = r.Run.Entrypoint
1820

19-
return engine.Run(ctx, step, out)
21+
exited, err := engine.Run(ctx, step, out)
22+
if rerr := report.ParseAndUploadTests(ctx, r.TestReport, step.Name); rerr != nil {
23+
logrus.WithError(rerr).WithField("step", step.Name).Errorln("failed to upload report")
24+
}
25+
26+
return exited, err
2027
}

go.mod

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,22 @@ require (
1313
github.com/drone/runner-go v1.9.0
1414
github.com/go-chi/chi v1.5.4
1515
github.com/gofrs/uuid v4.0.0+incompatible
16-
github.com/google/go-cmp v0.3.0
1716
github.com/hashicorp/go-multierror v1.0.0
1817
github.com/joho/godotenv v1.4.0
1918
github.com/kelseyhightower/envconfig v1.4.0
2019
github.com/pkg/errors v0.9.1
2120
github.com/sirupsen/logrus v1.8.1
21+
github.com/stretchr/testify v1.4.0
2222
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
2323
gopkg.in/alecthomas/kingpin.v2 v2.2.6
2424
)
2525

26+
require (
27+
github.com/davecgh/go-spew v1.1.1 // indirect
28+
github.com/pmezard/go-difflib v1.0.0 // indirect
29+
gopkg.in/yaml.v2 v2.2.2 // indirect
30+
)
31+
2632
require (
2733
github.com/99designs/httpsignatures-go v0.0.0-20170731043157-88528bf4ca7e // indirect
2834
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
@@ -40,6 +46,7 @@ require (
4046
github.com/gorilla/mux v1.7.4 // indirect
4147
github.com/hashicorp/errwrap v1.0.0 // indirect
4248
github.com/kr/pretty v0.1.0 // indirect
49+
github.com/mattn/go-zglob v0.0.3
4350
github.com/morikuni/aec v1.0.0 // indirect
4451
github.com/natessilva/dag v0.0.0-20180124060714-7194b8dcc5c4 // indirect
4552
github.com/opencontainers/go-digest v1.0.0-rc1 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
7676
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
7777
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
7878
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
79+
github.com/mattn/go-zglob v0.0.3 h1:6Ry4EYsScDyt5di4OI6xw1bYhOqfE5S33Z1OPy+d+To=
80+
github.com/mattn/go-zglob v0.0.3/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
7981
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
8082
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
8183
github.com/natessilva/dag v0.0.0-20180124060714-7194b8dcc5c4 h1:dnMxwus89s86tI8rcGVp2HwZzlz7c5o92VOy7dSckBQ=

0 commit comments

Comments
 (0)