Pass assigned nodes to the launcher

This fleshes out the nodepool stub a little more.  It passes some
node information to the launcher after node requests have been
fulfilled.  It also corrects some logic errors in the node request
framework.  It moves data structures related to node requests into
the model.  Finally, it adds nodes to the configuration of some
tests to exercise the system, and adds a test to verify the correct
node is supplied on a job that has a branch variant.

Change-Id: I395ce23ae865df3a55436ee92d04e0eae07c963a
diff --git a/tests/test_scheduler.py b/tests/test_scheduler.py
index afd4027..4cce777 100755
--- a/tests/test_scheduler.py
+++ b/tests/test_scheduler.py
@@ -61,6 +61,8 @@
                          'SUCCESS')
         self.assertEqual(A.data['status'], 'MERGED')
         self.assertEqual(A.reported, 2)
+        self.assertEqual(self.getJobFromHistory('project-test1').node,
+                         'image1')
 
         # TODOv3(jeblair): we may want to report stats by tenant (also?).
         self.assertReportedStat('gerrit.event.comment-added', value='1|c')
@@ -88,6 +90,25 @@
         self.assertReportedStat('zuul.pipeline.check.current_changes',
                                 value='0|g')
 
+    def test_job_branch(self):
+        "Test the correct variant of a job runs on a branch"
+        self.create_branch('org/project', 'stable')
+        A = self.fake_gerrit.addFakeChange('org/project', 'stable', 'A')
+        A.addApproval('code-review', 2)
+        self.fake_gerrit.addEvent(A.addApproval('approved', 1))
+        self.waitUntilSettled()
+        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,
+                         "A should report start and success")
+        self.assertIn('gate', A.messages[1],
+                      "A should transit gate")
+        self.assertEqual(self.getJobFromHistory('project-test1').node,
+                         'image2')
+
     @skip("Disabled for early v3 development")
     def test_duplicate_pipelines(self):
         "Test that a change matching multiple pipelines works"