diff --git a/go/gen/sift/test_reports/v1/test_reports.pb.go b/go/gen/sift/test_reports/v1/test_reports.pb.go index 40996d2a8..3bd06ed48 100644 --- a/go/gen/sift/test_reports/v1/test_reports.pb.go +++ b/go/gen/sift/test_reports/v1/test_reports.pb.go @@ -231,6 +231,8 @@ type TestReport struct { ArchivedDate *timestamppb.Timestamp `protobuf:"bytes,12,opt,name=archived_date,json=archivedDate,proto3" json:"archived_date,omitempty"` // Whether the test run is archived (externally exposed) IsArchived bool `protobuf:"varint,13,opt,name=is_archived,json=isArchived,proto3" json:"is_archived,omitempty"` + // The run ID for the test run + RunId string `protobuf:"bytes,14,opt,name=run_id,json=runId,proto3" json:"run_id,omitempty"` } func (x *TestReport) Reset() { @@ -356,6 +358,13 @@ func (x *TestReport) GetIsArchived() bool { return false } +func (x *TestReport) GetRunId() string { + if x != nil { + return x.RunId + } + return "" +} + type TestStep struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -976,6 +985,8 @@ type CreateTestReportRequest struct { PartNumber string `protobuf:"bytes,9,opt,name=part_number,json=partNumber,proto3" json:"part_number,omitempty"` // Unique identifier for user owner SystemOperator string `protobuf:"bytes,10,opt,name=system_operator,json=systemOperator,proto3" json:"system_operator,omitempty"` + // The run ID for the test report + RunId string `protobuf:"bytes,11,opt,name=run_id,json=runId,proto3" json:"run_id,omitempty"` } func (x *CreateTestReportRequest) Reset() { @@ -1080,6 +1091,13 @@ func (x *CreateTestReportRequest) GetSystemOperator() string { return "" } +func (x *CreateTestReportRequest) GetRunId() string { + if x != nil { + return x.RunId + } + return "" +} + // Response message for CreateTestReport type CreateTestReportResponse struct { state protoimpl.MessageState @@ -1246,7 +1264,7 @@ type ListTestReportsRequest struct { // A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. // Available fields to filter by are `test_report_id`, `status`, `name`, `test_system_name`, // `test_case`, `start_time`, `end_time`, `serial_number`, `created_by_user_id`, `modified_by_user_id`, - // `part_number`, `system_operator`, `archived_date`, and `metadata`. + // `part_number`, `system_operator`, `run_id`, `archived_date`, and `metadata`. // Metadata can be used in filters by using `metadata.{metadata_key_name}` as the field name. // For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). // For more information about the fields used for filtering, please refer to [this definition](/docs/api/grpc/protocol-buffers/test-results#testreport). Optional. @@ -1388,7 +1406,7 @@ type UpdateTestReportRequest struct { TestReport *TestReport `protobuf:"bytes,1,opt,name=test_report,json=testReport,proto3" json:"test_report,omitempty"` // The field mask specifying which fields to update. The fields available to be updated are // `status`, `name`, `test_system_name`, `test_case`, `start_time`, `end_time`, `serial_number`, - // `part_number`, `system_operator`, and `is_archived`. + // `part_number`, `system_operator`, `run_id`, and `is_archived`. UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"` } @@ -2799,7 +2817,7 @@ var file_sift_test_reports_v1_test_reports_proto_rawDesc = []byte{ 0x6f, 0x1a, 0x1f, 0x73, 0x69, 0x66, 0x74, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x73, 0x69, 0x66, 0x74, 0x2f, 0x75, 0x6e, 0x69, 0x74, 0x2f, 0x76, 0x32, - 0x2f, 0x75, 0x6e, 0x69, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x88, 0x05, 0x0a, 0x0a, + 0x2f, 0x75, 0x6e, 0x69, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa4, 0x05, 0x0a, 0x0a, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x29, 0x0a, 0x0e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, @@ -2840,159 +2858,285 @@ var file_sift_test_reports_v1_test_reports_proto_rawDesc = []byte{ 0x41, 0x01, 0x52, 0x0c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x44, 0x61, 0x74, 0x65, 0x12, 0x24, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0a, 0x69, 0x73, 0x41, 0x72, - 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x22, 0xaf, 0x04, 0x0a, 0x08, 0x54, 0x65, 0x73, 0x74, 0x53, - 0x74, 0x65, 0x70, 0x12, 0x25, 0x0a, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0a, + 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x06, 0x72, 0x75, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x05, 0x72, 0x75, 0x6e, + 0x49, 0x64, 0x22, 0xaf, 0x04, 0x0a, 0x08, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x12, + 0x25, 0x0a, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0a, 0x74, 0x65, 0x73, 0x74, + 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x0e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, + 0xe0, 0x41, 0x02, 0x52, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x49, + 0x64, 0x12, 0x29, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, + 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0c, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x09, + 0x73, 0x74, 0x65, 0x70, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x22, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x54, + 0x79, 0x70, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x08, 0x73, 0x74, 0x65, 0x70, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x20, 0x0a, 0x09, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x08, 0x73, 0x74, 0x65, 0x70, + 0x50, 0x61, 0x74, 0x68, 0x12, 0x3d, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x3e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, + 0x43, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, + 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x59, 0x0a, 0x09, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x22, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x28, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, + 0x02, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, + 0xab, 0x05, 0x0a, 0x0f, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x0e, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, + 0x52, 0x0d, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, + 0x59, 0x0a, 0x10, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x73, 0x69, 0x66, 0x74, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, + 0x2e, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0f, 0x6d, 0x65, 0x61, 0x73, 0x75, + 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, + 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x0e, 0x74, 0x65, - 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, - 0x73, 0x74, 0x65, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, - 0x41, 0x01, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, - 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, - 0xe0, 0x41, 0x02, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, - 0xe0, 0x41, 0x01, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x44, 0x0a, 0x09, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, - 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, - 0x74, 0x65, 0x70, 0x54, 0x79, 0x70, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x08, 0x73, 0x74, - 0x65, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x09, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x70, - 0x61, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x08, - 0x73, 0x74, 0x65, 0x70, 0x50, 0x61, 0x74, 0x68, 0x12, 0x3d, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, - 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, - 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x09, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, - 0x69, 0x6d, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x66, - 0x6f, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, - 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x59, 0x0a, 0x09, 0x45, 0x72, 0x72, 0x6f, - 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x22, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, - 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x09, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x28, 0x0a, 0x0d, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x22, 0xab, 0x05, 0x0a, 0x0f, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, - 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x0e, 0x6d, 0x65, 0x61, 0x73, 0x75, - 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0d, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x49, 0x64, 0x12, 0x59, 0x0a, 0x10, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, - 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0f, 0x6d, - 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, - 0x02, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, - 0x73, 0x74, 0x65, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, - 0x41, 0x02, 0x52, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x29, - 0x0a, 0x0e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x64, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0c, 0x74, 0x65, 0x73, - 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0d, 0x6e, 0x75, 0x6d, - 0x65, 0x72, 0x69, 0x63, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, - 0x48, 0x00, 0x52, 0x0c, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x23, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x25, 0x0a, 0x0d, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, - 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x0c, - 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2b, 0x0a, 0x04, - 0x75, 0x6e, 0x69, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x69, 0x66, - 0x74, 0x2e, 0x75, 0x6e, 0x69, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x6e, 0x69, 0x74, 0x42, 0x03, - 0xe0, 0x41, 0x01, 0x52, 0x04, 0x75, 0x6e, 0x69, 0x74, 0x12, 0x4c, 0x0a, 0x0e, 0x6e, 0x75, 0x6d, - 0x65, 0x72, 0x69, 0x63, 0x5f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, - 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x48, 0x01, 0x52, 0x0d, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, - 0x63, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x12, 0x49, 0x0a, 0x0d, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x5f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, - 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x42, 0x6f, 0x75, 0x6e, - 0x64, 0x73, 0x48, 0x01, 0x52, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x42, 0x6f, 0x75, 0x6e, - 0x64, 0x73, 0x12, 0x1b, 0x0a, 0x06, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, - 0x28, 0x08, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x12, - 0x3d, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0d, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, - 0xe0, 0x41, 0x02, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x07, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x62, 0x6f, 0x75, 0x6e, 0x64, - 0x73, 0x22, 0x57, 0x0a, 0x0d, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x42, 0x6f, 0x75, 0x6e, - 0x64, 0x73, 0x12, 0x1a, 0x0a, 0x03, 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x42, - 0x03, 0xe0, 0x41, 0x01, 0x48, 0x00, 0x52, 0x03, 0x6d, 0x69, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x1a, - 0x0a, 0x03, 0x6d, 0x61, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x42, 0x03, 0xe0, 0x41, 0x01, - 0x48, 0x01, 0x52, 0x03, 0x6d, 0x61, 0x78, 0x88, 0x01, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x6d, - 0x69, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x6d, 0x61, 0x78, 0x22, 0x3a, 0x0a, 0x0c, 0x53, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x0e, 0x65, 0x78, - 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0d, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, - 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x44, 0x0a, 0x17, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, - 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x29, 0x0a, 0x0e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0c, - 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x22, 0x5d, 0x0a, 0x18, - 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x74, 0x65, 0x73, 0x74, - 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, + 0x6f, 0x72, 0x74, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0d, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, + 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, 0x52, 0x0c, + 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x25, 0x0a, 0x0d, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x5f, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x6f, 0x6f, 0x6c, + 0x65, 0x61, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x75, 0x6e, 0x69, 0x74, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x75, 0x6e, + 0x69, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x6e, 0x69, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, + 0x04, 0x75, 0x6e, 0x69, 0x74, 0x12, 0x4c, 0x0a, 0x0e, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, + 0x5f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, - 0x0a, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x22, 0xfe, 0x03, 0x0a, 0x17, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, - 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, - 0x65, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x2d, 0x0a, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0e, - 0x74, 0x65, 0x73, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, - 0x0a, 0x09, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x08, 0x74, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, - 0x12, 0x3e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, - 0x12, 0x3a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x42, 0x6f, 0x75, 0x6e, + 0x64, 0x73, 0x48, 0x01, 0x52, 0x0d, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x42, 0x6f, 0x75, + 0x6e, 0x64, 0x73, 0x12, 0x49, 0x0a, 0x0d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x62, 0x6f, + 0x75, 0x6e, 0x64, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x69, 0x66, + 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x48, 0x01, + 0x52, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x12, 0x1b, + 0x0a, 0x06, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x42, 0x03, + 0xe0, 0x41, 0x02, 0x52, 0x06, 0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x12, 0x3d, 0x0a, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x22, 0x57, 0x0a, + 0x0d, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x12, 0x1a, + 0x0a, 0x03, 0x6d, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x42, 0x03, 0xe0, 0x41, 0x01, + 0x48, 0x00, 0x52, 0x03, 0x6d, 0x69, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x1a, 0x0a, 0x03, 0x6d, 0x61, + 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x48, 0x01, 0x52, 0x03, + 0x6d, 0x61, 0x78, 0x88, 0x01, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x6d, 0x69, 0x6e, 0x42, 0x06, + 0x0a, 0x04, 0x5f, 0x6d, 0x61, 0x78, 0x22, 0x3a, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x0e, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, + 0xe0, 0x41, 0x02, 0x52, 0x0d, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x22, 0x44, 0x0a, 0x17, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x65, 0x73, 0x74, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, + 0x0e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0c, 0x72, 0x65, 0x6d, 0x6f, + 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x64, 0x22, 0x5d, 0x0a, 0x18, 0x49, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x66, 0x74, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, + 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x0a, 0x74, 0x65, 0x73, + 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x9a, 0x04, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x3d, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, + 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x10, 0x74, + 0x65, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0e, 0x74, 0x65, 0x73, 0x74, + 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x09, 0x74, 0x65, + 0x73, 0x74, 0x5f, 0x63, 0x61, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, + 0x41, 0x02, 0x52, 0x08, 0x74, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0a, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, + 0x02, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x08, + 0x65, 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, + 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x69, 0x66, + 0x74, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x03, 0xe0, 0x41, 0x01, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x28, 0x0a, 0x0d, 0x73, 0x65, + 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x5f, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0a, + 0x70, 0x61, 0x72, 0x74, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x0f, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x06, 0x72, 0x75, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x05, 0x72, + 0x75, 0x6e, 0x49, 0x64, 0x22, 0x5d, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, + 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x41, 0x0a, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, + 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, + 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x22, 0x41, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x0e, 0x74, + 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x49, 0x64, 0x22, 0x5a, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x54, 0x65, 0x73, + 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x41, 0x0a, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x22, 0x9b, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, + 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, + 0x22, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x12, 0x1e, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, + 0x22, 0x86, 0x01, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0c, + 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x52, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, + 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xa3, 0x01, 0x0a, 0x17, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x46, 0x0a, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x66, + 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, + 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x03, 0xe0, 0x41, + 0x02, 0x52, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x40, 0x0a, + 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x03, - 0xe0, 0x41, 0x02, 0x52, 0x07, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x08, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, - 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x28, - 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x69, - 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x74, - 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, - 0x41, 0x01, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2c, - 0x0a, 0x0f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, - 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0e, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x5d, 0x0a, 0x18, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x74, 0x65, 0x73, 0x74, - 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, - 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, - 0x0a, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x41, 0x0a, 0x14, 0x47, - 0x65, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x0e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, - 0x52, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x49, 0x64, 0x22, 0x5a, - 0x0a, 0x15, 0x47, 0x65, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, - 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x42, 0x03, + 0xe0, 0x41, 0x01, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, + 0x5d, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x74, + 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x20, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x52, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x44, + 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x0e, 0x74, 0x65, 0x73, + 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x49, 0x64, 0x22, 0x1a, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, + 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x59, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, + 0x65, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x09, 0x74, 0x65, 0x73, + 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x0a, - 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x9b, 0x01, 0x0a, 0x16, 0x4c, - 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x42, 0x03, 0xe0, 0x41, + 0x02, 0x52, 0x08, 0x74, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x22, 0x55, 0x0a, 0x16, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x09, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x74, + 0x65, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, + 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x08, 0x74, 0x65, 0x73, 0x74, 0x53, 0x74, + 0x65, 0x70, 0x22, 0x99, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, + 0x74, 0x65, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x09, 0x70, + 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x03, + 0xe0, 0x41, 0x01, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, + 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x12, 0x1b, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1e, + 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x22, 0x7e, + 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, + 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x69, + 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x09, 0x74, 0x65, 0x73, + 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, + 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x9b, + 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, + 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x09, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x69, + 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x02, + 0x52, 0x08, 0x74, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x12, 0x40, 0x0a, 0x0b, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x42, 0x03, 0xe0, 0x41, 0x01, + 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x55, 0x0a, 0x16, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x09, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, + 0x74, 0x65, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x69, 0x66, 0x74, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, + 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x08, 0x74, 0x65, 0x73, 0x74, 0x53, + 0x74, 0x65, 0x70, 0x22, 0x3e, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, + 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0c, + 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, + 0x70, 0x49, 0x64, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, + 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x75, 0x0a, + 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, + 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x55, 0x0a, + 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, + 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x03, + 0xe0, 0x41, 0x02, 0x52, 0x0f, 0x74, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x71, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, + 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6d, 0x65, + 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x25, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, + 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0f, 0x74, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, + 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x78, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, + 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x4d, + 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, + 0x10, 0x74, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x22, 0x91, 0x01, 0x0a, 0x1e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, + 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x1a, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x18, 0x6d, + 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x0f, 0x6d, 0x65, 0x61, 0x73, 0x75, + 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, + 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0e, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x49, 0x64, 0x73, 0x22, 0xa0, 0x01, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, + 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, @@ -3001,461 +3145,338 @@ var file_sift_test_reports_v1_test_reports_proto_rawDesc = []byte{ 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, - 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x22, 0x86, 0x01, 0x0a, 0x17, 0x4c, 0x69, 0x73, - 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x66, + 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x22, 0x9a, 0x01, 0x0a, 0x1c, 0x4c, 0x69, 0x73, + 0x74, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x11, 0x74, 0x65, 0x73, + 0x74, 0x5f, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, + 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x10, 0x74, 0x65, 0x73, + 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x26, 0x0a, + 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x34, 0x0a, 0x15, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, + 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, + 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, + 0xe0, 0x41, 0x01, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x2e, 0x0a, 0x16, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3b, 0x0a, 0x1c, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x06, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, + 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x35, 0x0a, 0x1d, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, + 0xb7, 0x01, 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, + 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x55, 0x0a, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, - 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x0b, 0x74, 0x65, - 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, - 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x22, 0xa3, 0x01, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x46, 0x0a, - 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x40, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, - 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, - 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0a, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x5d, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, - 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, - 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x0a, 0x74, 0x65, 0x73, 0x74, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x44, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x29, 0x0a, 0x0e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0c, - 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x49, 0x64, 0x22, 0x1a, 0x0a, 0x18, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x59, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x40, 0x0a, 0x09, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0f, 0x74, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, + 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0a, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x71, 0x0a, 0x1d, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x10, 0x74, 0x65, + 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, - 0x53, 0x74, 0x65, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x08, 0x74, 0x65, 0x73, 0x74, 0x53, - 0x74, 0x65, 0x70, 0x22, 0x55, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, - 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, - 0x09, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1e, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, - 0x52, 0x08, 0x74, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x22, 0x99, 0x01, 0x0a, 0x14, 0x4c, - 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, 0x70, 0x61, 0x67, - 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x22, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, - 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x06, 0x66, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x06, - 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, - 0x62, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x07, 0x6f, - 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x22, 0x7e, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, - 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x3d, 0x0a, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, - 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, - 0x74, 0x65, 0x70, 0x52, 0x09, 0x74, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x12, 0x26, - 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, - 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x9b, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x40, 0x0a, 0x09, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, - 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, - 0x74, 0x65, 0x70, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x08, 0x74, 0x65, 0x73, 0x74, 0x53, 0x74, - 0x65, 0x70, 0x12, 0x40, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, - 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, - 0x61, 0x73, 0x6b, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x55, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, - 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, - 0x0a, 0x09, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, - 0x70, 0x52, 0x08, 0x74, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x22, 0x3e, 0x0a, 0x15, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x65, - 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, - 0x0a, 0x74, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x22, 0x18, 0x0a, 0x16, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x75, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, - 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x55, 0x0a, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6d, 0x65, - 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x25, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, - 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0f, 0x74, 0x65, 0x73, - 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x71, 0x0a, 0x1d, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, - 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, - 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, - 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0f, - 0x74, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x22, - 0x78, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, - 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x57, 0x0a, 0x11, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x69, - 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, - 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x10, 0x74, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, - 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x91, 0x01, 0x0a, 0x1e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x1a, - 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, - 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x18, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x2c, 0x0a, 0x0f, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, - 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0e, 0x6d, - 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x22, 0xa0, 0x01, - 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, - 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, - 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, - 0x22, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x12, 0x1e, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, - 0x22, 0x9a, 0x01, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, - 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x52, 0x0a, 0x11, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, - 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x52, 0x10, 0x74, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, - 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, - 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x34, 0x0a, - 0x15, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x06, 0x66, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x22, 0x2e, 0x0a, 0x16, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, 0x74, - 0x53, 0x74, 0x65, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x22, 0x3b, 0x0a, 0x1c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, 0x74, - 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x22, 0x35, 0x0a, 0x1d, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, - 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xb7, 0x01, 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, + 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0f, 0x74, 0x65, 0x73, + 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x4a, 0x0a, 0x1c, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x0e, + 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0d, 0x6d, 0x65, 0x61, 0x73, 0x75, + 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x1f, 0x0a, 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x55, 0x0a, 0x10, 0x74, 0x65, 0x73, 0x74, - 0x5f, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, - 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x0f, - 0x74, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, - 0x40, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, - 0x42, 0x03, 0xe0, 0x41, 0x01, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, - 0x6b, 0x22, 0x71, 0x0a, 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, - 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x50, 0x0a, 0x10, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x61, 0x73, 0x75, - 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, - 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x52, 0x0f, 0x74, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x4a, 0x0a, 0x1c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, - 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x0e, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, - 0x02, 0x52, 0x0d, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, - 0x22, 0x1f, 0x0a, 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, - 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2a, 0xd6, 0x01, 0x0a, 0x0a, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, - 0x11, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x52, 0x41, - 0x46, 0x54, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x45, 0x44, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, - 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, - 0x45, 0x44, 0x10, 0x03, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x41, 0x42, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x04, 0x12, 0x15, 0x0a, - 0x11, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x10, 0x05, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, - 0x06, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, - 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, 0x07, 0x2a, 0xa1, 0x01, 0x0a, 0x0c, 0x54, - 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x1a, 0x54, - 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x54, - 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x45, - 0x51, 0x55, 0x45, 0x4e, 0x43, 0x45, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x45, 0x53, 0x54, - 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, - 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x03, 0x12, 0x1f, 0x0a, - 0x1b, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x10, 0x04, 0x2a, 0xc4, - 0x01, 0x0a, 0x13, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x21, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4d, - 0x45, 0x41, 0x53, 0x55, 0x52, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x20, 0x0a, - 0x1c, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45, 0x4d, 0x45, 0x4e, - 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, - 0x20, 0x0a, 0x1c, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45, 0x4d, - 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, - 0x03, 0x12, 0x21, 0x0a, 0x1d, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, - 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x45, - 0x41, 0x4e, 0x10, 0x04, 0x12, 0x1f, 0x0a, 0x1b, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x45, 0x41, - 0x53, 0x55, 0x52, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x49, - 0x4d, 0x49, 0x54, 0x10, 0x05, 0x32, 0xd7, 0x1c, 0x0a, 0x11, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xe4, 0x01, 0x0a, 0x10, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0xd6, 0x01, 0x0a, 0x0a, 0x54, 0x65, + 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x45, 0x53, 0x54, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x52, 0x41, 0x46, 0x54, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, + 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x41, 0x53, 0x53, + 0x45, 0x44, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x12, 0x17, 0x0a, 0x13, + 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x42, 0x4f, 0x52, + 0x54, 0x45, 0x44, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x05, 0x12, 0x1b, 0x0a, 0x17, + 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x49, 0x4e, 0x5f, 0x50, + 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x06, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, + 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, + 0x10, 0x07, 0x2a, 0xa1, 0x01, 0x0a, 0x0c, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x45, 0x50, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x45, 0x50, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x45, 0x51, 0x55, 0x45, 0x4e, 0x43, 0x45, 0x10, 0x01, + 0x12, 0x18, 0x0a, 0x14, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x54, 0x45, + 0x53, 0x54, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x43, 0x54, + 0x49, 0x4f, 0x4e, 0x10, 0x03, 0x12, 0x1f, 0x0a, 0x1b, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x53, 0x54, + 0x45, 0x50, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x43, 0x4f, 0x4e, + 0x54, 0x52, 0x4f, 0x4c, 0x10, 0x04, 0x2a, 0xc4, 0x01, 0x0a, 0x13, 0x54, 0x65, 0x73, 0x74, 0x4d, + 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, + 0x0a, 0x21, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45, 0x4d, 0x45, + 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x20, 0x0a, 0x1c, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x45, + 0x41, 0x53, 0x55, 0x52, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, + 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x54, 0x45, 0x53, 0x54, 0x5f, + 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x21, 0x0a, 0x1d, 0x54, 0x45, 0x53, + 0x54, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x10, 0x04, 0x12, 0x1f, 0x0a, 0x1b, + 0x54, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45, 0x4d, 0x45, 0x4e, 0x54, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x05, 0x32, 0xd7, 0x1c, + 0x0a, 0x11, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0xe4, 0x01, 0x0a, 0x10, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x65, + 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x2d, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, + 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x12, 0x2d, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x65, - 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2e, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x65, 0x73, - 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x71, 0x92, 0x41, 0x48, 0x12, 0x10, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x65, 0x73, 0x74, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x34, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x20, - 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x66, 0x72, - 0x6f, 0x6d, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x2d, 0x75, 0x70, - 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, - 0x65, 0x73, 0x74, 0x2d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x3a, 0x69, 0x6d, 0x70, 0x6f, - 0x72, 0x74, 0x12, 0xbe, 0x01, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, - 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x2d, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, - 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, - 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4b, 0x92, 0x41, 0x29, 0x12, 0x10, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x15, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x72, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x71, 0x92, 0x41, 0x48, 0x12, 0x10, 0x49, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x34, + 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, + 0x72, 0x65, 0x61, 0x64, 0x79, 0x2d, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 0x66, + 0x69, 0x6c, 0x65, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x72, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x73, 0x12, 0xc4, 0x01, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x2a, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, - 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2b, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x65, 0x73, 0x74, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5a, - 0x92, 0x41, 0x2a, 0x12, 0x0d, 0x47, 0x65, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x1a, 0x19, 0x47, 0x65, 0x74, 0x73, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, - 0x65, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, - 0x74, 0x2d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x73, 0x74, 0x5f, - 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xcc, 0x01, 0x0a, 0x0f, 0x4c, - 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x2c, - 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x73, - 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5c, 0x92, 0x41, 0x3d, - 0x12, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x73, 0x1a, 0x2a, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x72, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, - 0x74, 0x2d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0xbe, 0x01, 0x0a, 0x10, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x2d, - 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, - 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4b, 0x92, - 0x41, 0x29, 0x12, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, - 0x74, 0x65, 0x73, 0x74, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x19, 0x3a, 0x01, 0x2a, 0x32, 0x14, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, - 0x73, 0x74, 0x2d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0xcc, 0x01, 0x0a, 0x10, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, + 0x72, 0x74, 0x73, 0x3a, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0xbe, 0x01, 0x0a, 0x10, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x2d, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, + 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x59, - 0x92, 0x41, 0x29, 0x12, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x20, 0x61, + 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4b, + 0x92, 0x41, 0x29, 0x12, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x27, 0x2a, 0x25, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, - 0x2d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xb2, 0x01, 0x0a, 0x0e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x12, 0x2b, 0x2e, 0x73, - 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, - 0x65, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x69, 0x66, 0x74, + 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, + 0x65, 0x73, 0x74, 0x2d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0xc4, 0x01, 0x0a, 0x0d, + 0x47, 0x65, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x2a, 0x2e, + 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x45, 0x92, 0x41, 0x25, 0x12, 0x0e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x1a, 0x13, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x73, 0x74, 0x65, - 0x70, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x3a, 0x01, 0x2a, 0x22, 0x12, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x73, 0x74, 0x65, 0x70, 0x73, 0x12, 0xc0, - 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, - 0x12, 0x2a, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, - 0x53, 0x74, 0x65, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x73, - 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x56, 0x92, 0x41, 0x39, 0x12, 0x0d, - 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x1a, 0x28, 0x4c, - 0x69, 0x73, 0x74, 0x73, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x73, 0x74, 0x65, 0x70, 0x73, 0x20, - 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x73, 0x74, 0x65, 0x70, - 0x73, 0x12, 0xb2, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, + 0x2e, 0x47, 0x65, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5a, 0x92, 0x41, 0x2a, 0x12, 0x0d, 0x47, 0x65, 0x74, + 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x19, 0x47, 0x65, 0x74, 0x73, + 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, + 0x64, 0x7d, 0x12, 0xcc, 0x01, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x2c, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x5c, 0x92, 0x41, 0x3d, 0x12, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, + 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x1a, 0x2a, 0x4c, 0x69, 0x73, 0x74, 0x73, + 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x20, 0x77, 0x69, + 0x74, 0x68, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x69, 0x6e, 0x67, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x12, 0xbe, 0x01, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x2d, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, + 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4b, 0x92, 0x41, 0x29, 0x12, 0x10, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x15, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x72, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x32, 0x14, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x12, 0xcc, 0x01, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, + 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x2d, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x59, 0x92, 0x41, 0x29, 0x12, 0x10, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x15, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x72, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x2a, 0x25, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, + 0x2f, 0x7b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x64, + 0x7d, 0x12, 0xb2, 0x01, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x12, 0x2b, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, - 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x45, 0x92, 0x41, 0x25, 0x12, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, - 0x53, 0x74, 0x65, 0x70, 0x1a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, + 0x45, 0x92, 0x41, 0x25, 0x12, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, + 0x53, 0x74, 0x65, 0x70, 0x1a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x73, 0x74, 0x65, 0x70, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x3a, - 0x01, 0x2a, 0x32, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, - 0x2d, 0x73, 0x74, 0x65, 0x70, 0x73, 0x12, 0xbe, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x12, 0x2b, 0x2e, 0x73, 0x69, 0x66, 0x74, + 0x01, 0x2a, 0x22, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, + 0x2d, 0x73, 0x74, 0x65, 0x70, 0x73, 0x12, 0xc0, 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x54, + 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x12, 0x2a, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, + 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x56, 0x92, 0x41, 0x39, 0x12, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, + 0x53, 0x74, 0x65, 0x70, 0x73, 0x1a, 0x28, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x74, 0x65, 0x73, + 0x74, 0x20, 0x73, 0x74, 0x65, 0x70, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, + 0x65, 0x73, 0x74, 0x2d, 0x73, 0x74, 0x65, 0x70, 0x73, 0x12, 0xb2, 0x01, 0x0a, 0x0e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x12, 0x2b, 0x2e, 0x73, + 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, + 0x65, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, - 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x51, 0x92, 0x41, 0x25, 0x12, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x1a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x73, 0x74, 0x65, 0x70, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x23, 0x2a, 0x21, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, - 0x73, 0x74, 0x2d, 0x73, 0x74, 0x65, 0x70, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, - 0x74, 0x65, 0x70, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xdc, 0x01, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x12, 0x32, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, - 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, - 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5a, 0x92, 0x41, 0x33, 0x12, - 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, - 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, - 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x82, 0x02, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x45, 0x92, 0x41, 0x25, 0x12, 0x0e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x1a, 0x13, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x73, 0x74, 0x65, + 0x70, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x3a, 0x01, 0x2a, 0x32, 0x12, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x73, 0x74, 0x65, 0x70, 0x73, 0x12, 0xbe, + 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, + 0x70, 0x12, 0x2b, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, + 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, + 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, + 0x53, 0x74, 0x65, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x51, 0x92, 0x41, + 0x25, 0x12, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, + 0x70, 0x1a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, + 0x74, 0x20, 0x73, 0x74, 0x65, 0x70, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x23, 0x2a, 0x21, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x73, 0x74, 0x65, 0x70, 0x73, + 0x2f, 0x7b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x5f, 0x69, 0x64, 0x7d, 0x12, + 0xdc, 0x01, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, + 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x32, 0x2e, 0x73, 0x69, 0x66, 0x74, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, + 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, + 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, + 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x5a, 0x92, 0x41, 0x33, 0x12, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, + 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0x1a, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, + 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, + 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, + 0x74, 0x2d, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x82, + 0x02, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, + 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x33, 0x2e, 0x73, 0x69, 0x66, 0x74, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, + 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, + 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, + 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7d, 0x92, 0x41, 0x50, 0x12, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x12, 0x33, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, - 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, - 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7d, 0x92, 0x41, - 0x50, 0x12, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, - 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x36, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x73, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x74, 0x65, 0x73, 0x74, - 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x69, 0x6e, - 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, 0x01, 0x2a, 0x22, 0x1f, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x12, 0xea, 0x01, 0x0a, 0x14, - 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x12, 0x31, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, - 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, - 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6b, 0x92, 0x41, 0x47, - 0x12, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x2f, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x74, 0x65, - 0x73, 0x74, 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, - 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6d, 0x65, 0x61, 0x73, - 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0xcb, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x12, 0x2b, 0x2e, 0x73, 0x69, - 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, + 0x73, 0x1a, 0x36, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, + 0x70, 0x6c, 0x65, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x73, 0x69, 0x6e, 0x67, 0x6c, + 0x65, 0x20, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, + 0x01, 0x2a, 0x22, 0x1f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, + 0x2d, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x62, 0x61, + 0x74, 0x63, 0x68, 0x12, 0xea, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, + 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x31, 0x2e, 0x73, + 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, + 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x32, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x73, 0x74, 0x4d, + 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x6b, 0x92, 0x41, 0x47, 0x12, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, + 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x2f, + 0x4c, 0x69, 0x73, 0x74, 0x73, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, + 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, + 0x65, 0x73, 0x74, 0x2d, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x12, 0xcb, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, + 0x65, 0x70, 0x73, 0x12, 0x2b, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, + 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2c, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, + 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5e, + 0x92, 0x41, 0x3b, 0x12, 0x0e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, + 0x65, 0x70, 0x73, 0x1a, 0x29, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x65, 0x73, 0x74, + 0x20, 0x73, 0x74, 0x65, 0x70, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, + 0x73, 0x74, 0x2d, 0x73, 0x74, 0x65, 0x70, 0x73, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0xf5, + 0x01, 0x0a, 0x15, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, + 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x32, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5e, 0x92, 0x41, 0x3b, 0x12, 0x0e, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x54, 0x65, 0x73, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x1a, 0x29, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x73, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x73, 0x74, 0x65, 0x70, 0x73, 0x20, 0x77, - 0x69, 0x74, 0x68, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x73, 0x74, 0x65, 0x70, 0x73, - 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0xf5, 0x01, 0x0a, 0x15, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x73, + 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, + 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x73, 0x92, 0x41, 0x49, 0x12, 0x15, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, + 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x30, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, + 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, + 0x65, 0x73, 0x74, 0x2d, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0xdc, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x32, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, - 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, + 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, - 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x75, 0x6e, - 0x74, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x73, 0x92, 0x41, 0x49, 0x12, 0x15, - 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x30, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x65, - 0x73, 0x74, 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, - 0x77, 0x69, 0x74, 0x68, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6d, 0x65, 0x61, 0x73, - 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0xdc, - 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, - 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x32, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, - 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5a, 0x92, 0x41, 0x33, 0x12, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x73, - 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, - 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x5a, 0x92, 0x41, 0x33, 0x12, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x65, - 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0x1a, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, - 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, - 0x01, 0x2a, 0x32, 0x19, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, - 0x2d, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0xea, 0x01, - 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, - 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x32, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, - 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0x1a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, + 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x32, 0x19, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0xea, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, + 0x32, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, + 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, + 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x68, 0x92, 0x41, 0x33, 0x12, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x73, 0x69, - 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, - 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x61, - 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x68, 0x92, 0x41, 0x33, 0x12, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x65, 0x73, - 0x74, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0x1a, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x61, - 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x2a, 0x2a, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6d, 0x65, 0x61, - 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x61, 0x73, 0x75, - 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x1a, 0x23, 0x92, 0x41, 0x20, 0x12, - 0x1e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x6d, 0x61, 0x6e, 0x61, - 0x67, 0x65, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x42, - 0xfc, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, - 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x54, 0x65, - 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x66, - 0x74, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x69, 0x66, 0x74, 0x2f, 0x67, 0x6f, 0x2f, - 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x69, 0x66, 0x74, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x53, 0x54, 0x58, 0xaa, 0x02, 0x13, - 0x53, 0x69, 0x66, 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, - 0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x53, 0x69, 0x66, 0x74, 0x5c, 0x54, 0x65, 0x73, 0x74, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1f, 0x53, 0x69, 0x66, 0x74, - 0x5c, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5c, 0x56, 0x31, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x15, 0x53, 0x69, - 0x66, 0x74, 0x3a, 0x3a, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x3a, - 0x3a, 0x56, 0x31, 0x92, 0x41, 0x18, 0x12, 0x16, 0x0a, 0x14, 0x54, 0x65, 0x73, 0x74, 0x20, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0x1a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x20, 0x61, 0x20, + 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x2a, 0x2a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x31, 0x2f, + 0x74, 0x65, 0x73, 0x74, 0x2d, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, + 0x64, 0x7d, 0x1a, 0x23, 0x92, 0x41, 0x20, 0x12, 0x1e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x20, 0x74, 0x6f, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, + 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x42, 0xfc, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, + 0x73, 0x69, 0x66, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x66, 0x74, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, + 0x73, 0x69, 0x66, 0x74, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x69, 0x66, 0x74, + 0x2f, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2f, 0x76, 0x31, + 0x3b, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x76, 0x31, 0xa2, + 0x02, 0x03, 0x53, 0x54, 0x58, 0xaa, 0x02, 0x13, 0x53, 0x69, 0x66, 0x74, 0x2e, 0x54, 0x65, 0x73, + 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x53, 0x69, + 0x66, 0x74, 0x5c, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x5c, 0x56, + 0x31, 0xe2, 0x02, 0x1f, 0x53, 0x69, 0x66, 0x74, 0x5c, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x73, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0xea, 0x02, 0x15, 0x53, 0x69, 0x66, 0x74, 0x3a, 0x3a, 0x54, 0x65, 0x73, 0x74, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x3a, 0x3a, 0x56, 0x31, 0x92, 0x41, 0x18, 0x12, 0x16, + 0x0a, 0x14, 0x54, 0x65, 0x73, 0x74, 0x20, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x20, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/go/gen/sift/test_reports/v1/test_reports_vtproto.pb.go b/go/gen/sift/test_reports/v1/test_reports_vtproto.pb.go index d23f6e295..b41d487de 100644 --- a/go/gen/sift/test_reports/v1/test_reports_vtproto.pb.go +++ b/go/gen/sift/test_reports/v1/test_reports_vtproto.pb.go @@ -49,6 +49,7 @@ func (m *TestReport) CloneVT() *TestReport { r.SystemOperator = m.SystemOperator r.ArchivedDate = (*timestamppb.Timestamp)((*timestamppb1.Timestamp)(m.ArchivedDate).CloneVT()) r.IsArchived = m.IsArchived + r.RunId = m.RunId if rhs := m.Metadata; rhs != nil { tmpContainer := make([]*v1.MetadataValue, len(rhs)) for k, v := range rhs { @@ -290,6 +291,7 @@ func (m *CreateTestReportRequest) CloneVT() *CreateTestReportRequest { r.SerialNumber = m.SerialNumber r.PartNumber = m.PartNumber r.SystemOperator = m.SystemOperator + r.RunId = m.RunId if rhs := m.Metadata; rhs != nil { tmpContainer := make([]*v1.MetadataValue, len(rhs)) for k, v := range rhs { @@ -943,6 +945,9 @@ func (this *TestReport) EqualVT(that *TestReport) bool { if this.IsArchived != that.IsArchived { return false } + if this.RunId != that.RunId { + return false + } return string(this.unknownFields) == string(that.unknownFields) } @@ -1326,6 +1331,9 @@ func (this *CreateTestReportRequest) EqualVT(that *CreateTestReportRequest) bool if this.SystemOperator != that.SystemOperator { return false } + if this.RunId != that.RunId { + return false + } return string(this.unknownFields) == string(that.unknownFields) } @@ -2758,6 +2766,13 @@ func (m *TestReport) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.RunId) > 0 { + i -= len(m.RunId) + copy(dAtA[i:], m.RunId) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.RunId))) + i-- + dAtA[i] = 0x72 + } if m.IsArchived { i-- if m.IsArchived { @@ -3445,6 +3460,13 @@ func (m *CreateTestReportRequest) MarshalToSizedBufferVT(dAtA []byte) (int, erro i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.RunId) > 0 { + i -= len(m.RunId) + copy(dAtA[i:], m.RunId) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.RunId))) + i-- + dAtA[i] = 0x5a + } if len(m.SystemOperator) > 0 { i -= len(m.SystemOperator) copy(dAtA[i:], m.SystemOperator) @@ -4955,6 +4977,13 @@ func (m *TestReport) MarshalToSizedBufferVTStrict(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.RunId) > 0 { + i -= len(m.RunId) + copy(dAtA[i:], m.RunId) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.RunId))) + i-- + dAtA[i] = 0x72 + } if m.IsArchived { i-- if m.IsArchived { @@ -5659,6 +5688,13 @@ func (m *CreateTestReportRequest) MarshalToSizedBufferVTStrict(dAtA []byte) (int i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.RunId) > 0 { + i -= len(m.RunId) + copy(dAtA[i:], m.RunId) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.RunId))) + i-- + dAtA[i] = 0x5a + } if len(m.SystemOperator) > 0 { i -= len(m.SystemOperator) copy(dAtA[i:], m.SystemOperator) @@ -7203,6 +7239,10 @@ func (m *TestReport) SizeVT() (n int) { if m.IsArchived { n += 2 } + l = len(m.RunId) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } n += len(m.unknownFields) return n } @@ -7491,6 +7531,10 @@ func (m *CreateTestReportRequest) SizeVT() (n int) { if l > 0 { n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } + l = len(m.RunId) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } n += len(m.unknownFields) return n } @@ -8427,6 +8471,38 @@ func (m *TestReport) UnmarshalVT(dAtA []byte) error { } } m.IsArchived = bool(v != 0) + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RunId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RunId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -10066,6 +10142,38 @@ func (m *CreateTestReportRequest) UnmarshalVT(dAtA []byte) error { } m.SystemOperator = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RunId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RunId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -13537,6 +13645,42 @@ func (m *TestReport) UnmarshalVTUnsafe(dAtA []byte) error { } } m.IsArchived = bool(v != 0) + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RunId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var stringValue string + if intStringLen > 0 { + stringValue = unsafe.String(&dAtA[iNdEx], intStringLen) + } + m.RunId = stringValue + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -15256,6 +15400,42 @@ func (m *CreateTestReportRequest) UnmarshalVTUnsafe(dAtA []byte) error { } m.SystemOperator = stringValue iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RunId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var stringValue string + if intStringLen > 0 { + stringValue = unsafe.String(&dAtA[iNdEx], intStringLen) + } + m.RunId = stringValue + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/protos/sift/test_reports/v1/test_reports.proto b/protos/sift/test_reports/v1/test_reports.proto index 478a6d701..ce36eabed 100644 --- a/protos/sift/test_reports/v1/test_reports.proto +++ b/protos/sift/test_reports/v1/test_reports.proto @@ -53,6 +53,9 @@ message TestReport { // Whether the test run is archived (externally exposed) bool is_archived = 13 [(google.api.field_behavior) = OPTIONAL]; + + // The run ID for the test run + string run_id = 14 [(google.api.field_behavior) = OPTIONAL]; } enum TestStatus { @@ -378,6 +381,9 @@ message CreateTestReportRequest { // Unique identifier for user owner string system_operator = 10 [(google.api.field_behavior) = OPTIONAL]; + + // The run ID for the test report + string run_id = 11 [(google.api.field_behavior) = OPTIONAL]; } // Response message for CreateTestReport @@ -415,7 +421,7 @@ message ListTestReportsRequest { // A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. // Available fields to filter by are `test_report_id`, `status`, `name`, `test_system_name`, // `test_case`, `start_time`, `end_time`, `serial_number`, `created_by_user_id`, `modified_by_user_id`, - // `part_number`, `system_operator`, `archived_date`, and `metadata`. + // `part_number`, `system_operator`, `run_id`, `archived_date`, and `metadata`. // Metadata can be used in filters by using `metadata.{metadata_key_name}` as the field name. // For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). // For more information about the fields used for filtering, please refer to [this definition](/docs/api/grpc/protocol-buffers/test-results#testreport). Optional. @@ -446,7 +452,7 @@ message UpdateTestReportRequest { // The field mask specifying which fields to update. The fields available to be updated are // `status`, `name`, `test_system_name`, `test_case`, `start_time`, `end_time`, `serial_number`, - // `part_number`, `system_operator`, and `is_archived`. + // `part_number`, `system_operator`, `run_id`, and `is_archived`. google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = OPTIONAL]; } diff --git a/python/lib/sift/test_reports/v1/test_reports_pb2.py b/python/lib/sift/test_reports/v1/test_reports_pb2.py index b5f5fa31c..41bf2a24c 100644 --- a/python/lib/sift/test_reports/v1/test_reports_pb2.py +++ b/python/lib/sift/test_reports/v1/test_reports_pb2.py @@ -21,7 +21,7 @@ from sift.unit.v2 import unit_pb2 as sift_dot_unit_dot_v2_dot_unit__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\'sift/test_reports/v1/test_reports.proto\x12\x14sift.test_reports.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a google/protobuf/field_mask.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\x1a\x1fsift/metadata/v1/metadata.proto\x1a\x17sift/unit/v2/unit.proto\"\x88\x05\n\nTestReport\x12)\n\x0etest_report_id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\x0ctestReportId\x12=\n\x06status\x18\x02 \x01(\x0e\x32 .sift.test_reports.v1.TestStatusB\x03\xe0\x41\x02R\x06status\x12\x17\n\x04name\x18\x03 \x01(\tB\x03\xe0\x41\x02R\x04name\x12-\n\x10test_system_name\x18\x04 \x01(\tB\x03\xe0\x41\x02R\x0etestSystemName\x12 \n\ttest_case\x18\x05 \x01(\tB\x03\xe0\x41\x02R\x08testCase\x12>\n\nstart_time\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x02R\tstartTime\x12:\n\x08\x65nd_time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x02R\x07\x65ndTime\x12@\n\x08metadata\x18\x08 \x03(\x0b\x32\x1f.sift.metadata.v1.MetadataValueB\x03\xe0\x41\x01R\x08metadata\x12(\n\rserial_number\x18\t \x01(\tB\x03\xe0\x41\x01R\x0cserialNumber\x12$\n\x0bpart_number\x18\n \x01(\tB\x03\xe0\x41\x01R\npartNumber\x12,\n\x0fsystem_operator\x18\x0b \x01(\tB\x03\xe0\x41\x01R\x0esystemOperator\x12\x44\n\rarchived_date\x18\x0c \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x01R\x0c\x61rchivedDate\x12$\n\x0bis_archived\x18\r \x01(\x08\x42\x03\xe0\x41\x01R\nisArchived\"\xaf\x04\n\x08TestStep\x12%\n\x0ctest_step_id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\ntestStepId\x12)\n\x0etest_report_id\x18\x02 \x01(\tB\x03\xe0\x41\x02R\x0ctestReportId\x12)\n\x0eparent_step_id\x18\x03 \x01(\tB\x03\xe0\x41\x01R\x0cparentStepId\x12\x17\n\x04name\x18\x04 \x01(\tB\x03\xe0\x41\x02R\x04name\x12%\n\x0b\x64\x65scription\x18\x05 \x01(\tB\x03\xe0\x41\x01R\x0b\x64\x65scription\x12\x44\n\tstep_type\x18\x06 \x01(\x0e\x32\".sift.test_reports.v1.TestStepTypeB\x03\xe0\x41\x02R\x08stepType\x12 \n\tstep_path\x18\x07 \x01(\tB\x03\xe0\x41\x02R\x08stepPath\x12=\n\x06status\x18\x08 \x01(\x0e\x32 .sift.test_reports.v1.TestStatusB\x03\xe0\x41\x02R\x06status\x12>\n\nstart_time\x18\t \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x02R\tstartTime\x12:\n\x08\x65nd_time\x18\n \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x02R\x07\x65ndTime\x12\x43\n\nerror_info\x18\x0b \x01(\x0b\x32\x1f.sift.test_reports.v1.ErrorInfoB\x03\xe0\x41\x01R\terrorInfo\"Y\n\tErrorInfo\x12\"\n\nerror_code\x18\x01 \x01(\x05\x42\x03\xe0\x41\x02R\terrorCode\x12(\n\rerror_message\x18\x02 \x01(\tB\x03\xe0\x41\x02R\x0c\x65rrorMessage\"\xab\x05\n\x0fTestMeasurement\x12*\n\x0emeasurement_id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\rmeasurementId\x12Y\n\x10measurement_type\x18\x02 \x01(\x0e\x32).sift.test_reports.v1.TestMeasurementTypeB\x03\xe0\x41\x02R\x0fmeasurementType\x12\x17\n\x04name\x18\x03 \x01(\tB\x03\xe0\x41\x02R\x04name\x12%\n\x0ctest_step_id\x18\x04 \x01(\tB\x03\xe0\x41\x02R\ntestStepId\x12)\n\x0etest_report_id\x18\x05 \x01(\tB\x03\xe0\x41\x02R\x0ctestReportId\x12%\n\rnumeric_value\x18\x06 \x01(\x01H\x00R\x0cnumericValue\x12#\n\x0cstring_value\x18\x07 \x01(\tH\x00R\x0bstringValue\x12%\n\rboolean_value\x18\x08 \x01(\x08H\x00R\x0c\x62ooleanValue\x12+\n\x04unit\x18\t \x01(\x0b\x32\x12.sift.unit.v2.UnitB\x03\xe0\x41\x01R\x04unit\x12L\n\x0enumeric_bounds\x18\n \x01(\x0b\x32#.sift.test_reports.v1.NumericBoundsH\x01R\rnumericBounds\x12I\n\rstring_bounds\x18\x0b \x01(\x0b\x32\".sift.test_reports.v1.StringBoundsH\x01R\x0cstringBounds\x12\x1b\n\x06passed\x18\x0c \x01(\x08\x42\x03\xe0\x41\x02R\x06passed\x12=\n\ttimestamp\x18\r \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x02R\ttimestampB\x07\n\x05valueB\x08\n\x06\x62ounds\"W\n\rNumericBounds\x12\x1a\n\x03min\x18\x01 \x01(\x01\x42\x03\xe0\x41\x01H\x00R\x03min\x88\x01\x01\x12\x1a\n\x03max\x18\x02 \x01(\x01\x42\x03\xe0\x41\x01H\x01R\x03max\x88\x01\x01\x42\x06\n\x04_minB\x06\n\x04_max\":\n\x0cStringBounds\x12*\n\x0e\x65xpected_value\x18\x01 \x01(\tB\x03\xe0\x41\x02R\rexpectedValue\"D\n\x17ImportTestReportRequest\x12)\n\x0eremote_file_id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\x0cremoteFileId\"]\n\x18ImportTestReportResponse\x12\x41\n\x0btest_report\x18\x01 \x01(\x0b\x32 .sift.test_reports.v1.TestReportR\ntestReport\"\xfe\x03\n\x17\x43reateTestReportRequest\x12=\n\x06status\x18\x01 \x01(\x0e\x32 .sift.test_reports.v1.TestStatusB\x03\xe0\x41\x02R\x06status\x12\x17\n\x04name\x18\x02 \x01(\tB\x03\xe0\x41\x02R\x04name\x12-\n\x10test_system_name\x18\x03 \x01(\tB\x03\xe0\x41\x02R\x0etestSystemName\x12 \n\ttest_case\x18\x04 \x01(\tB\x03\xe0\x41\x02R\x08testCase\x12>\n\nstart_time\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x02R\tstartTime\x12:\n\x08\x65nd_time\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x02R\x07\x65ndTime\x12@\n\x08metadata\x18\x07 \x03(\x0b\x32\x1f.sift.metadata.v1.MetadataValueB\x03\xe0\x41\x01R\x08metadata\x12(\n\rserial_number\x18\x08 \x01(\tB\x03\xe0\x41\x01R\x0cserialNumber\x12$\n\x0bpart_number\x18\t \x01(\tB\x03\xe0\x41\x01R\npartNumber\x12,\n\x0fsystem_operator\x18\n \x01(\tB\x03\xe0\x41\x01R\x0esystemOperator\"]\n\x18\x43reateTestReportResponse\x12\x41\n\x0btest_report\x18\x01 \x01(\x0b\x32 .sift.test_reports.v1.TestReportR\ntestReport\"A\n\x14GetTestReportRequest\x12)\n\x0etest_report_id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\x0ctestReportId\"Z\n\x15GetTestReportResponse\x12\x41\n\x0btest_report\x18\x01 \x01(\x0b\x32 .sift.test_reports.v1.TestReportR\ntestReport\"\x9b\x01\n\x16ListTestReportsRequest\x12 \n\tpage_size\x18\x01 \x01(\rB\x03\xe0\x41\x01R\x08pageSize\x12\"\n\npage_token\x18\x02 \x01(\tB\x03\xe0\x41\x01R\tpageToken\x12\x1b\n\x06\x66ilter\x18\x03 \x01(\tB\x03\xe0\x41\x01R\x06\x66ilter\x12\x1e\n\x08order_by\x18\x04 \x01(\tB\x03\xe0\x41\x01R\x07orderBy\"\x86\x01\n\x17ListTestReportsResponse\x12\x43\n\x0ctest_reports\x18\x01 \x03(\x0b\x32 .sift.test_reports.v1.TestReportR\x0btestReports\x12&\n\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"\xa3\x01\n\x17UpdateTestReportRequest\x12\x46\n\x0btest_report\x18\x01 \x01(\x0b\x32 .sift.test_reports.v1.TestReportB\x03\xe0\x41\x02R\ntestReport\x12@\n\x0bupdate_mask\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.FieldMaskB\x03\xe0\x41\x01R\nupdateMask\"]\n\x18UpdateTestReportResponse\x12\x41\n\x0btest_report\x18\x01 \x01(\x0b\x32 .sift.test_reports.v1.TestReportR\ntestReport\"D\n\x17\x44\x65leteTestReportRequest\x12)\n\x0etest_report_id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\x0ctestReportId\"\x1a\n\x18\x44\x65leteTestReportResponse\"Y\n\x15\x43reateTestStepRequest\x12@\n\ttest_step\x18\x01 \x01(\x0b\x32\x1e.sift.test_reports.v1.TestStepB\x03\xe0\x41\x02R\x08testStep\"U\n\x16\x43reateTestStepResponse\x12;\n\ttest_step\x18\x01 \x01(\x0b\x32\x1e.sift.test_reports.v1.TestStepR\x08testStep\"\x99\x01\n\x14ListTestStepsRequest\x12 \n\tpage_size\x18\x01 \x01(\rB\x03\xe0\x41\x01R\x08pageSize\x12\"\n\npage_token\x18\x02 \x01(\tB\x03\xe0\x41\x01R\tpageToken\x12\x1b\n\x06\x66ilter\x18\x03 \x01(\tB\x03\xe0\x41\x01R\x06\x66ilter\x12\x1e\n\x08order_by\x18\x04 \x01(\tB\x03\xe0\x41\x01R\x07orderBy\"~\n\x15ListTestStepsResponse\x12=\n\ntest_steps\x18\x01 \x03(\x0b\x32\x1e.sift.test_reports.v1.TestStepR\ttestSteps\x12&\n\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"\x9b\x01\n\x15UpdateTestStepRequest\x12@\n\ttest_step\x18\x01 \x01(\x0b\x32\x1e.sift.test_reports.v1.TestStepB\x03\xe0\x41\x02R\x08testStep\x12@\n\x0bupdate_mask\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.FieldMaskB\x03\xe0\x41\x01R\nupdateMask\"U\n\x16UpdateTestStepResponse\x12;\n\ttest_step\x18\x01 \x01(\x0b\x32\x1e.sift.test_reports.v1.TestStepR\x08testStep\">\n\x15\x44\x65leteTestStepRequest\x12%\n\x0ctest_step_id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\ntestStepId\"\x18\n\x16\x44\x65leteTestStepResponse\"u\n\x1c\x43reateTestMeasurementRequest\x12U\n\x10test_measurement\x18\x01 \x01(\x0b\x32%.sift.test_reports.v1.TestMeasurementB\x03\xe0\x41\x02R\x0ftestMeasurement\"q\n\x1d\x43reateTestMeasurementResponse\x12P\n\x10test_measurement\x18\x01 \x01(\x0b\x32%.sift.test_reports.v1.TestMeasurementR\x0ftestMeasurement\"x\n\x1d\x43reateTestMeasurementsRequest\x12W\n\x11test_measurements\x18\x01 \x03(\x0b\x32%.sift.test_reports.v1.TestMeasurementB\x03\xe0\x41\x02R\x10testMeasurements\"\x91\x01\n\x1e\x43reateTestMeasurementsResponse\x12\x41\n\x1ameasurements_created_count\x18\x01 \x01(\x05\x42\x03\xe0\x41\x02R\x18measurementsCreatedCount\x12,\n\x0fmeasurement_ids\x18\x02 \x03(\tB\x03\xe0\x41\x02R\x0emeasurementIds\"\xa0\x01\n\x1bListTestMeasurementsRequest\x12 \n\tpage_size\x18\x01 \x01(\rB\x03\xe0\x41\x01R\x08pageSize\x12\"\n\npage_token\x18\x02 \x01(\tB\x03\xe0\x41\x01R\tpageToken\x12\x1b\n\x06\x66ilter\x18\x03 \x01(\tB\x03\xe0\x41\x01R\x06\x66ilter\x12\x1e\n\x08order_by\x18\x04 \x01(\tB\x03\xe0\x41\x01R\x07orderBy\"\x9a\x01\n\x1cListTestMeasurementsResponse\x12R\n\x11test_measurements\x18\x01 \x03(\x0b\x32%.sift.test_reports.v1.TestMeasurementR\x10testMeasurements\x12&\n\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"4\n\x15\x43ountTestStepsRequest\x12\x1b\n\x06\x66ilter\x18\x01 \x01(\tB\x03\xe0\x41\x01R\x06\x66ilter\".\n\x16\x43ountTestStepsResponse\x12\x14\n\x05\x63ount\x18\x01 \x01(\x03R\x05\x63ount\";\n\x1c\x43ountTestMeasurementsRequest\x12\x1b\n\x06\x66ilter\x18\x01 \x01(\tB\x03\xe0\x41\x01R\x06\x66ilter\"5\n\x1d\x43ountTestMeasurementsResponse\x12\x14\n\x05\x63ount\x18\x01 \x01(\x03R\x05\x63ount\"\xb7\x01\n\x1cUpdateTestMeasurementRequest\x12U\n\x10test_measurement\x18\x01 \x01(\x0b\x32%.sift.test_reports.v1.TestMeasurementB\x03\xe0\x41\x02R\x0ftestMeasurement\x12@\n\x0bupdate_mask\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.FieldMaskB\x03\xe0\x41\x01R\nupdateMask\"q\n\x1dUpdateTestMeasurementResponse\x12P\n\x10test_measurement\x18\x01 \x01(\x0b\x32%.sift.test_reports.v1.TestMeasurementR\x0ftestMeasurement\"J\n\x1c\x44\x65leteTestMeasurementRequest\x12*\n\x0emeasurement_id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\rmeasurementId\"\x1f\n\x1d\x44\x65leteTestMeasurementResponse*\xd6\x01\n\nTestStatus\x12\x1b\n\x17TEST_STATUS_UNSPECIFIED\x10\x00\x12\x15\n\x11TEST_STATUS_DRAFT\x10\x01\x12\x16\n\x12TEST_STATUS_PASSED\x10\x02\x12\x16\n\x12TEST_STATUS_FAILED\x10\x03\x12\x17\n\x13TEST_STATUS_ABORTED\x10\x04\x12\x15\n\x11TEST_STATUS_ERROR\x10\x05\x12\x1b\n\x17TEST_STATUS_IN_PROGRESS\x10\x06\x12\x17\n\x13TEST_STATUS_SKIPPED\x10\x07*\xa1\x01\n\x0cTestStepType\x12\x1e\n\x1aTEST_STEP_TYPE_UNSPECIFIED\x10\x00\x12\x1b\n\x17TEST_STEP_TYPE_SEQUENCE\x10\x01\x12\x18\n\x14TEST_STEP_TYPE_GROUP\x10\x02\x12\x19\n\x15TEST_STEP_TYPE_ACTION\x10\x03\x12\x1f\n\x1bTEST_STEP_TYPE_FLOW_CONTROL\x10\x04*\xc4\x01\n\x13TestMeasurementType\x12%\n!TEST_MEASUREMENT_TYPE_UNSPECIFIED\x10\x00\x12 \n\x1cTEST_MEASUREMENT_TYPE_DOUBLE\x10\x01\x12 \n\x1cTEST_MEASUREMENT_TYPE_STRING\x10\x03\x12!\n\x1dTEST_MEASUREMENT_TYPE_BOOLEAN\x10\x04\x12\x1f\n\x1bTEST_MEASUREMENT_TYPE_LIMIT\x10\x05\x32\xd7\x1c\n\x11TestReportService\x12\xe4\x01\n\x10ImportTestReport\x12-.sift.test_reports.v1.ImportTestReportRequest\x1a..sift.test_reports.v1.ImportTestReportResponse\"q\x92\x41H\x12\x10ImportTestReport\x1a\x34Imports a test report from an already-uploaded file.\x82\xd3\xe4\x93\x02 \"\x1b/api/v1/test-reports:import:\x01*\x12\xbe\x01\n\x10\x43reateTestReport\x12-.sift.test_reports.v1.CreateTestReportRequest\x1a..sift.test_reports.v1.CreateTestReportResponse\"K\x92\x41)\x12\x10\x43reateTestReport\x1a\x15\x43reates a test report\x82\xd3\xe4\x93\x02\x19\"\x14/api/v1/test-reports:\x01*\x12\xc4\x01\n\rGetTestReport\x12*.sift.test_reports.v1.GetTestReportRequest\x1a+.sift.test_reports.v1.GetTestReportResponse\"Z\x92\x41*\x12\rGetTestReport\x1a\x19Gets a single test report\x82\xd3\xe4\x93\x02\'\x12%/api/v1/test-reports/{test_report_id}\x12\xcc\x01\n\x0fListTestReports\x12,.sift.test_reports.v1.ListTestReportsRequest\x1a-.sift.test_reports.v1.ListTestReportsResponse\"\\\x92\x41=\x12\x0fListTestReports\x1a*Lists test reports with optional filtering\x82\xd3\xe4\x93\x02\x16\x12\x14/api/v1/test-reports\x12\xbe\x01\n\x10UpdateTestReport\x12-.sift.test_reports.v1.UpdateTestReportRequest\x1a..sift.test_reports.v1.UpdateTestReportResponse\"K\x92\x41)\x12\x10UpdateTestReport\x1a\x15Updates a test report\x82\xd3\xe4\x93\x02\x19\x32\x14/api/v1/test-reports:\x01*\x12\xcc\x01\n\x10\x44\x65leteTestReport\x12-.sift.test_reports.v1.DeleteTestReportRequest\x1a..sift.test_reports.v1.DeleteTestReportResponse\"Y\x92\x41)\x12\x10\x44\x65leteTestReport\x1a\x15\x44\x65letes a test report\x82\xd3\xe4\x93\x02\'*%/api/v1/test-reports/{test_report_id}\x12\xb2\x01\n\x0e\x43reateTestStep\x12+.sift.test_reports.v1.CreateTestStepRequest\x1a,.sift.test_reports.v1.CreateTestStepResponse\"E\x92\x41%\x12\x0e\x43reateTestStep\x1a\x13\x43reates a test step\x82\xd3\xe4\x93\x02\x17\"\x12/api/v1/test-steps:\x01*\x12\xc0\x01\n\rListTestSteps\x12*.sift.test_reports.v1.ListTestStepsRequest\x1a+.sift.test_reports.v1.ListTestStepsResponse\"V\x92\x41\x39\x12\rListTestSteps\x1a(Lists test steps with optional filtering\x82\xd3\xe4\x93\x02\x14\x12\x12/api/v1/test-steps\x12\xb2\x01\n\x0eUpdateTestStep\x12+.sift.test_reports.v1.UpdateTestStepRequest\x1a,.sift.test_reports.v1.UpdateTestStepResponse\"E\x92\x41%\x12\x0eUpdateTestStep\x1a\x13Updates a test step\x82\xd3\xe4\x93\x02\x17\x32\x12/api/v1/test-steps:\x01*\x12\xbe\x01\n\x0e\x44\x65leteTestStep\x12+.sift.test_reports.v1.DeleteTestStepRequest\x1a,.sift.test_reports.v1.DeleteTestStepResponse\"Q\x92\x41%\x12\x0e\x44\x65leteTestStep\x1a\x13\x44\x65letes a test step\x82\xd3\xe4\x93\x02#*!/api/v1/test-steps/{test_step_id}\x12\xdc\x01\n\x15\x43reateTestMeasurement\x12\x32.sift.test_reports.v1.CreateTestMeasurementRequest\x1a\x33.sift.test_reports.v1.CreateTestMeasurementResponse\"Z\x92\x41\x33\x12\x15\x43reateTestMeasurement\x1a\x1a\x43reates a test measurement\x82\xd3\xe4\x93\x02\x1e\"\x19/api/v1/test-measurements:\x01*\x12\x82\x02\n\x16\x43reateTestMeasurements\x12\x33.sift.test_reports.v1.CreateTestMeasurementsRequest\x1a\x34.sift.test_reports.v1.CreateTestMeasurementsResponse\"}\x92\x41P\x12\x16\x43reateTestMeasurements\x1a\x36\x43reates multiple test measurements in a single request\x82\xd3\xe4\x93\x02$\"\x1f/api/v1/test-measurements:batch:\x01*\x12\xea\x01\n\x14ListTestMeasurements\x12\x31.sift.test_reports.v1.ListTestMeasurementsRequest\x1a\x32.sift.test_reports.v1.ListTestMeasurementsResponse\"k\x92\x41G\x12\x14ListTestMeasurements\x1a/Lists test measurements with optional filtering\x82\xd3\xe4\x93\x02\x1b\x12\x19/api/v1/test-measurements\x12\xcb\x01\n\x0e\x43ountTestSteps\x12+.sift.test_reports.v1.CountTestStepsRequest\x1a,.sift.test_reports.v1.CountTestStepsResponse\"^\x92\x41;\x12\x0e\x43ountTestSteps\x1a)Counts test steps with optional filtering\x82\xd3\xe4\x93\x02\x1a\x12\x18/api/v1/test-steps/count\x12\xf5\x01\n\x15\x43ountTestMeasurements\x12\x32.sift.test_reports.v1.CountTestMeasurementsRequest\x1a\x33.sift.test_reports.v1.CountTestMeasurementsResponse\"s\x92\x41I\x12\x15\x43ountTestMeasurements\x1a\x30\x43ounts test measurements with optional filtering\x82\xd3\xe4\x93\x02!\x12\x1f/api/v1/test-measurements/count\x12\xdc\x01\n\x15UpdateTestMeasurement\x12\x32.sift.test_reports.v1.UpdateTestMeasurementRequest\x1a\x33.sift.test_reports.v1.UpdateTestMeasurementResponse\"Z\x92\x41\x33\x12\x15UpdateTestMeasurement\x1a\x1aUpdates a test measurement\x82\xd3\xe4\x93\x02\x1e\x32\x19/api/v1/test-measurements:\x01*\x12\xea\x01\n\x15\x44\x65leteTestMeasurement\x12\x32.sift.test_reports.v1.DeleteTestMeasurementRequest\x1a\x33.sift.test_reports.v1.DeleteTestMeasurementResponse\"h\x92\x41\x33\x12\x15\x44\x65leteTestMeasurement\x1a\x1a\x44\x65letes a test measurement\x82\xd3\xe4\x93\x02,**/api/v1/test-measurements/{measurement_id}\x1a#\x92\x41 \x12\x1eService to manage test reportsB\xb5\x01\n\x18\x63om.sift.test_reports.v1B\x10TestReportsProtoP\x01\xa2\x02\x03STX\xaa\x02\x13Sift.TestReports.V1\xca\x02\x13Sift\\TestReports\\V1\xe2\x02\x1fSift\\TestReports\\V1\\GPBMetadata\xea\x02\x15Sift::TestReports::V1\x92\x41\x18\x12\x16\n\x14Test Results Serviceb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\'sift/test_reports/v1/test_reports.proto\x12\x14sift.test_reports.v1\x1a\x1cgoogle/api/annotations.proto\x1a\x1fgoogle/api/field_behavior.proto\x1a google/protobuf/field_mask.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\x1a\x1fsift/metadata/v1/metadata.proto\x1a\x17sift/unit/v2/unit.proto\"\xa4\x05\n\nTestReport\x12)\n\x0etest_report_id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\x0ctestReportId\x12=\n\x06status\x18\x02 \x01(\x0e\x32 .sift.test_reports.v1.TestStatusB\x03\xe0\x41\x02R\x06status\x12\x17\n\x04name\x18\x03 \x01(\tB\x03\xe0\x41\x02R\x04name\x12-\n\x10test_system_name\x18\x04 \x01(\tB\x03\xe0\x41\x02R\x0etestSystemName\x12 \n\ttest_case\x18\x05 \x01(\tB\x03\xe0\x41\x02R\x08testCase\x12>\n\nstart_time\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x02R\tstartTime\x12:\n\x08\x65nd_time\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x02R\x07\x65ndTime\x12@\n\x08metadata\x18\x08 \x03(\x0b\x32\x1f.sift.metadata.v1.MetadataValueB\x03\xe0\x41\x01R\x08metadata\x12(\n\rserial_number\x18\t \x01(\tB\x03\xe0\x41\x01R\x0cserialNumber\x12$\n\x0bpart_number\x18\n \x01(\tB\x03\xe0\x41\x01R\npartNumber\x12,\n\x0fsystem_operator\x18\x0b \x01(\tB\x03\xe0\x41\x01R\x0esystemOperator\x12\x44\n\rarchived_date\x18\x0c \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x01R\x0c\x61rchivedDate\x12$\n\x0bis_archived\x18\r \x01(\x08\x42\x03\xe0\x41\x01R\nisArchived\x12\x1a\n\x06run_id\x18\x0e \x01(\tB\x03\xe0\x41\x01R\x05runId\"\xaf\x04\n\x08TestStep\x12%\n\x0ctest_step_id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\ntestStepId\x12)\n\x0etest_report_id\x18\x02 \x01(\tB\x03\xe0\x41\x02R\x0ctestReportId\x12)\n\x0eparent_step_id\x18\x03 \x01(\tB\x03\xe0\x41\x01R\x0cparentStepId\x12\x17\n\x04name\x18\x04 \x01(\tB\x03\xe0\x41\x02R\x04name\x12%\n\x0b\x64\x65scription\x18\x05 \x01(\tB\x03\xe0\x41\x01R\x0b\x64\x65scription\x12\x44\n\tstep_type\x18\x06 \x01(\x0e\x32\".sift.test_reports.v1.TestStepTypeB\x03\xe0\x41\x02R\x08stepType\x12 \n\tstep_path\x18\x07 \x01(\tB\x03\xe0\x41\x02R\x08stepPath\x12=\n\x06status\x18\x08 \x01(\x0e\x32 .sift.test_reports.v1.TestStatusB\x03\xe0\x41\x02R\x06status\x12>\n\nstart_time\x18\t \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x02R\tstartTime\x12:\n\x08\x65nd_time\x18\n \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x02R\x07\x65ndTime\x12\x43\n\nerror_info\x18\x0b \x01(\x0b\x32\x1f.sift.test_reports.v1.ErrorInfoB\x03\xe0\x41\x01R\terrorInfo\"Y\n\tErrorInfo\x12\"\n\nerror_code\x18\x01 \x01(\x05\x42\x03\xe0\x41\x02R\terrorCode\x12(\n\rerror_message\x18\x02 \x01(\tB\x03\xe0\x41\x02R\x0c\x65rrorMessage\"\xab\x05\n\x0fTestMeasurement\x12*\n\x0emeasurement_id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\rmeasurementId\x12Y\n\x10measurement_type\x18\x02 \x01(\x0e\x32).sift.test_reports.v1.TestMeasurementTypeB\x03\xe0\x41\x02R\x0fmeasurementType\x12\x17\n\x04name\x18\x03 \x01(\tB\x03\xe0\x41\x02R\x04name\x12%\n\x0ctest_step_id\x18\x04 \x01(\tB\x03\xe0\x41\x02R\ntestStepId\x12)\n\x0etest_report_id\x18\x05 \x01(\tB\x03\xe0\x41\x02R\x0ctestReportId\x12%\n\rnumeric_value\x18\x06 \x01(\x01H\x00R\x0cnumericValue\x12#\n\x0cstring_value\x18\x07 \x01(\tH\x00R\x0bstringValue\x12%\n\rboolean_value\x18\x08 \x01(\x08H\x00R\x0c\x62ooleanValue\x12+\n\x04unit\x18\t \x01(\x0b\x32\x12.sift.unit.v2.UnitB\x03\xe0\x41\x01R\x04unit\x12L\n\x0enumeric_bounds\x18\n \x01(\x0b\x32#.sift.test_reports.v1.NumericBoundsH\x01R\rnumericBounds\x12I\n\rstring_bounds\x18\x0b \x01(\x0b\x32\".sift.test_reports.v1.StringBoundsH\x01R\x0cstringBounds\x12\x1b\n\x06passed\x18\x0c \x01(\x08\x42\x03\xe0\x41\x02R\x06passed\x12=\n\ttimestamp\x18\r \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x02R\ttimestampB\x07\n\x05valueB\x08\n\x06\x62ounds\"W\n\rNumericBounds\x12\x1a\n\x03min\x18\x01 \x01(\x01\x42\x03\xe0\x41\x01H\x00R\x03min\x88\x01\x01\x12\x1a\n\x03max\x18\x02 \x01(\x01\x42\x03\xe0\x41\x01H\x01R\x03max\x88\x01\x01\x42\x06\n\x04_minB\x06\n\x04_max\":\n\x0cStringBounds\x12*\n\x0e\x65xpected_value\x18\x01 \x01(\tB\x03\xe0\x41\x02R\rexpectedValue\"D\n\x17ImportTestReportRequest\x12)\n\x0eremote_file_id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\x0cremoteFileId\"]\n\x18ImportTestReportResponse\x12\x41\n\x0btest_report\x18\x01 \x01(\x0b\x32 .sift.test_reports.v1.TestReportR\ntestReport\"\x9a\x04\n\x17\x43reateTestReportRequest\x12=\n\x06status\x18\x01 \x01(\x0e\x32 .sift.test_reports.v1.TestStatusB\x03\xe0\x41\x02R\x06status\x12\x17\n\x04name\x18\x02 \x01(\tB\x03\xe0\x41\x02R\x04name\x12-\n\x10test_system_name\x18\x03 \x01(\tB\x03\xe0\x41\x02R\x0etestSystemName\x12 \n\ttest_case\x18\x04 \x01(\tB\x03\xe0\x41\x02R\x08testCase\x12>\n\nstart_time\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x02R\tstartTime\x12:\n\x08\x65nd_time\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.TimestampB\x03\xe0\x41\x02R\x07\x65ndTime\x12@\n\x08metadata\x18\x07 \x03(\x0b\x32\x1f.sift.metadata.v1.MetadataValueB\x03\xe0\x41\x01R\x08metadata\x12(\n\rserial_number\x18\x08 \x01(\tB\x03\xe0\x41\x01R\x0cserialNumber\x12$\n\x0bpart_number\x18\t \x01(\tB\x03\xe0\x41\x01R\npartNumber\x12,\n\x0fsystem_operator\x18\n \x01(\tB\x03\xe0\x41\x01R\x0esystemOperator\x12\x1a\n\x06run_id\x18\x0b \x01(\tB\x03\xe0\x41\x01R\x05runId\"]\n\x18\x43reateTestReportResponse\x12\x41\n\x0btest_report\x18\x01 \x01(\x0b\x32 .sift.test_reports.v1.TestReportR\ntestReport\"A\n\x14GetTestReportRequest\x12)\n\x0etest_report_id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\x0ctestReportId\"Z\n\x15GetTestReportResponse\x12\x41\n\x0btest_report\x18\x01 \x01(\x0b\x32 .sift.test_reports.v1.TestReportR\ntestReport\"\x9b\x01\n\x16ListTestReportsRequest\x12 \n\tpage_size\x18\x01 \x01(\rB\x03\xe0\x41\x01R\x08pageSize\x12\"\n\npage_token\x18\x02 \x01(\tB\x03\xe0\x41\x01R\tpageToken\x12\x1b\n\x06\x66ilter\x18\x03 \x01(\tB\x03\xe0\x41\x01R\x06\x66ilter\x12\x1e\n\x08order_by\x18\x04 \x01(\tB\x03\xe0\x41\x01R\x07orderBy\"\x86\x01\n\x17ListTestReportsResponse\x12\x43\n\x0ctest_reports\x18\x01 \x03(\x0b\x32 .sift.test_reports.v1.TestReportR\x0btestReports\x12&\n\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"\xa3\x01\n\x17UpdateTestReportRequest\x12\x46\n\x0btest_report\x18\x01 \x01(\x0b\x32 .sift.test_reports.v1.TestReportB\x03\xe0\x41\x02R\ntestReport\x12@\n\x0bupdate_mask\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.FieldMaskB\x03\xe0\x41\x01R\nupdateMask\"]\n\x18UpdateTestReportResponse\x12\x41\n\x0btest_report\x18\x01 \x01(\x0b\x32 .sift.test_reports.v1.TestReportR\ntestReport\"D\n\x17\x44\x65leteTestReportRequest\x12)\n\x0etest_report_id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\x0ctestReportId\"\x1a\n\x18\x44\x65leteTestReportResponse\"Y\n\x15\x43reateTestStepRequest\x12@\n\ttest_step\x18\x01 \x01(\x0b\x32\x1e.sift.test_reports.v1.TestStepB\x03\xe0\x41\x02R\x08testStep\"U\n\x16\x43reateTestStepResponse\x12;\n\ttest_step\x18\x01 \x01(\x0b\x32\x1e.sift.test_reports.v1.TestStepR\x08testStep\"\x99\x01\n\x14ListTestStepsRequest\x12 \n\tpage_size\x18\x01 \x01(\rB\x03\xe0\x41\x01R\x08pageSize\x12\"\n\npage_token\x18\x02 \x01(\tB\x03\xe0\x41\x01R\tpageToken\x12\x1b\n\x06\x66ilter\x18\x03 \x01(\tB\x03\xe0\x41\x01R\x06\x66ilter\x12\x1e\n\x08order_by\x18\x04 \x01(\tB\x03\xe0\x41\x01R\x07orderBy\"~\n\x15ListTestStepsResponse\x12=\n\ntest_steps\x18\x01 \x03(\x0b\x32\x1e.sift.test_reports.v1.TestStepR\ttestSteps\x12&\n\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"\x9b\x01\n\x15UpdateTestStepRequest\x12@\n\ttest_step\x18\x01 \x01(\x0b\x32\x1e.sift.test_reports.v1.TestStepB\x03\xe0\x41\x02R\x08testStep\x12@\n\x0bupdate_mask\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.FieldMaskB\x03\xe0\x41\x01R\nupdateMask\"U\n\x16UpdateTestStepResponse\x12;\n\ttest_step\x18\x01 \x01(\x0b\x32\x1e.sift.test_reports.v1.TestStepR\x08testStep\">\n\x15\x44\x65leteTestStepRequest\x12%\n\x0ctest_step_id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\ntestStepId\"\x18\n\x16\x44\x65leteTestStepResponse\"u\n\x1c\x43reateTestMeasurementRequest\x12U\n\x10test_measurement\x18\x01 \x01(\x0b\x32%.sift.test_reports.v1.TestMeasurementB\x03\xe0\x41\x02R\x0ftestMeasurement\"q\n\x1d\x43reateTestMeasurementResponse\x12P\n\x10test_measurement\x18\x01 \x01(\x0b\x32%.sift.test_reports.v1.TestMeasurementR\x0ftestMeasurement\"x\n\x1d\x43reateTestMeasurementsRequest\x12W\n\x11test_measurements\x18\x01 \x03(\x0b\x32%.sift.test_reports.v1.TestMeasurementB\x03\xe0\x41\x02R\x10testMeasurements\"\x91\x01\n\x1e\x43reateTestMeasurementsResponse\x12\x41\n\x1ameasurements_created_count\x18\x01 \x01(\x05\x42\x03\xe0\x41\x02R\x18measurementsCreatedCount\x12,\n\x0fmeasurement_ids\x18\x02 \x03(\tB\x03\xe0\x41\x02R\x0emeasurementIds\"\xa0\x01\n\x1bListTestMeasurementsRequest\x12 \n\tpage_size\x18\x01 \x01(\rB\x03\xe0\x41\x01R\x08pageSize\x12\"\n\npage_token\x18\x02 \x01(\tB\x03\xe0\x41\x01R\tpageToken\x12\x1b\n\x06\x66ilter\x18\x03 \x01(\tB\x03\xe0\x41\x01R\x06\x66ilter\x12\x1e\n\x08order_by\x18\x04 \x01(\tB\x03\xe0\x41\x01R\x07orderBy\"\x9a\x01\n\x1cListTestMeasurementsResponse\x12R\n\x11test_measurements\x18\x01 \x03(\x0b\x32%.sift.test_reports.v1.TestMeasurementR\x10testMeasurements\x12&\n\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\"4\n\x15\x43ountTestStepsRequest\x12\x1b\n\x06\x66ilter\x18\x01 \x01(\tB\x03\xe0\x41\x01R\x06\x66ilter\".\n\x16\x43ountTestStepsResponse\x12\x14\n\x05\x63ount\x18\x01 \x01(\x03R\x05\x63ount\";\n\x1c\x43ountTestMeasurementsRequest\x12\x1b\n\x06\x66ilter\x18\x01 \x01(\tB\x03\xe0\x41\x01R\x06\x66ilter\"5\n\x1d\x43ountTestMeasurementsResponse\x12\x14\n\x05\x63ount\x18\x01 \x01(\x03R\x05\x63ount\"\xb7\x01\n\x1cUpdateTestMeasurementRequest\x12U\n\x10test_measurement\x18\x01 \x01(\x0b\x32%.sift.test_reports.v1.TestMeasurementB\x03\xe0\x41\x02R\x0ftestMeasurement\x12@\n\x0bupdate_mask\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.FieldMaskB\x03\xe0\x41\x01R\nupdateMask\"q\n\x1dUpdateTestMeasurementResponse\x12P\n\x10test_measurement\x18\x01 \x01(\x0b\x32%.sift.test_reports.v1.TestMeasurementR\x0ftestMeasurement\"J\n\x1c\x44\x65leteTestMeasurementRequest\x12*\n\x0emeasurement_id\x18\x01 \x01(\tB\x03\xe0\x41\x02R\rmeasurementId\"\x1f\n\x1d\x44\x65leteTestMeasurementResponse*\xd6\x01\n\nTestStatus\x12\x1b\n\x17TEST_STATUS_UNSPECIFIED\x10\x00\x12\x15\n\x11TEST_STATUS_DRAFT\x10\x01\x12\x16\n\x12TEST_STATUS_PASSED\x10\x02\x12\x16\n\x12TEST_STATUS_FAILED\x10\x03\x12\x17\n\x13TEST_STATUS_ABORTED\x10\x04\x12\x15\n\x11TEST_STATUS_ERROR\x10\x05\x12\x1b\n\x17TEST_STATUS_IN_PROGRESS\x10\x06\x12\x17\n\x13TEST_STATUS_SKIPPED\x10\x07*\xa1\x01\n\x0cTestStepType\x12\x1e\n\x1aTEST_STEP_TYPE_UNSPECIFIED\x10\x00\x12\x1b\n\x17TEST_STEP_TYPE_SEQUENCE\x10\x01\x12\x18\n\x14TEST_STEP_TYPE_GROUP\x10\x02\x12\x19\n\x15TEST_STEP_TYPE_ACTION\x10\x03\x12\x1f\n\x1bTEST_STEP_TYPE_FLOW_CONTROL\x10\x04*\xc4\x01\n\x13TestMeasurementType\x12%\n!TEST_MEASUREMENT_TYPE_UNSPECIFIED\x10\x00\x12 \n\x1cTEST_MEASUREMENT_TYPE_DOUBLE\x10\x01\x12 \n\x1cTEST_MEASUREMENT_TYPE_STRING\x10\x03\x12!\n\x1dTEST_MEASUREMENT_TYPE_BOOLEAN\x10\x04\x12\x1f\n\x1bTEST_MEASUREMENT_TYPE_LIMIT\x10\x05\x32\xd7\x1c\n\x11TestReportService\x12\xe4\x01\n\x10ImportTestReport\x12-.sift.test_reports.v1.ImportTestReportRequest\x1a..sift.test_reports.v1.ImportTestReportResponse\"q\x92\x41H\x12\x10ImportTestReport\x1a\x34Imports a test report from an already-uploaded file.\x82\xd3\xe4\x93\x02 \"\x1b/api/v1/test-reports:import:\x01*\x12\xbe\x01\n\x10\x43reateTestReport\x12-.sift.test_reports.v1.CreateTestReportRequest\x1a..sift.test_reports.v1.CreateTestReportResponse\"K\x92\x41)\x12\x10\x43reateTestReport\x1a\x15\x43reates a test report\x82\xd3\xe4\x93\x02\x19\"\x14/api/v1/test-reports:\x01*\x12\xc4\x01\n\rGetTestReport\x12*.sift.test_reports.v1.GetTestReportRequest\x1a+.sift.test_reports.v1.GetTestReportResponse\"Z\x92\x41*\x12\rGetTestReport\x1a\x19Gets a single test report\x82\xd3\xe4\x93\x02\'\x12%/api/v1/test-reports/{test_report_id}\x12\xcc\x01\n\x0fListTestReports\x12,.sift.test_reports.v1.ListTestReportsRequest\x1a-.sift.test_reports.v1.ListTestReportsResponse\"\\\x92\x41=\x12\x0fListTestReports\x1a*Lists test reports with optional filtering\x82\xd3\xe4\x93\x02\x16\x12\x14/api/v1/test-reports\x12\xbe\x01\n\x10UpdateTestReport\x12-.sift.test_reports.v1.UpdateTestReportRequest\x1a..sift.test_reports.v1.UpdateTestReportResponse\"K\x92\x41)\x12\x10UpdateTestReport\x1a\x15Updates a test report\x82\xd3\xe4\x93\x02\x19\x32\x14/api/v1/test-reports:\x01*\x12\xcc\x01\n\x10\x44\x65leteTestReport\x12-.sift.test_reports.v1.DeleteTestReportRequest\x1a..sift.test_reports.v1.DeleteTestReportResponse\"Y\x92\x41)\x12\x10\x44\x65leteTestReport\x1a\x15\x44\x65letes a test report\x82\xd3\xe4\x93\x02\'*%/api/v1/test-reports/{test_report_id}\x12\xb2\x01\n\x0e\x43reateTestStep\x12+.sift.test_reports.v1.CreateTestStepRequest\x1a,.sift.test_reports.v1.CreateTestStepResponse\"E\x92\x41%\x12\x0e\x43reateTestStep\x1a\x13\x43reates a test step\x82\xd3\xe4\x93\x02\x17\"\x12/api/v1/test-steps:\x01*\x12\xc0\x01\n\rListTestSteps\x12*.sift.test_reports.v1.ListTestStepsRequest\x1a+.sift.test_reports.v1.ListTestStepsResponse\"V\x92\x41\x39\x12\rListTestSteps\x1a(Lists test steps with optional filtering\x82\xd3\xe4\x93\x02\x14\x12\x12/api/v1/test-steps\x12\xb2\x01\n\x0eUpdateTestStep\x12+.sift.test_reports.v1.UpdateTestStepRequest\x1a,.sift.test_reports.v1.UpdateTestStepResponse\"E\x92\x41%\x12\x0eUpdateTestStep\x1a\x13Updates a test step\x82\xd3\xe4\x93\x02\x17\x32\x12/api/v1/test-steps:\x01*\x12\xbe\x01\n\x0e\x44\x65leteTestStep\x12+.sift.test_reports.v1.DeleteTestStepRequest\x1a,.sift.test_reports.v1.DeleteTestStepResponse\"Q\x92\x41%\x12\x0e\x44\x65leteTestStep\x1a\x13\x44\x65letes a test step\x82\xd3\xe4\x93\x02#*!/api/v1/test-steps/{test_step_id}\x12\xdc\x01\n\x15\x43reateTestMeasurement\x12\x32.sift.test_reports.v1.CreateTestMeasurementRequest\x1a\x33.sift.test_reports.v1.CreateTestMeasurementResponse\"Z\x92\x41\x33\x12\x15\x43reateTestMeasurement\x1a\x1a\x43reates a test measurement\x82\xd3\xe4\x93\x02\x1e\"\x19/api/v1/test-measurements:\x01*\x12\x82\x02\n\x16\x43reateTestMeasurements\x12\x33.sift.test_reports.v1.CreateTestMeasurementsRequest\x1a\x34.sift.test_reports.v1.CreateTestMeasurementsResponse\"}\x92\x41P\x12\x16\x43reateTestMeasurements\x1a\x36\x43reates multiple test measurements in a single request\x82\xd3\xe4\x93\x02$\"\x1f/api/v1/test-measurements:batch:\x01*\x12\xea\x01\n\x14ListTestMeasurements\x12\x31.sift.test_reports.v1.ListTestMeasurementsRequest\x1a\x32.sift.test_reports.v1.ListTestMeasurementsResponse\"k\x92\x41G\x12\x14ListTestMeasurements\x1a/Lists test measurements with optional filtering\x82\xd3\xe4\x93\x02\x1b\x12\x19/api/v1/test-measurements\x12\xcb\x01\n\x0e\x43ountTestSteps\x12+.sift.test_reports.v1.CountTestStepsRequest\x1a,.sift.test_reports.v1.CountTestStepsResponse\"^\x92\x41;\x12\x0e\x43ountTestSteps\x1a)Counts test steps with optional filtering\x82\xd3\xe4\x93\x02\x1a\x12\x18/api/v1/test-steps/count\x12\xf5\x01\n\x15\x43ountTestMeasurements\x12\x32.sift.test_reports.v1.CountTestMeasurementsRequest\x1a\x33.sift.test_reports.v1.CountTestMeasurementsResponse\"s\x92\x41I\x12\x15\x43ountTestMeasurements\x1a\x30\x43ounts test measurements with optional filtering\x82\xd3\xe4\x93\x02!\x12\x1f/api/v1/test-measurements/count\x12\xdc\x01\n\x15UpdateTestMeasurement\x12\x32.sift.test_reports.v1.UpdateTestMeasurementRequest\x1a\x33.sift.test_reports.v1.UpdateTestMeasurementResponse\"Z\x92\x41\x33\x12\x15UpdateTestMeasurement\x1a\x1aUpdates a test measurement\x82\xd3\xe4\x93\x02\x1e\x32\x19/api/v1/test-measurements:\x01*\x12\xea\x01\n\x15\x44\x65leteTestMeasurement\x12\x32.sift.test_reports.v1.DeleteTestMeasurementRequest\x1a\x33.sift.test_reports.v1.DeleteTestMeasurementResponse\"h\x92\x41\x33\x12\x15\x44\x65leteTestMeasurement\x1a\x1a\x44\x65letes a test measurement\x82\xd3\xe4\x93\x02,**/api/v1/test-measurements/{measurement_id}\x1a#\x92\x41 \x12\x1eService to manage test reportsB\xb5\x01\n\x18\x63om.sift.test_reports.v1B\x10TestReportsProtoP\x01\xa2\x02\x03STX\xaa\x02\x13Sift.TestReports.V1\xca\x02\x13Sift\\TestReports\\V1\xe2\x02\x1fSift\\TestReports\\V1\\GPBMetadata\xea\x02\x15Sift::TestReports::V1\x92\x41\x18\x12\x16\n\x14Test Results Serviceb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -55,6 +55,8 @@ _globals['_TESTREPORT'].fields_by_name['archived_date']._serialized_options = b'\340A\001' _globals['_TESTREPORT'].fields_by_name['is_archived']._loaded_options = None _globals['_TESTREPORT'].fields_by_name['is_archived']._serialized_options = b'\340A\001' + _globals['_TESTREPORT'].fields_by_name['run_id']._loaded_options = None + _globals['_TESTREPORT'].fields_by_name['run_id']._serialized_options = b'\340A\001' _globals['_TESTSTEP'].fields_by_name['test_step_id']._loaded_options = None _globals['_TESTSTEP'].fields_by_name['test_step_id']._serialized_options = b'\340A\002' _globals['_TESTSTEP'].fields_by_name['test_report_id']._loaded_options = None @@ -125,6 +127,8 @@ _globals['_CREATETESTREPORTREQUEST'].fields_by_name['part_number']._serialized_options = b'\340A\001' _globals['_CREATETESTREPORTREQUEST'].fields_by_name['system_operator']._loaded_options = None _globals['_CREATETESTREPORTREQUEST'].fields_by_name['system_operator']._serialized_options = b'\340A\001' + _globals['_CREATETESTREPORTREQUEST'].fields_by_name['run_id']._loaded_options = None + _globals['_CREATETESTREPORTREQUEST'].fields_by_name['run_id']._serialized_options = b'\340A\001' _globals['_GETTESTREPORTREQUEST'].fields_by_name['test_report_id']._loaded_options = None _globals['_GETTESTREPORTREQUEST'].fields_by_name['test_report_id']._serialized_options = b'\340A\002' _globals['_LISTTESTREPORTSREQUEST'].fields_by_name['page_size']._loaded_options = None @@ -219,92 +223,92 @@ _globals['_TESTREPORTSERVICE'].methods_by_name['UpdateTestMeasurement']._serialized_options = b'\222A3\022\025UpdateTestMeasurement\032\032Updates a test measurement\202\323\344\223\002\0362\031/api/v1/test-measurements:\001*' _globals['_TESTREPORTSERVICE'].methods_by_name['DeleteTestMeasurement']._loaded_options = None _globals['_TESTREPORTSERVICE'].methods_by_name['DeleteTestMeasurement']._serialized_options = b'\222A3\022\025DeleteTestMeasurement\032\032Deletes a test measurement\202\323\344\223\002,**/api/v1/test-measurements/{measurement_id}' - _globals['_TESTSTATUS']._serialized_start=6276 - _globals['_TESTSTATUS']._serialized_end=6490 - _globals['_TESTSTEPTYPE']._serialized_start=6493 - _globals['_TESTSTEPTYPE']._serialized_end=6654 - _globals['_TESTMEASUREMENTTYPE']._serialized_start=6657 - _globals['_TESTMEASUREMENTTYPE']._serialized_end=6853 + _globals['_TESTSTATUS']._serialized_start=6332 + _globals['_TESTSTATUS']._serialized_end=6546 + _globals['_TESTSTEPTYPE']._serialized_start=6549 + _globals['_TESTSTEPTYPE']._serialized_end=6710 + _globals['_TESTMEASUREMENTTYPE']._serialized_start=6713 + _globals['_TESTMEASUREMENTTYPE']._serialized_end=6909 _globals['_TESTREPORT']._serialized_start=302 - _globals['_TESTREPORT']._serialized_end=950 - _globals['_TESTSTEP']._serialized_start=953 - _globals['_TESTSTEP']._serialized_end=1512 - _globals['_ERRORINFO']._serialized_start=1514 - _globals['_ERRORINFO']._serialized_end=1603 - _globals['_TESTMEASUREMENT']._serialized_start=1606 - _globals['_TESTMEASUREMENT']._serialized_end=2289 - _globals['_NUMERICBOUNDS']._serialized_start=2291 - _globals['_NUMERICBOUNDS']._serialized_end=2378 - _globals['_STRINGBOUNDS']._serialized_start=2380 - _globals['_STRINGBOUNDS']._serialized_end=2438 - _globals['_IMPORTTESTREPORTREQUEST']._serialized_start=2440 - _globals['_IMPORTTESTREPORTREQUEST']._serialized_end=2508 - _globals['_IMPORTTESTREPORTRESPONSE']._serialized_start=2510 - _globals['_IMPORTTESTREPORTRESPONSE']._serialized_end=2603 - _globals['_CREATETESTREPORTREQUEST']._serialized_start=2606 - _globals['_CREATETESTREPORTREQUEST']._serialized_end=3116 - _globals['_CREATETESTREPORTRESPONSE']._serialized_start=3118 - _globals['_CREATETESTREPORTRESPONSE']._serialized_end=3211 - _globals['_GETTESTREPORTREQUEST']._serialized_start=3213 - _globals['_GETTESTREPORTREQUEST']._serialized_end=3278 - _globals['_GETTESTREPORTRESPONSE']._serialized_start=3280 - _globals['_GETTESTREPORTRESPONSE']._serialized_end=3370 - _globals['_LISTTESTREPORTSREQUEST']._serialized_start=3373 - _globals['_LISTTESTREPORTSREQUEST']._serialized_end=3528 - _globals['_LISTTESTREPORTSRESPONSE']._serialized_start=3531 - _globals['_LISTTESTREPORTSRESPONSE']._serialized_end=3665 - _globals['_UPDATETESTREPORTREQUEST']._serialized_start=3668 - _globals['_UPDATETESTREPORTREQUEST']._serialized_end=3831 - _globals['_UPDATETESTREPORTRESPONSE']._serialized_start=3833 - _globals['_UPDATETESTREPORTRESPONSE']._serialized_end=3926 - _globals['_DELETETESTREPORTREQUEST']._serialized_start=3928 - _globals['_DELETETESTREPORTREQUEST']._serialized_end=3996 - _globals['_DELETETESTREPORTRESPONSE']._serialized_start=3998 - _globals['_DELETETESTREPORTRESPONSE']._serialized_end=4024 - _globals['_CREATETESTSTEPREQUEST']._serialized_start=4026 - _globals['_CREATETESTSTEPREQUEST']._serialized_end=4115 - _globals['_CREATETESTSTEPRESPONSE']._serialized_start=4117 - _globals['_CREATETESTSTEPRESPONSE']._serialized_end=4202 - _globals['_LISTTESTSTEPSREQUEST']._serialized_start=4205 - _globals['_LISTTESTSTEPSREQUEST']._serialized_end=4358 - _globals['_LISTTESTSTEPSRESPONSE']._serialized_start=4360 - _globals['_LISTTESTSTEPSRESPONSE']._serialized_end=4486 - _globals['_UPDATETESTSTEPREQUEST']._serialized_start=4489 - _globals['_UPDATETESTSTEPREQUEST']._serialized_end=4644 - _globals['_UPDATETESTSTEPRESPONSE']._serialized_start=4646 - _globals['_UPDATETESTSTEPRESPONSE']._serialized_end=4731 - _globals['_DELETETESTSTEPREQUEST']._serialized_start=4733 - _globals['_DELETETESTSTEPREQUEST']._serialized_end=4795 - _globals['_DELETETESTSTEPRESPONSE']._serialized_start=4797 - _globals['_DELETETESTSTEPRESPONSE']._serialized_end=4821 - _globals['_CREATETESTMEASUREMENTREQUEST']._serialized_start=4823 - _globals['_CREATETESTMEASUREMENTREQUEST']._serialized_end=4940 - _globals['_CREATETESTMEASUREMENTRESPONSE']._serialized_start=4942 - _globals['_CREATETESTMEASUREMENTRESPONSE']._serialized_end=5055 - _globals['_CREATETESTMEASUREMENTSREQUEST']._serialized_start=5057 - _globals['_CREATETESTMEASUREMENTSREQUEST']._serialized_end=5177 - _globals['_CREATETESTMEASUREMENTSRESPONSE']._serialized_start=5180 - _globals['_CREATETESTMEASUREMENTSRESPONSE']._serialized_end=5325 - _globals['_LISTTESTMEASUREMENTSREQUEST']._serialized_start=5328 - _globals['_LISTTESTMEASUREMENTSREQUEST']._serialized_end=5488 - _globals['_LISTTESTMEASUREMENTSRESPONSE']._serialized_start=5491 - _globals['_LISTTESTMEASUREMENTSRESPONSE']._serialized_end=5645 - _globals['_COUNTTESTSTEPSREQUEST']._serialized_start=5647 - _globals['_COUNTTESTSTEPSREQUEST']._serialized_end=5699 - _globals['_COUNTTESTSTEPSRESPONSE']._serialized_start=5701 - _globals['_COUNTTESTSTEPSRESPONSE']._serialized_end=5747 - _globals['_COUNTTESTMEASUREMENTSREQUEST']._serialized_start=5749 - _globals['_COUNTTESTMEASUREMENTSREQUEST']._serialized_end=5808 - _globals['_COUNTTESTMEASUREMENTSRESPONSE']._serialized_start=5810 - _globals['_COUNTTESTMEASUREMENTSRESPONSE']._serialized_end=5863 - _globals['_UPDATETESTMEASUREMENTREQUEST']._serialized_start=5866 - _globals['_UPDATETESTMEASUREMENTREQUEST']._serialized_end=6049 - _globals['_UPDATETESTMEASUREMENTRESPONSE']._serialized_start=6051 - _globals['_UPDATETESTMEASUREMENTRESPONSE']._serialized_end=6164 - _globals['_DELETETESTMEASUREMENTREQUEST']._serialized_start=6166 - _globals['_DELETETESTMEASUREMENTREQUEST']._serialized_end=6240 - _globals['_DELETETESTMEASUREMENTRESPONSE']._serialized_start=6242 - _globals['_DELETETESTMEASUREMENTRESPONSE']._serialized_end=6273 - _globals['_TESTREPORTSERVICE']._serialized_start=6856 - _globals['_TESTREPORTSERVICE']._serialized_end=10527 + _globals['_TESTREPORT']._serialized_end=978 + _globals['_TESTSTEP']._serialized_start=981 + _globals['_TESTSTEP']._serialized_end=1540 + _globals['_ERRORINFO']._serialized_start=1542 + _globals['_ERRORINFO']._serialized_end=1631 + _globals['_TESTMEASUREMENT']._serialized_start=1634 + _globals['_TESTMEASUREMENT']._serialized_end=2317 + _globals['_NUMERICBOUNDS']._serialized_start=2319 + _globals['_NUMERICBOUNDS']._serialized_end=2406 + _globals['_STRINGBOUNDS']._serialized_start=2408 + _globals['_STRINGBOUNDS']._serialized_end=2466 + _globals['_IMPORTTESTREPORTREQUEST']._serialized_start=2468 + _globals['_IMPORTTESTREPORTREQUEST']._serialized_end=2536 + _globals['_IMPORTTESTREPORTRESPONSE']._serialized_start=2538 + _globals['_IMPORTTESTREPORTRESPONSE']._serialized_end=2631 + _globals['_CREATETESTREPORTREQUEST']._serialized_start=2634 + _globals['_CREATETESTREPORTREQUEST']._serialized_end=3172 + _globals['_CREATETESTREPORTRESPONSE']._serialized_start=3174 + _globals['_CREATETESTREPORTRESPONSE']._serialized_end=3267 + _globals['_GETTESTREPORTREQUEST']._serialized_start=3269 + _globals['_GETTESTREPORTREQUEST']._serialized_end=3334 + _globals['_GETTESTREPORTRESPONSE']._serialized_start=3336 + _globals['_GETTESTREPORTRESPONSE']._serialized_end=3426 + _globals['_LISTTESTREPORTSREQUEST']._serialized_start=3429 + _globals['_LISTTESTREPORTSREQUEST']._serialized_end=3584 + _globals['_LISTTESTREPORTSRESPONSE']._serialized_start=3587 + _globals['_LISTTESTREPORTSRESPONSE']._serialized_end=3721 + _globals['_UPDATETESTREPORTREQUEST']._serialized_start=3724 + _globals['_UPDATETESTREPORTREQUEST']._serialized_end=3887 + _globals['_UPDATETESTREPORTRESPONSE']._serialized_start=3889 + _globals['_UPDATETESTREPORTRESPONSE']._serialized_end=3982 + _globals['_DELETETESTREPORTREQUEST']._serialized_start=3984 + _globals['_DELETETESTREPORTREQUEST']._serialized_end=4052 + _globals['_DELETETESTREPORTRESPONSE']._serialized_start=4054 + _globals['_DELETETESTREPORTRESPONSE']._serialized_end=4080 + _globals['_CREATETESTSTEPREQUEST']._serialized_start=4082 + _globals['_CREATETESTSTEPREQUEST']._serialized_end=4171 + _globals['_CREATETESTSTEPRESPONSE']._serialized_start=4173 + _globals['_CREATETESTSTEPRESPONSE']._serialized_end=4258 + _globals['_LISTTESTSTEPSREQUEST']._serialized_start=4261 + _globals['_LISTTESTSTEPSREQUEST']._serialized_end=4414 + _globals['_LISTTESTSTEPSRESPONSE']._serialized_start=4416 + _globals['_LISTTESTSTEPSRESPONSE']._serialized_end=4542 + _globals['_UPDATETESTSTEPREQUEST']._serialized_start=4545 + _globals['_UPDATETESTSTEPREQUEST']._serialized_end=4700 + _globals['_UPDATETESTSTEPRESPONSE']._serialized_start=4702 + _globals['_UPDATETESTSTEPRESPONSE']._serialized_end=4787 + _globals['_DELETETESTSTEPREQUEST']._serialized_start=4789 + _globals['_DELETETESTSTEPREQUEST']._serialized_end=4851 + _globals['_DELETETESTSTEPRESPONSE']._serialized_start=4853 + _globals['_DELETETESTSTEPRESPONSE']._serialized_end=4877 + _globals['_CREATETESTMEASUREMENTREQUEST']._serialized_start=4879 + _globals['_CREATETESTMEASUREMENTREQUEST']._serialized_end=4996 + _globals['_CREATETESTMEASUREMENTRESPONSE']._serialized_start=4998 + _globals['_CREATETESTMEASUREMENTRESPONSE']._serialized_end=5111 + _globals['_CREATETESTMEASUREMENTSREQUEST']._serialized_start=5113 + _globals['_CREATETESTMEASUREMENTSREQUEST']._serialized_end=5233 + _globals['_CREATETESTMEASUREMENTSRESPONSE']._serialized_start=5236 + _globals['_CREATETESTMEASUREMENTSRESPONSE']._serialized_end=5381 + _globals['_LISTTESTMEASUREMENTSREQUEST']._serialized_start=5384 + _globals['_LISTTESTMEASUREMENTSREQUEST']._serialized_end=5544 + _globals['_LISTTESTMEASUREMENTSRESPONSE']._serialized_start=5547 + _globals['_LISTTESTMEASUREMENTSRESPONSE']._serialized_end=5701 + _globals['_COUNTTESTSTEPSREQUEST']._serialized_start=5703 + _globals['_COUNTTESTSTEPSREQUEST']._serialized_end=5755 + _globals['_COUNTTESTSTEPSRESPONSE']._serialized_start=5757 + _globals['_COUNTTESTSTEPSRESPONSE']._serialized_end=5803 + _globals['_COUNTTESTMEASUREMENTSREQUEST']._serialized_start=5805 + _globals['_COUNTTESTMEASUREMENTSREQUEST']._serialized_end=5864 + _globals['_COUNTTESTMEASUREMENTSRESPONSE']._serialized_start=5866 + _globals['_COUNTTESTMEASUREMENTSRESPONSE']._serialized_end=5919 + _globals['_UPDATETESTMEASUREMENTREQUEST']._serialized_start=5922 + _globals['_UPDATETESTMEASUREMENTREQUEST']._serialized_end=6105 + _globals['_UPDATETESTMEASUREMENTRESPONSE']._serialized_start=6107 + _globals['_UPDATETESTMEASUREMENTRESPONSE']._serialized_end=6220 + _globals['_DELETETESTMEASUREMENTREQUEST']._serialized_start=6222 + _globals['_DELETETESTMEASUREMENTREQUEST']._serialized_end=6296 + _globals['_DELETETESTMEASUREMENTRESPONSE']._serialized_start=6298 + _globals['_DELETETESTMEASUREMENTRESPONSE']._serialized_end=6329 + _globals['_TESTREPORTSERVICE']._serialized_start=6912 + _globals['_TESTREPORTSERVICE']._serialized_end=10583 # @@protoc_insertion_point(module_scope) diff --git a/python/lib/sift/test_reports/v1/test_reports_pb2.pyi b/python/lib/sift/test_reports/v1/test_reports_pb2.pyi index 968729bb6..cde2b0583 100644 --- a/python/lib/sift/test_reports/v1/test_reports_pb2.pyi +++ b/python/lib/sift/test_reports/v1/test_reports_pb2.pyi @@ -119,6 +119,7 @@ class TestReport(google.protobuf.message.Message): SYSTEM_OPERATOR_FIELD_NUMBER: builtins.int ARCHIVED_DATE_FIELD_NUMBER: builtins.int IS_ARCHIVED_FIELD_NUMBER: builtins.int + RUN_ID_FIELD_NUMBER: builtins.int test_report_id: builtins.str """Unique identifier for the run""" status: global___TestStatus.ValueType @@ -137,6 +138,8 @@ class TestReport(google.protobuf.message.Message): """Unique identifier for user owner""" is_archived: builtins.bool """Whether the test run is archived (externally exposed)""" + run_id: builtins.str + """The run ID for the test run""" @property def start_time(self) -> google.protobuf.timestamp_pb2.Timestamp: """The start time of the test run""" @@ -169,9 +172,10 @@ class TestReport(google.protobuf.message.Message): system_operator: builtins.str = ..., archived_date: google.protobuf.timestamp_pb2.Timestamp | None = ..., is_archived: builtins.bool = ..., + run_id: builtins.str = ..., ) -> None: ... def HasField(self, field_name: typing.Literal["archived_date", b"archived_date", "end_time", b"end_time", "start_time", b"start_time"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["archived_date", b"archived_date", "end_time", b"end_time", "is_archived", b"is_archived", "metadata", b"metadata", "name", b"name", "part_number", b"part_number", "serial_number", b"serial_number", "start_time", b"start_time", "status", b"status", "system_operator", b"system_operator", "test_case", b"test_case", "test_report_id", b"test_report_id", "test_system_name", b"test_system_name"]) -> None: ... + def ClearField(self, field_name: typing.Literal["archived_date", b"archived_date", "end_time", b"end_time", "is_archived", b"is_archived", "metadata", b"metadata", "name", b"name", "part_number", b"part_number", "run_id", b"run_id", "serial_number", b"serial_number", "start_time", b"start_time", "status", b"status", "system_operator", b"system_operator", "test_case", b"test_case", "test_report_id", b"test_report_id", "test_system_name", b"test_system_name"]) -> None: ... global___TestReport = TestReport @@ -409,6 +413,7 @@ class CreateTestReportRequest(google.protobuf.message.Message): SERIAL_NUMBER_FIELD_NUMBER: builtins.int PART_NUMBER_FIELD_NUMBER: builtins.int SYSTEM_OPERATOR_FIELD_NUMBER: builtins.int + RUN_ID_FIELD_NUMBER: builtins.int status: global___TestStatus.ValueType """The status of the test run""" name: builtins.str @@ -423,6 +428,8 @@ class CreateTestReportRequest(google.protobuf.message.Message): """The part number for the DUT""" system_operator: builtins.str """Unique identifier for user owner""" + run_id: builtins.str + """The run ID for the test report""" @property def start_time(self) -> google.protobuf.timestamp_pb2.Timestamp: """The start time of the test run""" @@ -448,9 +455,10 @@ class CreateTestReportRequest(google.protobuf.message.Message): serial_number: builtins.str = ..., part_number: builtins.str = ..., system_operator: builtins.str = ..., + run_id: builtins.str = ..., ) -> None: ... def HasField(self, field_name: typing.Literal["end_time", b"end_time", "start_time", b"start_time"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["end_time", b"end_time", "metadata", b"metadata", "name", b"name", "part_number", b"part_number", "serial_number", b"serial_number", "start_time", b"start_time", "status", b"status", "system_operator", b"system_operator", "test_case", b"test_case", "test_system_name", b"test_system_name"]) -> None: ... + def ClearField(self, field_name: typing.Literal["end_time", b"end_time", "metadata", b"metadata", "name", b"name", "part_number", b"part_number", "run_id", b"run_id", "serial_number", b"serial_number", "start_time", b"start_time", "status", b"status", "system_operator", b"system_operator", "test_case", b"test_case", "test_system_name", b"test_system_name"]) -> None: ... global___CreateTestReportRequest = CreateTestReportRequest @@ -540,7 +548,7 @@ class ListTestReportsRequest(google.protobuf.message.Message): """A [Common Expression Language (CEL)](https://github.com/google/cel-spec) filter string. Available fields to filter by are `test_report_id`, `status`, `name`, `test_system_name`, `test_case`, `start_time`, `end_time`, `serial_number`, `created_by_user_id`, `modified_by_user_id`, - `part_number`, `system_operator`, `archived_date`, and `metadata`. + `part_number`, `system_operator`, `run_id`, `archived_date`, and `metadata`. Metadata can be used in filters by using `metadata.{metadata_key_name}` as the field name. For further information about how to use CELs, please refer to [this guide](https://github.com/google/cel-spec/blob/master/doc/langdef.md#standard-definitions). For more information about the fields used for filtering, please refer to [this definition](/docs/api/grpc/protocol-buffers/test-results#testreport). Optional. @@ -605,7 +613,7 @@ class UpdateTestReportRequest(google.protobuf.message.Message): def update_mask(self) -> google.protobuf.field_mask_pb2.FieldMask: """The field mask specifying which fields to update. The fields available to be updated are `status`, `name`, `test_system_name`, `test_case`, `start_time`, `end_time`, `serial_number`, - `part_number`, `system_operator`, and `is_archived`. + `part_number`, `system_operator`, `run_id`, and `is_archived`. """ def __init__( diff --git a/python/lib/sift_client/_internal/low_level_wrappers/test_results.py b/python/lib/sift_client/_internal/low_level_wrappers/test_results.py index 4f9eafbe3..d0cf8b827 100644 --- a/python/lib/sift_client/_internal/low_level_wrappers/test_results.py +++ b/python/lib/sift_client/_internal/low_level_wrappers/test_results.py @@ -3,13 +3,11 @@ import logging from typing import TYPE_CHECKING, Any, cast -from google.protobuf.timestamp_pb2 import Timestamp from sift.test_reports.v1.test_reports_pb2 import ( CreateTestMeasurementRequest, CreateTestMeasurementResponse, CreateTestMeasurementsRequest, CreateTestMeasurementsResponse, - CreateTestReportRequest, CreateTestReportResponse, CreateTestStepRequest, CreateTestStepResponse, @@ -43,13 +41,11 @@ TestReport, TestReportCreate, TestReportUpdate, - TestStatus, TestStep, TestStepCreate, TestStepUpdate, ) from sift_client.transport import WithGrpcClient -from sift_client.util.metadata import metadata_dict_to_proto if TYPE_CHECKING: from sift_client.transport.grpc_transport import GrpcClient @@ -105,37 +101,7 @@ async def create_test_report( Returns: The created TestReport. """ - request_kwargs: dict[str, Any] = { - "status": test_report.status.value - if isinstance(test_report.status, TestStatus) - else test_report.status, - "name": test_report.name, - "test_system_name": test_report.test_system_name, - "test_case": test_report.test_case, - } - - # Handle timestamps - start_ts = Timestamp() - start_ts.FromDatetime(test_report.start_time) - request_kwargs["start_time"] = start_ts - - end_ts = Timestamp() - end_ts.FromDatetime(test_report.end_time) - request_kwargs["end_time"] = end_ts - - if test_report.metadata is not None: - request_kwargs["metadata"] = metadata_dict_to_proto(test_report.metadata) - - if test_report.serial_number is not None: - request_kwargs["serial_number"] = test_report.serial_number - - if test_report.part_number is not None: - request_kwargs["part_number"] = test_report.part_number - - if test_report.system_operator is not None: - request_kwargs["system_operator"] = test_report.system_operator - - request = CreateTestReportRequest(**request_kwargs) + request = test_report.to_proto() response = await self._grpc_client.get_stub(TestReportServiceStub).CreateTestReport(request) grpc_test_report = cast("CreateTestReportResponse", response).test_report return TestReport._from_proto(grpc_test_report) @@ -336,7 +302,9 @@ async def update_test_step(self, update: TestStepUpdate) -> TestStep: The updated TestStep. """ test_step_proto, field_mask = update.to_proto_with_mask() - + has_error_info = test_step_proto.HasField("error_info") + if has_error_info: + field_mask.paths.append("error_info") request = UpdateTestStepRequest(test_step=test_step_proto, update_mask=field_mask) response = await self._grpc_client.get_stub(TestReportServiceStub).UpdateTestStep(request) grpc_test_step = cast("UpdateTestStepResponse", response).test_step diff --git a/python/lib/sift_client/_tests/conftest.py b/python/lib/sift_client/_tests/conftest.py index 397848d7e..a5ab84d26 100644 --- a/python/lib/sift_client/_tests/conftest.py +++ b/python/lib/sift_client/_tests/conftest.py @@ -20,7 +20,7 @@ def sift_client() -> SiftClient: rest_url = os.getenv("SIFT_REST_URI", "localhost:8080") api_key = os.getenv("SIFT_API_KEY", "") - return SiftClient( + client = SiftClient( connection_config=SiftConnectionConfig( api_key=api_key, grpc_url=grpc_url, @@ -29,6 +29,23 @@ def sift_client() -> SiftClient: ) ) + return client + + +@pytest.fixture(scope="session") +def client_has_connection(sift_client): + """Check if the SiftClient has a connection to the Sift server. + + Can be used to skip tests that require a connection to the Sift server. + """ + has_connection = False + try: + sift_client.ping.ping() + has_connection = True + except Exception: + has_connection = False + return has_connection + @pytest.fixture def mock_client(): @@ -70,3 +87,6 @@ def ci_pytest_tag(sift_client): tag = sift_client.tags.find_or_create(names=["sift-client-pytest"])[0] assert tag is not None return tag + + +from sift_client.util.test_results.pytest import module_substep, report_context, step # noqa: F401 diff --git a/python/lib/sift_client/_tests/resources/test_runs.py b/python/lib/sift_client/_tests/resources/test_runs.py index 798555635..40cce6323 100644 --- a/python/lib/sift_client/_tests/resources/test_runs.py +++ b/python/lib/sift_client/_tests/resources/test_runs.py @@ -182,7 +182,11 @@ class TestFind: async def test_find_run(self, runs_api_async, test_run): """Test finding a single run.""" # Find the same run by name - found_run = await runs_api_async.find(name=test_run.name) + found_run = await runs_api_async.find( + name=test_run.name, + created_after=test_run.created_date - timedelta(seconds=10), + created_before=test_run.created_date + timedelta(seconds=10), + ) assert found_run is not None assert found_run.id_ == test_run.id_ diff --git a/python/lib/sift_client/_tests/resources/test_results.py b/python/lib/sift_client/_tests/resources/test_test_results.py similarity index 98% rename from python/lib/sift_client/_tests/resources/test_results.py rename to python/lib/sift_client/_tests/resources/test_test_results.py index b09b9b839..a2f0a3a5e 100644 --- a/python/lib/sift_client/_tests/resources/test_results.py +++ b/python/lib/sift_client/_tests/resources/test_test_results.py @@ -38,7 +38,7 @@ class TestResultsTest: test_steps: ClassVar[dict[str, TestStep]] = {} test_measurements: ClassVar[dict[str, TestMeasurement]] = {} - def test_create_test_report(self, sift_client): + def test_create_test_report(self, sift_client, nostromo_run): # Create a test report simulated_time = datetime.now(timezone.utc) test_report = sift_client.test_results.create( @@ -49,9 +49,11 @@ def test_create_test_report(self, sift_client): "test_case": "Test Case", "start_time": simulated_time, "end_time": simulated_time, + "run_id": nostromo_run.id_, }, ) assert test_report.id_ is not None + assert test_report.run_id == nostromo_run.id_ self.test_reports["basic_test_report"] = test_report def test_create_test_steps(self, sift_client): @@ -74,7 +76,6 @@ def test_create_test_steps(self, sift_client): ), ) simulated_time = simulated_time + timedelta(seconds=10.1) - # Create a step using a dict step1_1 = sift_client.test_results.create_step( { @@ -288,6 +289,7 @@ def test_update_test_report(self, sift_client): "automated": True, }, end_time=new_end_time, + run_id="", ), ) @@ -303,6 +305,7 @@ def test_update_test_report(self, sift_client): } assert updated_report.status == TestStatus.FAILED assert updated_report.end_time == new_end_time + assert updated_report.run_id is None self.test_reports["basic_test_report"] = updated_report diff --git a/python/lib/sift_client/_tests/util/test_test_results_utils.py b/python/lib/sift_client/_tests/util/test_test_results_utils.py new file mode 100644 index 000000000..d901fc5cc --- /dev/null +++ b/python/lib/sift_client/_tests/util/test_test_results_utils.py @@ -0,0 +1,358 @@ +from datetime import datetime, timezone + +import pytest + +from sift_client.sift_types.test_report import ( + TestMeasurementCreate, + TestMeasurementType, + TestMeasurementUpdate, + TestStatus, + TestStepType, +) +from sift_client.util.test_results.bounds import ( + assign_value_to_measurement, + evaluate_measurement_bounds, +) +from sift_client.util.test_results.context_manager import NewStep + +pytestmark = pytest.mark.integration + + +class TestContextManager: + def test_new_step(self, report_context): + initial_end_time = report_context.report.end_time + first_step_path = report_context.get_next_step_path() + substep_path = f"{first_step_path}.1" + nested_substep_path = f"{substep_path}.1" + sibling_substep_path = f"{first_step_path}.2" + sibling_nested_substep_path = f"{substep_path}.2" + first_step_path_parts = first_step_path.split(".") + prefix = "" + if len(first_step_path_parts) > 1: + prefix = f"{'.'.join(first_step_path_parts[:-1])}." + second_step_path = f"{prefix}{int(first_step_path_parts[-1]) + 1}" + test_step = None + # Test NewStep as a context manager directly + with NewStep(report_context, "Test Step", "Test Description") as new_step: + test_step = new_step.current_step + assert test_step.test_report_id == report_context.report.id_ + assert test_step.name == "Test Step" + assert test_step.description == "Test Description" + assert test_step.start_time + assert test_step.end_time + assert test_step.status == TestStatus.IN_PROGRESS + assert test_step.step_path == first_step_path + assert test_step.step_type == TestStepType.ACTION + assert test_step.error_info == None + + with new_step.substep("Substep", "Substep Description") as substep: + current_substep = substep.current_step + assert current_substep.test_report_id == report_context.report.id_ + assert current_substep.name == "Substep" + assert current_substep.description == "Substep Description" + assert current_substep.step_path == substep_path + assert current_substep.parent_step_id == test_step.id_ + assert current_substep.start_time + assert current_substep.end_time + assert current_substep.status == TestStatus.IN_PROGRESS + assert current_substep.step_type == TestStepType.ACTION + assert current_substep.error_info == None + + with substep.substep( + "nested substep", "Nested substep Description" + ) as nested_substep: + current_nested_substep = nested_substep.current_step + assert current_nested_substep.test_report_id == report_context.report.id_ + assert current_nested_substep.name == "nested substep" + assert current_nested_substep.description == "Nested substep Description" + assert current_nested_substep.step_path == nested_substep_path + assert current_nested_substep.parent_step_id == current_substep.id_ + assert current_nested_substep.start_time + assert current_nested_substep.end_time + assert current_nested_substep.parent_step_id == current_substep.id_ + + with substep.substep( + "sibling nested substep", "Sibling nested substep Description" + ) as sibling_substep: + current_sibling_substep = sibling_substep.current_step + assert current_sibling_substep.test_report_id == report_context.report.id_ + assert current_sibling_substep.name == "sibling nested substep" + assert ( + current_sibling_substep.description == "Sibling nested substep Description" + ) + assert current_sibling_substep.step_path == sibling_nested_substep_path + assert current_sibling_substep.parent_step_id == current_substep.id_ + + with new_step.substep( + "sibling substep", "Sibling substep Description" + ) as sibling_substep: + current_sibling_substep = sibling_substep.current_step + assert current_sibling_substep.test_report_id == report_context.report.id_ + assert current_sibling_substep.name == "sibling substep" + assert current_sibling_substep.description == "Sibling substep Description" + assert current_sibling_substep.step_path == sibling_substep_path + assert current_sibling_substep.parent_step_id == test_step.id_ + + with report_context.new_step("Test Step 2", "Test Step 2 Description") as new_step_2: + test_step_2 = new_step_2.current_step + assert test_step_2.test_report_id == report_context.report.id_ + assert test_step_2.name == "Test Step 2" + assert test_step_2.description == "Test Step 2 Description" + assert test_step_2.step_path == second_step_path + + assert test_step.end_time > initial_end_time + assert test_step_2.start_time > test_step.end_time + assert test_step.status == TestStatus.PASSED + + def test_measurement_update(self, report_context): + test_step = None + with report_context.new_step("Test Measure", "Test Measure Description") as new_step: + test_step = new_step.current_step + new_step.measure(name="Test Measurement", value=10, bounds={"min": 0, "max": 10}) + new_step.measure(name="Test Measurement 2", value="string value", bounds="string value") + new_step.measure(name="Test Measurement 3", value=True, bounds="true") + + assert len(test_step.measurements) == 3 + assert test_step.measurements[0].name == "Test Measurement" + assert test_step.measurements[0].numeric_value == 10 + assert test_step.measurements[0].measurement_type == TestMeasurementType.DOUBLE + assert test_step.measurements[1].name == "Test Measurement 2" + assert test_step.measurements[1].string_value == "string value" + assert test_step.measurements[1].measurement_type == TestMeasurementType.STRING + assert test_step.measurements[2].name == "Test Measurement 3" + assert test_step.measurements[2].boolean_value == True + assert test_step.measurements[2].measurement_type == TestMeasurementType.BOOLEAN + + def test_error_info(self, report_context, step): + test_step = None + parent_step_path = step.current_step.step_path + initial_open_step_result = report_context.open_step_results.get(parent_step_path, True) + initial_any_failures = report_context.any_failures + + with report_context.new_step("Test Error", "Test Error Description") as new_step: + test_step = new_step.current_step + raise Exception("Test Error") + assert test_step.error_info is not None + assert test_step.error_info.error_code == 1 + assert "Test Error" in test_step.error_info.error_message + assert test_step.status == TestStatus.ERROR + # If the parent step is not marked as failed already, make sure it remains passed at this point. + if initial_open_step_result: + report_context.open_step_results[parent_step_path] = True + if not initial_any_failures: + report_context.any_failures = False + + +class TestBounds: + def test_assign_value_to_measurement(self): + measurement = TestMeasurementUpdate( + measurement_type=TestMeasurementType.DOUBLE, + ) + assign_value_to_measurement(measurement, 10) + assert measurement.numeric_value == 10 + assert measurement.measurement_type == TestMeasurementType.DOUBLE + measurement = TestMeasurementCreate( + test_step_id="test_step_id", + name="Test Measurement", + passed=True, + timestamp=datetime.now(timezone.utc), + ) + assign_value_to_measurement(measurement, "string value") + assert measurement.string_value == "string value" + assert measurement.measurement_type == TestMeasurementType.STRING + measurement = TestMeasurementUpdate() + assign_value_to_measurement(measurement, True) + assert measurement.boolean_value == True + + def test_evaluate_measurement_bounds(self): + measurement = TestMeasurementUpdate( + measurement_type=TestMeasurementType.DOUBLE, + ) + result = evaluate_measurement_bounds(measurement, 10, {"min": 0, "max": 10}) + assert result == True + assert measurement.passed == True + + def test_evaluate_measurement_bounds_numeric_within_range(self): + """Test numeric value within min and max bounds.""" + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, 5.0, {"min": 0.0, "max": 10.0}) + assert result == True + assert measurement.passed == True + assert measurement.numeric_value == 5.0 + assert measurement.measurement_type == TestMeasurementType.DOUBLE + + def test_evaluate_measurement_bounds_numeric_at_min(self): + """Test numeric value exactly at minimum bound.""" + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, 0.0, {"min": 0.0, "max": 10.0}) + assert result == True + assert measurement.passed == True + + def test_evaluate_measurement_bounds_numeric_at_max(self): + """Test numeric value exactly at maximum bound.""" + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, 10.0, {"min": 0.0, "max": 10.0}) + assert result == True + assert measurement.passed == True + + def test_evaluate_measurement_bounds_numeric_below_min(self): + """Test numeric value below minimum bound.""" + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, -1.0, {"min": 0.0, "max": 10.0}) + assert result == False + assert measurement.passed == False + + def test_evaluate_measurement_bounds_numeric_above_max(self): + """Test numeric value above maximum bound.""" + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, 11.0, {"min": 0.0, "max": 10.0}) + assert result == False + assert measurement.passed == False + + def test_evaluate_measurement_bounds_numeric_min_only(self): + """Test numeric value with only minimum bound.""" + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, 5.0, {"min": 0.0}) + assert result == True + assert measurement.passed == True + + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, -1.0, {"min": 0.0}) + assert result == False + assert measurement.passed == False + + def test_evaluate_measurement_bounds_numeric_max_only(self): + """Test numeric value with only maximum bound.""" + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, 5.0, {"max": 10.0}) + assert result == True + assert measurement.passed == True + + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, 11.0, {"max": 10.0}) + assert result == False + assert measurement.passed == False + + def test_evaluate_measurement_bounds_with_numeric_bounds_object(self): + """Test using NumericBounds object instead of dict.""" + from sift_client.sift_types.test_report import NumericBounds + + measurement = TestMeasurementUpdate() + bounds = NumericBounds(min=0.0, max=10.0) + result = evaluate_measurement_bounds(measurement, 5.0, bounds) + assert result == True + assert measurement.passed == True + assert measurement.numeric_bounds.min == 0.0 + assert measurement.numeric_bounds.max == 10.0 + + def test_evaluate_measurement_bounds_string_matching(self): + """Test string value matching expected string.""" + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, "expected", "expected") + assert result == True + assert measurement.passed == True + assert measurement.string_value == "expected" + assert measurement.string_expected_value == "expected" + assert measurement.measurement_type == TestMeasurementType.STRING + + def test_evaluate_measurement_bounds_string_not_matching(self): + """Test string value not matching expected string.""" + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, "actual", "expected") + assert result == False + assert measurement.passed == False + assert measurement.string_value == "actual" + assert measurement.string_expected_value == "expected" + + def test_evaluate_measurement_bounds_boolean_matching(self): + """Test boolean value matching expected string.""" + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, True, "true") + assert result == True + assert measurement.passed == True + assert measurement.boolean_value == True + assert measurement.string_expected_value == "true" + assert measurement.measurement_type == TestMeasurementType.BOOLEAN + + def test_evaluate_measurement_bounds_boolean_not_matching(self): + """Test boolean value not matching expected string.""" + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, False, "true") + assert result == False + assert measurement.passed == False + assert measurement.boolean_value == False + assert measurement.string_expected_value == "true" + + def test_evaluate_measurement_bounds_boolean_case_insensitive(self): + """Test boolean comparison is case insensitive.""" + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, True, "TRUE") + assert result == True + assert measurement.passed == True + + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, True, "True") + assert result == True + assert measurement.passed == True + + def test_evaluate_measurement_bounds_no_bounds(self): + """Test measurement without bounds. Expected behavior is that the measurement's passed value is unchanged.""" + measurement = TestMeasurementUpdate(passed=False) + result = evaluate_measurement_bounds(measurement, 5.0, None) + assert result == False # + assert measurement.passed == False + assert measurement.numeric_value == 5.0 + + measurement = TestMeasurementUpdate(passed=True) + result = evaluate_measurement_bounds(measurement, "string value", None) + assert result == True + assert measurement.passed == True + assert measurement.string_value == "string value" + + def test_evaluate_measurement_bounds_integer_value(self): + """Test that integer values are converted to float.""" + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, 5, {"min": 0, "max": 10}) + assert result == True + assert measurement.passed == True + assert measurement.numeric_value == 5.0 + assert measurement.measurement_type == TestMeasurementType.DOUBLE + + def test_evaluate_measurement_bounds_with_test_measurement_create(self): + """Test evaluation with TestMeasurementCreate.""" + measurement = TestMeasurementCreate( + test_step_id="test_step_id", + name="Test Measurement", + passed=True, + timestamp=datetime.now(timezone.utc), + ) + result = evaluate_measurement_bounds(measurement, 5.0, {"min": 0.0, "max": 10.0}) + assert result == True + assert measurement.passed == True + assert measurement.numeric_value == 5.0 + + def test_evaluate_measurement_bounds_negative_range(self): + """Test numeric bounds with negative values.""" + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, -5.0, {"min": -10.0, "max": -1.0}) + assert result == True + assert measurement.passed == True + + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, 0.0, {"min": -10.0, "max": -1.0}) + assert result == False + assert measurement.passed == False + + def test_evaluate_measurement_bounds_large_values(self): + """Test numeric bounds with large values.""" + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, 1e6, {"min": 0.0, "max": 1e9}) + assert result == True + assert measurement.passed == True + + def test_evaluate_measurement_bounds_small_precision(self): + """Test numeric bounds with small decimal precision.""" + measurement = TestMeasurementUpdate() + result = evaluate_measurement_bounds(measurement, 0.00001, {"min": 0.0, "max": 0.0001}) + assert result == True + assert measurement.passed == True diff --git a/python/lib/sift_client/sift_types/test_report.py b/python/lib/sift_client/sift_types/test_report.py index 7621bdf37..74914332b 100644 --- a/python/lib/sift_client/sift_types/test_report.py +++ b/python/lib/sift_client/sift_types/test_report.py @@ -4,6 +4,9 @@ from enum import Enum from typing import TYPE_CHECKING, ClassVar +from sift.test_reports.v1.test_reports_pb2 import ( + CreateTestReportRequest as CreateTestReportRequestProto, +) from sift.test_reports.v1.test_reports_pb2 import ( ErrorInfo as ErrorInfoProto, ) @@ -69,101 +72,6 @@ class TestMeasurementType(Enum): LIMIT = 5 -class TestReportBase(ModelCreateUpdateBase): - """Base model for TestReportUpdate and TestReportCreate. Contains shared fields for all test reports. Update and create models differ mostly in what fields are required vs optional.""" - - status: TestStatus | None = None - metadata: dict[str, str | float | bool] | None = None - serial_number: str | None = None - part_number: str | None = None - system_operator: str | None = None - - _to_proto_helpers: ClassVar[dict[str, MappingHelper]] = { - "metadata": MappingHelper( - proto_attr_path="metadata", update_field="metadata", converter=metadata_dict_to_proto - ), - } - - def _get_proto_class(self) -> type[TestReportProto]: - return TestReportProto - - -class TestReportUpdate(TestReportBase, ModelUpdate[TestReportProto]): - """Update model for TestReport.""" - - name: str | None = None - test_system_name: str | None = None - test_case: str | None = None - start_time: datetime | None = None - end_time: datetime | None = None - - is_archived: bool | None = None - - def _add_resource_id_to_proto(self, proto_msg: TestReportProto): - if self._resource_id is None: - raise ValueError("Resource ID must be set before adding to proto") - proto_msg.test_report_id = self._resource_id - - -class TestReportCreate(TestReportBase, ModelCreate[TestReportProto]): - """Create model for TestReport.""" - - name: str - test_system_name: str - test_case: str - start_time: datetime - end_time: datetime - - def to_proto(self) -> TestReportProto: - """Convert to protobuf message with custom logic.""" - proto = TestReportProto( - status=self.status.value, # type: ignore - name=self.name, - test_system_name=self.test_system_name, - test_case=self.test_case, - metadata=metadata_dict_to_proto(self.metadata) if self.metadata else {}, - is_archived=False, - ) - - proto.start_time.FromDatetime(self.start_time) - proto.end_time.FromDatetime(self.end_time) - - if self.serial_number: - proto.serial_number = self.serial_number - - if self.part_number: - proto.part_number = self.part_number - - if self.system_operator: - proto.system_operator = self.system_operator - - return proto - - -class ErrorInfo(BaseType[ErrorInfoProto, "ErrorInfo"]): - """ErrorInfo model representing error information in a test step.""" - - error_code: int - error_message: str - - @classmethod - def _from_proto(cls, proto: ErrorInfoProto, sift_client: SiftClient | None = None) -> ErrorInfo: - return cls( - proto=proto, - id_=None, - error_code=proto.error_code, - error_message=proto.error_message, - _client=sift_client, - ) - - def _to_proto(self) -> ErrorInfoProto: - """Convert to protobuf message.""" - return ErrorInfoProto( - error_code=self.error_code, - error_message=self.error_message, - ) - - class TestStepBase(ModelCreateUpdateBase): """Base model for TestStepUpdate and TestStepCreate. Contains shared fields for all test steps. Update and create models differ mostly in what fields are required vs optional.""" @@ -336,16 +244,26 @@ class TestMeasurementBase(ModelCreateUpdateBase): unit: str | None = None numeric_bounds: NumericBounds | None = None string_expected_value: str | None = None + measurement_type: TestMeasurementType | None = None def _get_proto_class(self) -> type[TestMeasurementProto]: return TestMeasurementProto + def _resolve_measurement_type(self) -> TestMeasurementType: + if self.numeric_value is not None: + return TestMeasurementType.DOUBLE + elif self.string_value is not None: + return TestMeasurementType.STRING + elif self.boolean_value is not None: + return TestMeasurementType.BOOLEAN + else: + raise ValueError("No measurement value provided") + class TestMeasurementUpdate(TestMeasurementBase, ModelUpdate[TestMeasurementProto]): """Update model for TestMeasurement.""" name: str | None = None - measurement_type: int | None = None passed: bool | None = None timestamp: datetime | None = None @@ -364,16 +282,18 @@ def _add_resource_id_to_proto(self, proto_msg: TestMeasurementProto): class TestMeasurementCreate(TestMeasurementBase, ModelCreate[TestMeasurementProto]): """Create model for TestMeasurement.""" - measurement_type: TestMeasurementType name: str test_step_id: str passed: bool timestamp: datetime + unit: str | None = None def to_proto(self) -> TestMeasurementProto: """Convert to protobuf message with custom logic.""" proto = TestMeasurementProto( - measurement_type=self.measurement_type.value, # type: ignore + measurement_type=self.measurement_type.value + if self.measurement_type + else self._resolve_measurement_type().value, # type: ignore name=self.name, test_step_id=self.test_step_id, passed=self.passed, @@ -500,6 +420,99 @@ def update( return self +class TestReportBase(ModelCreateUpdateBase): + """Base model for TestReportUpdate and TestReportCreate. Contains shared fields for all test reports. Update and create models differ mostly in what fields are required vs optional.""" + + status: TestStatus | None = None + metadata: dict[str, str | float | bool] | None = None + serial_number: str | None = None + part_number: str | None = None + system_operator: str | None = None + run_id: str | None = None + + _to_proto_helpers: ClassVar[dict[str, MappingHelper]] = { + "metadata": MappingHelper( + proto_attr_path="metadata", update_field="metadata", converter=metadata_dict_to_proto + ), + } + + +class TestReportUpdate(TestReportBase, ModelUpdate[TestReportProto]): + """Update model for TestReport.""" + + name: str | None = None + test_system_name: str | None = None + test_case: str | None = None + start_time: datetime | None = None + end_time: datetime | None = None + + is_archived: bool | None = None + + def _get_proto_class(self) -> type[TestReportProto]: + return TestReportProto + + def _add_resource_id_to_proto(self, proto_msg: TestReportProto): + if self._resource_id is None: + raise ValueError("Resource ID must be set before adding to proto") + proto_msg.test_report_id = self._resource_id + + +class TestReportCreate(TestReportBase, ModelCreate[CreateTestReportRequestProto]): + """Create model for TestReport.""" + + name: str + test_system_name: str + test_case: str + start_time: datetime + end_time: datetime + + def _get_proto_class(self) -> type[CreateTestReportRequestProto]: + return CreateTestReportRequestProto + + def to_proto(self) -> CreateTestReportRequestProto: + """Convert to protobuf message with custom logic.""" + proto = CreateTestReportRequestProto( + status=self.status.value, # type: ignore + name=self.name or "", + test_system_name=self.test_system_name or "", + test_case=self.test_case or "", + serial_number=self.serial_number or "", + part_number=self.part_number or "", + system_operator=self.system_operator or "", + run_id=self.run_id if self.run_id else "", + metadata=metadata_dict_to_proto(self.metadata) if self.metadata else {}, + ) + + proto.start_time.FromDatetime(self.start_time) + proto.end_time.FromDatetime(self.end_time) + + return proto + + +class ErrorInfo(BaseType[ErrorInfoProto, "ErrorInfo"]): + """ErrorInfo model representing error information in a test step.""" + + error_code: int + error_message: str + + @classmethod + def _from_proto(cls, proto: ErrorInfoProto, sift_client: SiftClient | None = None) -> ErrorInfo: + return cls( + proto=proto, + id_=None, + error_code=proto.error_code, + error_message=proto.error_message, + _client=sift_client, + ) + + def _to_proto(self) -> ErrorInfoProto: + """Convert to protobuf message.""" + return ErrorInfoProto( + error_code=self.error_code, + error_message=self.error_message, + ) + + class TestReport(BaseType[TestReportProto, "TestReport"]): """TestReport model representing a test report.""" @@ -513,6 +526,7 @@ class TestReport(BaseType[TestReportProto, "TestReport"]): serial_number: str | None = None part_number: str | None = None system_operator: str | None = None + run_id: str | None = None archived_date: datetime | None = None is_archived: bool @@ -533,6 +547,7 @@ def _from_proto( serial_number=proto.serial_number if proto.serial_number else None, part_number=proto.part_number if proto.part_number else None, system_operator=proto.system_operator if proto.system_operator else None, + run_id=proto.run_id if proto.run_id else None, archived_date=proto.archived_date.ToDatetime(tzinfo=timezone.utc) if proto.HasField("archived_date") else None, @@ -564,6 +579,9 @@ def _to_proto(self) -> TestReportProto: if self.system_operator: proto.system_operator = self.system_operator + if self.run_id: + proto.run_id = self.run_id + if self.archived_date: proto.archived_date.FromDatetime(self.archived_date) diff --git a/python/lib/sift_client/util/test_results/__init__.py b/python/lib/sift_client/util/test_results/__init__.py new file mode 100644 index 000000000..36ff86cf3 --- /dev/null +++ b/python/lib/sift_client/util/test_results/__init__.py @@ -0,0 +1,37 @@ +"""Test Results Utilities. + +This module provides utilities for working with test results. + +# Context Managers +- `ReportContext` - Context manager for a new TestReport. +- `NewStep` - Context manager to create a new step in a test report. + +### Examples + +```python +with ReportContext(client, name="Example Report", description="Example Report") as rc: + with rc.new_step(name="Setup") as step: + controller_setup(step) + with rc.new_step(name="Example Step", description=desc) as parent_step: + cmd_interface.cmd("ec1", "rtv.cmd", 75.0) + sleep(0.01) + + with parent_step.substep(name="Substep 1", description="Measure position") as substep: + ec = "ec1" + pos_channel = "rtv.pos" + pos = tlm.read(ec, pos_channel) + result = substep.measure(pos, name=f"{ec}.{pos_channel}", bounds=(min=74.9, max=75.1)) + return result # This is optional for other uses, but the step and its parents will be updated correctly i.e. failed if the measurement fails. +``` +#### Pytest Fixtures + +The report context and steps can also be accessed in pytest via the `report_context` and `step` fixtures. +These fixtures are set to autouse and will automatically create a report and steps for each test function. +If you want each module(file) to be marked as a step w/ each test as a substep, import the `module_substep` fixture. + +""" + +from .context_manager import NewStep, ReportContext +from .pytest import report_context + +__all__ = ["NewStep", "ReportContext", "report_context"] diff --git a/python/lib/sift_client/util/test_results/bounds.py b/python/lib/sift_client/util/test_results/bounds.py new file mode 100644 index 000000000..b69f7ac24 --- /dev/null +++ b/python/lib/sift_client/util/test_results/bounds.py @@ -0,0 +1,71 @@ +from __future__ import annotations + +from sift_client.sift_types.test_report import ( + NumericBounds, + TestMeasurement, + TestMeasurementCreate, + TestMeasurementType, + TestMeasurementUpdate, +) + + +def assign_value_to_measurement( + measurement: TestMeasurement | TestMeasurementCreate | TestMeasurementUpdate, + value: float | str | bool, +) -> None: + """Assign the resolved value type to a measurement.""" + if isinstance(value, bool): + measurement.boolean_value = value + measurement.measurement_type = TestMeasurementType.BOOLEAN + elif isinstance(value, float) or isinstance(value, int): + measurement.numeric_value = float(value) + measurement.measurement_type = TestMeasurementType.DOUBLE + elif isinstance(value, str): + measurement.string_value = value + measurement.measurement_type = TestMeasurementType.STRING + else: + raise ValueError("Invalid value type") + + +def evaluate_measurement_bounds( + measurement: TestMeasurement | TestMeasurementCreate | TestMeasurementUpdate, + value: float | str | bool, + bounds: dict[str, float] | NumericBounds | str | None, +) -> bool: + """Update a measurement with the resolved bounds type and result of evaluating the given value against those bounds. + + Args: + measurement: The measurement to update. + value: The value to evaluate the bounds of. + bounds: The bounds to evaluate the value against. + + Returns: + True if the value is within the bounds, False otherwise. + """ + assign_value_to_measurement(measurement, value) + if bounds is None: + return bool(measurement.passed) + + if isinstance(bounds, dict): + bounds = NumericBounds(min=bounds.get("min"), max=bounds.get("max")) + if isinstance(bounds, str): + if not (isinstance(value, str) or isinstance(value, bool)): + raise ValueError("Value must be a string if bounds provided is a string") + measurement.string_expected_value = bounds + if isinstance(value, bool): + measurement.passed = str(value).lower() == str(bounds).lower() + else: + measurement.passed = value == bounds + elif isinstance(bounds, NumericBounds): + measurement.numeric_bounds = bounds + measurement.passed = True + float_value = float(value) + if measurement.numeric_bounds.min is not None: + measurement.passed = ( + measurement.passed and measurement.numeric_bounds.min <= float_value + ) + if measurement.numeric_bounds.max is not None: + measurement.passed = ( + measurement.passed and measurement.numeric_bounds.max >= float_value + ) + return bool(measurement.passed) diff --git a/python/lib/sift_client/util/test_results/context_manager.py b/python/lib/sift_client/util/test_results/context_manager.py new file mode 100644 index 000000000..188239861 --- /dev/null +++ b/python/lib/sift_client/util/test_results/context_manager.py @@ -0,0 +1,269 @@ +from __future__ import annotations + +import getpass +import os +import socket +import traceback +from contextlib import AbstractContextManager +from datetime import datetime, timezone +from typing import TYPE_CHECKING + +from sift_client.sift_types.test_report import ( + ErrorInfo, + NumericBounds, + TestMeasurement, + TestMeasurementCreate, + TestReport, + TestReportCreate, + TestStatus, + TestStep, + TestStepCreate, + TestStepType, +) +from sift_client.util.test_results.bounds import ( + evaluate_measurement_bounds, +) + +if TYPE_CHECKING: + from sift_client.client import SiftClient + + +class ReportContext(AbstractContextManager): + """Context for a new TestReport.""" + + report: TestReport + step_is_open: bool + step_stack: list[TestStep] + step_number_at_depth: dict[int, int] + open_step_results: dict[str, bool] + any_failures: bool + + def __init__( + self, + client: SiftClient, + name: str, + test_system_name: str | None = None, + system_operator: str | None = None, + test_case: str | None = None, + ): + """Initialize a new report context. + + Args: + client: The Sift client to use to create the report. + name: The name of the report. + test_system_name: The name of the test system. Will default to the hostname if not provided. + system_operator: The operator of the test system. Will default to the current user if not provided. + test_case: The name of the test case. Will default to the basename of the file containing the test if not provided. + """ + self.step_is_open = False + self.step_stack = [] + self.step_number_at_depth = {} + self.open_step_results = {} + self.any_failures = False + + # Create the report. + test_case = test_case if test_case else os.path.basename(__file__) + test_system_name = test_system_name if test_system_name else socket.gethostname() + system_operator = system_operator if system_operator else getpass.getuser() + create = TestReportCreate( + name=name, + test_system_name=test_system_name, + test_case=test_case, + start_time=datetime.now(timezone.utc), + end_time=datetime.now(timezone.utc), + status=TestStatus.IN_PROGRESS, + system_operator=system_operator, + ) + self.report = client.test_results.create(create) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + update = { + "end_time": datetime.now(timezone.utc), + } + if self.any_failures or exc_type: + update["status"] = TestStatus.FAILED + else: + update["status"] = TestStatus.PASSED + self.report.update(update) + return True + + def new_step(self, name: str, description: str | None = None) -> NewStep: + """Alias to return a new step context manager from this report context. Use create_step for actually creating a TestStep in the current context.""" + return NewStep(self, name=name, description=description) + + def get_next_step_path(self) -> str: + """Get the next step path for the current depth.""" + top_step = self.step_stack[-1] if self.step_stack else None + step_path = top_step.step_path if top_step else "" + next_step_number = self.step_number_at_depth.get(len(self.step_stack), 0) + 1 + prefix = f"{step_path}." if step_path else "" + return f"{prefix}{next_step_number}" + + def create_step(self, name: str, description: str | None = None) -> TestStep: + """Create a new step in the report context.""" + step_path = self.get_next_step_path() + parent_step = self.step_stack[-1] if self.step_stack else None + + step = self.report.client.test_results.create_step( + TestStepCreate( + test_report_id=str(self.report.id_), + name=name, + step_type=TestStepType.ACTION, + step_path=step_path, + status=TestStatus.IN_PROGRESS, + start_time=datetime.now(timezone.utc), + end_time=datetime.now(timezone.utc), + description=description, + parent_step_id=parent_step.id_ if parent_step else None, + ) + ) + + # Update the step tracking structures. + self.step_number_at_depth[len(self.step_stack)] = ( + self.step_number_at_depth.get(len(self.step_stack), 0) + 1 + ) + self.step_stack.append(step) + self.open_step_results[step.step_path] = True + + return step + + def report_measurement(self, measurement: TestMeasurement, step: TestStep): + """Report a failure to the report context.""" + # Failures will be propogated when the step exits. + if not measurement.passed: + self.open_step_results[step.step_path] = False + self.any_failures = True + + def resolve_and_propagate_step_result( + self, + step: TestStep, + parent_step: TestStep | None = None, + error_info: ErrorInfo | None = None, + ) -> bool: + """Resolve the result of a step and propagate the result to the parent step if it failed.""" + result = self.open_step_results.get(step.step_path, True) + if error_info: + result = False + if step.status != TestStatus.IN_PROGRESS: + # The step was manually completed so use that result. + result = step.status == TestStatus.PASSED + + # Update the parent step results if this step failed (true by default so no need to do anything if we didn't fail). + if not result: + self.any_failures = True + if parent_step: + self.open_step_results[parent_step.step_path] = False + + return result + + def exit_step(self, step: TestStep): + """Exit a step and update the report context.""" + self.step_number_at_depth[len(self.step_stack)] = 0 + stack_top = self.step_stack.pop() + self.open_step_results.pop(step.step_path) + + if stack_top.id_ != step.id_: + raise ValueError( + "The popped step was not the top of the stack. This should never happen." + ) + + +class NewStep(AbstractContextManager): + """Context manager to create a new step in a test report.""" + + report_context: ReportContext + client: SiftClient + current_step: TestStep | None = None + name: str | None = None + description: str | None = None + parent_step: TestStep | None = None + + def __init__( + self, + report_context: ReportContext, + name: str | None = None, + description: str | None = None, + ): + """Initialize a new step context. + + Args: + report_context: The report context to create the step in. + name: The name of the step. + description: The description of the step. + """ + self.report_context = report_context + self.client = report_context.report.client + self.description = description + self.name = name + + def __enter__(self): + """Enter the context manager to create a new step. + + returns: The current step. + """ + self.current_step = self.report_context.create_step(self.name, self.description) + self.name = self.current_step.name + + return self + + def __exit__(self, exc, exc_value, tb): + error_info = None + if exc: + trace = "".join(traceback.format_exception(exc, exc_value, tb, limit=10)) + error_info = ErrorInfo( + error_code=1, + error_message=trace, + ) + + # Resolve the status of this step (i.e. fail if children failed) and propagate the result to the parent step. + result = self.report_context.resolve_and_propagate_step_result( + self.current_step, self.parent_step, error_info + ) + + # Mark the step as completed + status = TestStatus.PASSED if result else TestStatus.FAILED + if error_info: + status = TestStatus.ERROR + self.current_step.update( + { + "status": status, + "end_time": datetime.now(timezone.utc), + "error_info": error_info, + } + ) + + # Now that the step is updated. Let the report context handle removing it from the stack and updating the report context. + self.report_context.exit_step(self.current_step) + + return True + + def measure( + self, + *, + name: str, + value: float | str | bool, + bounds: dict[str, float] | NumericBounds | str | None = None, + ) -> bool: + """Measure a value and return the result. + + returns: The measurement object. + """ + assert self.current_step is not None + create = TestMeasurementCreate( + test_step_id=str(self.current_step.id_), + name=name, + passed=True, + timestamp=datetime.now(timezone.utc), + ) + evaluate_measurement_bounds(create, value, bounds) + measurement = self.client.test_results.create_measurement(create) + self.report_context.report_measurement(measurement, self.current_step) + + return measurement.passed + + def substep(self, name: str, description: str | None = None) -> NewStep: + """Alias to return a new step context manager from the current step. The ReportContext will manage nesting of steps.""" + return self.report_context.new_step(name=name, description=description) diff --git a/python/lib/sift_client/util/test_results/pytest.py b/python/lib/sift_client/util/test_results/pytest.py new file mode 100644 index 000000000..3d179b379 --- /dev/null +++ b/python/lib/sift_client/util/test_results/pytest.py @@ -0,0 +1,62 @@ +from __future__ import annotations + +from datetime import datetime, timezone +from pathlib import Path +from typing import TYPE_CHECKING, Generator + +import pytest + +from sift_client.util.test_results import ReportContext + +if TYPE_CHECKING: + from sift_client.client import SiftClient + from sift_client.util.test_results.context_manager import NewStep + + +@pytest.fixture(scope="session", autouse=True) +def report_context( + sift_client: SiftClient, client_has_connection: bool, request: pytest.FixtureRequest +) -> Generator[ReportContext | None, None, None]: + """Create a report context for the session.""" + if client_has_connection: + test_path = Path(request.config.invocation_params.args[0]) + base_name = ( + test_path.name + if test_path.exists() + else "pytest " + " ".join(request.config.invocation_params.args) + ) + test_case = test_path if test_path.exists() else base_name + with ReportContext( + sift_client, + name=f"{base_name} {datetime.now(timezone.utc).isoformat()}", + test_case=str(test_case), + ) as context: + yield context + else: + yield None + + +@pytest.fixture(autouse=True) +def step( + report_context: ReportContext, client_has_connection: bool, request: pytest.FixtureRequest +) -> Generator[NewStep | None, None, None]: + """Create an outer step for the function.""" + if client_has_connection: + name = str(request.node.name) + with report_context.new_step(name=name) as new_step: + yield new_step + else: + yield None + + +@pytest.fixture(scope="module", autouse=True) +def module_substep( + report_context: ReportContext, client_has_connection: bool, request: pytest.FixtureRequest +) -> Generator[NewStep | None, None, None]: + """Create a step per module.""" + if client_has_connection: + name = str(request.node.name) + with report_context.new_step(name=name) as new_step: + yield new_step + else: + yield None diff --git a/rust/crates/sift_rs/src/gen/sift.test_reports.v1.rs b/rust/crates/sift_rs/src/gen/sift.test_reports.v1.rs index bb9d700d7..c91f26392 100644 --- a/rust/crates/sift_rs/src/gen/sift.test_reports.v1.rs +++ b/rust/crates/sift_rs/src/gen/sift.test_reports.v1.rs @@ -29,6 +29,8 @@ pub struct TestReport { pub archived_date: ::core::option::Option<::pbjson_types::Timestamp>, #[prost(bool, tag="13")] pub is_archived: bool, + #[prost(string, tag="14")] + pub run_id: ::prost::alloc::string::String, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -158,6 +160,8 @@ pub struct CreateTestReportRequest { pub part_number: ::prost::alloc::string::String, #[prost(string, tag="10")] pub system_operator: ::prost::alloc::string::String, + #[prost(string, tag="11")] + pub run_id: ::prost::alloc::string::String, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] diff --git a/rust/crates/sift_rs/src/gen/sift.test_reports.v1.serde.rs b/rust/crates/sift_rs/src/gen/sift.test_reports.v1.serde.rs index 0980d17ff..6eab083bc 100644 --- a/rust/crates/sift_rs/src/gen/sift.test_reports.v1.serde.rs +++ b/rust/crates/sift_rs/src/gen/sift.test_reports.v1.serde.rs @@ -795,6 +795,9 @@ impl serde::Serialize for CreateTestReportRequest { if !self.system_operator.is_empty() { len += 1; } + if !self.run_id.is_empty() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("sift.test_reports.v1.CreateTestReportRequest", len)?; if self.status != 0 { let v = TestStatus::try_from(self.status) @@ -828,6 +831,9 @@ impl serde::Serialize for CreateTestReportRequest { if !self.system_operator.is_empty() { struct_ser.serialize_field("systemOperator", &self.system_operator)?; } + if !self.run_id.is_empty() { + struct_ser.serialize_field("runId", &self.run_id)?; + } struct_ser.end() } } @@ -855,6 +861,8 @@ impl<'de> serde::Deserialize<'de> for CreateTestReportRequest { "partNumber", "system_operator", "systemOperator", + "run_id", + "runId", ]; #[allow(clippy::enum_variant_names)] @@ -869,6 +877,7 @@ impl<'de> serde::Deserialize<'de> for CreateTestReportRequest { SerialNumber, PartNumber, SystemOperator, + RunId, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -900,6 +909,7 @@ impl<'de> serde::Deserialize<'de> for CreateTestReportRequest { "serialNumber" | "serial_number" => Ok(GeneratedField::SerialNumber), "partNumber" | "part_number" => Ok(GeneratedField::PartNumber), "systemOperator" | "system_operator" => Ok(GeneratedField::SystemOperator), + "runId" | "run_id" => Ok(GeneratedField::RunId), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -929,6 +939,7 @@ impl<'de> serde::Deserialize<'de> for CreateTestReportRequest { let mut serial_number__ = None; let mut part_number__ = None; let mut system_operator__ = None; + let mut run_id__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::Status => { @@ -991,6 +1002,12 @@ impl<'de> serde::Deserialize<'de> for CreateTestReportRequest { } system_operator__ = Some(map_.next_value()?); } + GeneratedField::RunId => { + if run_id__.is_some() { + return Err(serde::de::Error::duplicate_field("runId")); + } + run_id__ = Some(map_.next_value()?); + } } } Ok(CreateTestReportRequest { @@ -1004,6 +1021,7 @@ impl<'de> serde::Deserialize<'de> for CreateTestReportRequest { serial_number: serial_number__.unwrap_or_default(), part_number: part_number__.unwrap_or_default(), system_operator: system_operator__.unwrap_or_default(), + run_id: run_id__.unwrap_or_default(), }) } } @@ -3658,6 +3676,9 @@ impl serde::Serialize for TestReport { if self.is_archived { len += 1; } + if !self.run_id.is_empty() { + len += 1; + } let mut struct_ser = serializer.serialize_struct("sift.test_reports.v1.TestReport", len)?; if !self.test_report_id.is_empty() { struct_ser.serialize_field("testReportId", &self.test_report_id)?; @@ -3700,6 +3721,9 @@ impl serde::Serialize for TestReport { if self.is_archived { struct_ser.serialize_field("isArchived", &self.is_archived)?; } + if !self.run_id.is_empty() { + struct_ser.serialize_field("runId", &self.run_id)?; + } struct_ser.end() } } @@ -3733,6 +3757,8 @@ impl<'de> serde::Deserialize<'de> for TestReport { "archivedDate", "is_archived", "isArchived", + "run_id", + "runId", ]; #[allow(clippy::enum_variant_names)] @@ -3750,6 +3776,7 @@ impl<'de> serde::Deserialize<'de> for TestReport { SystemOperator, ArchivedDate, IsArchived, + RunId, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -3784,6 +3811,7 @@ impl<'de> serde::Deserialize<'de> for TestReport { "systemOperator" | "system_operator" => Ok(GeneratedField::SystemOperator), "archivedDate" | "archived_date" => Ok(GeneratedField::ArchivedDate), "isArchived" | "is_archived" => Ok(GeneratedField::IsArchived), + "runId" | "run_id" => Ok(GeneratedField::RunId), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -3816,6 +3844,7 @@ impl<'de> serde::Deserialize<'de> for TestReport { let mut system_operator__ = None; let mut archived_date__ = None; let mut is_archived__ = None; + let mut run_id__ = None; while let Some(k) = map_.next_key()? { match k { GeneratedField::TestReportId => { @@ -3896,6 +3925,12 @@ impl<'de> serde::Deserialize<'de> for TestReport { } is_archived__ = Some(map_.next_value()?); } + GeneratedField::RunId => { + if run_id__.is_some() { + return Err(serde::de::Error::duplicate_field("runId")); + } + run_id__ = Some(map_.next_value()?); + } } } Ok(TestReport { @@ -3912,6 +3947,7 @@ impl<'de> serde::Deserialize<'de> for TestReport { system_operator: system_operator__.unwrap_or_default(), archived_date: archived_date__, is_archived: is_archived__.unwrap_or_default(), + run_id: run_id__.unwrap_or_default(), }) } } diff --git a/rust/crates/sift_rs/src/gen/sift.test_reports.v1.tonic.rs b/rust/crates/sift_rs/src/gen/sift.test_reports.v1.tonic.rs index 6a9028f3a..526e0e8ef 100644 --- a/rust/crates/sift_rs/src/gen/sift.test_reports.v1.tonic.rs +++ b/rust/crates/sift_rs/src/gen/sift.test_reports.v1.tonic.rs @@ -435,6 +435,8 @@ pub mod test_report_service_client { ); self.inner.unary(req, path, codec).await } + /** Creates multiple test measurements in a single request +*/ pub async fn create_test_measurements( &mut self, request: impl tonic::IntoRequest, @@ -721,6 +723,8 @@ pub mod test_report_service_server { tonic::Response, tonic::Status, >; + /** Creates multiple test measurements in a single request +*/ async fn create_test_measurements( &self, request: tonic::Request,