// 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_UNKNOWN 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: "UNKNOWN",
	1: "TASK_BOT_COUNT",
	2: "MAX_PEND_TIME",
	3: "PASS_FAIL_COUNT",
}

var MonitoringMode_value = map[string]int32{
	"UNKNOWN":         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{
	// 338 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x91, 0xcb, 0x8e, 0xa2, 0x40,
	0x14, 0x86, 0x07, 0x71, 0x6e, 0xc7, 0xc8, 0x68, 0xcd, 0x86, 0x98, 0x31, 0x21, 0x26, 0x93, 0x90,
	0x59, 0xc0, 0xc4, 0x99, 0xb8, 0xeb, 0x05, 0x5e, 0x3a, 0x6d, 0x6c, 0xd0, 0x00, 0xa6, 0x2f, 0x9b,
	0x0a, 0x02, 0x62, 0x45, 0xa9, 0x63, 0x0a, 0x4c, 0xa7, 0xdf, 0xad, 0x1f, 0xae, 0x23, 0xed, 0x05,
	0x76, 0x55, 0xff, 0xf9, 0xfe, 0xaa, 0x2f, 0x39, 0xd0, 0x0d, 0x37, 0x02, 0x53, 0x76, 0x48, 0x31,
	0x33, 0xa3, 0x43, 0x4e, 0x73, 0x11, 0x84, 0x5b, 0xc6, 0x13, 0x63, 0x2f, 0x30, 0x47, 0x02, 0xd7,
	0x71, 0xe7, 0x57, 0x09, 0x5d, 0x61, 0x4e, 0xb3, 0x30, 0xd8, 0x5d, 0xc8, 0xde, 0x9b, 0x04, 0x8a,
	0x7f, 0x2a, 0x2f, 0x70, 0xc7, 0xc2, 0x57, 0x42, 0xa0, 0xce, 0x83, 0x34, 0x56, 0x25, 0x4d, 0xd2,
	0xbf, 0xbb, 0xc5, 0x99, 0xdc, 0x00, 0x44, 0x2c, 0x8d, 0x79, 0xc6, 0x90, 0x67, 0x6a, 0x4d, 0x93,
	0xf5, 0x46, 0xbf, 0x6b, 0x5c, 0x5f, 0x36, 0xbc, 0x97, 0x40, 0xa4, 0x8c, 0x27, 0xe3, 0x33, 0xe5,
	0x96, 0x0a, 0xe4, 0x2f, 0x7c, 0x4e, 0x31, 0x8a, 0x33, 0x55, 0xd6, 0x64, 0x5d, 0xe9, 0x77, 0xca,
	0x4d, 0x1b, 0x39, 0xcb, 0x51, 0x30, 0x9e, 0xd8, 0x18, 0xc5, 0xee, 0x07, 0x48, 0x7e, 0x83, 0xb2,
	0x43, 0xdc, 0xae, 0x82, 0x70, 0x4b, 0x37, 0x78, 0x10, 0x99, 0x5a, 0xd7, 0x24, 0xbd, 0xed, 0x36,
	0xcf, 0xe9, 0xdd, 0x31, 0xec, 0xcd, 0xa0, 0x5d, 0xb5, 0x1f, 0xad, 0x13, 0x32, 0x80, 0x6f, 0xfb,
	0xe3, 0x85, 0xc5, 0x99, 0x2a, 0x15, 0xaa, 0x95, 0x0f, 0xab, 0x05, 0xf7, 0xc2, 0xfe, 0x79, 0x02,
	0xa5, 0x2a, 0x43, 0x1a, 0xf0, 0x75, 0xe9, 0xcc, 0x9c, 0xf9, 0x83, 0xd3, 0xfa, 0x44, 0x08, 0x28,
	0xbe, 0xe5, 0xcd, 0xe8, 0x70, 0xee, 0xd3, 0xd1, 0x7c, 0xe9, 0xf8, 0x2d, 0x89, 0xb4, 0xa1, 0x69,
	0x5b, 0x8f, 0x74, 0x31, 0x71, 0xc6, 0xd4, 0x9f, 0xda, 0x93, 0x56, 0x8d, 0xfc, 0x84, 0x1f, 0x0b,
	0xcb, 0xf3, 0xe8, 0xad, 0x35, 0xbd, 0x3f, 0x71, 0xf2, 0x70, 0xf0, 0xfc, 0x3f, 0xc1, 0x8b, 0x84,
	0x81, 0x22, 0x31, 0x4b, 0x6b, 0x61, 0x7c, 0x2d, 0x02, 0xb3, 0x58, 0x88, 0x99, 0x60, 0x69, 0xb2,
	0xfa, 0x52, 0x84, 0xff, 0xde, 0x03, 0x00, 0x00, 0xff, 0xff, 0xfc, 0xf1, 0x90, 0x86, 0xf0, 0x01,
	0x00, 0x00,
}
