@@ -726,3 +726,110 @@ print("BBPATH is {{}}".format(os.environ["BBPATH"]))
self.assertEqual(f.read(), 'conflicting-upstream\n',
"re-cloned layer must contain the upstream content after conflict backup")
del os.environ['BBPATH']
+
+ def test_extra_remotes(self):
+ """
+ Test that extra-remotes are added and filtered correctly during init and update.
+
+ Covers:
+ 1. Default 'non-optional' filter: non-optional remote added, optional skipped.
+ 2. --extra-remotes-filter=all: both optional and non-optional remotes added.
+ 3. --extra-remotes-filter=none: no extra remotes added.
+ 4. --extra-remotes-filter=<name>: only the explicitly named remote added.
+ 5. update re-applies extra remotes and updates the URI of an existing remote.
+ """
+ if 'BBPATH' in os.environ:
+ del os.environ['BBPATH']
+ os.chdir(self.tempdir)
+
+ self.runbbsetup("settings set default registry 'git://{};protocol=file;branch=master;rev=master'".format(self.registrypath))
+ self.add_file_to_testrepo('test-file', 'initial\n')
+
+ # Two local repos used as extra remote targets (remote_a = initial URI, remote_b = updated URI)
+ remote_a = os.path.join(self.tempdir, 'extra-remote-a')
+ remote_b = os.path.join(self.tempdir, 'extra-remote-b')
+ for remote in (remote_a, remote_b):
+ os.makedirs(remote)
+ self.git_init(cwd=remote)
+ self.git('commit --allow-empty -m "Initial commit"', cwd=remote)
+
+ # Config with one non-optional and one optional extra-remote
+ sources_both = '''
+ "test-repo": {
+ "git-remote": {
+ "remotes": {"origin": {"uri": "file://%s"}},
+ "branch": "master",
+ "rev": "master",
+ "extra-remotes": {
+ "required-remote": {"uri": "file://%s"},
+ "optional-remote": {"uri": "file://%s", "optional": true}
+ }
+ }
+ }
+ ''' % (self.testrepopath, remote_a, remote_b)
+ self._add_json_config_to_registry_helper('er-test.conf.json', sources_both)
+
+ def get_remotes(layer_path):
+ return self.git('remote', cwd=layer_path).split()
+
+ # 1. Default filter 'non-optional': required-remote added, optional-remote skipped
+ out = self.runbbsetup("init --non-interactive er-test gadget")
+ setuppath = self.get_setup_path('er-test', 'gadget')
+ layer_path = os.path.join(setuppath, 'layers', 'test-repo')
+ remotes = get_remotes(layer_path)
+ self.assertIn('required-remote', remotes,
+ "non-optional extra remote must be added with the default 'non-optional' filter")
+ self.assertNotIn('optional-remote', remotes,
+ "optional extra remote must be skipped by the default 'non-optional' filter")
+ self.assertEqual(
+ self.git('remote get-url required-remote', cwd=layer_path).strip(),
+ 'file://' + remote_a)
+ self.assertIn("Added extra remote 'required-remote'", out[0])
+
+ # 2. --extra-remotes-filter=all: both optional and non-optional remotes added
+ self.runbbsetup("init --non-interactive --extra-remotes-filter=all --setup-dir-name er-filter-all er-test gadget")
+ all_layer = os.path.join(self.tempdir, 'bitbake-builds', 'er-filter-all', 'layers', 'test-repo')
+ remotes = get_remotes(all_layer)
+ self.assertIn('required-remote', remotes)
+ self.assertIn('optional-remote', remotes)
+
+ # 3. --extra-remotes-filter=none: no extra remotes added
+ self.runbbsetup("init --non-interactive --extra-remotes-filter=none --setup-dir-name er-filter-none er-test gadget")
+ none_layer = os.path.join(self.tempdir, 'bitbake-builds', 'er-filter-none', 'layers', 'test-repo')
+ remotes = get_remotes(none_layer)
+ self.assertNotIn('required-remote', remotes)
+ self.assertNotIn('optional-remote', remotes)
+
+ # 4. --extra-remotes-filter=<name>: only the explicitly named remote added
+ self.runbbsetup("init --non-interactive --extra-remotes-filter=optional-remote --setup-dir-name er-filter-named er-test gadget")
+ named_layer = os.path.join(self.tempdir, 'bitbake-builds', 'er-filter-named', 'layers', 'test-repo')
+ remotes = get_remotes(named_layer)
+ self.assertNotIn('required-remote', remotes)
+ self.assertIn('optional-remote', remotes)
+
+ # 5. update re-applies extra remotes and updates the URI of an existing remote
+ sources_updated = '''
+ "test-repo": {
+ "git-remote": {
+ "remotes": {"origin": {"uri": "file://%s"}},
+ "branch": "master",
+ "rev": "master",
+ "extra-remotes": {
+ "required-remote": {"uri": "file://%s"}
+ }
+ }
+ }
+ ''' % (self.testrepopath, remote_b)
+ config_path = os.path.join(self.registrypath, 'er-test.conf.json')
+ os.remove(config_path)
+ self._add_json_config_to_registry_helper('er-test.conf.json', sources_updated)
+
+ os.environ['BBPATH'] = os.path.join(setuppath, 'build')
+ out = self.runbbsetup("update --update-bb-conf='no'")
+ del os.environ['BBPATH']
+
+ self.assertEqual(
+ self.git('remote get-url required-remote', cwd=layer_path).strip(),
+ 'file://' + remote_b,
+ "update must call 'git remote set-url' to update the existing remote to the new URI")
+ self.assertIn("Updated extra remote 'required-remote'", out[0])