def test_replicate_private_config_multiple_build_configs(self): """An error is thrown if there is more than one build config.""" replication_config = ReplicationConfig(file_replication_rules=[ FileReplicationRule(source_path=self.private_config_path, destination_path=self.public_config_path, file_type=FILE_TYPE_JSON, replication_type=REPLICATION_TYPE_FILTER, destination_fields=FieldMask(paths=['a'])), FileReplicationRule(source_path=self.private_config_path, destination_path=self.public_config_path, file_type=FILE_TYPE_JSON, replication_type=REPLICATION_TYPE_FILTER, destination_fields=FieldMask(paths=['a'])) ]) osutils.WriteFile(self.replication_config_path, json_format.MessageToJson(replication_config)) refs = [ GitRef(path='/chromeos/overlays/overlay-coral-private', ref='master', revision='123') ] with self.assertRaisesRegex( ValueError, 'Expected at most one build_config.json destination path.'): packages.replicate_private_config(_build_targets=None, refs=refs, chroot=Chroot())
def testReplicateInvalidRules(self): """Tests invalid FileReplicationRules cause errors.""" with self.assertRaisesRegex( ValueError, 'Rule for JSON source a.json must use REPLICATION_TYPE_FILTER' ): replication_lib.Replicate( ReplicationConfig(file_replication_rules=[ FileReplicationRule( source_path='a.json', destination_path='b.json', file_type=FILE_TYPE_JSON, replication_type=REPLICATION_TYPE_COPY, ), ])) with self.assertRaisesRegex( ValueError, 'Rule for source a.bin must use REPLICATION_TYPE_COPY'): replication_lib.Replicate( ReplicationConfig(file_replication_rules=[ FileReplicationRule( source_path='a.bin', destination_path='b.bin', file_type=FILE_TYPE_OTHER, replication_type=REPLICATION_TYPE_FILTER, ), ])) with self.assertRaisesRegex( ValueError, 'Rule with REPLICATION_TYPE_COPY cannot use destination_fields' ): replication_lib.Replicate( ReplicationConfig(file_replication_rules=[ FileReplicationRule( source_path='a.bin', destination_path='b.bin', file_type=FILE_TYPE_OTHER, replication_type=REPLICATION_TYPE_COPY, destination_fields=FieldMask(paths=['c', 'd']), ), ])) with self.assertRaisesRegex( ValueError, 'Rule with REPLICATION_TYPE_FILTER must use destination_fields' ): replication_lib.Replicate( ReplicationConfig(file_replication_rules=[ FileReplicationRule( source_path='a.json', destination_path='b.json', file_type=FILE_TYPE_JSON, replication_type=REPLICATION_TYPE_FILTER, ), ]))
def testReplicate(self): """Test basic Replication functionality. - destination_fields used to filter JSON payload. - firmware.bin not copied. """ build_config_dst_path = os.path.join(self.tempdir, 'dst', 'build_config.json') audio_dst_path = os.path.join(self.tempdir, 'dst', 'audio_file') replication_config = ReplicationConfig(file_replication_rules=[ FileReplicationRule(source_path=self.build_config_path, destination_path=build_config_dst_path, file_type=FILE_TYPE_JSON, replication_type=REPLICATION_TYPE_FILTER, destination_fields=FieldMask( paths=['name', 'field2'])), FileReplicationRule( source_path=self.audio_path, destination_path=audio_dst_path, file_type=FILE_TYPE_OTHER, replication_type=REPLICATION_TYPE_COPY, ), ]) replication_lib.Replicate(replication_config) expected_file_layout = ( D('src', ['build_config.json', 'audio_file', 'firmware.bin']), D('dst', ['build_config.json', 'audio_file']), ) cros_test_lib.VerifyOnDiskHierarchy(self.tempdir, expected_file_layout) build_config_dst = json.loads(osutils.ReadFile(build_config_dst_path)) expected_build_config_dst = { 'chromeos': { 'configs': [ { 'name': 'A', 'field2': 2, }, { 'name': 'B', 'field2': 4, }, ] } } self.assertDictEqual(expected_build_config_dst, build_config_dst) self.assertFileContents(audio_dst_path, '[Speaker A Settings]')
def testRun(self): """Basic test of the 'run' command.""" audio_dst_path = os.path.join(self.tempdir, 'dst', 'audio_file') replication_config = ReplicationConfig(file_replication_rules=[ FileReplicationRule( source_path=self.audio_path, destination_path=audio_dst_path, file_type=FILE_TYPE_OTHER, replication_type=REPLICATION_TYPE_COPY, ), ]) replication_config_path = os.path.join(self.tempdir, 'replication_config.jsonpb') osutils.WriteFile(replication_config_path, json_format.MessageToJson(replication_config)) replication_util.main(['run', replication_config_path]) expected_file_layout = ( D('src', ['audio_file']), D('dst', ['audio_file']), 'replication_config.jsonpb', ) cros_test_lib.VerifyOnDiskHierarchy(self.tempdir, expected_file_layout) self.assertFileContents(audio_dst_path, '[Speaker A Settings]')
def testReplicateFileMode(self): """Tests file mode data is replicated.""" # Check that the original mode is not 777 and then chmod. full_audio_path = os.path.join(self.tempdir, self.audio_path) self.assertNotEqual(stat.S_IMODE(os.stat(full_audio_path).st_mode), 0o777) os.chmod(full_audio_path, 0o777) audio_dst_path = os.path.join('dst', 'audio_file') replication_config = ReplicationConfig(file_replication_rules=[ FileReplicationRule( source_path=self.audio_path, destination_path=audio_dst_path, file_type=FILE_TYPE_OTHER, replication_type=REPLICATION_TYPE_COPY, ), ]) replication_lib.Replicate(replication_config) self.assertEqual( stat.S_IMODE( os.stat(os.path.join(self.tempdir, audio_dst_path)).st_mode), 0o777)
def testReplicateDestinationExists(self): """Test existing files are overwritten.""" file_layout = (D('dst', ['audio_file']), ) cros_test_lib.CreateOnDiskHierarchy(self.tempdir, file_layout) audio_dst_path = os.path.join('dst', 'audio_file') self.WriteTempFile(audio_dst_path, 'Original audio data') replication_config = ReplicationConfig(file_replication_rules=[ FileReplicationRule( source_path=self.audio_path, destination_path=audio_dst_path, file_type=FILE_TYPE_OTHER, replication_type=REPLICATION_TYPE_COPY, ), ]) replication_lib.Replicate(replication_config) expected_file_layout = ( D('src', ['build_config.json', 'audio_file', 'firmware.bin']), D('dst', ['audio_file']), ) cros_test_lib.VerifyOnDiskHierarchy(self.tempdir, expected_file_layout) self.assertTempFileContents(audio_dst_path, '[Speaker A Settings]')
def test_replicate_private_config_no_build_config(self): """If there is no build config, don't generate C files.""" # Modify the replication config to write to "other_config.json" instead of # "build_config.json" modified_destination_path = self.public_config_path.replace( 'build_config', 'other_config') replication_config = ReplicationConfig(file_replication_rules=[ FileReplicationRule(source_path=self.private_config_path, destination_path=modified_destination_path, file_type=FILE_TYPE_JSON, replication_type=REPLICATION_TYPE_FILTER, destination_fields=FieldMask(paths=['a'])) ]) osutils.WriteFile(self.replication_config_path, json_format.MessageToJson(replication_config)) refs = [ GitRef(path='/chromeos/overlays/overlay-coral-private', ref='master', revision='123') ] result = packages.replicate_private_config(_build_targets=None, refs=refs, chroot=Chroot()) self.assertEqual(len(result.modified), 1) self.assertEqual( result.modified[0].files, [os.path.join(self.tempdir, modified_destination_path)])
def setUp(self): # Set up fake public and private chromeos-config overlays. private_package_root = ( 'src/private-overlays/overlay-coral-private/chromeos-base/' 'chromeos-config-bsp') self.public_package_root = ( 'src/overlays/overlay-coral/chromeos-base/chromeos-config-bsp') file_layout = ( D(os.path.join(private_package_root, 'files'), ['build_config.json']), D(private_package_root, ['replication_config.jsonpb']), D(os.path.join(self.public_package_root, 'files'), ['build_config.json']), ) cros_test_lib.CreateOnDiskHierarchy(self.tempdir, file_layout) # Private config contains 'a' and 'b' fields. self.private_config_path = os.path.join(private_package_root, 'files', 'build_config.json') self.WriteTempFile( self.private_config_path, json.dumps({'chromeos': { 'configs': [{ 'a': 3, 'b': 2 }] }})) # Public config only contains the 'a' field. Note that the value of 'a' is # 1 in the public config; it will get updated to 3 when the private config # is replicated. self.public_config_path = os.path.join(self.public_package_root, 'files', 'build_config.json') self.WriteTempFile(self.public_config_path, json.dumps({'chromeos': { 'configs': [{ 'a': 1 }] }})) # Put a ReplicationConfig JSONPB in the private package. Note that it # specifies only the 'a' field is replicated. self.replication_config_path = os.path.join( self.tempdir, private_package_root, 'replication_config.jsonpb') replication_config = ReplicationConfig(file_replication_rules=[ FileReplicationRule(source_path=self.private_config_path, destination_path=self.public_config_path, file_type=FILE_TYPE_JSON, replication_type=REPLICATION_TYPE_FILTER, destination_fields=FieldMask(paths=['a'])) ]) osutils.WriteFile(self.replication_config_path, json_format.MessageToJson(replication_config)) self.PatchObject(constants, 'SOURCE_ROOT', new=self.tempdir) self.rc.SetDefaultCmdResult(side_effect=self._write_generated_c_files)
def testReplicateJsonTrailingNewline(self): """Test JSON payloads have a trailing newline.""" build_config_dst_path = os.path.join('dst', 'build_config.json') replication_config = ReplicationConfig(file_replication_rules=[ FileReplicationRule(source_path=self.build_config_path, destination_path=build_config_dst_path, file_type=FILE_TYPE_JSON, replication_type=REPLICATION_TYPE_FILTER, destination_fields=FieldMask( paths=['name', 'field2'])), ]) replication_lib.Replicate(replication_config) self.assertEqual(self.ReadTempFile(build_config_dst_path)[-1], '\n')
def testReplicateNonChromeOSConfig(self): """Tests replicating a JSON file that is not a ChromeOS Config payload.""" src_path = os.path.join('src', 'other.json') dst_path = os.path.join('dst', 'other.json') self.WriteTempFile(src_path, json.dumps({'a': 1, 'b': 2})) replication_config = ReplicationConfig(file_replication_rules=[ FileReplicationRule(source_path=src_path, destination_path=dst_path, file_type=FILE_TYPE_JSON, replication_type=REPLICATION_TYPE_FILTER, destination_fields=FieldMask(paths=['a'])), ]) with self.assertRaisesRegex( NotImplementedError, 'Currently only ChromeOS Configs are supported'): replication_lib.Replicate(replication_config)
def testReplicateStringReplicationRules(self): audio_dst_path = os.path.join('dst', 'audio_file') replication_config = ReplicationConfig(file_replication_rules=[ FileReplicationRule( source_path=self.audio_path, destination_path=audio_dst_path, file_type=FILE_TYPE_OTHER, replication_type=REPLICATION_TYPE_COPY, string_replacement_rules=[ StringReplacementRule(before='A', after='B'), StringReplacementRule(before='Settings', after='Settings (Updated)'), ]), ]) replication_lib.Replicate(replication_config) self.assertTempFileContents(audio_dst_path, '[Speaker B Settings (Updated)]')
def testUnknownFieldInConfig(self): """Test that unknown fields in the ReplicationConfig cause an error.""" audio_dst_path = os.path.join(self.tempdir, 'dst', 'audio_file') replication_config = ReplicationConfig(file_replication_rules=[ FileReplicationRule( source_path=self.audio_path, destination_path=audio_dst_path, file_type=FILE_TYPE_OTHER, replication_type=REPLICATION_TYPE_COPY, ), ]) replication_config_path = os.path.join(self.tempdir, 'replication_config.jsonpb') replication_config_dict = json_format.MessageToDict(replication_config) replication_config_dict['new_field'] = 1 osutils.WriteFile(replication_config_path, json.dumps(replication_config_dict)) with self.assertRaises(json_format.ParseError): replication_util.main(['run', replication_config_path])