afdo: Provide build endpoint for auto-committing builder changes.
Implement build API for go/cros-recipe-builder-commits, includes
providing a new endpoint. This API only supports updating kernel
afdo metadata for now but can be extended to support more in the
future.
Leave commit footers empty for now.
BUG=chromium:1081332
TEST=build_api test passed locally; unittests passed
Change-Id: I69509482b2e0875987714c9b3a3ea194a9aeea03
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/2628347
Reviewed-by: Alex Klein <saklein@chromium.org>
Reviewed-by: LaMont Jones <lamontjones@chromium.org>
Tested-by: Tiancong Wang <tcwang@google.com>
Commit-Queue: Tiancong Wang <tcwang@google.com>
diff --git a/api/controller/toolchain.py b/api/controller/toolchain.py
index 77dccf7..a889b3d 100644
--- a/api/controller/toolchain.py
+++ b/api/controller/toolchain.py
@@ -79,6 +79,11 @@
toolchain_util.BundleArtifacts),
}
+_TOOLCHAIN_COMMIT_HANDLERS = {
+ BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE:
+ 'VerifiedKernelCwpAfdoFile'
+}
+
def _GetProfileInfoDict(profile_info):
"""Convert profile_info to a dict.
@@ -227,6 +232,54 @@
art_info.artifacts.add().path = artifact
+def _GetUpdatedFilesResponse(_input_proto, output_proto, _config):
+ """Add successful status to the faux response."""
+ file_info = output_proto.updated_files.add()
+ file_info.path = '/any/modified/file'
+ output_proto.commit_message = 'Commit message'
+
+
+@faux.empty_error
+@faux.success(_GetUpdatedFilesResponse)
+@validate.require('uploaded_artifacts')
+@validate.validation_complete
+def GetUpdatedFiles(input_proto, output_proto, _config):
+ """Use uploaded artifacts to update some updates in a chromeos checkout.
+
+ The function will call toolchain_util.GetUpdatedFiles using the type of
+ uploaded artifacts to make some changes in a checkout, and return the list
+ of change files together with commit message.
+ updated_artifacts: A list of UpdatedArtifacts type which contains a tuple
+ of artifact info and profile info.
+ Note: the actual creation of the commit is done by CI, not here.
+
+ Args:
+ input_proto (GetUpdatedFilesRequest): The input proto
+ output_proto (GetUpdatedFilesResponse): The output proto
+ _config (api_config.ApiConfig): The API call config.
+ """
+ commit_message = ''
+ for artifact in input_proto.uploaded_artifacts:
+ artifact_type = artifact.artifact_info.artifact_type
+ if artifact_type not in _TOOLCHAIN_COMMIT_HANDLERS:
+ logging.error('%s not understood', artifact_type)
+ return controller.RETURN_CODE_UNRECOVERABLE
+ artifact_name = _TOOLCHAIN_COMMIT_HANDLERS[artifact_type]
+ if artifact_name:
+ assert len(artifact.artifact_info.artifacts) == 1, (
+ 'Only one file to update per each artifact')
+ updated_files, message = toolchain_util.GetUpdatedFiles(
+ artifact_name, artifact.artifact_info.artifacts[0].path,
+ _GetProfileInfoDict(artifact.profile_info))
+ for f in updated_files:
+ file_info = output_proto.updated_files.add()
+ file_info.path = f
+
+ commit_message += message + '\n'
+ output_proto.commit_message = commit_message
+ # No commit footer is added for now. Can add more here if needed
+
+
# TODO(crbug/1019868): Remove legacy code when cbuildbot builders are gone.
_NAMES_FOR_AFDO_ARTIFACTS = {
toolchain_pb2.ORDERFILE: 'orderfile',
diff --git a/api/controller/toolchain_unittest.py b/api/controller/toolchain_unittest.py
index 6f63a1b..b8d61ef 100644
--- a/api/controller/toolchain_unittest.py
+++ b/api/controller/toolchain_unittest.py
@@ -372,3 +372,60 @@
artifacts=[
artifacts_pb2.Artifact(path=self.bundle.return_value[0])
]))
+
+
+class GetUpdatedFilesTest(cros_test_lib.MockTempDirTestCase,
+ api_config.ApiConfigMixin):
+ """Unittests for GetUpdatedFiles."""
+
+ def setUp(self):
+ self.response = toolchain_pb2.GetUpdatedFilesResponse()
+ self.artifact_path = '/any/path/to/metadata'
+ self.profile_info = common_pb2.ArtifactProfileInfo(kernel_version='4.4')
+ self.update = self.PatchObject(
+ toolchain_util, 'GetUpdatedFiles', return_value=([], ''))
+
+ def _GetRequest(self, uploaded_artifacts):
+ uploaded = []
+ for artifact_type, artifact_path, profile_info in uploaded_artifacts:
+ uploaded.append(
+ toolchain_pb2.GetUpdatedFilesRequest.UploadedArtifacts(
+ artifact_info=toolchain_pb2.ArtifactInfo(
+ artifact_type=artifact_type,
+ artifacts=[artifacts_pb2.Artifact(path=artifact_path)]),
+ profile_info=profile_info))
+ return toolchain_pb2.GetUpdatedFilesRequest(uploaded_artifacts=uploaded)
+
+ def testRaisesForUnknown(self):
+ request = self._GetRequest([
+ (BuilderConfig.Artifacts.UNVERIFIED_KERNEL_CWP_AFDO_FILE,
+ self.artifact_path, self.profile_info)
+ ])
+ self.assertEqual(
+ controller.RETURN_CODE_UNRECOVERABLE,
+ toolchain.GetUpdatedFiles(request, self.response, self.api_config))
+
+ def testValidateOnly(self):
+ """Sanity check that a validate only call does not execute any logic."""
+ request = self._GetRequest([
+ (BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE,
+ self.artifact_path, self.profile_info)
+ ])
+ toolchain.GetUpdatedFiles(request, self.response, self.validate_only_config)
+
+ def testUpdateSuccess(self):
+ updated_file = '/path/to/updated_file'
+ self.update.return_value = ([updated_file], 'Commit Message')
+ request = self._GetRequest([
+ (BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE,
+ self.artifact_path, self.profile_info)
+ ])
+ toolchain.GetUpdatedFiles(request, self.response, self.api_config)
+ print(self.response.updated_files)
+ self.assertEqual(len(self.response.updated_files), 1)
+ self.assertEqual(
+ self.response.updated_files[0],
+ toolchain_pb2.GetUpdatedFilesResponse.UpdatedFile(path=updated_file),
+ )
+ self.assertIn('Commit Message', self.response.commit_message)
+ self.assertEqual(len(self.response.commit_footer), 0)
diff --git a/api/gen/chromite/api/toolchain_pb2.py b/api/gen/chromite/api/toolchain_pb2.py
index 75222a5..9fd86d7 100644
--- a/api/gen/chromite/api/toolchain_pb2.py
+++ b/api/gen/chromite/api/toolchain_pb2.py
@@ -25,7 +25,7 @@
package='chromite.api',
syntax='proto3',
serialized_options=_b('Z6go.chromium.org/chromiumos/infra/proto/go/chromite/api'),
- serialized_pb=_b('\n\x1c\x63hromite/api/toolchain.proto\x12\x0c\x63hromite.api\x1a\x1c\x63hromite/api/artifacts.proto\x1a\x1c\x63hromite/api/build_api.proto\x1a\x1a\x63hromite/api/sysroot.proto\x1a\x1f\x63hromiumos/builder_config.proto\x1a\x17\x63hromiumos/common.proto\"\x83\x01\n\x0c\x41rtifactInfo\x12H\n\rartifact_type\x18\x01 \x01(\x0e\x32\x31.chromiumos.BuilderConfig.Artifacts.ArtifactTypes\x12)\n\tartifacts\x18\x02 \x03(\x0b\x32\x16.chromite.api.Artifact\"\x83\x03\n\x1fPrepareForToolchainBuildRequest\x12I\n\x0e\x61rtifact_types\x18\x01 \x03(\x0e\x32\x31.chromiumos.BuilderConfig.Artifacts.ArtifactTypes\x12\"\n\x06\x63hroot\x18\x02 \x01(\x0b\x32\x12.chromiumos.Chroot\x12&\n\x07sysroot\x18\x03 \x01(\x0b\x32\x15.chromite.api.Sysroot\x12N\n\x0finput_artifacts\x18\x04 \x03(\x0b\x32\x35.chromiumos.BuilderConfig.Artifacts.InputArtifactInfo\x12\x42\n\x0f\x61\x64\x64itional_args\x18\x05 \x01(\x0b\x32).chromiumos.PrepareForBuildAdditionalArgs\x12\x35\n\x0cprofile_info\x18\x06 \x01(\x0b\x32\x1f.chromiumos.ArtifactProfileInfo\"q\n PrepareForToolchainBuildResponse\x12M\n\x0f\x62uild_relevance\x18\x01 \x01(\x0e\x32\x34.chromite.api.PrepareForBuildResponse.BuildRelevance\"\xbe\x02\n\x16\x42undleToolchainRequest\x12\"\n\x06\x63hroot\x18\x01 \x01(\x0b\x32\x12.chromiumos.Chroot\x12&\n\x07sysroot\x18\x02 \x01(\x0b\x32\x15.chromite.api.Sysroot\x12\x12\n\noutput_dir\x18\x03 \x01(\t\x12I\n\x0e\x61rtifact_types\x18\x04 \x03(\x0e\x32\x31.chromiumos.BuilderConfig.Artifacts.ArtifactTypes\x12\x42\n\x0f\x61\x64\x64itional_args\x18\x05 \x01(\x0b\x32).chromiumos.PrepareForBuildAdditionalArgs\x12\x35\n\x0cprofile_info\x18\x06 \x01(\x0b\x32\x1f.chromiumos.ArtifactProfileInfo\"S\n\x17\x42undleToolchainResponse\x12\x32\n\x0e\x61rtifacts_info\x18\x02 \x03(\x0b\x32\x1a.chromite.api.ArtifactInfoJ\x04\x08\x01\x10\x02\"\x80\x01\n\x1aVerifyAFDOArtifactsRequest\x12-\n\x0c\x62uild_target\x18\x01 \x01(\x0b\x32\x17.chromiumos.BuildTarget\x12\x33\n\rartifact_type\x18\x02 \x01(\x0e\x32\x1c.chromiumos.AFDOArtifactType\"-\n\x1bVerifyAFDOArtifactsResponse\x12\x0e\n\x06status\x18\x01 \x01(\x08*f\n\x10\x41\x46\x44OArtifactType\x12\r\n\tNONE_TYPE\x10\x00\x12\r\n\tORDERFILE\x10\x01\x12\x12\n\x0e\x42\x45NCHMARK_AFDO\x10\x02\x12\x0f\n\x0bKERNEL_AFDO\x10\x03\x12\x0f\n\x0b\x43HROME_AFDO\x10\x04\x32\xef\x03\n\x10ToolchainService\x12|\n\x1dUpdateEbuildWithAFDOArtifacts\x12(.chromite.api.VerifyAFDOArtifactsRequest\x1a).chromite.api.VerifyAFDOArtifactsResponse\"\x06\xc2\xed\x1a\x02\x10\x01\x12x\n\x19UploadVettedAFDOArtifacts\x12(.chromite.api.VerifyAFDOArtifactsRequest\x1a).chromite.api.VerifyAFDOArtifactsResponse\"\x06\xc2\xed\x1a\x02\x10\x01\x12p\n\x0fPrepareForBuild\x12-.chromite.api.PrepareForToolchainBuildRequest\x1a..chromite.api.PrepareForToolchainBuildResponse\x12^\n\x0f\x42undleArtifacts\x12$.chromite.api.BundleToolchainRequest\x1a%.chromite.api.BundleToolchainResponse\x1a\x11\xc2\xed\x1a\r\n\ttoolchain\x10\x02\x42\x38Z6go.chromium.org/chromiumos/infra/proto/go/chromite/apib\x06proto3')
+ serialized_pb=_b('\n\x1c\x63hromite/api/toolchain.proto\x12\x0c\x63hromite.api\x1a\x1c\x63hromite/api/artifacts.proto\x1a\x1c\x63hromite/api/build_api.proto\x1a\x1a\x63hromite/api/sysroot.proto\x1a\x1f\x63hromiumos/builder_config.proto\x1a\x17\x63hromiumos/common.proto\"\x83\x01\n\x0c\x41rtifactInfo\x12H\n\rartifact_type\x18\x01 \x01(\x0e\x32\x31.chromiumos.BuilderConfig.Artifacts.ArtifactTypes\x12)\n\tartifacts\x18\x02 \x03(\x0b\x32\x16.chromite.api.Artifact\"\x83\x03\n\x1fPrepareForToolchainBuildRequest\x12I\n\x0e\x61rtifact_types\x18\x01 \x03(\x0e\x32\x31.chromiumos.BuilderConfig.Artifacts.ArtifactTypes\x12\"\n\x06\x63hroot\x18\x02 \x01(\x0b\x32\x12.chromiumos.Chroot\x12&\n\x07sysroot\x18\x03 \x01(\x0b\x32\x15.chromite.api.Sysroot\x12N\n\x0finput_artifacts\x18\x04 \x03(\x0b\x32\x35.chromiumos.BuilderConfig.Artifacts.InputArtifactInfo\x12\x42\n\x0f\x61\x64\x64itional_args\x18\x05 \x01(\x0b\x32).chromiumos.PrepareForBuildAdditionalArgs\x12\x35\n\x0cprofile_info\x18\x06 \x01(\x0b\x32\x1f.chromiumos.ArtifactProfileInfo\"q\n PrepareForToolchainBuildResponse\x12M\n\x0f\x62uild_relevance\x18\x01 \x01(\x0e\x32\x34.chromite.api.PrepareForBuildResponse.BuildRelevance\"\xbe\x02\n\x16\x42undleToolchainRequest\x12\"\n\x06\x63hroot\x18\x01 \x01(\x0b\x32\x12.chromiumos.Chroot\x12&\n\x07sysroot\x18\x02 \x01(\x0b\x32\x15.chromite.api.Sysroot\x12\x12\n\noutput_dir\x18\x03 \x01(\t\x12I\n\x0e\x61rtifact_types\x18\x04 \x03(\x0e\x32\x31.chromiumos.BuilderConfig.Artifacts.ArtifactTypes\x12\x42\n\x0f\x61\x64\x64itional_args\x18\x05 \x01(\x0b\x32).chromiumos.PrepareForBuildAdditionalArgs\x12\x35\n\x0cprofile_info\x18\x06 \x01(\x0b\x32\x1f.chromiumos.ArtifactProfileInfo\"S\n\x17\x42undleToolchainResponse\x12\x32\n\x0e\x61rtifacts_info\x18\x02 \x03(\x0b\x32\x1a.chromite.api.ArtifactInfoJ\x04\x08\x01\x10\x02\"\xeb\x01\n\x16GetUpdatedFilesRequest\x12R\n\x12uploaded_artifacts\x18\x01 \x03(\x0b\x32\x36.chromite.api.GetUpdatedFilesRequest.UploadedArtifacts\x1a}\n\x11UploadedArtifacts\x12\x31\n\rartifact_info\x18\x01 \x01(\x0b\x32\x1a.chromite.api.ArtifactInfo\x12\x35\n\x0cprofile_info\x18\x02 \x01(\x0b\x32\x1f.chromiumos.ArtifactProfileInfo\"\xf4\x03\n\x17GetUpdatedFilesResponse\x12H\n\rupdated_files\x18\x01 \x03(\x0b\x32\x31.chromite.api.GetUpdatedFilesResponse.UpdatedFile\x12\x16\n\x0e\x63ommit_message\x18\x02 \x01(\t\x12I\n\rcommit_footer\x18\x03 \x03(\x0b\x32\x32.chromite.api.GetUpdatedFilesResponse.CommitFooter\x1a\x1b\n\x0bUpdatedFile\x12\x0c\n\x04path\x18\x01 \x01(\t\x1a\x41\n\x0e\x43qDependFooter\x12/\n\rgerrit_change\x18\x01 \x03(\x0b\x32\x18.chromiumos.GerritChange\x1a\x1c\n\rCqClTagFooter\x12\x0b\n\x03tag\x18\x01 \x01(\t\x1a\xad\x01\n\x0c\x43ommitFooter\x12I\n\tcq_depend\x18\x01 \x01(\x0b\x32\x34.chromite.api.GetUpdatedFilesResponse.CqDependFooterH\x00\x12H\n\tcq_cl_tag\x18\x02 \x01(\x0b\x32\x33.chromite.api.GetUpdatedFilesResponse.CqClTagFooterH\x00\x42\x08\n\x06\x66ooter\"\x80\x01\n\x1aVerifyAFDOArtifactsRequest\x12-\n\x0c\x62uild_target\x18\x01 \x01(\x0b\x32\x17.chromiumos.BuildTarget\x12\x33\n\rartifact_type\x18\x02 \x01(\x0e\x32\x1c.chromiumos.AFDOArtifactType\"-\n\x1bVerifyAFDOArtifactsResponse\x12\x0e\n\x06status\x18\x01 \x01(\x08*f\n\x10\x41\x46\x44OArtifactType\x12\r\n\tNONE_TYPE\x10\x00\x12\r\n\tORDERFILE\x10\x01\x12\x12\n\x0e\x42\x45NCHMARK_AFDO\x10\x02\x12\x0f\n\x0bKERNEL_AFDO\x10\x03\x12\x0f\n\x0b\x43HROME_AFDO\x10\x04\x32\xcf\x04\n\x10ToolchainService\x12|\n\x1dUpdateEbuildWithAFDOArtifacts\x12(.chromite.api.VerifyAFDOArtifactsRequest\x1a).chromite.api.VerifyAFDOArtifactsResponse\"\x06\xc2\xed\x1a\x02\x10\x01\x12x\n\x19UploadVettedAFDOArtifacts\x12(.chromite.api.VerifyAFDOArtifactsRequest\x1a).chromite.api.VerifyAFDOArtifactsResponse\"\x06\xc2\xed\x1a\x02\x10\x01\x12p\n\x0fPrepareForBuild\x12-.chromite.api.PrepareForToolchainBuildRequest\x1a..chromite.api.PrepareForToolchainBuildResponse\x12^\n\x0f\x42undleArtifacts\x12$.chromite.api.BundleToolchainRequest\x1a%.chromite.api.BundleToolchainResponse\x12^\n\x0fGetUpdatedFiles\x12$.chromite.api.GetUpdatedFilesRequest\x1a%.chromite.api.GetUpdatedFilesResponse\x1a\x11\xc2\xed\x1a\r\n\ttoolchain\x10\x02\x42\x38Z6go.chromium.org/chromiumos/infra/proto/go/chromite/apib\x06proto3')
,
dependencies=[chromite_dot_api_dot_artifacts__pb2.DESCRIPTOR,chromite_dot_api_dot_build__api__pb2.DESCRIPTOR,chromite_dot_api_dot_sysroot__pb2.DESCRIPTOR,chromiumos_dot_builder__config__pb2.DESCRIPTOR,chromiumos_dot_common__pb2.DESCRIPTOR,])
@@ -58,8 +58,8 @@
],
containing_type=None,
serialized_options=None,
- serialized_start=1415,
- serialized_end=1517,
+ serialized_start=2156,
+ serialized_end=2258,
)
_sym_db.RegisterEnumDescriptor(_AFDOARTIFACTTYPE)
@@ -304,6 +304,249 @@
)
+_GETUPDATEDFILESREQUEST_UPLOADEDARTIFACTS = _descriptor.Descriptor(
+ name='UploadedArtifacts',
+ full_name='chromite.api.GetUpdatedFilesRequest.UploadedArtifacts',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='artifact_info', full_name='chromite.api.GetUpdatedFilesRequest.UploadedArtifacts.artifact_info', 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='profile_info', full_name='chromite.api.GetUpdatedFilesRequest.UploadedArtifacts.profile_info', 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),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ serialized_options=None,
+ is_extendable=False,
+ syntax='proto3',
+ extension_ranges=[],
+ oneofs=[
+ ],
+ serialized_start=1348,
+ serialized_end=1473,
+)
+
+_GETUPDATEDFILESREQUEST = _descriptor.Descriptor(
+ name='GetUpdatedFilesRequest',
+ full_name='chromite.api.GetUpdatedFilesRequest',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='uploaded_artifacts', full_name='chromite.api.GetUpdatedFilesRequest.uploaded_artifacts', 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=[_GETUPDATEDFILESREQUEST_UPLOADEDARTIFACTS, ],
+ enum_types=[
+ ],
+ serialized_options=None,
+ is_extendable=False,
+ syntax='proto3',
+ extension_ranges=[],
+ oneofs=[
+ ],
+ serialized_start=1238,
+ serialized_end=1473,
+)
+
+
+_GETUPDATEDFILESRESPONSE_UPDATEDFILE = _descriptor.Descriptor(
+ name='UpdatedFile',
+ full_name='chromite.api.GetUpdatedFilesResponse.UpdatedFile',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='path', full_name='chromite.api.GetUpdatedFilesResponse.UpdatedFile.path', 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=1676,
+ serialized_end=1703,
+)
+
+_GETUPDATEDFILESRESPONSE_CQDEPENDFOOTER = _descriptor.Descriptor(
+ name='CqDependFooter',
+ full_name='chromite.api.GetUpdatedFilesResponse.CqDependFooter',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='gerrit_change', full_name='chromite.api.GetUpdatedFilesResponse.CqDependFooter.gerrit_change', 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=1705,
+ serialized_end=1770,
+)
+
+_GETUPDATEDFILESRESPONSE_CQCLTAGFOOTER = _descriptor.Descriptor(
+ name='CqClTagFooter',
+ full_name='chromite.api.GetUpdatedFilesResponse.CqClTagFooter',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='tag', full_name='chromite.api.GetUpdatedFilesResponse.CqClTagFooter.tag', 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=1772,
+ serialized_end=1800,
+)
+
+_GETUPDATEDFILESRESPONSE_COMMITFOOTER = _descriptor.Descriptor(
+ name='CommitFooter',
+ full_name='chromite.api.GetUpdatedFilesResponse.CommitFooter',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='cq_depend', full_name='chromite.api.GetUpdatedFilesResponse.CommitFooter.cq_depend', 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='cq_cl_tag', full_name='chromite.api.GetUpdatedFilesResponse.CommitFooter.cq_cl_tag', 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),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ serialized_options=None,
+ is_extendable=False,
+ syntax='proto3',
+ extension_ranges=[],
+ oneofs=[
+ _descriptor.OneofDescriptor(
+ name='footer', full_name='chromite.api.GetUpdatedFilesResponse.CommitFooter.footer',
+ index=0, containing_type=None, fields=[]),
+ ],
+ serialized_start=1803,
+ serialized_end=1976,
+)
+
+_GETUPDATEDFILESRESPONSE = _descriptor.Descriptor(
+ name='GetUpdatedFilesResponse',
+ full_name='chromite.api.GetUpdatedFilesResponse',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='updated_files', full_name='chromite.api.GetUpdatedFilesResponse.updated_files', 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),
+ _descriptor.FieldDescriptor(
+ name='commit_message', full_name='chromite.api.GetUpdatedFilesResponse.commit_message', 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='commit_footer', full_name='chromite.api.GetUpdatedFilesResponse.commit_footer', index=2,
+ number=3, 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=[_GETUPDATEDFILESRESPONSE_UPDATEDFILE, _GETUPDATEDFILESRESPONSE_CQDEPENDFOOTER, _GETUPDATEDFILESRESPONSE_CQCLTAGFOOTER, _GETUPDATEDFILESRESPONSE_COMMITFOOTER, ],
+ enum_types=[
+ ],
+ serialized_options=None,
+ is_extendable=False,
+ syntax='proto3',
+ extension_ranges=[],
+ oneofs=[
+ ],
+ serialized_start=1476,
+ serialized_end=1976,
+)
+
+
_VERIFYAFDOARTIFACTSREQUEST = _descriptor.Descriptor(
name='VerifyAFDOArtifactsRequest',
full_name='chromite.api.VerifyAFDOArtifactsRequest',
@@ -337,8 +580,8 @@
extension_ranges=[],
oneofs=[
],
- serialized_start=1238,
- serialized_end=1366,
+ serialized_start=1979,
+ serialized_end=2107,
)
@@ -368,8 +611,8 @@
extension_ranges=[],
oneofs=[
],
- serialized_start=1368,
- serialized_end=1413,
+ serialized_start=2109,
+ serialized_end=2154,
)
_ARTIFACTINFO.fields_by_name['artifact_type'].enum_type = chromiumos_dot_builder__config__pb2._BUILDERCONFIG_ARTIFACTS_ARTIFACTTYPES
@@ -387,6 +630,25 @@
_BUNDLETOOLCHAINREQUEST.fields_by_name['additional_args'].message_type = chromiumos_dot_common__pb2._PREPAREFORBUILDADDITIONALARGS
_BUNDLETOOLCHAINREQUEST.fields_by_name['profile_info'].message_type = chromiumos_dot_common__pb2._ARTIFACTPROFILEINFO
_BUNDLETOOLCHAINRESPONSE.fields_by_name['artifacts_info'].message_type = _ARTIFACTINFO
+_GETUPDATEDFILESREQUEST_UPLOADEDARTIFACTS.fields_by_name['artifact_info'].message_type = _ARTIFACTINFO
+_GETUPDATEDFILESREQUEST_UPLOADEDARTIFACTS.fields_by_name['profile_info'].message_type = chromiumos_dot_common__pb2._ARTIFACTPROFILEINFO
+_GETUPDATEDFILESREQUEST_UPLOADEDARTIFACTS.containing_type = _GETUPDATEDFILESREQUEST
+_GETUPDATEDFILESREQUEST.fields_by_name['uploaded_artifacts'].message_type = _GETUPDATEDFILESREQUEST_UPLOADEDARTIFACTS
+_GETUPDATEDFILESRESPONSE_UPDATEDFILE.containing_type = _GETUPDATEDFILESRESPONSE
+_GETUPDATEDFILESRESPONSE_CQDEPENDFOOTER.fields_by_name['gerrit_change'].message_type = chromiumos_dot_common__pb2._GERRITCHANGE
+_GETUPDATEDFILESRESPONSE_CQDEPENDFOOTER.containing_type = _GETUPDATEDFILESRESPONSE
+_GETUPDATEDFILESRESPONSE_CQCLTAGFOOTER.containing_type = _GETUPDATEDFILESRESPONSE
+_GETUPDATEDFILESRESPONSE_COMMITFOOTER.fields_by_name['cq_depend'].message_type = _GETUPDATEDFILESRESPONSE_CQDEPENDFOOTER
+_GETUPDATEDFILESRESPONSE_COMMITFOOTER.fields_by_name['cq_cl_tag'].message_type = _GETUPDATEDFILESRESPONSE_CQCLTAGFOOTER
+_GETUPDATEDFILESRESPONSE_COMMITFOOTER.containing_type = _GETUPDATEDFILESRESPONSE
+_GETUPDATEDFILESRESPONSE_COMMITFOOTER.oneofs_by_name['footer'].fields.append(
+ _GETUPDATEDFILESRESPONSE_COMMITFOOTER.fields_by_name['cq_depend'])
+_GETUPDATEDFILESRESPONSE_COMMITFOOTER.fields_by_name['cq_depend'].containing_oneof = _GETUPDATEDFILESRESPONSE_COMMITFOOTER.oneofs_by_name['footer']
+_GETUPDATEDFILESRESPONSE_COMMITFOOTER.oneofs_by_name['footer'].fields.append(
+ _GETUPDATEDFILESRESPONSE_COMMITFOOTER.fields_by_name['cq_cl_tag'])
+_GETUPDATEDFILESRESPONSE_COMMITFOOTER.fields_by_name['cq_cl_tag'].containing_oneof = _GETUPDATEDFILESRESPONSE_COMMITFOOTER.oneofs_by_name['footer']
+_GETUPDATEDFILESRESPONSE.fields_by_name['updated_files'].message_type = _GETUPDATEDFILESRESPONSE_UPDATEDFILE
+_GETUPDATEDFILESRESPONSE.fields_by_name['commit_footer'].message_type = _GETUPDATEDFILESRESPONSE_COMMITFOOTER
_VERIFYAFDOARTIFACTSREQUEST.fields_by_name['build_target'].message_type = chromiumos_dot_common__pb2._BUILDTARGET
_VERIFYAFDOARTIFACTSREQUEST.fields_by_name['artifact_type'].enum_type = chromiumos_dot_common__pb2._AFDOARTIFACTTYPE
DESCRIPTOR.message_types_by_name['ArtifactInfo'] = _ARTIFACTINFO
@@ -394,6 +656,8 @@
DESCRIPTOR.message_types_by_name['PrepareForToolchainBuildResponse'] = _PREPAREFORTOOLCHAINBUILDRESPONSE
DESCRIPTOR.message_types_by_name['BundleToolchainRequest'] = _BUNDLETOOLCHAINREQUEST
DESCRIPTOR.message_types_by_name['BundleToolchainResponse'] = _BUNDLETOOLCHAINRESPONSE
+DESCRIPTOR.message_types_by_name['GetUpdatedFilesRequest'] = _GETUPDATEDFILESREQUEST
+DESCRIPTOR.message_types_by_name['GetUpdatedFilesResponse'] = _GETUPDATEDFILESRESPONSE
DESCRIPTOR.message_types_by_name['VerifyAFDOArtifactsRequest'] = _VERIFYAFDOARTIFACTSREQUEST
DESCRIPTOR.message_types_by_name['VerifyAFDOArtifactsResponse'] = _VERIFYAFDOARTIFACTSRESPONSE
DESCRIPTOR.enum_types_by_name['AFDOArtifactType'] = _AFDOARTIFACTTYPE
@@ -434,6 +698,60 @@
))
_sym_db.RegisterMessage(BundleToolchainResponse)
+GetUpdatedFilesRequest = _reflection.GeneratedProtocolMessageType('GetUpdatedFilesRequest', (_message.Message,), dict(
+
+ UploadedArtifacts = _reflection.GeneratedProtocolMessageType('UploadedArtifacts', (_message.Message,), dict(
+ DESCRIPTOR = _GETUPDATEDFILESREQUEST_UPLOADEDARTIFACTS,
+ __module__ = 'chromite.api.toolchain_pb2'
+ # @@protoc_insertion_point(class_scope:chromite.api.GetUpdatedFilesRequest.UploadedArtifacts)
+ ))
+ ,
+ DESCRIPTOR = _GETUPDATEDFILESREQUEST,
+ __module__ = 'chromite.api.toolchain_pb2'
+ # @@protoc_insertion_point(class_scope:chromite.api.GetUpdatedFilesRequest)
+ ))
+_sym_db.RegisterMessage(GetUpdatedFilesRequest)
+_sym_db.RegisterMessage(GetUpdatedFilesRequest.UploadedArtifacts)
+
+GetUpdatedFilesResponse = _reflection.GeneratedProtocolMessageType('GetUpdatedFilesResponse', (_message.Message,), dict(
+
+ UpdatedFile = _reflection.GeneratedProtocolMessageType('UpdatedFile', (_message.Message,), dict(
+ DESCRIPTOR = _GETUPDATEDFILESRESPONSE_UPDATEDFILE,
+ __module__ = 'chromite.api.toolchain_pb2'
+ # @@protoc_insertion_point(class_scope:chromite.api.GetUpdatedFilesResponse.UpdatedFile)
+ ))
+ ,
+
+ CqDependFooter = _reflection.GeneratedProtocolMessageType('CqDependFooter', (_message.Message,), dict(
+ DESCRIPTOR = _GETUPDATEDFILESRESPONSE_CQDEPENDFOOTER,
+ __module__ = 'chromite.api.toolchain_pb2'
+ # @@protoc_insertion_point(class_scope:chromite.api.GetUpdatedFilesResponse.CqDependFooter)
+ ))
+ ,
+
+ CqClTagFooter = _reflection.GeneratedProtocolMessageType('CqClTagFooter', (_message.Message,), dict(
+ DESCRIPTOR = _GETUPDATEDFILESRESPONSE_CQCLTAGFOOTER,
+ __module__ = 'chromite.api.toolchain_pb2'
+ # @@protoc_insertion_point(class_scope:chromite.api.GetUpdatedFilesResponse.CqClTagFooter)
+ ))
+ ,
+
+ CommitFooter = _reflection.GeneratedProtocolMessageType('CommitFooter', (_message.Message,), dict(
+ DESCRIPTOR = _GETUPDATEDFILESRESPONSE_COMMITFOOTER,
+ __module__ = 'chromite.api.toolchain_pb2'
+ # @@protoc_insertion_point(class_scope:chromite.api.GetUpdatedFilesResponse.CommitFooter)
+ ))
+ ,
+ DESCRIPTOR = _GETUPDATEDFILESRESPONSE,
+ __module__ = 'chromite.api.toolchain_pb2'
+ # @@protoc_insertion_point(class_scope:chromite.api.GetUpdatedFilesResponse)
+ ))
+_sym_db.RegisterMessage(GetUpdatedFilesResponse)
+_sym_db.RegisterMessage(GetUpdatedFilesResponse.UpdatedFile)
+_sym_db.RegisterMessage(GetUpdatedFilesResponse.CqDependFooter)
+_sym_db.RegisterMessage(GetUpdatedFilesResponse.CqClTagFooter)
+_sym_db.RegisterMessage(GetUpdatedFilesResponse.CommitFooter)
+
VerifyAFDOArtifactsRequest = _reflection.GeneratedProtocolMessageType('VerifyAFDOArtifactsRequest', (_message.Message,), dict(
DESCRIPTOR = _VERIFYAFDOARTIFACTSREQUEST,
__module__ = 'chromite.api.toolchain_pb2'
@@ -457,8 +775,8 @@
file=DESCRIPTOR,
index=0,
serialized_options=_b('\302\355\032\r\n\ttoolchain\020\002'),
- serialized_start=1520,
- serialized_end=2015,
+ serialized_start=2261,
+ serialized_end=2852,
methods=[
_descriptor.MethodDescriptor(
name='UpdateEbuildWithAFDOArtifacts',
@@ -496,6 +814,15 @@
output_type=_BUNDLETOOLCHAINRESPONSE,
serialized_options=None,
),
+ _descriptor.MethodDescriptor(
+ name='GetUpdatedFiles',
+ full_name='chromite.api.ToolchainService.GetUpdatedFiles',
+ index=4,
+ containing_service=None,
+ input_type=_GETUPDATEDFILESREQUEST,
+ output_type=_GETUPDATEDFILESRESPONSE,
+ serialized_options=None,
+ ),
])
_sym_db.RegisterServiceDescriptor(_TOOLCHAINSERVICE)
diff --git a/lib/toolchain_util.py b/lib/toolchain_util.py
index 6fd468b..ff69157 100644
--- a/lib/toolchain_util.py
+++ b/lib/toolchain_util.py
@@ -207,6 +207,10 @@
"""Error for BundleArtifactsHandler class."""
+class GetUpdatedFilesForCommitError(Error):
+ """Error for GetUpdatedFilesForCommit class."""
+
+
class NoArtifactsToBundleError(Error):
"""Error for bundling empty collection of artifacts."""
@@ -2577,6 +2581,71 @@
profile_info=profile_info).Bundle()
+class GetUpdatedFilesHandler(object):
+ """Find all changed files in the checkout and create a commit message."""
+
+ @staticmethod
+ def _UpdateKernelMetadata(kernel_version: str, profile_version: str):
+ """Update afdo_metadata json file"""
+ kernel_version = kernel_version.replace('.', '_')
+ json_file = os.path.join(TOOLCHAIN_UTILS_PATH, 'afdo_metadata',
+ f'kernel_afdo_{kernel_version}.json')
+ assert os.path.exists(json_file), \
+ f'Metadata for {kernel_version} does not exist'
+ afdo_versions = json.loads(osutils.ReadFile(json_file))
+ kernel_name = f'chromeos-kernel-{kernel_version}'
+ assert kernel_name in afdo_versions, \
+ f'To update {kernel_name}, the entry should be in kernel_afdo.json'
+ old_value = afdo_versions[kernel_name]['name']
+ update_to_newer_profile = _RankValidCWPProfiles(
+ old_value) < _RankValidCWPProfiles(profile_version)
+ # This function is called after Bundle, so normally the profile is newer
+ # is guaranteed because Bundle function only runs when a new profile is
+ # needed to verify at the beginning of the builder. This check is to
+ # make sure there's no other updates happen between the start of the
+ # builder and the time of this function call.
+ assert update_to_newer_profile, (
+ f'Failed to update JSON file because {profile_version} is not '
+ f'newer than {old_value}')
+ afdo_versions[kernel_name]['name'] = profile_version
+ pformat.json(afdo_versions, fp=json_file)
+ return [json_file]
+
+ def __init__(self, artifact_type, artifact_path, profile_info):
+ self.artifact_path = artifact_path
+ self.profile_info = profile_info
+ if artifact_type == 'VerifiedKernelCwpAfdoFile':
+ self._update_func = self.UpdateKernelProfileMetadata
+ else:
+ raise GetUpdatedFilesForCommitError(
+ f'{artifact_type} has no handler in GetUpdatedFiles')
+
+ def UpdateKernelProfileMetadata(self):
+ kernel_version = self.profile_info.get('kernel_version')
+ if not kernel_version:
+ raise GetUpdatedFilesForCommitError('kernel_version not provided')
+ # The path obtained from artifact_path is the full path, containing
+ # extension, so we need to remove it here.
+ profile_version = os.path.basename(self.artifact_path).replace(
+ KERNEL_AFDO_COMPRESSION_SUFFIX, '')
+ files = self._UpdateKernelMetadata(kernel_version, profile_version)
+ commit_message = (
+ f'afdo_metadata: Publish new kernel profiles for {kernel_version}\n\n'
+ f'Update {kernel_version} to {profile_version}\n\n'
+ 'Automatically generated in kernel verifier.\n\n'
+ 'BUG=None\n'
+ 'TEST=Verified in kernel-release-afdo-verify-orchestrator\n')
+ return files, commit_message
+
+ def Update(self):
+ return self._update_func()
+
+
+def GetUpdatedFiles(artifact_type, artifact_path, profile_info):
+ return GetUpdatedFilesHandler(artifact_type, artifact_path,
+ profile_info).Update()
+
+
# ###########################################################################
#
# TODO(crbug/1019868): delete once cbuildbot is gone.
diff --git a/lib/toolchain_util_unittest.py b/lib/toolchain_util_unittest.py
index afdcc91..c01b64b 100644
--- a/lib/toolchain_util_unittest.py
+++ b/lib/toolchain_util_unittest.py
@@ -528,7 +528,10 @@
self.artifact_type = 'Unspecified'
self.outdir = None
self.afdo_tmp_path = None
- self.profile_info = {}
+ self.kernel_version = '4_4'
+ self.profile_info = {
+ 'kernel_version': self.kernel_version.replace('_', '.'),
+ }
self.orderfile_name = (
'chromeos-chrome-orderfile-field-78-3877.0-1567418235-'
'benchmark-78.0.3893.0-r1.orderfile')
@@ -537,6 +540,7 @@
self.debug_binary_name = 'chromeos-chrome-amd64-78.0.3893.0_rc-r1.debug'
self.merged_afdo_name = (
'chromeos-chrome-amd64-78.0.3893.0_rc-r1-merged.afdo')
+ self.kernel_name = 'R89-13638.0-1607337135'
self.gen_order = self.PatchObject(
toolchain_util.GenerateChromeOrderfile, 'Bundle', new=_Bundle)
@@ -725,6 +729,22 @@
print_cmd=True,
)
+ def testBundleVerifiedKernelCwpAfdoFile(self):
+ self.SetUpBundle('VerifiedKernelCwpAfdoFile')
+ mock_ebuild = self.PatchObject(
+ self.obj, '_GetArtifactVersionInEbuild', return_value=self.kernel_name)
+ ret = self.obj.Bundle()
+ profile_name = self.kernel_name + \
+ toolchain_util.KERNEL_AFDO_COMPRESSION_SUFFIX
+ verified_profile = os.path.join(self.outdir, profile_name)
+ self.assertEqual([verified_profile], ret)
+ mock_ebuild.assert_called_once_with(
+ f'chromeos-kernel-{self.kernel_version}', 'AFDO_PROFILE_VERSION')
+ profile_path = os.path.join(
+ self.chroot.path, self.sysroot[1:], 'usr', 'lib', 'debug', 'boot',
+ f'chromeos-kernel-{self.kernel_version}-{profile_name}')
+ self.copy2.assert_called_once_with(profile_path, verified_profile)
+
def runToolchainBundleTest(self, artifact_path, tarball_name, input_files,
expected_output_files):
"""Asserts that the given artifact_path is tarred up properly.
@@ -1421,6 +1441,78 @@
mocks.compress_file.assert_not_called()
+class GetUpdatedFilesTest(cros_test_lib.MockTempDirTestCase):
+ """Test functions in class GetUpdatedFilesForCommit."""
+
+ def setUp(self):
+ # Prepare a JSON file containing metadata
+ toolchain_util.TOOLCHAIN_UTILS_PATH = self.tempdir
+ osutils.SafeMakedirs(os.path.join(self.tempdir, 'afdo_metadata'))
+ self.json_file = os.path.join(self.tempdir,
+ 'afdo_metadata/kernel_afdo_4_14.json')
+ self.kernel = '4.14'
+ self.kernel_name = self.kernel.replace('.', '_')
+ self.kernel_key_name = f'chromeos-kernel-{self.kernel_name}'
+ self.afdo_sorted_by_freshness = [
+ 'R78-3865.0-1560000000.afdo', 'R78-3869.38-1562580965.afdo',
+ 'R78-3866.0-1570000000.afdo'
+ ]
+ self.afdo_versions = {
+ self.kernel_key_name: {
+ 'name': self.afdo_sorted_by_freshness[1],
+ },
+ }
+
+ with open(self.json_file, 'w') as f:
+ json.dump(self.afdo_versions, f)
+ self.artifact_path = os.path.join(
+ '/any/path/to/',
+ self.afdo_sorted_by_freshness[2] + \
+ toolchain_util.KERNEL_AFDO_COMPRESSION_SUFFIX
+ )
+ self.profile_info = {'kernel_version': self.kernel}
+
+ def testUpdateKernelMetadataFailureWithInvalidKernel(self):
+ with self.assertRaises(AssertionError) as context:
+ toolchain_util.GetUpdatedFilesHandler._UpdateKernelMetadata('3.8', None)
+ self.assertIn('does not exist', str(context.exception))
+
+ def testUpdateKernelMetadataFailureWithOlderProfile(self):
+ with self.assertRaises(AssertionError) as context:
+ toolchain_util.GetUpdatedFilesHandler._UpdateKernelMetadata(
+ self.kernel, self.afdo_sorted_by_freshness[0])
+ self.assertIn('is not newer than', str(context.exception))
+
+ def testUpdateKernelMetadataPass(self):
+ toolchain_util.GetUpdatedFilesHandler._UpdateKernelMetadata(
+ self.kernel, self.afdo_sorted_by_freshness[2])
+ # Check changes in JSON file
+ new_afdo_versions = json.loads(osutils.ReadFile(self.json_file))
+ self.assertEqual(len(self.afdo_versions), len(new_afdo_versions))
+ self.assertEqual(new_afdo_versions[self.kernel_key_name]['name'],
+ self.afdo_sorted_by_freshness[2])
+ for k in self.afdo_versions:
+ # Make sure other fields are not changed
+ if k != self.kernel_key_name:
+ self.assertEqual(self.afdo_versions[k], new_afdo_versions[k])
+
+ def testUpdateKernelProfileMetadata(self):
+ ret_files, ret_commit = toolchain_util.GetUpdatedFiles(
+ 'VerifiedKernelCwpAfdoFile', self.artifact_path, self.profile_info)
+ file_to_update = os.path.join(self.tempdir, 'afdo_metadata',
+ f'kernel_afdo_{self.kernel_name}.json')
+ self.assertEqual(ret_files, [file_to_update])
+ self.assertIn('Publish new kernel profiles', ret_commit)
+ self.assertIn(f'Update 4.14 to {self.afdo_sorted_by_freshness[2]}',
+ ret_commit)
+
+ def testUpdateFailWithOtherTypes(self):
+ with self.assertRaises(
+ toolchain_util.GetUpdatedFilesForCommitError) as context:
+ toolchain_util.GetUpdatedFiles('OtherType', '', '')
+ self.assertIn('has no handler in GetUpdatedFiles', str(context.exception))
+
+
class FindEbuildPathTest(cros_test_lib.MockTempDirTestCase):
"""Test top-level function _FindEbuildPath()."""