// Code generated by protoc-gen-go. DO NOT EDIT.
// source: test_platform/skylab_test_runner/config.proto

package skylab_test_runner

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	phosphorus "go.chromium.org/chromiumos/infra/proto/go/test_platform/phosphorus"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

// Config defines configuration parameters of skylab_test_runner.
type Config struct {
	Lab     *Config_Lab     `protobuf:"bytes,1,opt,name=lab,proto3" json:"lab,omitempty"`
	Harness *Config_Harness `protobuf:"bytes,2,opt,name=harness,proto3" json:"harness,omitempty"`
	Output  *Config_Output  `protobuf:"bytes,3,opt,name=output,proto3" json:"output,omitempty"`
	// Result flow topic: test_runner publishes messages to this topic at the
	// start and the end of the build.
	// The messages in this topic should be ACKed only by the result_flow
	// pipeline.
	ResultFlowPubsub     *Config_PubSub                `protobuf:"bytes,4,opt,name=result_flow_pubsub,json=resultFlowPubsub,proto3" json:"result_flow_pubsub,omitempty"`
	LogDataUploadStep    *phosphorus.LogDataUploadStep `protobuf:"bytes,5,opt,name=log_data_upload_step,json=logDataUploadStep,proto3" json:"log_data_upload_step,omitempty"`
	FetchCrashesStep     *phosphorus.FetchCrashesStep  `protobuf:"bytes,6,opt,name=fetch_crashes_step,json=fetchCrashesStep,proto3" json:"fetch_crashes_step,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                      `json:"-"`
	XXX_unrecognized     []byte                        `json:"-"`
	XXX_sizecache        int32                         `json:"-"`
}

func (m *Config) Reset()         { *m = Config{} }
func (m *Config) String() string { return proto.CompactTextString(m) }
func (*Config) ProtoMessage()    {}
func (*Config) Descriptor() ([]byte, []int) {
	return fileDescriptor_b2c5f9be4f684081, []int{0}
}

func (m *Config) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_Config.Unmarshal(m, b)
}
func (m *Config) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_Config.Marshal(b, m, deterministic)
}
func (m *Config) XXX_Merge(src proto.Message) {
	xxx_messageInfo_Config.Merge(m, src)
}
func (m *Config) XXX_Size() int {
	return xxx_messageInfo_Config.Size(m)
}
func (m *Config) XXX_DiscardUnknown() {
	xxx_messageInfo_Config.DiscardUnknown(m)
}

var xxx_messageInfo_Config proto.InternalMessageInfo

func (m *Config) GetLab() *Config_Lab {
	if m != nil {
		return m.Lab
	}
	return nil
}

func (m *Config) GetHarness() *Config_Harness {
	if m != nil {
		return m.Harness
	}
	return nil
}

func (m *Config) GetOutput() *Config_Output {
	if m != nil {
		return m.Output
	}
	return nil
}

func (m *Config) GetResultFlowPubsub() *Config_PubSub {
	if m != nil {
		return m.ResultFlowPubsub
	}
	return nil
}

func (m *Config) GetLogDataUploadStep() *phosphorus.LogDataUploadStep {
	if m != nil {
		return m.LogDataUploadStep
	}
	return nil
}

func (m *Config) GetFetchCrashesStep() *phosphorus.FetchCrashesStep {
	if m != nil {
		return m.FetchCrashesStep
	}
	return nil
}

// Lab defines configuration parameters related to the lab and the lab
// platform services.
type Config_Lab struct {
	// Admin service host, e.g. foo.appspot.com.
	AdminService string `protobuf:"bytes,1,opt,name=admin_service,json=adminService,proto3" json:"admin_service,omitempty"`
	// Inventory V2 service host, e.g. cros-lab-inventory.appspot.com.
	CrosInventoryService string `protobuf:"bytes,2,opt,name=cros_inventory_service,json=crosInventoryService,proto3" json:"cros_inventory_service,omitempty"`
	// Unified Fleet System service host, e.g. ufs.api.cr.dev.
	CrosUfsService       string   `protobuf:"bytes,3,opt,name=cros_ufs_service,json=crosUfsService,proto3" json:"cros_ufs_service,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *Config_Lab) Reset()         { *m = Config_Lab{} }
func (m *Config_Lab) String() string { return proto.CompactTextString(m) }
func (*Config_Lab) ProtoMessage()    {}
func (*Config_Lab) Descriptor() ([]byte, []int) {
	return fileDescriptor_b2c5f9be4f684081, []int{0, 0}
}

func (m *Config_Lab) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_Config_Lab.Unmarshal(m, b)
}
func (m *Config_Lab) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_Config_Lab.Marshal(b, m, deterministic)
}
func (m *Config_Lab) XXX_Merge(src proto.Message) {
	xxx_messageInfo_Config_Lab.Merge(m, src)
}
func (m *Config_Lab) XXX_Size() int {
	return xxx_messageInfo_Config_Lab.Size(m)
}
func (m *Config_Lab) XXX_DiscardUnknown() {
	xxx_messageInfo_Config_Lab.DiscardUnknown(m)
}

var xxx_messageInfo_Config_Lab proto.InternalMessageInfo

func (m *Config_Lab) GetAdminService() string {
	if m != nil {
		return m.AdminService
	}
	return ""
}

func (m *Config_Lab) GetCrosInventoryService() string {
	if m != nil {
		return m.CrosInventoryService
	}
	return ""
}

func (m *Config_Lab) GetCrosUfsService() string {
	if m != nil {
		return m.CrosUfsService
	}
	return ""
}

// Harness defines configuration parameters related to the test harness
// (autotest, tast, etc).
type Config_Harness struct {
	// Autotest directory inside the drone container,
	// e.g. "/usr/local/autotest".
	AutotestDir string `protobuf:"bytes,1,opt,name=autotest_dir,json=autotestDir,proto3" json:"autotest_dir,omitempty"`
	// The name of the base lxc image used for Server Side Packaging (SSP).
	//
	// autoserv fetches the base image from a hard-coded path on Google
	// Storage: gs://abci-ssp/autotest-containers/{name}.tar.xz
	//
	// See go/ctp-ssp for an overview of SSP.
	SspBaseImageName string `protobuf:"bytes,3,opt,name=ssp_base_image_name,json=sspBaseImageName,proto3" json:"ssp_base_image_name,omitempty"`
	// The maximum duration for prejobs (e.g. provisioning).
	PrejobDeadlineSeconds int64    `protobuf:"varint,4,opt,name=prejob_deadline_seconds,json=prejobDeadlineSeconds,proto3" json:"prejob_deadline_seconds,omitempty"`
	XXX_NoUnkeyedLiteral  struct{} `json:"-"`
	XXX_unrecognized      []byte   `json:"-"`
	XXX_sizecache         int32    `json:"-"`
}

func (m *Config_Harness) Reset()         { *m = Config_Harness{} }
func (m *Config_Harness) String() string { return proto.CompactTextString(m) }
func (*Config_Harness) ProtoMessage()    {}
func (*Config_Harness) Descriptor() ([]byte, []int) {
	return fileDescriptor_b2c5f9be4f684081, []int{0, 1}
}

func (m *Config_Harness) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_Config_Harness.Unmarshal(m, b)
}
func (m *Config_Harness) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_Config_Harness.Marshal(b, m, deterministic)
}
func (m *Config_Harness) XXX_Merge(src proto.Message) {
	xxx_messageInfo_Config_Harness.Merge(m, src)
}
func (m *Config_Harness) XXX_Size() int {
	return xxx_messageInfo_Config_Harness.Size(m)
}
func (m *Config_Harness) XXX_DiscardUnknown() {
	xxx_messageInfo_Config_Harness.DiscardUnknown(m)
}

var xxx_messageInfo_Config_Harness proto.InternalMessageInfo

func (m *Config_Harness) GetAutotestDir() string {
	if m != nil {
		return m.AutotestDir
	}
	return ""
}

func (m *Config_Harness) GetSspBaseImageName() string {
	if m != nil {
		return m.SspBaseImageName
	}
	return ""
}

func (m *Config_Harness) GetPrejobDeadlineSeconds() int64 {
	if m != nil {
		return m.PrejobDeadlineSeconds
	}
	return 0
}

// Output defines parameters around how the task will deliver output to
// the callers, e.g. Google Storage bucket.
type Config_Output struct {
	// A Google Storage path prefix to upload all log-data to synchronously.
	// Reflected in the test_platform.skylab_test_runner.Result.log_data
	// returned by the task.
	LogDataGsRoot        string   `protobuf:"bytes,2,opt,name=log_data_gs_root,json=logDataGsRoot,proto3" json:"log_data_gs_root,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *Config_Output) Reset()         { *m = Config_Output{} }
func (m *Config_Output) String() string { return proto.CompactTextString(m) }
func (*Config_Output) ProtoMessage()    {}
func (*Config_Output) Descriptor() ([]byte, []int) {
	return fileDescriptor_b2c5f9be4f684081, []int{0, 2}
}

func (m *Config_Output) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_Config_Output.Unmarshal(m, b)
}
func (m *Config_Output) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_Config_Output.Marshal(b, m, deterministic)
}
func (m *Config_Output) XXX_Merge(src proto.Message) {
	xxx_messageInfo_Config_Output.Merge(m, src)
}
func (m *Config_Output) XXX_Size() int {
	return xxx_messageInfo_Config_Output.Size(m)
}
func (m *Config_Output) XXX_DiscardUnknown() {
	xxx_messageInfo_Config_Output.DiscardUnknown(m)
}

var xxx_messageInfo_Config_Output proto.InternalMessageInfo

func (m *Config_Output) GetLogDataGsRoot() string {
	if m != nil {
		return m.LogDataGsRoot
	}
	return ""
}

// PubSub defines the configuration parameters for PubSub topic.
type Config_PubSub struct {
	Project              string   `protobuf:"bytes,1,opt,name=project,proto3" json:"project,omitempty"`
	Topic                string   `protobuf:"bytes,2,opt,name=topic,proto3" json:"topic,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *Config_PubSub) Reset()         { *m = Config_PubSub{} }
func (m *Config_PubSub) String() string { return proto.CompactTextString(m) }
func (*Config_PubSub) ProtoMessage()    {}
func (*Config_PubSub) Descriptor() ([]byte, []int) {
	return fileDescriptor_b2c5f9be4f684081, []int{0, 3}
}

func (m *Config_PubSub) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_Config_PubSub.Unmarshal(m, b)
}
func (m *Config_PubSub) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_Config_PubSub.Marshal(b, m, deterministic)
}
func (m *Config_PubSub) XXX_Merge(src proto.Message) {
	xxx_messageInfo_Config_PubSub.Merge(m, src)
}
func (m *Config_PubSub) XXX_Size() int {
	return xxx_messageInfo_Config_PubSub.Size(m)
}
func (m *Config_PubSub) XXX_DiscardUnknown() {
	xxx_messageInfo_Config_PubSub.DiscardUnknown(m)
}

var xxx_messageInfo_Config_PubSub proto.InternalMessageInfo

func (m *Config_PubSub) GetProject() string {
	if m != nil {
		return m.Project
	}
	return ""
}

func (m *Config_PubSub) GetTopic() string {
	if m != nil {
		return m.Topic
	}
	return ""
}

func init() {
	proto.RegisterType((*Config)(nil), "test_platform.skylab_test_runner.Config")
	proto.RegisterType((*Config_Lab)(nil), "test_platform.skylab_test_runner.Config.Lab")
	proto.RegisterType((*Config_Harness)(nil), "test_platform.skylab_test_runner.Config.Harness")
	proto.RegisterType((*Config_Output)(nil), "test_platform.skylab_test_runner.Config.Output")
	proto.RegisterType((*Config_PubSub)(nil), "test_platform.skylab_test_runner.Config.PubSub")
}

func init() {
	proto.RegisterFile("test_platform/skylab_test_runner/config.proto", fileDescriptor_b2c5f9be4f684081)
}

var fileDescriptor_b2c5f9be4f684081 = []byte{
	// 582 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0xdf, 0x6e, 0xd3, 0x30,
	0x14, 0xc6, 0xd5, 0x76, 0x6b, 0x87, 0xb7, 0xa1, 0x62, 0x0a, 0x54, 0xbd, 0x1a, 0x20, 0xc4, 0x04,
	0x2c, 0x41, 0x80, 0x10, 0x57, 0x5c, 0x6c, 0xd5, 0xc6, 0xaa, 0x0a, 0xa6, 0x54, 0x93, 0x10, 0x02,
	0x59, 0x4e, 0xe2, 0xfc, 0x19, 0x89, 0x8f, 0xe5, 0x63, 0x6f, 0xda, 0x2b, 0xf0, 0x32, 0x5c, 0xf0,
	0x82, 0xa8, 0x76, 0x32, 0xb4, 0x21, 0xb4, 0x71, 0xe9, 0xef, 0x7c, 0xdf, 0xcf, 0x39, 0x39, 0x27,
	0x21, 0x3b, 0x46, 0xa0, 0x61, 0xaa, 0xe2, 0x26, 0x03, 0x5d, 0x87, 0xf8, 0xfd, 0xbc, 0xe2, 0x31,
	0x73, 0xa2, 0xb6, 0x52, 0x0a, 0x1d, 0x26, 0x20, 0xb3, 0x32, 0x0f, 0x94, 0x06, 0x03, 0x74, 0xeb,
	0x92, 0x3d, 0xf8, 0xdb, 0x3e, 0x79, 0x72, 0x19, 0xa8, 0x0a, 0x40, 0x55, 0x80, 0xb6, 0x18, 0x26,
	0x50, 0xd7, 0x20, 0x3d, 0xe8, 0xd1, 0xaf, 0x01, 0xe9, 0xef, 0x39, 0x32, 0x7d, 0x4f, 0x7a, 0x15,
	0x8f, 0xc7, 0x9d, 0xad, 0xce, 0xf6, 0xfa, 0xab, 0x17, 0xc1, 0x75, 0x37, 0x04, 0x3e, 0x16, 0xcc,
	0x79, 0x1c, 0x2d, 0x83, 0x74, 0x46, 0x06, 0x05, 0xd7, 0x52, 0x20, 0x8e, 0xbb, 0x8e, 0xf1, 0xf2,
	0xc6, 0x8c, 0x0f, 0x3e, 0x17, 0xb5, 0x00, 0x7a, 0x40, 0xfa, 0x60, 0x8d, 0xb2, 0x66, 0xdc, 0x73,
	0xa8, 0xf0, 0xc6, 0xa8, 0x4f, 0x2e, 0x16, 0x35, 0x71, 0xfa, 0x8d, 0x50, 0x2d, 0xd0, 0x56, 0x86,
	0x65, 0x15, 0x9c, 0x31, 0x65, 0x63, 0xb4, 0xf1, 0x78, 0xe5, 0x3f, 0xa1, 0x47, 0x36, 0x5e, 0xd8,
	0x38, 0x1a, 0x7a, 0xd4, 0x7e, 0x05, 0x67, 0x47, 0x0e, 0x44, 0xbf, 0x92, 0x51, 0x05, 0x39, 0x4b,
	0xb9, 0xe1, 0xcc, 0xaa, 0x0a, 0x78, 0xca, 0xd0, 0x08, 0x35, 0x5e, 0x75, 0x17, 0x3c, 0xbf, 0x72,
	0xc1, 0x9f, 0x21, 0x04, 0x73, 0xc8, 0xa7, 0xdc, 0xf0, 0x63, 0x97, 0x59, 0x18, 0xa1, 0xa2, 0x3b,
	0xd5, 0x55, 0x89, 0x7e, 0x26, 0x34, 0x13, 0x26, 0x29, 0x58, 0xa2, 0x39, 0x16, 0x02, 0x3d, 0xbb,
	0xef, 0xd8, 0xcf, 0xfe, 0xcd, 0xde, 0x5f, 0x66, 0xf6, 0x7c, 0xc4, 0xa1, 0x87, 0xd9, 0x15, 0x65,
	0xf2, 0xa3, 0x43, 0x7a, 0x73, 0x1e, 0xd3, 0xc7, 0x64, 0x93, 0xa7, 0x75, 0x29, 0x19, 0x0a, 0x7d,
	0x5a, 0x26, 0xc2, 0x4d, 0xff, 0x56, 0xb4, 0xe1, 0xc4, 0x85, 0xd7, 0xe8, 0x1b, 0x72, 0x3f, 0xd1,
	0x80, 0xac, 0x94, 0xa7, 0x42, 0x1a, 0xd0, 0xe7, 0x17, 0xee, 0xae, 0x73, 0x8f, 0x96, 0xd5, 0xc3,
	0xb6, 0xd8, 0xa6, 0xb6, 0xc9, 0xd0, 0xa5, 0x6c, 0x86, 0x17, 0xfe, 0x9e, 0xf3, 0xdf, 0x5e, 0xea,
	0xc7, 0x19, 0x36, 0xce, 0xc9, 0xcf, 0x0e, 0x19, 0x34, 0x1b, 0x40, 0x1f, 0x92, 0x0d, 0x6e, 0x0d,
	0xb8, 0xde, 0xd2, 0x52, 0x37, 0xcf, 0xb3, 0xde, 0x6a, 0xd3, 0x52, 0xd3, 0x1d, 0x72, 0x17, 0x51,
	0xb1, 0x98, 0xa3, 0x60, 0x65, 0xcd, 0x73, 0xc1, 0x24, 0xaf, 0x5b, 0xf6, 0x10, 0x51, 0xed, 0x72,
	0x14, 0x87, 0xcb, 0xc2, 0x47, 0x5e, 0x0b, 0xfa, 0x96, 0x3c, 0x50, 0x5a, 0x9c, 0x40, 0xcc, 0x52,
	0xc1, 0xd3, 0xaa, 0x94, 0x82, 0xa1, 0x48, 0x40, 0xa6, 0xe8, 0xd6, 0xa0, 0x17, 0xdd, 0xf3, 0xe5,
	0x69, 0x53, 0x5d, 0xf8, 0xe2, 0x6c, 0x65, 0xad, 0x3b, 0xec, 0x45, 0x23, 0x3c, 0x97, 0x49, 0xc1,
	0x20, 0xcb, 0xfc, 0x70, 0x6d, 0x9c, 0x96, 0x7a, 0x32, 0x25, 0x7d, 0xbf, 0x67, 0xf4, 0x29, 0x19,
	0x5e, 0x2c, 0x40, 0x8e, 0x4c, 0x03, 0x98, 0xe6, 0xad, 0x6c, 0x36, 0xf3, 0x3c, 0xc0, 0x08, 0xc0,
	0xcc, 0x56, 0xd6, 0x3a, 0xc3, 0x6e, 0xb4, 0xde, 0x78, 0x96, 0xbd, 0x4d, 0xde, 0x91, 0xbe, 0x5f,
	0x2c, 0x3a, 0x26, 0x03, 0xa5, 0xe1, 0x44, 0x24, 0xa6, 0x69, 0xb8, 0x3d, 0xd2, 0x11, 0x59, 0x35,
	0xa0, 0xca, 0xa4, 0x81, 0xfa, 0xc3, 0xee, 0xfc, 0xcb, 0x2c, 0x87, 0x20, 0x29, 0x34, 0xd4, 0xa5,
	0xad, 0x03, 0xd0, 0x79, 0xd8, 0x1e, 0x00, 0xc3, 0x52, 0x66, 0x9a, 0x87, 0xee, 0xfb, 0x0e, 0x73,
	0x08, 0xaf, 0xfb, 0xb3, 0xc4, 0x7d, 0x67, 0x7d, 0xfd, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x94, 0xd8,
	0xe2, 0x49, 0x84, 0x04, 0x00, 0x00,
}
