Move test_model.test_job_inheritance_configloader

This test (and others like it) are difficult to maintain because
they rely heavily on internal interfaces which we change frequently.

Now that more of the framework is in place, make it more of a
functional test where we validate the output of the whole system.

Change-Id: Ib987b4a289682e87c5192043c05efb085fee5942
diff --git a/tests/base.py b/tests/base.py
index d3c5d62..2da4d47 100755
--- a/tests/base.py
+++ b/tests/base.py
@@ -67,6 +67,7 @@
 import zuul.model
 import zuul.nodepool
 import zuul.zk
+import zuul.configloader
 from zuul.exceptions import MergeFailure
 
 FIXTURE_DIR = os.path.join(os.path.dirname(__file__),
@@ -2231,6 +2232,14 @@
             if 'job' in item:
                 jobname = item['job']['name']
                 files['playbooks/%s.yaml' % jobname] = ''
+                if 'run' in item['job']:
+                    files['%s.yaml' % item['job']['run']] = ''
+                for fn in zuul.configloader.as_list(
+                        item['job'].get('pre-run', [])):
+                    files['%s.yaml' % fn] = ''
+                for fn in zuul.configloader.as_list(
+                        item['job'].get('post-run', [])):
+                    files['%s.yaml' % fn] = ''
 
         root = os.path.join(self.test_root, "config")
         if not os.path.exists(root):
diff --git a/tests/fixtures/layouts/job-variants.yaml b/tests/fixtures/layouts/job-variants.yaml
new file mode 100644
index 0000000..de99e8a
--- /dev/null
+++ b/tests/fixtures/layouts/job-variants.yaml
@@ -0,0 +1,61 @@
+- pipeline:
+    name: check
+    manager: independent
+    trigger:
+      gerrit:
+        - event: patchset-created
+    success:
+      gerrit:
+        Verified: 1
+    failure:
+      gerrit:
+        Verified: -1
+
+- job:
+    name: base
+    parent: null
+    pre-run: base-pre
+    post-run: base-post
+    nodeset:
+      nodes:
+        - name: controller
+          label: base
+
+- job:
+    name: python27
+    parent: base
+    timeout: 40
+    pre-run: py27-pre
+    post-run:
+      - py27-post-a
+      - py27-post-b
+    nodeset:
+      nodes:
+        - name: controller
+          label: new
+
+- job:
+    name: python27
+    timeout: 50
+    branches:
+      - stable/diablo
+    pre-run: py27-diablo-pre
+    run: py27-diablo
+    post-run: py27-diablo-post
+    nodeset:
+      nodes:
+        - name: controller
+          label: old
+
+- job:
+    name: python27
+    branches:
+      - stable/essex
+    pre-run: py27-essex-pre
+    post-run: py27-essex-post
+
+- project:
+    name: org/project
+    check:
+      jobs:
+        - python27
diff --git a/tests/unit/test_model.py b/tests/unit/test_model.py
index 628a45c..63e9aaa 100644
--- a/tests/unit/test_model.py
+++ b/tests/unit/test_model.py
@@ -170,185 +170,6 @@
                 "Unable to modify final job"):
             job.applyVariant(bad_final)
 
-    def test_job_inheritance_configloader(self):
-        # TODO(jeblair): move this to a configloader test
-        tenant = model.Tenant('tenant')
-        layout = model.Layout(tenant)
-
-        pipeline = model.Pipeline('gate', layout)
-        layout.addPipeline(pipeline)
-        queue = model.ChangeQueue(pipeline)
-        project = model.Project('project', self.source)
-        tpc = model.TenantProjectConfig(project)
-        tenant.addUntrustedProject(tpc)
-
-        base = configloader.JobParser.fromYaml(tenant, layout, {
-            '_source_context': self.context,
-            '_start_mark': self.start_mark,
-            'name': 'base',
-            'parent': None,
-            'timeout': 30,
-            'pre-run': 'base-pre',
-            'post-run': 'base-post',
-            'nodeset': {
-                'nodes': [{
-                    'name': 'controller',
-                    'label': 'base',
-                }],
-            },
-        })
-        layout.addJob(base)
-        python27 = configloader.JobParser.fromYaml(tenant, layout, {
-            '_source_context': self.context,
-            '_start_mark': self.start_mark,
-            'name': 'python27',
-            'parent': 'base',
-            'pre-run': 'py27-pre',
-            'post-run': ['py27-post-a', 'py27-post-b'],
-            'nodeset': {
-                'nodes': [{
-                    'name': 'controller',
-                    'label': 'new',
-                }],
-            },
-            'timeout': 40,
-        })
-        layout.addJob(python27)
-        python27diablo = configloader.JobParser.fromYaml(tenant, layout, {
-            '_source_context': self.context,
-            '_start_mark': self.start_mark,
-            'name': 'python27',
-            'branches': [
-                'stable/diablo'
-            ],
-            'pre-run': 'py27-diablo-pre',
-            'run': 'py27-diablo',
-            'post-run': 'py27-diablo-post',
-            'nodeset': {
-                'nodes': [{
-                    'name': 'controller',
-                    'label': 'old',
-                }],
-            },
-            'timeout': 50,
-        })
-        layout.addJob(python27diablo)
-
-        python27essex = configloader.JobParser.fromYaml(tenant, layout, {
-            '_source_context': self.context,
-            '_start_mark': self.start_mark,
-            'name': 'python27',
-            'branches': [
-                'stable/essex'
-            ],
-            'pre-run': 'py27-essex-pre',
-            'post-run': 'py27-essex-post',
-        })
-        layout.addJob(python27essex)
-
-        project_template_parser = configloader.ProjectTemplateParser(
-            tenant, layout)
-        project_parser = configloader.ProjectParser(
-            tenant, layout, project_template_parser)
-        project_config = project_parser.fromYaml([{
-            '_source_context': self.context,
-            '_start_mark': self.start_mark,
-            'name': 'project',
-            'gate': {
-                'jobs': [
-                    'python27'
-                ]
-            }
-        }])
-        layout.addProjectConfig(project_config)
-
-        change = model.Change(project)
-        # Test master
-        change.branch = 'master'
-        item = queue.enqueueChange(change)
-        item.layout = layout
-
-        self.assertTrue(base.changeMatches(change))
-        self.assertTrue(python27.changeMatches(change))
-        self.assertFalse(python27diablo.changeMatches(change))
-        self.assertFalse(python27essex.changeMatches(change))
-
-        item.freezeJobGraph()
-        self.assertEqual(len(item.getJobs()), 1)
-        job = item.getJobs()[0]
-        self.assertEqual(job.name, 'python27')
-        self.assertEqual(job.timeout, 40)
-        nodes = job.nodeset.getNodes()
-        self.assertEqual(len(nodes), 1)
-        self.assertEqual(nodes[0].label, 'new')
-        self.assertEqual([x.path for x in job.pre_run],
-                         ['base-pre',
-                          'py27-pre'])
-        self.assertEqual([x.path for x in job.post_run],
-                         ['py27-post-a',
-                          'py27-post-b',
-                          'base-post'])
-        self.assertEqual([x.path for x in job.run],
-                         ['playbooks/python27',
-                          'playbooks/base'])
-
-        # Test diablo
-        change.branch = 'stable/diablo'
-        item = queue.enqueueChange(change)
-        item.layout = layout
-
-        self.assertTrue(base.changeMatches(change))
-        self.assertTrue(python27.changeMatches(change))
-        self.assertTrue(python27diablo.changeMatches(change))
-        self.assertFalse(python27essex.changeMatches(change))
-
-        item.freezeJobGraph()
-        self.assertEqual(len(item.getJobs()), 1)
-        job = item.getJobs()[0]
-        self.assertEqual(job.name, 'python27')
-        self.assertEqual(job.timeout, 50)
-        nodes = job.nodeset.getNodes()
-        self.assertEqual(len(nodes), 1)
-        self.assertEqual(nodes[0].label, 'old')
-        self.assertEqual([x.path for x in job.pre_run],
-                         ['base-pre',
-                          'py27-pre',
-                          'py27-diablo-pre'])
-        self.assertEqual([x.path for x in job.post_run],
-                         ['py27-diablo-post',
-                          'py27-post-a',
-                          'py27-post-b',
-                          'base-post'])
-        self.assertEqual([x.path for x in job.run],
-                         ['py27-diablo']),
-
-        # Test essex
-        change.branch = 'stable/essex'
-        item = queue.enqueueChange(change)
-        item.layout = layout
-
-        self.assertTrue(base.changeMatches(change))
-        self.assertTrue(python27.changeMatches(change))
-        self.assertFalse(python27diablo.changeMatches(change))
-        self.assertTrue(python27essex.changeMatches(change))
-
-        item.freezeJobGraph()
-        self.assertEqual(len(item.getJobs()), 1)
-        job = item.getJobs()[0]
-        self.assertEqual(job.name, 'python27')
-        self.assertEqual([x.path for x in job.pre_run],
-                         ['base-pre',
-                          'py27-pre',
-                          'py27-essex-pre'])
-        self.assertEqual([x.path for x in job.post_run],
-                         ['py27-essex-post',
-                          'py27-post-a',
-                          'py27-post-b',
-                          'base-post'])
-        self.assertEqual([x.path for x in job.run],
-                         ['playbooks/python27',
-                          'playbooks/base'])
-
     def test_job_auth_inheritance(self):
         tenant = self.tenant
         layout = self.layout
diff --git a/tests/unit/test_scheduler.py b/tests/unit/test_scheduler.py
index a97e47e..22d1139 100755
--- a/tests/unit/test_scheduler.py
+++ b/tests/unit/test_scheduler.py
@@ -2430,6 +2430,62 @@
         self.assertEqual(rp, set(['org/project', 'org/project0',
                                   'org/project3']))
 
+    @simple_layout('layouts/job-variants.yaml')
+    def test_job_branch_variants(self):
+        self.create_branch('org/project', 'stable/diablo')
+        self.create_branch('org/project', 'stable/essex')
+        A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
+        self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1))
+        self.waitUntilSettled()
+
+        B = self.fake_gerrit.addFakeChange('org/project', 'stable/diablo', 'B')
+        self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1))
+        self.waitUntilSettled()
+
+        C = self.fake_gerrit.addFakeChange('org/project', 'stable/essex', 'C')
+        self.fake_gerrit.addEvent(C.getPatchsetCreatedEvent(1))
+        self.waitUntilSettled()
+        self.assertHistory([
+            dict(name='python27', result='SUCCESS'),
+            dict(name='python27', result='SUCCESS'),
+            dict(name='python27', result='SUCCESS'),
+        ])
+
+        p = self.history[0].parameters
+        self.assertEqual(p['timeout'], 40)
+        self.assertEqual(len(p['nodes']), 1)
+        self.assertEqual(p['nodes'][0]['label'], 'new')
+        self.assertEqual([x['path'] for x in p['pre_playbooks']],
+                         ['base-pre', 'py27-pre'])
+        self.assertEqual([x['path'] for x in p['post_playbooks']],
+                         ['py27-post-a', 'py27-post-b', 'base-post'])
+        self.assertEqual([x['path'] for x in p['playbooks']],
+                         ['playbooks/python27', 'playbooks/base'])
+
+        p = self.history[1].parameters
+        self.assertEqual(p['timeout'], 50)
+        self.assertEqual(len(p['nodes']), 1)
+        self.assertEqual(p['nodes'][0]['label'], 'old')
+        self.assertEqual([x['path'] for x in p['pre_playbooks']],
+                         ['base-pre', 'py27-pre', 'py27-diablo-pre'])
+        self.assertEqual([x['path'] for x in p['post_playbooks']],
+                         ['py27-diablo-post', 'py27-post-a', 'py27-post-b',
+                          'base-post'])
+        self.assertEqual([x['path'] for x in p['playbooks']],
+                         ['py27-diablo'])
+
+        p = self.history[2].parameters
+        self.assertEqual(p['timeout'], 40)
+        self.assertEqual(len(p['nodes']), 1)
+        self.assertEqual(p['nodes'][0]['label'], 'new')
+        self.assertEqual([x['path'] for x in p['pre_playbooks']],
+                         ['base-pre', 'py27-pre', 'py27-essex-pre'])
+        self.assertEqual([x['path'] for x in p['post_playbooks']],
+                         ['py27-essex-post', 'py27-post-a', 'py27-post-b',
+                          'base-post'])
+        self.assertEqual([x['path'] for x in p['playbooks']],
+                         ['playbooks/python27', 'playbooks/base'])
+
     def test_queue_names(self):
         "Test shared change queue names"
         tenant = self.sched.abide.tenants.get('tenant-one')