Use override-checkout to select jobs

If a job is defined in a project with "master" and "stable" branches,
and a user wants to inherit from that job in a project with only a
"devel" branch, Zuul will not run the job because there are no matching
variants.  To correct this, have Zuul use the value of override-checkout
to mask the branch of the item under test so that it appears to match the
'override-checkout' branch.

Change-Id: I4619a6f9fe9c3203a7285e5eb4f74c52b650c737
diff --git a/tests/fixtures/config/branch-mismatch/git/common-config/playbooks/base.yaml b/tests/fixtures/config/branch-mismatch/git/common-config/playbooks/base.yaml
new file mode 100644
index 0000000..f679dce
--- /dev/null
+++ b/tests/fixtures/config/branch-mismatch/git/common-config/playbooks/base.yaml
@@ -0,0 +1,2 @@
+- hosts: all
+  tasks: []
diff --git a/tests/fixtures/config/branch-mismatch/git/common-config/zuul.yaml b/tests/fixtures/config/branch-mismatch/git/common-config/zuul.yaml
new file mode 100644
index 0000000..9954846
--- /dev/null
+++ b/tests/fixtures/config/branch-mismatch/git/common-config/zuul.yaml
@@ -0,0 +1,22 @@
+- pipeline:
+    name: check
+    manager: independent
+    trigger:
+      gerrit:
+        - event: patchset-created
+    success:
+      gerrit:
+        Verified: 1
+    failure:
+      gerrit:
+        Verified: -1
+
+- job:
+    name: base
+    parent: null
+    run: playbooks/base.yaml
+
+- project:
+    name: common-config
+    check:
+      jobs: []
diff --git a/tests/fixtures/config/branch-mismatch/git/org_project1/README b/tests/fixtures/config/branch-mismatch/git/org_project1/README
new file mode 100644
index 0000000..9daeafb
--- /dev/null
+++ b/tests/fixtures/config/branch-mismatch/git/org_project1/README
@@ -0,0 +1 @@
+test
diff --git a/tests/fixtures/config/branch-mismatch/git/org_project1/zuul.yaml b/tests/fixtures/config/branch-mismatch/git/org_project1/zuul.yaml
new file mode 100644
index 0000000..809f830
--- /dev/null
+++ b/tests/fixtures/config/branch-mismatch/git/org_project1/zuul.yaml
@@ -0,0 +1,7 @@
+- job:
+    name: project-test1
+
+- project:
+    check:
+      jobs:
+        - project-test1
diff --git a/tests/fixtures/config/branch-mismatch/git/org_project2/README b/tests/fixtures/config/branch-mismatch/git/org_project2/README
new file mode 100644
index 0000000..9daeafb
--- /dev/null
+++ b/tests/fixtures/config/branch-mismatch/git/org_project2/README
@@ -0,0 +1 @@
+test
diff --git a/tests/fixtures/config/branch-mismatch/git/org_project2/zuul.yaml b/tests/fixtures/config/branch-mismatch/git/org_project2/zuul.yaml
new file mode 100644
index 0000000..3a8e9df
--- /dev/null
+++ b/tests/fixtures/config/branch-mismatch/git/org_project2/zuul.yaml
@@ -0,0 +1,13 @@
+- job:
+    name: project-test2
+    parent: project-test1
+    override-checkout: stable
+
+- project:
+    check:
+      jobs:
+        - project-test1:
+            required-projects:
+              - name: org/project1
+                override-checkout: stable
+        - project-test2
diff --git a/tests/fixtures/config/branch-mismatch/main.yaml b/tests/fixtures/config/branch-mismatch/main.yaml
new file mode 100644
index 0000000..950b117
--- /dev/null
+++ b/tests/fixtures/config/branch-mismatch/main.yaml
@@ -0,0 +1,9 @@
+- tenant:
+    name: tenant-one
+    source:
+      gerrit:
+        config-projects:
+          - common-config
+        untrusted-projects:
+          - org/project1
+          - org/project2
diff --git a/tests/unit/test_v3.py b/tests/unit/test_v3.py
index 163a58b..164d5b4 100755
--- a/tests/unit/test_v3.py
+++ b/tests/unit/test_v3.py
@@ -497,6 +497,42 @@
         self.waitUntilSettled()
 
 
+class TestBranchMismatch(ZuulTestCase):
+    tenant_config_file = 'config/branch-mismatch/main.yaml'
+
+    def test_job_override_branch(self):
+        "Test that override-checkout overrides branch matchers as well"
+
+        # Make sure the parent job repo is branched, so it gets
+        # implied branch matchers.
+        self.create_branch('org/project1', 'stable')
+        self.fake_gerrit.addEvent(
+            self.fake_gerrit.getFakeBranchCreatedEvent(
+                'org/project1', 'stable'))
+
+        # The child job repo should have a branch which does not exist
+        # in the parent job repo.
+        self.create_branch('org/project2', 'devel')
+        self.fake_gerrit.addEvent(
+            self.fake_gerrit.getFakeBranchCreatedEvent(
+                'org/project2', 'devel'))
+
+        # A job in a repo with a weird branch name should use the
+        # parent job from the parent job's master (default) branch.
+        A = self.fake_gerrit.addFakeChange('org/project2', 'devel', 'A')
+        self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
+        self.waitUntilSettled()
+        # project-test2 should run because it inherits from
+        # project-test1 and we will use the fallback branch to find
+        # project-test1 variants, but project-test1 itself, even
+        # though it is in the project-pipeline config, should not run
+        # because it doesn't directly match.
+        self.assertHistory([
+            dict(name='project-test1', result='SUCCESS', changes='1,1'),
+            dict(name='project-test2', result='SUCCESS', changes='1,1'),
+        ], ordered=False)
+
+
 class TestCentralJobs(ZuulTestCase):
     tenant_config_file = 'config/central-jobs/main.yaml'