blob: 4ceef65a79a33bccba8f5a238296b1c82e5e0175 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package resultstore
import (
"log"
"time"
"github.com/golang/protobuf/ptypes"
"github.com/golang/protobuf/ptypes/duration"
"github.com/golang/protobuf/ptypes/timestamp"
api "google.golang.org/genproto/googleapis/devtools/resultstore/v2"
)
func timeToProtoTimestamp(input time.Time) *timestamp.Timestamp {
output, err := ptypes.TimestampProto(input)
if err != nil {
// We should never get here.
panic(err.Error())
}
return output
}
func durationToProtoDuration(input time.Duration) *duration.Duration {
return ptypes.DurationProto(input)
}
func mapToProperties(input map[string]string) []*api.Property {
var props []*api.Property
for k, v := range input {
props = append(props, &api.Property{Key: k, Value: v})
}
return props
}
func lookupFileURI(files []*api.File, fileID string) string {
for _, file := range files {
if file.Uid == fileID {
return file.Uri
}
}
return ""
}
// Invocation maps to a ResultStore Invocation. See full docs at:
// https://github.com/googleapis/googleapis/blob/master/google/devtools/resultstore/v2/invocation.proto
type Invocation struct {
// The name of this Invocation as it appears in ResultStore.
Name string
// The ID of this invocation as it appears in ResultStore.
ID string
ProjectID string
Users []string
Labels []string
Properties map[string]string
LogURL string
Status Status
StartTime time.Time
Duration time.Duration
}
func (i Invocation) ToResultStoreInvocation() *api.Invocation {
return &api.Invocation{
Name: i.Name,
Id: &api.Invocation_Id{
InvocationId: i.ID,
},
StatusAttributes: &api.StatusAttributes{
Status: i.Status.ToResultStoreStatus(),
},
Timing: &api.Timing{
StartTime: timeToProtoTimestamp(i.StartTime),
Duration: durationToProtoDuration(i.Duration),
},
InvocationAttributes: &api.InvocationAttributes{
ProjectId: i.ProjectID,
Users: i.Users,
Labels: i.Labels,
},
Files: []*api.File{
&api.File{Uid: "invocation.log", Uri: i.LogURL},
},
Properties: mapToProperties(i.Properties),
}
}
func (i *Invocation) FromResultStoreInvocation(input *api.Invocation) {
*i = Invocation{
Name: input.GetName(),
ID: input.GetId().InvocationId,
}
}
// Configuration maps to a ResultStore Configuration. See full docs at:
// https://github.com/googleapis/googleapis/blob/master/google/devtools/resultstore/v2/configuration.proto
type Configuration struct {
// The name of this Configuration as it appears in ResultStore.
Name string
// The ID of this Configuration as it appears in ResultStore.
ID string
InvocationID string
Properties map[string]string
}
func (c Configuration) ToResultStoreConfiguration() *api.Configuration {
return &api.Configuration{
Name: c.Name,
Id: &api.Configuration_Id{
InvocationId: c.InvocationID,
ConfigurationId: c.ID,
},
Properties: mapToProperties(c.Properties),
}
}
func (c *Configuration) FromResultStoreConfiguration(input *api.Configuration) {
*c = Configuration{
Name: input.GetName(),
ID: input.GetId().ConfigurationId,
InvocationID: input.GetId().InvocationId,
}
}
// Target maps to a ResultStore Target. See full docs at:
// https://github.com/googleapis/googleapis/blob/master/google/devtools/resultstore/v2/target.proto
type Target struct {
Name string
ID *TargetID
Properties map[string]string
Status Status
StartTime time.Time
Duration time.Duration
TestLogURI string
}
type TargetID struct {
ID string
InvocationID string
}
func (t Target) ToResultStoreTarget() *api.Target {
var id *api.Target_Id
if t.ID != nil {
id = &api.Target_Id{
InvocationId: t.ID.InvocationID,
TargetId: t.ID.ID,
}
}
return &api.Target{
Name: t.Name,
Id: id,
Timing: &api.Timing{
StartTime: timeToProtoTimestamp(t.StartTime),
Duration: durationToProtoDuration(t.Duration),
},
StatusAttributes: &api.StatusAttributes{
Status: t.Status.ToResultStoreStatus(),
},
Properties: mapToProperties(t.Properties),
Visible: true,
Files: []*api.File{
&api.File{
Uid: "test.log",
Uri: t.TestLogURI,
},
},
}
}
func (t *Target) FromResultStoreTarget(input *api.Target) {
*t = Target{
Name: input.GetName(),
ID: &TargetID{
ID: input.GetId().TargetId,
InvocationID: input.GetId().InvocationId,
},
}
}
// ConfiguredTarget maps to a ResultStore ConfiguredTarget. See full docs at:
// https://github.com/googleapis/googleapis/blob/master/google/devtools/resultstore/v2/configured_target.proto
type ConfiguredTarget struct {
Name string
ID *ConfiguredTargetID
Properties map[string]string
Status Status
StartTime time.Time
Duration time.Duration
}
type ConfiguredTargetID struct {
InvocationID string
TargetID string
ConfigID string
}
func (t ConfiguredTarget) ToResultStoreConfiguredTarget() *api.ConfiguredTarget {
var id *api.ConfiguredTarget_Id
if t.ID != nil {
id = &api.ConfiguredTarget_Id{
InvocationId: t.ID.InvocationID,
TargetId: t.ID.TargetID,
ConfigurationId: t.ID.ConfigID,
}
}
return &api.ConfiguredTarget{
Name: t.Name,
Id: id,
StatusAttributes: &api.StatusAttributes{
Status: t.Status.ToResultStoreStatus(),
},
Timing: &api.Timing{
StartTime: timeToProtoTimestamp(t.StartTime),
Duration: durationToProtoDuration(t.Duration),
},
Properties: mapToProperties(t.Properties),
}
}
func (t *ConfiguredTarget) FromResultStoreConfiguredTarget(input *api.ConfiguredTarget) {
*t = ConfiguredTarget{
Name: input.GetName(),
ID: &ConfiguredTargetID{
InvocationID: input.GetId().InvocationId,
TargetID: input.GetId().TargetId,
ConfigID: input.GetId().ConfigurationId,
},
}
}
// TestAction maps to a ResultStore Action with a child TestAction. See full docs at:
// https://github.com/googleapis/googleapis/blob/master/google/devtools/resultstore/v2/action.proto
type TestAction struct {
Name string
ID *TestActionID
TestSuite string
TestLogURI string
StartTime time.Time
Duration time.Duration
Status Status
}
type TestActionID struct {
ID string
InvocationID string
TargetID string
ConfigID string
}
func (a TestAction) ToResultStoreAction() *api.Action {
var id *api.Action_Id
if a.ID != nil {
id = &api.Action_Id{
InvocationId: a.ID.InvocationID,
TargetId: a.ID.TargetID,
ConfigurationId: a.ID.ConfigID,
ActionId: a.ID.ID,
}
}
return &api.Action{
Name: a.Name,
Id: id,
StatusAttributes: &api.StatusAttributes{
Status: a.Status.ToResultStoreStatus(),
},
ActionType: &api.Action_TestAction{
TestAction: &api.TestAction{
TestSuite: &api.TestSuite{
SuiteName: a.TestSuite,
},
},
},
Files: []*api.File{
&api.File{
Uid: "test.log",
Uri: a.TestLogURI,
},
},
Timing: &api.Timing{
StartTime: timeToProtoTimestamp(a.StartTime),
Duration: durationToProtoDuration(a.Duration),
},
}
}
func (a *TestAction) FromResultStoreAction(input *api.Action) {
*a = TestAction{
Name: input.GetName(),
ID: &TestActionID{
InvocationID: input.GetId().InvocationId,
TargetID: input.GetId().TargetId,
ConfigID: input.GetId().ConfigurationId,
ID: input.GetId().ActionId,
},
}
}
type Status string
const (
Building = Status("BUILDING")
Passed = Status("PASSED")
Failed = Status("FAILED")
TimedOut = Status("TIMED_OUT")
Testing = Status("TESTING")
Unknown = Status("Unknown")
)
func (r Status) ToResultStoreStatus() api.Status {
switch r {
case Building:
return api.Status_BUILDING
case Failed:
return api.Status_FAILED
case Passed:
return api.Status_PASSED
case Testing:
return api.Status_TESTING
case TimedOut:
return api.Status_TIMED_OUT
default:
log.Printf("unknown test status: %v", r)
return api.Status_UNKNOWN
}
}