[infra][ftx] Updates ftxclient to wait for task completion and respect more input options.
Bug: b/258456267
Change-Id: Ie3509775346b18db7ba3e8c38c291de7a9cafbbe
Reviewed-on: https://fuchsia-review.googlesource.com/c/infra/infra/+/864806
Reviewed-by: Rahul Bangar <rahulbn@google.com>
Commit-Queue: Vinicius Felizardo <felizardo@google.com>
diff --git a/cmd/ftxtest/proto/input.pb.go b/cmd/ftxtest/proto/input.pb.go
index 816d45e..2df3a35 100644
--- a/cmd/ftxtest/proto/input.pb.go
+++ b/cmd/ftxtest/proto/input.pb.go
@@ -33,14 +33,11 @@
// and run tests.
InputArtifactsDigest string `protobuf:"bytes,1,opt,name=input_artifacts_digest,json=inputArtifactsDigest,proto3" json:"input_artifacts_digest,omitempty"`
// Any CIPD packages needed to run the test task.
- CipdPackages []*CIPDPackage `protobuf:"bytes,2,rep,name=cipd_packages,json=cipdPackages,proto3" json:"cipd_packages,omitempty"`
- // Parameters controlling how the test target and the test environment are prepared.
- PreprationParams *PreparationParams `protobuf:"bytes,3,opt,name=prepration_params,json=preprationParams,proto3" json:"prepration_params,omitempty"`
- // The test command to run. The test binary should be in the input artifacts.
- TestCommand string `protobuf:"bytes,4,opt,name=test_command,json=testCommand,proto3" json:"test_command,omitempty"`
- // Test targeting metadata used to select devices/emulators to run on.
- // These will be discussed more comprehensively later.
+ CipdPackages []*CipdPackage `protobuf:"bytes,2,rep,name=cipd_packages,json=cipdPackages,proto3" json:"cipd_packages,omitempty"`
+ // Dimensions to select which swarming bots to target.
TargetDimensions map[string]string `protobuf:"bytes,5,rep,name=target_dimensions,json=targetDimensions,proto3" json:"target_dimensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ // Test execution details.
+ Test *GenericTest `protobuf:"bytes,8,opt,name=test,proto3" json:"test,omitempty"`
}
func (x *InputProperties) Reset() {
@@ -96,27 +93,13 @@
return ""
}
-func (x *InputProperties) GetCipdPackages() []*CIPDPackage {
+func (x *InputProperties) GetCipdPackages() []*CipdPackage {
if x != nil {
return x.CipdPackages
}
return nil
}
-func (x *InputProperties) GetPreprationParams() *PreparationParams {
- if x != nil {
- return x.PreprationParams
- }
- return nil
-}
-
-func (x *InputProperties) GetTestCommand() string {
- if x != nil {
- return x.TestCommand
- }
- return ""
-}
-
func (x *InputProperties) GetTargetDimensions() map[string]string {
if x != nil {
return x.TargetDimensions
@@ -124,17 +107,26 @@
return nil
}
-type CIPDPackage struct {
+func (x *InputProperties) GetTest() *GenericTest {
+ if x != nil {
+ return x.Test
+ }
+ return nil
+}
+
+type HostTest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
- Tag string `protobuf:"bytes,2,opt,name=tag,proto3" json:"tag,omitempty"`
+ // Command.
+ Command []string `protobuf:"bytes,1,rep,name=command,proto3" json:"command,omitempty"`
+ // System environment variables.
+ Env map[string]string `protobuf:"bytes,2,rep,name=env,proto3" json:"env,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
-func (x *CIPDPackage) Reset() {
- *x = CIPDPackage{}
+func (x *HostTest) Reset() {
+ *x = HostTest{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_input_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -142,13 +134,13 @@
}
}
-func (x *CIPDPackage) String() string {
+func (x *HostTest) String() string {
return protoimpl.X.MessageStringOf(x)
}
-func (*CIPDPackage) ProtoMessage() {}
+func (*HostTest) ProtoMessage() {}
-func (x *CIPDPackage) ProtoReflect() protoreflect.Message {
+func (x *HostTest) ProtoReflect() protoreflect.Message {
mi := &file_proto_input_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -160,39 +152,38 @@
return mi.MessageOf(x)
}
-// Deprecated: Use CIPDPackage.ProtoReflect.Descriptor instead.
-func (*CIPDPackage) Descriptor() ([]byte, []int) {
+// Deprecated: Use HostTest.ProtoReflect.Descriptor instead.
+func (*HostTest) Descriptor() ([]byte, []int) {
return file_proto_input_proto_rawDescGZIP(), []int{1}
}
-func (x *CIPDPackage) GetPath() string {
+func (x *HostTest) GetCommand() []string {
if x != nil {
- return x.Path
+ return x.Command
}
- return ""
+ return nil
}
-func (x *CIPDPackage) GetTag() string {
+func (x *HostTest) GetEnv() map[string]string {
if x != nil {
- return x.Tag
+ return x.Env
}
- return ""
+ return nil
}
-type PreparationParams struct {
+type GenericTest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
- Flash bool `protobuf:"varint,1,opt,name=flash,proto3" json:"flash,omitempty"`
- Pave bool `protobuf:"varint,2,opt,name=pave,proto3" json:"pave,omitempty"`
- Ramboot bool `protobuf:"varint,3,opt,name=ramboot,proto3" json:"ramboot,omitempty"`
- RunPackageServer bool `protobuf:"varint,4,opt,name=run_package_server,json=runPackageServer,proto3" json:"run_package_server,omitempty"`
- CaptureLogs bool `protobuf:"varint,5,opt,name=capture_logs,json=captureLogs,proto3" json:"capture_logs,omitempty"`
+ // Types that are assignable to Kind:
+ //
+ // *GenericTest_Host
+ Kind isGenericTest_Kind `protobuf_oneof:"kind"`
}
-func (x *PreparationParams) Reset() {
- *x = PreparationParams{}
+func (x *GenericTest) Reset() {
+ *x = GenericTest{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_input_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -200,13 +191,13 @@
}
}
-func (x *PreparationParams) String() string {
+func (x *GenericTest) String() string {
return protoimpl.X.MessageStringOf(x)
}
-func (*PreparationParams) ProtoMessage() {}
+func (*GenericTest) ProtoMessage() {}
-func (x *PreparationParams) ProtoReflect() protoreflect.Message {
+func (x *GenericTest) ProtoReflect() protoreflect.Message {
mi := &file_proto_input_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@@ -218,51 +209,107 @@
return mi.MessageOf(x)
}
-// Deprecated: Use PreparationParams.ProtoReflect.Descriptor instead.
-func (*PreparationParams) Descriptor() ([]byte, []int) {
+// Deprecated: Use GenericTest.ProtoReflect.Descriptor instead.
+func (*GenericTest) Descriptor() ([]byte, []int) {
return file_proto_input_proto_rawDescGZIP(), []int{2}
}
-func (x *PreparationParams) GetFlash() bool {
- if x != nil {
- return x.Flash
+func (m *GenericTest) GetKind() isGenericTest_Kind {
+ if m != nil {
+ return m.Kind
}
- return false
+ return nil
}
-func (x *PreparationParams) GetPave() bool {
- if x != nil {
- return x.Pave
+func (x *GenericTest) GetHost() *HostTest {
+ if x, ok := x.GetKind().(*GenericTest_Host); ok {
+ return x.Host
}
- return false
+ return nil
}
-func (x *PreparationParams) GetRamboot() bool {
- if x != nil {
- return x.Ramboot
- }
- return false
+type isGenericTest_Kind interface {
+ isGenericTest_Kind()
}
-func (x *PreparationParams) GetRunPackageServer() bool {
- if x != nil {
- return x.RunPackageServer
- }
- return false
+type GenericTest_Host struct {
+ // Runs arbitrary binaries directly on the host environment.
+ Host *HostTest `protobuf:"bytes,1,opt,name=host,proto3,oneof"`
}
-func (x *PreparationParams) GetCaptureLogs() bool {
- if x != nil {
- return x.CaptureLogs
+func (*GenericTest_Host) isGenericTest_Kind() {}
+
+type CipdPackage struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Name of the cipd package, i.e. fuchsia/sdk/core/${platform}
+ Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
+ // Version of the cipd package to install, i.e. latest
+ Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
+ // Path to install cipd package to, i.e. sdk
+ Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
+}
+
+func (x *CipdPackage) Reset() {
+ *x = CipdPackage{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_proto_input_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
}
- return false
+}
+
+func (x *CipdPackage) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CipdPackage) ProtoMessage() {}
+
+func (x *CipdPackage) ProtoReflect() protoreflect.Message {
+ mi := &file_proto_input_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use CipdPackage.ProtoReflect.Descriptor instead.
+func (*CipdPackage) Descriptor() ([]byte, []int) {
+ return file_proto_input_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *CipdPackage) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+func (x *CipdPackage) GetVersion() string {
+ if x != nil {
+ return x.Version
+ }
+ return ""
+}
+
+func (x *CipdPackage) GetPath() string {
+ if x != nil {
+ return x.Path
+ }
+ return ""
}
var File_proto_input_proto protoreflect.FileDescriptor
var file_proto_input_proto_rawDesc = []byte{
0x0a, 0x11, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x70, 0x72,
- 0x6f, 0x74, 0x6f, 0x22, 0xa8, 0x03, 0x0a, 0x0f, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x50, 0x72, 0x6f,
+ 0x6f, 0x74, 0x6f, 0x22, 0xe6, 0x02, 0x0a, 0x0f, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x50, 0x72, 0x6f,
0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x65,
0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x65,
@@ -271,41 +318,40 @@
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x41, 0x72,
0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a,
0x0d, 0x63, 0x69, 0x70, 0x64, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02,
- 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x43, 0x49, 0x50, 0x44, 0x50, 0x61, 0x63, 0x6b, 0x61,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x43, 0x69, 0x70, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61,
0x67, 0x65, 0x52, 0x0c, 0x63, 0x69, 0x70, 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73,
- 0x12, 0x3f, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x70, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70,
- 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x50, 0x72,
- 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52,
- 0x10, 0x70, 0x72, 0x65, 0x70, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d,
- 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
- 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x43, 0x6f, 0x6d,
- 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x53, 0x0a, 0x11, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x64,
- 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32,
- 0x26, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65,
- 0x73, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f,
- 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44,
- 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x43, 0x0a, 0x15, 0x54, 0x61, 0x72,
- 0x67, 0x65, 0x74, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74,
- 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x33,
- 0x0a, 0x0b, 0x43, 0x49, 0x50, 0x44, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a,
- 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74,
- 0x68, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
- 0x74, 0x61, 0x67, 0x22, 0xa8, 0x01, 0x0a, 0x11, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61,
- 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x12,
- 0x12, 0x0a, 0x04, 0x70, 0x61, 0x76, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x70,
- 0x61, 0x76, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x61, 0x6d, 0x62, 0x6f, 0x6f, 0x74, 0x18, 0x03,
- 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x61, 0x6d, 0x62, 0x6f, 0x6f, 0x74, 0x12, 0x2c, 0x0a,
- 0x12, 0x72, 0x75, 0x6e, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x65, 0x72,
- 0x76, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x72, 0x75, 0x6e, 0x50, 0x61,
- 0x63, 0x6b, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x63,
- 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28,
- 0x08, 0x52, 0x0b, 0x63, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x42, 0x28,
- 0x5a, 0x26, 0x67, 0x6f, 0x2e, 0x66, 0x75, 0x63, 0x68, 0x73, 0x69, 0x61, 0x2e, 0x64, 0x65, 0x76,
- 0x2f, 0x69, 0x6e, 0x66, 0x72, 0x61, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x66, 0x74, 0x78, 0x74, 0x65,
- 0x73, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x12, 0x53, 0x0a, 0x11, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x6d, 0x65, 0x6e,
+ 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x49, 0x6e,
+ 0x70, 0x75, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x2e, 0x54, 0x61,
+ 0x72, 0x67, 0x65, 0x74, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e,
+ 0x74, 0x72, 0x79, 0x52, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x44, 0x69, 0x6d, 0x65, 0x6e,
+ 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, 0x0a, 0x04, 0x74, 0x65, 0x73, 0x74, 0x18, 0x08, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x54, 0x65, 0x73,
+ 0x74, 0x52, 0x04, 0x74, 0x65, 0x73, 0x74, 0x1a, 0x43, 0x0a, 0x15, 0x54, 0x61, 0x72, 0x67, 0x65,
+ 0x74, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
+ 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
+ 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x82, 0x01, 0x0a,
+ 0x08, 0x48, 0x6f, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d,
+ 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d,
+ 0x61, 0x6e, 0x64, 0x12, 0x24, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x12, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x6e, 0x76, 0x45,
+ 0x6e, 0x74, 0x72, 0x79, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x1a, 0x36, 0x0a, 0x08, 0x45, 0x6e, 0x76,
+ 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
+ 0x01, 0x22, 0x36, 0x0a, 0x0b, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x54, 0x65, 0x73, 0x74,
+ 0x12, 0x1f, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09,
+ 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x68, 0x6f, 0x73,
+ 0x74, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0x4f, 0x0a, 0x0b, 0x43, 0x69, 0x70,
+ 0x64, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07,
+ 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76,
+ 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x42, 0x28, 0x5a, 0x26, 0x67, 0x6f,
+ 0x2e, 0x66, 0x75, 0x63, 0x68, 0x73, 0x69, 0x61, 0x2e, 0x64, 0x65, 0x76, 0x2f, 0x69, 0x6e, 0x66,
+ 0x72, 0x61, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x66, 0x74, 0x78, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -320,22 +366,26 @@
return file_proto_input_proto_rawDescData
}
-var file_proto_input_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_proto_input_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_proto_input_proto_goTypes = []interface{}{
- (*InputProperties)(nil), // 0: InputProperties
- (*CIPDPackage)(nil), // 1: CIPDPackage
- (*PreparationParams)(nil), // 2: PreparationParams
- nil, // 3: InputProperties.TargetDimensionsEntry
+ (*InputProperties)(nil), // 0: InputProperties
+ (*HostTest)(nil), // 1: HostTest
+ (*GenericTest)(nil), // 2: GenericTest
+ (*CipdPackage)(nil), // 3: CipdPackage
+ nil, // 4: InputProperties.TargetDimensionsEntry
+ nil, // 5: HostTest.EnvEntry
}
var file_proto_input_proto_depIdxs = []int32{
- 1, // 0: InputProperties.cipd_packages:type_name -> CIPDPackage
- 2, // 1: InputProperties.prepration_params:type_name -> PreparationParams
- 3, // 2: InputProperties.target_dimensions:type_name -> InputProperties.TargetDimensionsEntry
- 3, // [3:3] is the sub-list for method output_type
- 3, // [3:3] is the sub-list for method input_type
- 3, // [3:3] is the sub-list for extension type_name
- 3, // [3:3] is the sub-list for extension extendee
- 0, // [0:3] is the sub-list for field type_name
+ 3, // 0: InputProperties.cipd_packages:type_name -> CipdPackage
+ 4, // 1: InputProperties.target_dimensions:type_name -> InputProperties.TargetDimensionsEntry
+ 2, // 2: InputProperties.test:type_name -> GenericTest
+ 5, // 3: HostTest.env:type_name -> HostTest.EnvEntry
+ 1, // 4: GenericTest.host:type_name -> HostTest
+ 5, // [5:5] is the sub-list for method output_type
+ 5, // [5:5] is the sub-list for method input_type
+ 5, // [5:5] is the sub-list for extension type_name
+ 5, // [5:5] is the sub-list for extension extendee
+ 0, // [0:5] is the sub-list for field type_name
}
func init() { file_proto_input_proto_init() }
@@ -357,7 +407,7 @@
}
}
file_proto_input_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*CIPDPackage); i {
+ switch v := v.(*HostTest); i {
case 0:
return &v.state
case 1:
@@ -369,7 +419,19 @@
}
}
file_proto_input_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
- switch v := v.(*PreparationParams); i {
+ switch v := v.(*GenericTest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_proto_input_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CipdPackage); i {
case 0:
return &v.state
case 1:
@@ -381,13 +443,16 @@
}
}
}
+ file_proto_input_proto_msgTypes[2].OneofWrappers = []interface{}{
+ (*GenericTest_Host)(nil),
+ }
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_input_proto_rawDesc,
NumEnums: 0,
- NumMessages: 4,
+ NumMessages: 6,
NumExtensions: 0,
NumServices: 0,
},
diff --git a/cmd/ftxtest/proto/input.proto b/cmd/ftxtest/proto/input.proto
index 076ccf8..4e5da9d 100644
--- a/cmd/ftxtest/proto/input.proto
+++ b/cmd/ftxtest/proto/input.proto
@@ -11,25 +11,32 @@
// and run tests.
string input_artifacts_digest = 1;
// Any CIPD packages needed to run the test task.
- repeated CIPDPackage cipd_packages = 2;
- // Parameters controlling how the test target and the test environment are prepared.
- PreparationParams prepration_params = 3;
- // The test command to run. The test binary should be in the input artifacts.
- string test_command = 4;
- // Test targeting metadata used to select devices/emulators to run on.
- // These will be discussed more comprehensively later.
+ repeated CipdPackage cipd_packages = 2;
+ // Dimensions to select which swarming bots to target.
map<string, string> target_dimensions = 5;
+ // Test execution details.
+ GenericTest test = 8;
}
-message CIPDPackage {
+message HostTest {
+ // Command.
+ repeated string command = 1;
+ // System environment variables.
+ map<string, string> env = 2;
+}
+
+message GenericTest {
+ oneof kind {
+ // Runs arbitrary binaries directly on the host environment.
+ HostTest host = 1;
+ }
+}
+
+message CipdPackage {
+ // Name of the cipd package, i.e. fuchsia/sdk/core/${platform}
+ string name = 3;
+ // Version of the cipd package to install, i.e. latest
+ string version = 2;
+ // Path to install cipd package to, i.e. sdk
string path = 1;
- string tag = 2;
-}
-
-message PreparationParams {
- bool flash = 1;
- bool pave = 2;
- bool ramboot = 3;
- bool run_package_server = 4;
- bool capture_logs = 5;
-}
+}
\ No newline at end of file
diff --git a/cmd/ftxtest/run.go b/cmd/ftxtest/run.go
index c0a8589..e08fedc 100644
--- a/cmd/ftxtest/run.go
+++ b/cmd/ftxtest/run.go
@@ -7,7 +7,6 @@
"context"
"errors"
"fmt"
- "net/http"
"os"
"strings"
@@ -55,41 +54,66 @@
buildInput := &ftxproto.InputProperties{}
var writeOutputProps func(*any.Any)
build.Main(buildInput, &writeOutputProps, nil, func(ctx context.Context, extraArgs []string, state *build.State) error {
- if len(buildInput.Name) == 0 {
- return errors.New("Name is required.")
- }
- authenticator := auth.NewAuthenticator(ctx, auth.SilentLogin, r.parsedAuthOpts)
- httpClient, err := authenticator.Client()
+ swarming, err := r.authenticateStep(ctx, buildInput)
if err != nil {
- fmt.Fprintf(os.Stderr, "You need to login first by running:\n")
- fmt.Fprintf(os.Stderr, " luci-auth login -scopes %q\n", strings.Join(r.parsedAuthOpts.Scopes, " "))
- return errors.New("Not logged in.")
+ return fmt.Errorf("authenticateStep: %v", err)
}
- _, _, err = LaunchTaskStep(ctx, httpClient, buildInput)
+ taskId, err := r.launchTaskStep(ctx, swarming, buildInput)
if err != nil {
- return fmt.Errorf("LaunchTaskStep: %v", err)
+ return fmt.Errorf("launchTaskStep: %v", err)
+ }
+ if err := r.waitTaskStep(ctx, swarming, taskId); err != nil {
+ return fmt.Errorf("waitTaskStep: %v", err)
}
return nil
})
}
-func LaunchTaskStep(ctx context.Context, httpClient *http.Client, buildInput *ftxproto.InputProperties) (*Swarming, string, error) {
- step, ctx := build.StartStep(ctx, "Launch Swarming Task")
+func (r *runImpl) authenticateStep(ctx context.Context, buildInput *ftxproto.InputProperties) (*Swarming, error) {
+ step, ctx := build.StartStep(ctx, "Authenticate")
+ authenticator := auth.NewAuthenticator(ctx, auth.SilentLogin, r.parsedAuthOpts)
+ httpClient, err := authenticator.Client()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "You need to login first by running:\n")
+ fmt.Fprintf(os.Stderr, " luci-auth login -scopes %q\n", strings.Join(r.parsedAuthOpts.Scopes, " "))
+ return nil, errors.New("Not logged in.")
+ }
instance := instance(buildInput)
swarming, err := NewSwarming(ctx, httpClient, instance)
if err != nil {
step.End(err)
- return nil, "", fmt.Errorf("NewSwarming: %v", err)
+ return nil, fmt.Errorf("NewSwarming: %v", err)
+ }
+ step.End(nil)
+ return swarming, nil
+}
+
+func (r *runImpl) launchTaskStep(ctx context.Context, swarming *Swarming, buildInput *ftxproto.InputProperties) (string, error) {
+ step, ctx := build.StartStep(ctx, "Launch Swarming Task")
+ if len(buildInput.Name) == 0 {
+ err := errors.New("Name is required.")
+ step.End(err)
+ return "", err
}
task, err := swarming.LaunchTask(buildInput)
if err != nil {
step.End(err)
- return nil, "", fmt.Errorf("LaunchTask: %v", err)
+ return "", fmt.Errorf("LaunchTask: %v", err)
}
- md := fmt.Sprintf("* [swarming task](https://%s.appspot.com/task?id=%s)", instance, task.TaskId)
+ md := fmt.Sprintf("* [swarming task](https://%s.appspot.com/task?id=%s)", instance(buildInput), task.TaskId)
step.SetSummaryMarkdown(md)
step.End(nil)
- return swarming, task.TaskId, nil
+ return task.TaskId, nil
+}
+
+func (r *runImpl) waitTaskStep(ctx context.Context, swarming *Swarming, taskId string) error {
+ step, ctx := build.StartStep(ctx, "Wait Task Completion")
+ if err := swarming.WaitTask(taskId); err != nil {
+ step.End(err)
+ return err
+ }
+ step.End(nil)
+ return nil
}
func instance(buildInput *ftxproto.InputProperties) string {
diff --git a/cmd/ftxtest/swarming.go b/cmd/ftxtest/swarming.go
index 0f4f61c..8197945 100644
--- a/cmd/ftxtest/swarming.go
+++ b/cmd/ftxtest/swarming.go
@@ -5,6 +5,7 @@
import (
"context"
+ "errors"
"fmt"
"net/http"
"strconv"
@@ -24,6 +25,7 @@
taskPriority = 200
taskExpiration = 5 * time.Hour
taskExecutionTimeout = 2 * time.Hour
+ poolTaskInterval = 10 * time.Second
)
func NewSwarming(ctx context.Context, httpClient *http.Client, instance string) (*Swarming, error) {
@@ -44,6 +46,7 @@
if err != nil {
return nil, fmt.Errorf("casInput: %v", err)
}
+ hostTest := buildInput.Test.GetHost()
return s.service.Tasks.New(&swarming.SwarmingRpcsNewTaskRequest{
Name: buildInput.Name,
ExpirationSecs: int64(taskExpiration.Seconds()),
@@ -51,13 +54,34 @@
Realm: realm(buildInput),
Properties: &swarming.SwarmingRpcsTaskProperties{
ExecutionTimeoutSecs: int64(taskExpiration.Seconds()),
- Command: []string{buildInput.TestCommand},
+ Command: hostTest.Command,
CasInputRoot: casInput,
- Dimensions: dimensions(buildInput),
+ CipdInput: cipdInput(buildInput.CipdPackages),
+ Dimensions: swarmmingStringPair(buildInput.TargetDimensions),
+ Env: swarmmingStringPair(hostTest.Env),
},
}).Do()
}
+func (s *Swarming) WaitTask(taskId string) error {
+ for {
+ result, err := s.service.Task.Result(taskId).Fields("state", "failure", "internal_failure").Do()
+ if err != nil {
+ err = fmt.Errorf("swarming.Task.Result RPC failed: %v", err)
+ return err
+ }
+ if result.Failure || result.InternalFailure {
+ err = errors.New("Swarming task failed")
+ return err
+ }
+ if result.State == "PENDING" || result.State == "RUNNING" {
+ time.Sleep(poolTaskInterval)
+ continue
+ }
+ return nil
+ }
+}
+
func (s *Swarming) casInput(buildInput *ftxproto.InputProperties) (*swarming.SwarmingRpcsCASReference, error) {
digestSplit := strings.Split(buildInput.InputArtifactsDigest, "/")
sizeBytes, err := strconv.ParseInt(digestSplit[1], 10, 64)
@@ -73,9 +97,23 @@
}, nil
}
-func dimensions(buildInput *ftxproto.InputProperties) []*swarming.SwarmingRpcsStringPair {
+func cipdInput(cipdPackages []*ftxproto.CipdPackage) *swarming.SwarmingRpcsCipdInput {
+ packages := []*swarming.SwarmingRpcsCipdPackage{}
+ for _, inputPkg := range cipdPackages {
+ packages = append(packages, &swarming.SwarmingRpcsCipdPackage{
+ Path: inputPkg.Path,
+ Version: inputPkg.Version,
+ PackageName: inputPkg.Name,
+ })
+ }
+ return &swarming.SwarmingRpcsCipdInput{
+ Packages: packages,
+ }
+}
+
+func swarmmingStringPair(m map[string]string) []*swarming.SwarmingRpcsStringPair {
result := []*swarming.SwarmingRpcsStringPair{}
- for key, value := range buildInput.TargetDimensions {
+ for key, value := range m {
result = append(result, &swarming.SwarmingRpcsStringPair{
Key: key,
Value: value,
diff --git a/cmd/ftxtest/test/build.json b/cmd/ftxtest/test/build.json
index a3dff20..f97c529 100644
--- a/cmd/ftxtest/test/build.json
+++ b/cmd/ftxtest/test/build.json
@@ -3,10 +3,24 @@
"properties": {
"name": "hello_swarming_test",
"external": false,
- "input_artifacts_digest": "11ab3e1a0ba7bc9fbd6957c57222331f340dc981ec2bcb5edeffc05014e7a2ba/83",
- "test_command": "turquoise/infra/foundation/go/ftxclient/examples/hello_swarming/hello_swarming.par",
+ "input_artifacts_digest": "19a21c55f6790bc5e07f9e6c3be64dfd19fa696feaed629c6a9a8e15e5e469cb/83",
"target_dimensions": {
"pool": "fuchsia.dev.tests"
+ },
+ "cipd_packages": [
+ {
+ "name": "fuchsia/sdk/core/${platform}",
+ "path": "sdk",
+ "version": "git_revision:667a4d316e06b8ec073085c1af0596aeb23b4544"
+ }
+ ],
+ "test": {
+ "host": {
+ "command": ["turquoise/infra/foundation/go/ftxclient/examples/hello_swarming/hello_swarming"],
+ "env": {
+ "foo": "bar"
+ }
+ }
}
}
}