api: compile latest proto files for test_platform

BUG=chromium:1085958
TEST=./run_tests; ./api/compile_build_api_proto

Change-Id: I6e4ddcb025924d91381a30ad28576b17ee201550
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/2270906
Commit-Queue: Xinan Lin <linxinan@chromium.org>
Tested-by: Xinan Lin <linxinan@chromium.org>
Reviewed-by: Sean Abraham <seanabraham@chromium.org>
Reviewed-by: Xinan Lin <linxinan@chromium.org>
diff --git a/api/gen/test_platform/analytics/__init__.py b/api/gen/test_platform/analytics/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/api/gen/test_platform/analytics/__init__.py
diff --git a/api/gen/test_platform/analytics/result_pb2.py b/api/gen/test_platform/analytics/result_pb2.py
new file mode 100644
index 0000000..532245b
--- /dev/null
+++ b/api/gen/test_platform/analytics/result_pb2.py
@@ -0,0 +1,486 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: test_platform/analytics/result.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='test_platform/analytics/result.proto',
+  package='test_platform.analytics',
+  syntax='proto3',
+  serialized_options=_b('ZAgo.chromium.org/chromiumos/infra/proto/go/test_platform/analytics'),
+  serialized_pb=_b('\n$test_platform/analytics/result.proto\x12\x17test_platform.analytics\x1a\x1fgoogle/protobuf/timestamp.proto\"\xf8\x01\n\x0bTestPlanRun\x12\x0b\n\x03uid\x18\x01 \x01(\t\x12\x10\n\x08\x62uild_id\x18\x02 \x01(\x03\x12\r\n\x05suite\x18\x03 \x01(\t\x12\x15\n\rexecution_url\x18\x04 \x01(\t\x12\x10\n\x08\x64ut_pool\x18\x05 \x01(\t\x12\x14\n\x0c\x62uild_target\x18\x06 \x01(\t\x12\x16\n\x0e\x63hromeos_build\x18\x07 \x01(\t\x12/\n\x06status\x18\x08 \x01(\x0b\x32\x1f.test_platform.analytics.Status\x12\x33\n\x08timeline\x18\t \x01(\x0b\x32!.test_platform.analytics.Timeline\"\x90\x03\n\x07TestRun\x12\x10\n\x08\x62uild_id\x18\x01 \x01(\x03\x12\x14\n\x0c\x64isplay_name\x18\x02 \x01(\t\x12\x15\n\rexecution_url\x18\x03 \x01(\t\x12\x12\n\nparent_uid\x18\x04 \x01(\t\x12\r\n\x05model\x18\x05 \x01(\t\x12\x33\n\x08timeline\x18\x06 \x01(\x0b\x32!.test_platform.analytics.Timeline\x12/\n\x06status\x18\x07 \x01(\x0b\x32\x1f.test_platform.analytics.Status\x12\x31\n\x07verdict\x18\x08 \x01(\x0b\x32 .test_platform.analytics.Verdict\x12\x14\n\x0c\x66ull_log_url\x18\t \x01(\t\x12\x37\n\x06prejob\x18\n \x01(\x0b\x32\'.test_platform.analytics.TestRun.Prejob\x1a;\n\x06Prejob\x12\x31\n\x07verdict\x18\x01 \x01(\x0b\x32 .test_platform.analytics.Verdict\"\x9f\x01\n\x0eTestCaseResult\x12\x0b\n\x03uid\x18\x01 \x01(\t\x12\x14\n\x0c\x64isplay_name\x18\x02 \x01(\t\x12\x17\n\x0fparent_build_id\x18\x03 \x01(\t\x12\x31\n\x07verdict\x18\x04 \x01(\x0b\x32 .test_platform.analytics.Verdict\x12\x1e\n\x16human_readable_summary\x18\x05 \x01(\t\"\xcb\x01\n\x08Timeline\x12/\n\x0b\x63reate_time\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nstart_time\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12,\n\x08\x65nd_time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x0c\x61\x62\x61ndon_time\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\x17\n\x06Status\x12\r\n\x05value\x18\x01 \x01(\t\"\x18\n\x07Verdict\x12\r\n\x05value\x18\x01 \x01(\tBCZAgo.chromium.org/chromiumos/infra/proto/go/test_platform/analyticsb\x06proto3')
+  ,
+  dependencies=[google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,])
+
+
+
+
+_TESTPLANRUN = _descriptor.Descriptor(
+  name='TestPlanRun',
+  full_name='test_platform.analytics.TestPlanRun',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='uid', full_name='test_platform.analytics.TestPlanRun.uid', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='build_id', full_name='test_platform.analytics.TestPlanRun.build_id', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='suite', full_name='test_platform.analytics.TestPlanRun.suite', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='execution_url', full_name='test_platform.analytics.TestPlanRun.execution_url', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='dut_pool', full_name='test_platform.analytics.TestPlanRun.dut_pool', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='build_target', full_name='test_platform.analytics.TestPlanRun.build_target', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='chromeos_build', full_name='test_platform.analytics.TestPlanRun.chromeos_build', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='status', full_name='test_platform.analytics.TestPlanRun.status', index=7,
+      number=8, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='timeline', full_name='test_platform.analytics.TestPlanRun.timeline', index=8,
+      number=9, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=99,
+  serialized_end=347,
+)
+
+
+_TESTRUN_PREJOB = _descriptor.Descriptor(
+  name='Prejob',
+  full_name='test_platform.analytics.TestRun.Prejob',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='verdict', full_name='test_platform.analytics.TestRun.Prejob.verdict', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=691,
+  serialized_end=750,
+)
+
+_TESTRUN = _descriptor.Descriptor(
+  name='TestRun',
+  full_name='test_platform.analytics.TestRun',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='build_id', full_name='test_platform.analytics.TestRun.build_id', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='display_name', full_name='test_platform.analytics.TestRun.display_name', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='execution_url', full_name='test_platform.analytics.TestRun.execution_url', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='parent_uid', full_name='test_platform.analytics.TestRun.parent_uid', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='model', full_name='test_platform.analytics.TestRun.model', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='timeline', full_name='test_platform.analytics.TestRun.timeline', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='status', full_name='test_platform.analytics.TestRun.status', index=6,
+      number=7, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='verdict', full_name='test_platform.analytics.TestRun.verdict', index=7,
+      number=8, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='full_log_url', full_name='test_platform.analytics.TestRun.full_log_url', index=8,
+      number=9, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='prejob', full_name='test_platform.analytics.TestRun.prejob', index=9,
+      number=10, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[_TESTRUN_PREJOB, ],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=350,
+  serialized_end=750,
+)
+
+
+_TESTCASERESULT = _descriptor.Descriptor(
+  name='TestCaseResult',
+  full_name='test_platform.analytics.TestCaseResult',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='uid', full_name='test_platform.analytics.TestCaseResult.uid', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='display_name', full_name='test_platform.analytics.TestCaseResult.display_name', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='parent_build_id', full_name='test_platform.analytics.TestCaseResult.parent_build_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='verdict', full_name='test_platform.analytics.TestCaseResult.verdict', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='human_readable_summary', full_name='test_platform.analytics.TestCaseResult.human_readable_summary', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=753,
+  serialized_end=912,
+)
+
+
+_TIMELINE = _descriptor.Descriptor(
+  name='Timeline',
+  full_name='test_platform.analytics.Timeline',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='create_time', full_name='test_platform.analytics.Timeline.create_time', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='start_time', full_name='test_platform.analytics.Timeline.start_time', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='end_time', full_name='test_platform.analytics.Timeline.end_time', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='abandon_time', full_name='test_platform.analytics.Timeline.abandon_time', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=915,
+  serialized_end=1118,
+)
+
+
+_STATUS = _descriptor.Descriptor(
+  name='Status',
+  full_name='test_platform.analytics.Status',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='test_platform.analytics.Status.value', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1120,
+  serialized_end=1143,
+)
+
+
+_VERDICT = _descriptor.Descriptor(
+  name='Verdict',
+  full_name='test_platform.analytics.Verdict',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='test_platform.analytics.Verdict.value', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1145,
+  serialized_end=1169,
+)
+
+_TESTPLANRUN.fields_by_name['status'].message_type = _STATUS
+_TESTPLANRUN.fields_by_name['timeline'].message_type = _TIMELINE
+_TESTRUN_PREJOB.fields_by_name['verdict'].message_type = _VERDICT
+_TESTRUN_PREJOB.containing_type = _TESTRUN
+_TESTRUN.fields_by_name['timeline'].message_type = _TIMELINE
+_TESTRUN.fields_by_name['status'].message_type = _STATUS
+_TESTRUN.fields_by_name['verdict'].message_type = _VERDICT
+_TESTRUN.fields_by_name['prejob'].message_type = _TESTRUN_PREJOB
+_TESTCASERESULT.fields_by_name['verdict'].message_type = _VERDICT
+_TIMELINE.fields_by_name['create_time'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
+_TIMELINE.fields_by_name['start_time'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
+_TIMELINE.fields_by_name['end_time'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
+_TIMELINE.fields_by_name['abandon_time'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
+DESCRIPTOR.message_types_by_name['TestPlanRun'] = _TESTPLANRUN
+DESCRIPTOR.message_types_by_name['TestRun'] = _TESTRUN
+DESCRIPTOR.message_types_by_name['TestCaseResult'] = _TESTCASERESULT
+DESCRIPTOR.message_types_by_name['Timeline'] = _TIMELINE
+DESCRIPTOR.message_types_by_name['Status'] = _STATUS
+DESCRIPTOR.message_types_by_name['Verdict'] = _VERDICT
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+TestPlanRun = _reflection.GeneratedProtocolMessageType('TestPlanRun', (_message.Message,), dict(
+  DESCRIPTOR = _TESTPLANRUN,
+  __module__ = 'test_platform.analytics.result_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.analytics.TestPlanRun)
+  ))
+_sym_db.RegisterMessage(TestPlanRun)
+
+TestRun = _reflection.GeneratedProtocolMessageType('TestRun', (_message.Message,), dict(
+
+  Prejob = _reflection.GeneratedProtocolMessageType('Prejob', (_message.Message,), dict(
+    DESCRIPTOR = _TESTRUN_PREJOB,
+    __module__ = 'test_platform.analytics.result_pb2'
+    # @@protoc_insertion_point(class_scope:test_platform.analytics.TestRun.Prejob)
+    ))
+  ,
+  DESCRIPTOR = _TESTRUN,
+  __module__ = 'test_platform.analytics.result_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.analytics.TestRun)
+  ))
+_sym_db.RegisterMessage(TestRun)
+_sym_db.RegisterMessage(TestRun.Prejob)
+
+TestCaseResult = _reflection.GeneratedProtocolMessageType('TestCaseResult', (_message.Message,), dict(
+  DESCRIPTOR = _TESTCASERESULT,
+  __module__ = 'test_platform.analytics.result_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.analytics.TestCaseResult)
+  ))
+_sym_db.RegisterMessage(TestCaseResult)
+
+Timeline = _reflection.GeneratedProtocolMessageType('Timeline', (_message.Message,), dict(
+  DESCRIPTOR = _TIMELINE,
+  __module__ = 'test_platform.analytics.result_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.analytics.Timeline)
+  ))
+_sym_db.RegisterMessage(Timeline)
+
+Status = _reflection.GeneratedProtocolMessageType('Status', (_message.Message,), dict(
+  DESCRIPTOR = _STATUS,
+  __module__ = 'test_platform.analytics.result_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.analytics.Status)
+  ))
+_sym_db.RegisterMessage(Status)
+
+Verdict = _reflection.GeneratedProtocolMessageType('Verdict', (_message.Message,), dict(
+  DESCRIPTOR = _VERDICT,
+  __module__ = 'test_platform.analytics.result_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.analytics.Verdict)
+  ))
+_sym_db.RegisterMessage(Verdict)
+
+
+DESCRIPTOR._options = None
+# @@protoc_insertion_point(module_scope)
diff --git a/api/gen/test_platform/config/config_pb2.py b/api/gen/test_platform/config/config_pb2.py
index cc82613..9a53f72 100644
--- a/api/gen/test_platform/config/config_pb2.py
+++ b/api/gen/test_platform/config/config_pb2.py
@@ -12,6 +12,7 @@
 _sym_db = _symbol_database.Default()
 
 
+from chromite.api.gen.test_platform.migration.test_runner import config_pb2 as test__platform_dot_migration_dot_test__runner_dot_config__pb2
 
 
 DESCRIPTOR = _descriptor.FileDescriptor(
@@ -19,8 +20,9 @@
   package='test_platform.config',
   syntax='proto3',
   serialized_options=_b('Z>go.chromium.org/chromiumos/infra/proto/go/test_platform/config'),
-  serialized_pb=_b('\n!test_platform/config/config.proto\x12\x14test_platform.config\"\xa4\x06\n\x06\x43onfig\x12>\n\x0fskylab_swarming\x18\x01 \x01(\x0b\x32%.test_platform.config.Config.Swarming\x12<\n\x0eskylab_isolate\x18\x03 \x01(\x0b\x32$.test_platform.config.Config.Isolate\x12@\n\rskylab_worker\x18\x04 \x01(\x0b\x32).test_platform.config.Config.SkylabWorker\x12;\n\nversioning\x18\x07 \x01(\x0b\x32\'.test_platform.config.Config.Versioning\x12<\n\x0btest_runner\x18\x08 \x01(\x0b\x32\'.test_platform.config.Config.TestRunner\x1a\x32\n\x08Swarming\x12\x0e\n\x06server\x18\x01 \x01(\t\x12\x16\n\x0e\x61uth_json_path\x18\x02 \x01(\t\x1a!\n\x07Isolate\x12\x16\n\x0e\x61uth_json_path\x18\x01 \x01(\t\x1a:\n\x0cSkylabWorker\x12\x14\n\x0cluci_project\x18\x01 \x01(\t\x12\x14\n\x0clog_dog_host\x18\x02 \x01(\t\x1a\x9d\x01\n\nVersioning\x12\x61\n\x19\x63ros_test_platform_binary\x18\x01 \x01(\x0b\x32>.test_platform.config.Config.Versioning.CrosTestPlatformBinary\x1a,\n\x16\x43rosTestPlatformBinary\x12\x12\n\ncipd_label\x18\x01 \x01(\t\x1aM\n\x0b\x42uildbucket\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x62ucket\x18\x03 \x01(\t\x12\x0f\n\x07\x62uilder\x18\x04 \x01(\t\x1aK\n\nTestRunner\x12=\n\x0b\x62uildbucket\x18\x01 \x01(\x0b\x32(.test_platform.config.Config.BuildbucketJ\x04\x08\x02\x10\x03J\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07\x42@Z>go.chromium.org/chromiumos/infra/proto/go/test_platform/configb\x06proto3')
-)
+  serialized_pb=_b('\n!test_platform/config/config.proto\x12\x14test_platform.config\x1a\x30test_platform/migration/test_runner/config.proto\"\xf0\x06\n\x06\x43onfig\x12>\n\x0fskylab_swarming\x18\x01 \x01(\x0b\x32%.test_platform.config.Config.Swarming\x12<\n\x0eskylab_isolate\x18\x03 \x01(\x0b\x32$.test_platform.config.Config.Isolate\x12@\n\rskylab_worker\x18\x04 \x01(\x0b\x32).test_platform.config.Config.SkylabWorker\x12;\n\nversioning\x18\x07 \x01(\x0b\x32\'.test_platform.config.Config.Versioning\x12<\n\x0btest_runner\x18\x08 \x01(\x0b\x32\'.test_platform.config.Config.TestRunner\x12J\n\x15test_runner_migration\x18\t \x01(\x0b\x32+.test_platform.migration.test_runner.Config\x1a\x32\n\x08Swarming\x12\x0e\n\x06server\x18\x01 \x01(\t\x12\x16\n\x0e\x61uth_json_path\x18\x02 \x01(\t\x1a!\n\x07Isolate\x12\x16\n\x0e\x61uth_json_path\x18\x01 \x01(\t\x1a:\n\x0cSkylabWorker\x12\x14\n\x0cluci_project\x18\x01 \x01(\t\x12\x14\n\x0clog_dog_host\x18\x02 \x01(\t\x1a\x9d\x01\n\nVersioning\x12\x61\n\x19\x63ros_test_platform_binary\x18\x01 \x01(\x0b\x32>.test_platform.config.Config.Versioning.CrosTestPlatformBinary\x1a,\n\x16\x43rosTestPlatformBinary\x12\x12\n\ncipd_label\x18\x01 \x01(\t\x1aM\n\x0b\x42uildbucket\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x62ucket\x18\x03 \x01(\t\x12\x0f\n\x07\x62uilder\x18\x04 \x01(\t\x1aK\n\nTestRunner\x12=\n\x0b\x62uildbucket\x18\x01 \x01(\x0b\x32(.test_platform.config.Config.BuildbucketJ\x04\x08\x02\x10\x03J\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07\x42@Z>go.chromium.org/chromiumos/infra/proto/go/test_platform/configb\x06proto3')
+  ,
+  dependencies=[test__platform_dot_migration_dot_test__runner_dot_config__pb2.DESCRIPTOR,])
 
 
 
@@ -58,8 +60,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=385,
-  serialized_end=435,
+  serialized_start=511,
+  serialized_end=561,
 )
 
 _CONFIG_ISOLATE = _descriptor.Descriptor(
@@ -88,8 +90,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=437,
-  serialized_end=470,
+  serialized_start=563,
+  serialized_end=596,
 )
 
 _CONFIG_SKYLABWORKER = _descriptor.Descriptor(
@@ -125,8 +127,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=472,
-  serialized_end=530,
+  serialized_start=598,
+  serialized_end=656,
 )
 
 _CONFIG_VERSIONING_CROSTESTPLATFORMBINARY = _descriptor.Descriptor(
@@ -155,8 +157,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=646,
-  serialized_end=690,
+  serialized_start=772,
+  serialized_end=816,
 )
 
 _CONFIG_VERSIONING = _descriptor.Descriptor(
@@ -185,8 +187,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=533,
-  serialized_end=690,
+  serialized_start=659,
+  serialized_end=816,
 )
 
 _CONFIG_BUILDBUCKET = _descriptor.Descriptor(
@@ -236,8 +238,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=692,
-  serialized_end=769,
+  serialized_start=818,
+  serialized_end=895,
 )
 
 _CONFIG_TESTRUNNER = _descriptor.Descriptor(
@@ -266,8 +268,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=771,
-  serialized_end=846,
+  serialized_start=897,
+  serialized_end=972,
 )
 
 _CONFIG = _descriptor.Descriptor(
@@ -312,6 +314,13 @@
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='test_runner_migration', full_name='test_platform.config.Config.test_runner_migration', index=5,
+      number=9, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
   ],
   extensions=[
   ],
@@ -324,8 +333,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=60,
-  serialized_end=864,
+  serialized_start=110,
+  serialized_end=990,
 )
 
 _CONFIG_SWARMING.containing_type = _CONFIG
@@ -342,6 +351,7 @@
 _CONFIG.fields_by_name['skylab_worker'].message_type = _CONFIG_SKYLABWORKER
 _CONFIG.fields_by_name['versioning'].message_type = _CONFIG_VERSIONING
 _CONFIG.fields_by_name['test_runner'].message_type = _CONFIG_TESTRUNNER
+_CONFIG.fields_by_name['test_runner_migration'].message_type = test__platform_dot_migration_dot_test__runner_dot_config__pb2._CONFIG
 DESCRIPTOR.message_types_by_name['Config'] = _CONFIG
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
diff --git a/api/gen/test_platform/migration/test_runner/__init__.py b/api/gen/test_platform/migration/test_runner/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/api/gen/test_platform/migration/test_runner/__init__.py
diff --git a/api/gen/test_platform/migration/test_runner/config_pb2.py b/api/gen/test_platform/migration/test_runner/config_pb2.py
new file mode 100644
index 0000000..cc20d6d
--- /dev/null
+++ b/api/gen/test_platform/migration/test_runner/config_pb2.py
@@ -0,0 +1,164 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: test_platform/migration/test_runner/config.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='test_platform/migration/test_runner/config.proto',
+  package='test_platform.migration.test_runner',
+  syntax='proto3',
+  serialized_options=_b('ZMgo.chromium.org/chromiumos/infra/proto/go/test_platform/migration/test_runner'),
+  serialized_pb=_b('\n0test_platform/migration/test_runner/config.proto\x12#test_platform.migration.test_runner\"a\n\x06\x43onfig\x12W\n\x15redirect_instructions\x18\x01 \x03(\x0b\x32\x38.test_platform.migration.test_runner.RedirectInstruction\"~\n\x13RedirectInstruction\x12J\n\nconstraint\x18\x01 \x01(\x0b\x32\x36.test_platform.migration.test_runner.TrafficConstraint\x12\x1b\n\x13percent_of_requests\x18\x02 \x01(\x05\"<\n\x11TrafficConstraint\x12\x10\n\x08\x64ut_pool\x18\x01 \x01(\t\x12\x15\n\rquota_account\x18\x02 \x01(\tBOZMgo.chromium.org/chromiumos/infra/proto/go/test_platform/migration/test_runnerb\x06proto3')
+)
+
+
+
+
+_CONFIG = _descriptor.Descriptor(
+  name='Config',
+  full_name='test_platform.migration.test_runner.Config',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='redirect_instructions', full_name='test_platform.migration.test_runner.Config.redirect_instructions', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=89,
+  serialized_end=186,
+)
+
+
+_REDIRECTINSTRUCTION = _descriptor.Descriptor(
+  name='RedirectInstruction',
+  full_name='test_platform.migration.test_runner.RedirectInstruction',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='constraint', full_name='test_platform.migration.test_runner.RedirectInstruction.constraint', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='percent_of_requests', full_name='test_platform.migration.test_runner.RedirectInstruction.percent_of_requests', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=188,
+  serialized_end=314,
+)
+
+
+_TRAFFICCONSTRAINT = _descriptor.Descriptor(
+  name='TrafficConstraint',
+  full_name='test_platform.migration.test_runner.TrafficConstraint',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='dut_pool', full_name='test_platform.migration.test_runner.TrafficConstraint.dut_pool', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='quota_account', full_name='test_platform.migration.test_runner.TrafficConstraint.quota_account', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=316,
+  serialized_end=376,
+)
+
+_CONFIG.fields_by_name['redirect_instructions'].message_type = _REDIRECTINSTRUCTION
+_REDIRECTINSTRUCTION.fields_by_name['constraint'].message_type = _TRAFFICCONSTRAINT
+DESCRIPTOR.message_types_by_name['Config'] = _CONFIG
+DESCRIPTOR.message_types_by_name['RedirectInstruction'] = _REDIRECTINSTRUCTION
+DESCRIPTOR.message_types_by_name['TrafficConstraint'] = _TRAFFICCONSTRAINT
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+Config = _reflection.GeneratedProtocolMessageType('Config', (_message.Message,), dict(
+  DESCRIPTOR = _CONFIG,
+  __module__ = 'test_platform.migration.test_runner.config_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.migration.test_runner.Config)
+  ))
+_sym_db.RegisterMessage(Config)
+
+RedirectInstruction = _reflection.GeneratedProtocolMessageType('RedirectInstruction', (_message.Message,), dict(
+  DESCRIPTOR = _REDIRECTINSTRUCTION,
+  __module__ = 'test_platform.migration.test_runner.config_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.migration.test_runner.RedirectInstruction)
+  ))
+_sym_db.RegisterMessage(RedirectInstruction)
+
+TrafficConstraint = _reflection.GeneratedProtocolMessageType('TrafficConstraint', (_message.Message,), dict(
+  DESCRIPTOR = _TRAFFICCONSTRAINT,
+  __module__ = 'test_platform.migration.test_runner.config_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.migration.test_runner.TrafficConstraint)
+  ))
+_sym_db.RegisterMessage(TrafficConstraint)
+
+
+DESCRIPTOR._options = None
+# @@protoc_insertion_point(module_scope)
diff --git a/api/gen/test_platform/result_flow/__init__.py b/api/gen/test_platform/result_flow/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/api/gen/test_platform/result_flow/__init__.py
diff --git a/api/gen/test_platform/result_flow/common_pb2.py b/api/gen/test_platform/result_flow/common_pb2.py
new file mode 100644
index 0000000..306b320
--- /dev/null
+++ b/api/gen/test_platform/result_flow/common_pb2.py
@@ -0,0 +1,341 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: test_platform/result_flow/common.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='test_platform/result_flow/common.proto',
+  package='test_platform.result_flow',
+  syntax='proto3',
+  serialized_options=_b('ZCgo.chromium.org/chromiumos/infra/proto/go/test_platform/result_flow'),
+  serialized_pb=_b('\n&test_platform/result_flow/common.proto\x12\x19test_platform.result_flow\"d\n\x0cPubSubConfig\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\r\n\x05topic\x18\x02 \x01(\t\x12\x14\n\x0csubscription\x18\x03 \x01(\t\x12\x1e\n\x16max_receiving_messages\x18\x04 \x01(\x05\"S\n\x11\x42uildbucketConfig\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x0e\n\x06\x62ucket\x18\x03 \x01(\t\x12\x0f\n\x07\x62uilder\x18\x04 \x01(\t\"A\n\x0e\x42igqueryConfig\x12\x0f\n\x07project\x18\x01 \x01(\t\x12\x0f\n\x07\x64\x61taset\x18\x02 \x01(\t\x12\r\n\x05table\x18\x03 \x01(\t\"\x8b\x01\n\x06Source\x12\x37\n\x06pubsub\x18\x01 \x01(\x0b\x32\'.test_platform.result_flow.PubSubConfig\x12\x38\n\x02\x62\x62\x18\x02 \x01(\x0b\x32,.test_platform.result_flow.BuildbucketConfig\x12\x0e\n\x06\x66ields\x18\x03 \x03(\t\"?\n\x06Target\x12\x35\n\x02\x62q\x18\x01 \x01(\x0b\x32).test_platform.result_flow.BigqueryConfig*U\n\x05State\x12\x15\n\x11STATE_UNSPECIFIED\x10\x00\x12\r\n\tSUCCEEDED\x10\x01\x12\n\n\x06\x46\x41ILED\x10\x02\x12\r\n\tTIMED_OUT\x10\x03\x12\x0b\n\x07\x41\x42ORTED\x10\x04\x42\x45ZCgo.chromium.org/chromiumos/infra/proto/go/test_platform/result_flowb\x06proto3')
+)
+
+_STATE = _descriptor.EnumDescriptor(
+  name='State',
+  full_name='test_platform.result_flow.State',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='STATE_UNSPECIFIED', index=0, number=0,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='SUCCEEDED', index=1, number=1,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='FAILED', index=2, number=2,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='TIMED_OUT', index=3, number=3,
+      serialized_options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='ABORTED', index=4, number=4,
+      serialized_options=None,
+      type=None),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=530,
+  serialized_end=615,
+)
+_sym_db.RegisterEnumDescriptor(_STATE)
+
+State = enum_type_wrapper.EnumTypeWrapper(_STATE)
+STATE_UNSPECIFIED = 0
+SUCCEEDED = 1
+FAILED = 2
+TIMED_OUT = 3
+ABORTED = 4
+
+
+
+_PUBSUBCONFIG = _descriptor.Descriptor(
+  name='PubSubConfig',
+  full_name='test_platform.result_flow.PubSubConfig',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='project', full_name='test_platform.result_flow.PubSubConfig.project', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='topic', full_name='test_platform.result_flow.PubSubConfig.topic', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='subscription', full_name='test_platform.result_flow.PubSubConfig.subscription', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='max_receiving_messages', full_name='test_platform.result_flow.PubSubConfig.max_receiving_messages', index=3,
+      number=4, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=69,
+  serialized_end=169,
+)
+
+
+_BUILDBUCKETCONFIG = _descriptor.Descriptor(
+  name='BuildbucketConfig',
+  full_name='test_platform.result_flow.BuildbucketConfig',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='host', full_name='test_platform.result_flow.BuildbucketConfig.host', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='project', full_name='test_platform.result_flow.BuildbucketConfig.project', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='bucket', full_name='test_platform.result_flow.BuildbucketConfig.bucket', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='builder', full_name='test_platform.result_flow.BuildbucketConfig.builder', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=171,
+  serialized_end=254,
+)
+
+
+_BIGQUERYCONFIG = _descriptor.Descriptor(
+  name='BigqueryConfig',
+  full_name='test_platform.result_flow.BigqueryConfig',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='project', full_name='test_platform.result_flow.BigqueryConfig.project', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='dataset', full_name='test_platform.result_flow.BigqueryConfig.dataset', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='table', full_name='test_platform.result_flow.BigqueryConfig.table', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=256,
+  serialized_end=321,
+)
+
+
+_SOURCE = _descriptor.Descriptor(
+  name='Source',
+  full_name='test_platform.result_flow.Source',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='pubsub', full_name='test_platform.result_flow.Source.pubsub', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='bb', full_name='test_platform.result_flow.Source.bb', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='fields', full_name='test_platform.result_flow.Source.fields', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=324,
+  serialized_end=463,
+)
+
+
+_TARGET = _descriptor.Descriptor(
+  name='Target',
+  full_name='test_platform.result_flow.Target',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='bq', full_name='test_platform.result_flow.Target.bq', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=465,
+  serialized_end=528,
+)
+
+_SOURCE.fields_by_name['pubsub'].message_type = _PUBSUBCONFIG
+_SOURCE.fields_by_name['bb'].message_type = _BUILDBUCKETCONFIG
+_TARGET.fields_by_name['bq'].message_type = _BIGQUERYCONFIG
+DESCRIPTOR.message_types_by_name['PubSubConfig'] = _PUBSUBCONFIG
+DESCRIPTOR.message_types_by_name['BuildbucketConfig'] = _BUILDBUCKETCONFIG
+DESCRIPTOR.message_types_by_name['BigqueryConfig'] = _BIGQUERYCONFIG
+DESCRIPTOR.message_types_by_name['Source'] = _SOURCE
+DESCRIPTOR.message_types_by_name['Target'] = _TARGET
+DESCRIPTOR.enum_types_by_name['State'] = _STATE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+PubSubConfig = _reflection.GeneratedProtocolMessageType('PubSubConfig', (_message.Message,), dict(
+  DESCRIPTOR = _PUBSUBCONFIG,
+  __module__ = 'test_platform.result_flow.common_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.result_flow.PubSubConfig)
+  ))
+_sym_db.RegisterMessage(PubSubConfig)
+
+BuildbucketConfig = _reflection.GeneratedProtocolMessageType('BuildbucketConfig', (_message.Message,), dict(
+  DESCRIPTOR = _BUILDBUCKETCONFIG,
+  __module__ = 'test_platform.result_flow.common_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.result_flow.BuildbucketConfig)
+  ))
+_sym_db.RegisterMessage(BuildbucketConfig)
+
+BigqueryConfig = _reflection.GeneratedProtocolMessageType('BigqueryConfig', (_message.Message,), dict(
+  DESCRIPTOR = _BIGQUERYCONFIG,
+  __module__ = 'test_platform.result_flow.common_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.result_flow.BigqueryConfig)
+  ))
+_sym_db.RegisterMessage(BigqueryConfig)
+
+Source = _reflection.GeneratedProtocolMessageType('Source', (_message.Message,), dict(
+  DESCRIPTOR = _SOURCE,
+  __module__ = 'test_platform.result_flow.common_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.result_flow.Source)
+  ))
+_sym_db.RegisterMessage(Source)
+
+Target = _reflection.GeneratedProtocolMessageType('Target', (_message.Message,), dict(
+  DESCRIPTOR = _TARGET,
+  __module__ = 'test_platform.result_flow.common_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.result_flow.Target)
+  ))
+_sym_db.RegisterMessage(Target)
+
+
+DESCRIPTOR._options = None
+# @@protoc_insertion_point(module_scope)
diff --git a/api/gen/test_platform/result_flow/ctp_pb2.py b/api/gen/test_platform/result_flow/ctp_pb2.py
new file mode 100644
index 0000000..df2183a
--- /dev/null
+++ b/api/gen/test_platform/result_flow/ctp_pb2.py
@@ -0,0 +1,130 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: test_platform/result_flow/ctp.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from chromite.api.gen.test_platform.result_flow import common_pb2 as test__platform_dot_result__flow_dot_common__pb2
+from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='test_platform/result_flow/ctp.proto',
+  package='test_platform.result_flow',
+  syntax='proto3',
+  serialized_options=_b('ZCgo.chromium.org/chromiumos/infra/proto/go/test_platform/result_flow'),
+  serialized_pb=_b('\n#test_platform/result_flow/ctp.proto\x12\x19test_platform.result_flow\x1a&test_platform/result_flow/common.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xa4\x01\n\nCTPRequest\x12.\n\x03\x63tp\x18\x01 \x01(\x0b\x32!.test_platform.result_flow.Source\x12\x38\n\rtest_plan_run\x18\x02 \x01(\x0b\x32!.test_platform.result_flow.Target\x12,\n\x08\x64\x65\x61\x64line\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\">\n\x0b\x43TPResponse\x12/\n\x05state\x18\x01 \x01(\x0e\x32 .test_platform.result_flow.StateBEZCgo.chromium.org/chromiumos/infra/proto/go/test_platform/result_flowb\x06proto3')
+  ,
+  dependencies=[test__platform_dot_result__flow_dot_common__pb2.DESCRIPTOR,google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,])
+
+
+
+
+_CTPREQUEST = _descriptor.Descriptor(
+  name='CTPRequest',
+  full_name='test_platform.result_flow.CTPRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='ctp', full_name='test_platform.result_flow.CTPRequest.ctp', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='test_plan_run', full_name='test_platform.result_flow.CTPRequest.test_plan_run', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='deadline', full_name='test_platform.result_flow.CTPRequest.deadline', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=140,
+  serialized_end=304,
+)
+
+
+_CTPRESPONSE = _descriptor.Descriptor(
+  name='CTPResponse',
+  full_name='test_platform.result_flow.CTPResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='state', full_name='test_platform.result_flow.CTPResponse.state', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=306,
+  serialized_end=368,
+)
+
+_CTPREQUEST.fields_by_name['ctp'].message_type = test__platform_dot_result__flow_dot_common__pb2._SOURCE
+_CTPREQUEST.fields_by_name['test_plan_run'].message_type = test__platform_dot_result__flow_dot_common__pb2._TARGET
+_CTPREQUEST.fields_by_name['deadline'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
+_CTPRESPONSE.fields_by_name['state'].enum_type = test__platform_dot_result__flow_dot_common__pb2._STATE
+DESCRIPTOR.message_types_by_name['CTPRequest'] = _CTPREQUEST
+DESCRIPTOR.message_types_by_name['CTPResponse'] = _CTPRESPONSE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+CTPRequest = _reflection.GeneratedProtocolMessageType('CTPRequest', (_message.Message,), dict(
+  DESCRIPTOR = _CTPREQUEST,
+  __module__ = 'test_platform.result_flow.ctp_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.result_flow.CTPRequest)
+  ))
+_sym_db.RegisterMessage(CTPRequest)
+
+CTPResponse = _reflection.GeneratedProtocolMessageType('CTPResponse', (_message.Message,), dict(
+  DESCRIPTOR = _CTPRESPONSE,
+  __module__ = 'test_platform.result_flow.ctp_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.result_flow.CTPResponse)
+  ))
+_sym_db.RegisterMessage(CTPResponse)
+
+
+DESCRIPTOR._options = None
+# @@protoc_insertion_point(module_scope)
diff --git a/api/gen/test_platform/result_flow/publish_pb2.py b/api/gen/test_platform/result_flow/publish_pb2.py
new file mode 100644
index 0000000..9420bcf
--- /dev/null
+++ b/api/gen/test_platform/result_flow/publish_pb2.py
@@ -0,0 +1,144 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: test_platform/result_flow/publish.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from chromite.api.gen.test_platform.result_flow import common_pb2 as test__platform_dot_result__flow_dot_common__pb2
+from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='test_platform/result_flow/publish.proto',
+  package='test_platform.result_flow',
+  syntax='proto3',
+  serialized_options=_b('ZCgo.chromium.org/chromiumos/infra/proto/go/test_platform/result_flow'),
+  serialized_pb=_b('\n\'test_platform/result_flow/publish.proto\x12\x19test_platform.result_flow\x1a&test_platform/result_flow/common.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xdd\x01\n\x0ePublishRequest\x12\x10\n\x08\x62uild_id\x18\x01 \x01(\x03\x12\x17\n\x0fparent_build_id\x18\x02 \x01(\x03\x12\x34\n\x03\x63tp\x18\x03 \x01(\x0b\x32\'.test_platform.result_flow.PubSubConfig\x12<\n\x0btest_runner\x18\x04 \x01(\x0b\x32\'.test_platform.result_flow.PubSubConfig\x12,\n\x08\x64\x65\x61\x64line\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"B\n\x0fPublishResponse\x12/\n\x05state\x18\x01 \x01(\x0e\x32 .test_platform.result_flow.StateBEZCgo.chromium.org/chromiumos/infra/proto/go/test_platform/result_flowb\x06proto3')
+  ,
+  dependencies=[test__platform_dot_result__flow_dot_common__pb2.DESCRIPTOR,google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,])
+
+
+
+
+_PUBLISHREQUEST = _descriptor.Descriptor(
+  name='PublishRequest',
+  full_name='test_platform.result_flow.PublishRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='build_id', full_name='test_platform.result_flow.PublishRequest.build_id', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='parent_build_id', full_name='test_platform.result_flow.PublishRequest.parent_build_id', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='ctp', full_name='test_platform.result_flow.PublishRequest.ctp', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='test_runner', full_name='test_platform.result_flow.PublishRequest.test_runner', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='deadline', full_name='test_platform.result_flow.PublishRequest.deadline', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=144,
+  serialized_end=365,
+)
+
+
+_PUBLISHRESPONSE = _descriptor.Descriptor(
+  name='PublishResponse',
+  full_name='test_platform.result_flow.PublishResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='state', full_name='test_platform.result_flow.PublishResponse.state', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=367,
+  serialized_end=433,
+)
+
+_PUBLISHREQUEST.fields_by_name['ctp'].message_type = test__platform_dot_result__flow_dot_common__pb2._PUBSUBCONFIG
+_PUBLISHREQUEST.fields_by_name['test_runner'].message_type = test__platform_dot_result__flow_dot_common__pb2._PUBSUBCONFIG
+_PUBLISHREQUEST.fields_by_name['deadline'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
+_PUBLISHRESPONSE.fields_by_name['state'].enum_type = test__platform_dot_result__flow_dot_common__pb2._STATE
+DESCRIPTOR.message_types_by_name['PublishRequest'] = _PUBLISHREQUEST
+DESCRIPTOR.message_types_by_name['PublishResponse'] = _PUBLISHRESPONSE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+PublishRequest = _reflection.GeneratedProtocolMessageType('PublishRequest', (_message.Message,), dict(
+  DESCRIPTOR = _PUBLISHREQUEST,
+  __module__ = 'test_platform.result_flow.publish_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.result_flow.PublishRequest)
+  ))
+_sym_db.RegisterMessage(PublishRequest)
+
+PublishResponse = _reflection.GeneratedProtocolMessageType('PublishResponse', (_message.Message,), dict(
+  DESCRIPTOR = _PUBLISHRESPONSE,
+  __module__ = 'test_platform.result_flow.publish_pb2'
+  # @@protoc_insertion_point(class_scope:test_platform.result_flow.PublishResponse)
+  ))
+_sym_db.RegisterMessage(PublishResponse)
+
+
+DESCRIPTOR._options = None
+# @@protoc_insertion_point(module_scope)
diff --git a/api/gen/test_platform/skylab_local_state/load_pb2.py b/api/gen/test_platform/skylab_local_state/load_pb2.py
index a28665d..92687f6 100644
--- a/api/gen/test_platform/skylab_local_state/load_pb2.py
+++ b/api/gen/test_platform/skylab_local_state/load_pb2.py
@@ -21,7 +21,7 @@
   package='test_platform.skylab_local_state',
   syntax='proto3',
   serialized_options=_b('ZJgo.chromium.org/chromiumos/infra/proto/go/test_platform/skylab_local_state'),
-  serialized_pb=_b('\n+test_platform/skylab_local_state/load.proto\x12 test_platform.skylab_local_state\x1a-test_platform/skylab_local_state/common.proto\x1a-test_platform/skylab_test_runner/result.proto\"\x82\x01\n\x0bLoadRequest\x12\x38\n\x06\x63onfig\x18\x01 \x01(\x0b\x32(.test_platform.skylab_local_state.Config\x12\x17\n\x0bresults_dir\x18\x02 \x01(\tB\x02\x18\x01\x12\x10\n\x08\x64ut_name\x18\x03 \x01(\t\x12\x0e\n\x06run_id\x18\x04 \x01(\t\"\x8d\x02\n\x0cLoadResponse\x12\x65\n\x14provisionable_labels\x18\x01 \x03(\x0b\x32G.test_platform.skylab_local_state.LoadResponse.ProvisionableLabelsEntry\x12\x13\n\x0bresults_dir\x18\x02 \x01(\t\x12\x45\n\rasync_results\x18\x03 \x01(\x0b\x32..test_platform.skylab_test_runner.AsyncResults\x1a:\n\x18ProvisionableLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42LZJgo.chromium.org/chromiumos/infra/proto/go/test_platform/skylab_local_stateb\x06proto3')
+  serialized_pb=_b('\n+test_platform/skylab_local_state/load.proto\x12 test_platform.skylab_local_state\x1a-test_platform/skylab_local_state/common.proto\x1a-test_platform/skylab_test_runner/result.proto\"\x92\x01\n\x0bLoadRequest\x12\x38\n\x06\x63onfig\x18\x01 \x01(\x0b\x32(.test_platform.skylab_local_state.Config\x12\x17\n\x0bresults_dir\x18\x02 \x01(\tB\x02\x18\x01\x12\x10\n\x08\x64ut_name\x18\x03 \x01(\t\x12\x0e\n\x06run_id\x18\x04 \x01(\t\x12\x0e\n\x06\x64ut_id\x18\x05 \x01(\t\"\x8d\x02\n\x0cLoadResponse\x12\x65\n\x14provisionable_labels\x18\x01 \x03(\x0b\x32G.test_platform.skylab_local_state.LoadResponse.ProvisionableLabelsEntry\x12\x13\n\x0bresults_dir\x18\x02 \x01(\t\x12\x45\n\rasync_results\x18\x03 \x01(\x0b\x32..test_platform.skylab_test_runner.AsyncResults\x1a:\n\x18ProvisionableLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42LZJgo.chromium.org/chromiumos/infra/proto/go/test_platform/skylab_local_stateb\x06proto3')
   ,
   dependencies=[test__platform_dot_skylab__local__state_dot_common__pb2.DESCRIPTOR,test__platform_dot_skylab__test__runner_dot_result__pb2.DESCRIPTOR,])
 
@@ -63,6 +63,13 @@
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='dut_id', full_name='test_platform.skylab_local_state.LoadRequest.dut_id', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
   ],
   extensions=[
   ],
@@ -76,7 +83,7 @@
   oneofs=[
   ],
   serialized_start=176,
-  serialized_end=306,
+  serialized_end=322,
 )
 
 
@@ -113,8 +120,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=520,
-  serialized_end=578,
+  serialized_start=536,
+  serialized_end=594,
 )
 
 _LOADRESPONSE = _descriptor.Descriptor(
@@ -157,8 +164,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=309,
-  serialized_end=578,
+  serialized_start=325,
+  serialized_end=594,
 )
 
 _LOADREQUEST.fields_by_name['config'].message_type = test__platform_dot_skylab__local__state_dot_common__pb2._CONFIG