Add tenants

Change-Id: Ia6c21152c00c9380c17c559290ed98ff22cf767b
diff --git a/tests/base.py b/tests/base.py
index f3bfa4e..076a123 100755
--- a/tests/base.py
+++ b/tests/base.py
@@ -883,9 +883,9 @@
 
         # Make per test copy of Configuration.
         self.setup_config()
-        self.config.set('zuul', 'layout_config',
+        self.config.set('zuul', 'tenant_config',
                         os.path.join(FIXTURE_DIR,
-                                     self.config.get('zuul', 'layout_config')))
+                                     self.config.get('zuul', 'tenant_config')))
         self.config.set('merger', 'git_dir', self.git_root)
 
         # For each project in config:
@@ -1062,10 +1062,11 @@
                 repos.append(obj)
         self.assertEqual(len(repos), 0)
         self.assertEmptyQueues()
-        for pipeline in self.sched.layout.pipelines.values():
-            if isinstance(pipeline.manager,
-                          zuul.scheduler.IndependentPipelineManager):
-                self.assertEqual(len(pipeline.queues), 0)
+        for tenant in self.sched.abide.tenants.values():
+            for pipeline in tenant.layout.pipelines.values():
+                if isinstance(pipeline.manager,
+                              zuul.scheduler.IndependentPipelineManager):
+                    self.assertEqual(len(pipeline.queues), 0)
 
     def shutdown(self):
         self.log.debug("Shutting down after tests")
@@ -1172,9 +1173,10 @@
 
     def registerJobs(self):
         count = 0
-        for job in self.sched.layout.jobs.keys():
-            self.worker.registerFunction('build:' + job)
-            count += 1
+        for tenant in self.sched.abide.tenants.values():
+            for job in tenant.layout.jobs.keys():
+                self.worker.registerFunction('build:' + job)
+                count += 1
         self.worker.registerFunction('stop:' + self.worker.worker_id)
         count += 1
 
@@ -1329,13 +1331,14 @@
 
     def assertEmptyQueues(self):
         # Make sure there are no orphaned jobs
-        for pipeline in self.sched.layout.pipelines.values():
-            for queue in pipeline.queues:
-                if len(queue.queue) != 0:
-                    print 'pipeline %s queue %s contents %s' % (
-                        pipeline.name, queue.name, queue.queue)
-                self.assertEqual(len(queue.queue), 0,
-                                 "Pipelines queues should be empty")
+        for tenant in self.sched.abide.tenants.values():
+            for pipeline in tenant.layout.pipelines.values():
+                for queue in pipeline.queues:
+                    if len(queue.queue) != 0:
+                        print 'pipeline %s queue %s contents %s' % (
+                            pipeline.name, queue.name, queue.queue)
+                    self.assertEqual(len(queue.queue), 0,
+                                     "Pipelines queues should be empty")
 
     def assertReportedStat(self, key, value=None, kind=None):
         start = time.time()
@@ -1356,3 +1359,6 @@
 
         pprint.pprint(self.statsd.stats)
         raise Exception("Key %s not found in reported stats" % key)
+
+    def getPipeline(self, name):
+        return self.sched.abide.tenants[0].layout.pipelines.get(name)
diff --git a/tests/fixtures/layout.yaml b/tests/fixtures/layout.yaml
index 1d23443..99b135c 100644
--- a/tests/fixtures/layout.yaml
+++ b/tests/fixtures/layout.yaml
@@ -4,6 +4,8 @@
 pipelines:
   - name: check
     manager: IndependentPipelineManager
+    source:
+      gerrit
     trigger:
       gerrit:
         - event: patchset-created
@@ -16,6 +18,8 @@
 
   - name: post
     manager: IndependentPipelineManager
+    source:
+      gerrit
     trigger:
       gerrit:
         - event: ref-updated
@@ -24,6 +28,8 @@
   - name: gate
     manager: DependentPipelineManager
     failure-message: Build failed.  For information on how to proceed, see http://wiki.example.org/Test_Failures
+    source:
+      gerrit
     trigger:
       gerrit:
         - event: comment-added
@@ -44,6 +50,8 @@
   - name: unused
     manager: IndependentPipelineManager
     dequeue-on-new-patchset: false
+    source:
+      gerrit
     trigger:
       gerrit:
         - event: comment-added
@@ -52,6 +60,8 @@
 
   - name: dup1
     manager: IndependentPipelineManager
+    source:
+      gerrit
     trigger:
       gerrit:
         - event: change-restored
@@ -64,6 +74,8 @@
 
   - name: dup2
     manager: IndependentPipelineManager
+    source:
+      gerrit
     trigger:
       gerrit:
         - event: change-restored
@@ -77,6 +89,8 @@
   - name: conflict
     manager: DependentPipelineManager
     failure-message: Build failed.  For information on how to proceed, see http://wiki.example.org/Test_Failures
+    source:
+      gerrit
     trigger:
       gerrit:
         - event: comment-added
@@ -95,6 +109,8 @@
 
   - name: experimental
     manager: IndependentPipelineManager
+    source:
+      gerrit
     trigger:
       gerrit:
         - event: patchset-created
diff --git a/tests/fixtures/main.yaml b/tests/fixtures/main.yaml
new file mode 100644
index 0000000..f9ec378
--- /dev/null
+++ b/tests/fixtures/main.yaml
@@ -0,0 +1,4 @@
+tenants:
+  - name: openstack
+    include:
+      - layout.yaml
diff --git a/tests/fixtures/zuul.conf b/tests/fixtures/zuul.conf
index b250c6d..c08b5ad 100644
--- a/tests/fixtures/zuul.conf
+++ b/tests/fixtures/zuul.conf
@@ -2,7 +2,7 @@
 server=127.0.0.1
 
 [zuul]
-layout_config=layout.yaml
+tenant_config=main.yaml
 url_pattern=http://logs.example.com/{change.number}/{change.patchset}/{pipeline.name}/{job.name}/{build.number}
 job_name_in_report=true
 
diff --git a/tests/test_v3.py b/tests/test_v3.py
new file mode 100644
index 0000000..240cd61
--- /dev/null
+++ b/tests/test_v3.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+
+# Copyright 2012 Hewlett-Packard Development Company, L.P.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import logging
+
+from tests.base import (
+    ZuulTestCase,
+)
+
+logging.basicConfig(level=logging.DEBUG,
+                    format='%(asctime)s %(name)-32s '
+                    '%(levelname)-8s %(message)s')
+
+
+class TestV3(ZuulTestCase):
+    # A temporary class to hold new tests while others are disabled
+
+    def test_jobs_launched(self):
+        "Test that jobs are launched and a change is merged"
+
+        A = self.fake_gerrit.addFakeChange('org/project', 'master', 'A')
+        A.addApproval('CRVW', 2)
+        self.fake_gerrit.addEvent(A.addApproval('APRV', 1))
+        self.waitUntilSettled()
+        self.assertEqual(self.getJobFromHistory('project-merge').result,
+                         'SUCCESS')
+        self.assertEqual(self.getJobFromHistory('project-test1').result,
+                         'SUCCESS')
+        self.assertEqual(self.getJobFromHistory('project-test2').result,
+                         'SUCCESS')
+        self.assertEqual(A.data['status'], 'MERGED')
+        self.assertEqual(A.reported, 2)
+
+        self.assertReportedStat('gerrit.event.comment-added', value='1|c')
+        self.assertReportedStat('zuul.pipeline.gate.current_changes',
+                                value='1|g')
+        self.assertReportedStat('zuul.pipeline.gate.job.project-merge.SUCCESS',
+                                kind='ms')
+        self.assertReportedStat('zuul.pipeline.gate.job.project-merge.SUCCESS',
+                                value='1|c')
+        self.assertReportedStat('zuul.pipeline.gate.resident_time', kind='ms')
+        self.assertReportedStat('zuul.pipeline.gate.total_changes',
+                                value='1|c')
+        self.assertReportedStat(
+            'zuul.pipeline.gate.org.project.resident_time', kind='ms')
+        self.assertReportedStat(
+            'zuul.pipeline.gate.org.project.total_changes', value='1|c')
+
+        for build in self.builds:
+            self.assertEqual(build.parameters['ZUUL_VOTING'], '1')