Set job class attributes in __init__

The job class attributes have grown to include complex data
structures that may accidentally be modified in-place.  Ensure
that each time a Job is constructed, it is initialized properly.

Nodesets were erroneously relying on this behavior, to correct
this, NodeSets must be comparable, so implement equality checks
for them.

Change-Id: I7eb22fc48f7106e963b12503c30a01fbfba27b11
diff --git a/tests/unit/test_model.py b/tests/unit/test_model.py
index db98d14..ae40416 100644
--- a/tests/unit/test_model.py
+++ b/tests/unit/test_model.py
@@ -62,12 +62,20 @@
             '_source_project': project,
             'name': 'base',
             'timeout': 30,
+            'nodes': [{
+                'name': 'controller',
+                'image': 'base',
+            }],
         })
         layout.addJob(base)
         python27 = configloader.JobParser.fromYaml(layout, {
             '_source_project': project,
             'name': 'python27',
             'parent': 'base',
+            'nodes': [{
+                'name': 'controller',
+                'image': 'new',
+            }],
             'timeout': 40,
         })
         layout.addJob(python27)
@@ -77,6 +85,10 @@
             'branches': [
                 'stable/diablo'
             ],
+            'nodes': [{
+                'name': 'controller',
+                'image': 'old',
+            }],
             'timeout': 50,
         })
         layout.addJob(python27diablo)
@@ -92,6 +104,7 @@
         layout.addProjectConfig(project_config, update_pipeline=False)
 
         change = model.Change(project)
+        # Test master
         change.branch = 'master'
         item = queue.enqueueChange(change)
         item.current_build_set.layout = layout
@@ -105,7 +118,11 @@
         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].image, 'new')
 
+        # Test diablo
         change.branch = 'stable/diablo'
         item = queue.enqueueChange(change)
         item.current_build_set.layout = layout
@@ -119,6 +136,9 @@
         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].image, 'old')
 
     def test_job_auth_inheritance(self):
         layout = model.Layout()