// Code generated by protoc-gen-go. DO NOT EDIT.
// source: chromiumos/dut_tracking.proto

package chromiumos

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	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

// Defines the modes of monitoring to execute on swarming.
type MonitoringMode int32

const (
	MonitoringMode_DEFAULT_TRACKING MonitoringMode = 0
	// Track Task and Bot count.
	MonitoringMode_TASK_BOT_COUNT MonitoringMode = 1
	// Maximum pending time of the tasks.
	MonitoringMode_MAX_PEND_TIME MonitoringMode = 2
	// Success and failure count over a time period.
	MonitoringMode_PASS_FAIL_COUNT MonitoringMode = 3
)

var MonitoringMode_name = map[int32]string{
	0: "DEFAULT_TRACKING",
	1: "TASK_BOT_COUNT",
	2: "MAX_PEND_TIME",
	3: "PASS_FAIL_COUNT",
}

var MonitoringMode_value = map[string]int32{
	"DEFAULT_TRACKING": 0,
	"TASK_BOT_COUNT":   1,
	"MAX_PEND_TIME":    2,
	"PASS_FAIL_COUNT":  3,
}

func (x MonitoringMode) String() string {
	return proto.EnumName(MonitoringMode_name, int32(x))
}

func (MonitoringMode) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_31a1fc16820a6989, []int{0}
}

// Defines a tracking policy for a specific "bot group". This can be used
// to track a DUT, a model, a qs_account or tasks with certain priority.
type TrackingPolicy struct {
	// Bot group being tracked.
	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	// Dimensions to query swarming on.
	// DO NOT use values field here. Only value will be used.
	Dimensions []*SwarmingDimension `protobuf:"bytes,2,rep,name=dimensions,proto3" json:"dimensions,omitempty"`
	// What monitorings to apply on the bot group.
	Modes []MonitoringMode `protobuf:"varint,3,rep,packed,name=modes,proto3,enum=chromiumos.MonitoringMode" json:"modes,omitempty"`
	// Number of hours to lookback for Swarming stats.
	LookbackHours        int32    `protobuf:"zigzag32,4,opt,name=lookback_hours,json=lookbackHours,proto3" json:"lookback_hours,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_TrackingPolicy proto.InternalMessageInfo

func (m *TrackingPolicy) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

func (m *TrackingPolicy) GetDimensions() []*SwarmingDimension {
	if m != nil {
		return m.Dimensions
	}
	return nil
}

func (m *TrackingPolicy) GetModes() []MonitoringMode {
	if m != nil {
		return m.Modes
	}
	return nil
}

func (m *TrackingPolicy) GetLookbackHours() int32 {
	if m != nil {
		return m.LookbackHours
	}
	return 0
}

// Defines a root message.
type TrackingPolicyCfg struct {
	// All tracking policies.
	Policies             []*TrackingPolicy `protobuf:"bytes,1,rep,name=policies,proto3" json:"policies,omitempty"`
	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
	XXX_unrecognized     []byte            `json:"-"`
	XXX_sizecache        int32             `json:"-"`
}

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

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

var xxx_messageInfo_TrackingPolicyCfg proto.InternalMessageInfo

func (m *TrackingPolicyCfg) GetPolicies() []*TrackingPolicy {
	if m != nil {
		return m.Policies
	}
	return nil
}

func init() {
	proto.RegisterEnum("chromiumos.MonitoringMode", MonitoringMode_name, MonitoringMode_value)
	proto.RegisterType((*TrackingPolicy)(nil), "chromiumos.TrackingPolicy")
	proto.RegisterType((*TrackingPolicyCfg)(nil), "chromiumos.TrackingPolicyCfg")
}

func init() { proto.RegisterFile("chromiumos/dut_tracking.proto", fileDescriptor_31a1fc16820a6989) }

var fileDescriptor_31a1fc16820a6989 = []byte{
	// 343 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x91, 0x4b, 0x6b, 0xf2, 0x40,
	0x14, 0x86, 0xbf, 0x18, 0xbf, 0xd2, 0x4e, 0x31, 0x8d, 0xd3, 0x2e, 0x82, 0x54, 0x08, 0x42, 0x21,
	0x74, 0x91, 0x14, 0x5b, 0xdc, 0x75, 0x11, 0x6f, 0xad, 0x68, 0x54, 0x92, 0x08, 0xa5, 0x9b, 0x21,
	0x37, 0xe3, 0xa0, 0x99, 0x23, 0x93, 0x48, 0xe9, 0x7f, 0xeb, 0x8f, 0x2b, 0xa6, 0x5e, 0x92, 0xdd,
	0xcc, 0x7b, 0x9e, 0x77, 0xe6, 0x81, 0x83, 0x9a, 0xc1, 0x8a, 0x43, 0x42, 0x77, 0x09, 0xa4, 0x46,
	0xb8, 0xcb, 0x48, 0xc6, 0xbd, 0x60, 0x4d, 0x59, 0xac, 0x6f, 0x39, 0x64, 0x80, 0xd1, 0x79, 0xdc,
	0xb8, 0x2f, 0xa0, 0x3e, 0x64, 0x24, 0x0d, 0xbc, 0xcd, 0x89, 0x6c, 0xfd, 0x08, 0x48, 0x72, 0x0f,
	0xe5, 0x39, 0x6c, 0x68, 0xf0, 0x8d, 0x31, 0xaa, 0x32, 0x2f, 0x89, 0x14, 0x41, 0x15, 0xb4, 0x2b,
	0x3b, 0x3f, 0xe3, 0x57, 0x84, 0x42, 0x9a, 0x44, 0x2c, 0xa5, 0xc0, 0x52, 0xa5, 0xa2, 0x8a, 0xda,
	0x75, 0xbb, 0xa9, 0x9f, 0x5f, 0xd6, 0x9d, 0x2f, 0x8f, 0x27, 0x94, 0xc5, 0xfd, 0x23, 0x65, 0x17,
	0x0a, 0xf8, 0x09, 0xfd, 0x4f, 0x20, 0x8c, 0x52, 0x45, 0x54, 0x45, 0x4d, 0x6a, 0x37, 0x8a, 0x4d,
	0x0b, 0x18, 0xcd, 0x80, 0x53, 0x16, 0x5b, 0x10, 0x46, 0xf6, 0x1f, 0x88, 0x1f, 0x90, 0xb4, 0x01,
	0x58, 0xfb, 0x5e, 0xb0, 0x26, 0x2b, 0xd8, 0xf1, 0x54, 0xa9, 0xaa, 0x82, 0x56, 0xb7, 0x6b, 0xc7,
	0xf4, 0x7d, 0x1f, 0xb6, 0xc6, 0xa8, 0x5e, 0xb6, 0xef, 0x2d, 0x63, 0xdc, 0x41, 0x97, 0xdb, 0xfd,
	0x85, 0x46, 0xa9, 0x22, 0xe4, 0xaa, 0xa5, 0x0f, 0xcb, 0x05, 0xfb, 0xc4, 0x3e, 0xfa, 0x48, 0x2a,
	0xcb, 0xe0, 0x3b, 0x24, 0xf7, 0x07, 0x43, 0x73, 0x31, 0x71, 0x89, 0x6b, 0x9b, 0xbd, 0xf1, 0x68,
	0xfa, 0x26, 0xff, 0xc3, 0x18, 0x49, 0xae, 0xe9, 0x8c, 0x49, 0x77, 0xe6, 0x92, 0xde, 0x6c, 0x31,
	0x75, 0x65, 0x01, 0xd7, 0x51, 0xcd, 0x32, 0x3f, 0xc8, 0x7c, 0x30, 0xed, 0x13, 0x77, 0x64, 0x0d,
	0xe4, 0x0a, 0xbe, 0x45, 0x37, 0x73, 0xd3, 0x71, 0xc8, 0xd0, 0x1c, 0x4d, 0x0e, 0x9c, 0xd8, 0xed,
	0x7c, 0xbe, 0xc4, 0x70, 0xb2, 0xd1, 0x81, 0xc7, 0x46, 0x61, 0x3f, 0x94, 0x2d, 0xb9, 0x67, 0xe4,
	0x9b, 0x31, 0x62, 0x28, 0x4c, 0xfc, 0x8b, 0x3c, 0x7c, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x8d,
	0x5a, 0xa9, 0xe2, 0xf9, 0x01, 0x00, 0x00,
}
