Merge "Add docstrings to the model" into feature/zuulv3
diff --git a/zuul/model.py b/zuul/model.py
index 89d900d..8220f85 100644
--- a/zuul/model.py
+++ b/zuul/model.py
@@ -68,7 +68,14 @@
 
 
 class Pipeline(object):
-    """A top-level pipeline such as check, gate, post, etc."""
+    """A configuration that ties triggers, reporters, managers and sources.
+
+    Source is where changes should come from. It is a named connection to
+        an external service defined in zuul.conf
+    Trigger is a description of which events should be processed
+    Manager is responsible for enqueing and dequeing Changes
+    Reporters communicate success and failure results somewhere
+    """
     def __init__(self, name, layout):
         self.name = name
         self.layout = layout
@@ -187,11 +194,21 @@
 
 
 class ChangeQueue(object):
-    """DependentPipelines have multiple parallel queues shared by
-    different projects; this is one of them.  For instance, there may
-    a queue shared by interrelated projects foo and bar, and a second
-    queue for independent project baz.  Pipelines have one or more
-    ChangeQueues."""
+    """A ChangeQueue contains Changes to be processed related projects.
+
+    DependentPipelines have multiple parallel ChangeQueues shared by
+    different projects.  For instance, there may a ChangeQueue shared by
+    interrelated projects foo and bar, and a second queue for independent
+    project baz.
+
+    IndependentPipelinesManager puts every Change into its own ChangeQueue
+
+    The ChangeQueue Window is inspired by TCP windows and controlls how many
+    Changes in a given ChangeQueue will be considered active and ready to
+    be processed. If a Change succeeds, the Window is increased by
+    `window_increase_factor`. If a Change fails, the Window is decreased by
+    `window_decrease_factor`.
+    """
     def __init__(self, pipeline, window=0, window_floor=1,
                  window_increase_type='linear', window_increase_factor=1,
                  window_decrease_type='exponential', window_decrease_factor=2):
@@ -300,6 +317,8 @@
 
 
 class Project(object):
+    """A Project represents a git repository such as openstack/nova."""
+
     # NOTE: Projects should only be instantiated via a Source object
     # so that they are associated with and cached by their Connection.
     # This makes a Project instance a unique identifier for a given
@@ -323,6 +342,7 @@
 
 
 class Inheritable(object):
+    """Helper class for implementing context-aware job inheritance."""
     def __init__(self, parent=None):
         self.parent = parent
 
@@ -337,6 +357,8 @@
 
 
 class Job(object):
+    """A Job represents the defintion of actions to perform."""
+
     attributes = dict(
         timeout=None,
         # variables={},
@@ -415,9 +437,14 @@
 
 
 class JobTree(object):
-    """ A JobTree represents an instance of one Job, and holds JobTrees
-    whose jobs should be run if that Job succeeds.  A root node of a
-    JobTree will have no associated Job. """
+    """A JobTree holds one or more Jobs to represent Job dependencies.
+
+    If Job foo should only execute if Job bar succeeds, then there will
+    be a JobTree for foo, which will contain a JobTree for bar. A JobTree
+    can hold more than one dependent JobTrees, such that jobs bar and bang
+    both depend on job foo being successful.
+
+    A root node of a JobTree will have no associated Job."""
 
     def __init__(self, job):
         self.job = job
@@ -461,6 +488,8 @@
 
 
 class Build(object):
+    """A Build is an instance of a single running Job."""
+
     def __init__(self, job, uuid):
         self.job = job
         self.uuid = uuid
@@ -486,7 +515,7 @@
 
 
 class Worker(object):
-    """A model of the worker running a job"""
+    """Information about the specific worker executing a Build."""
     def __init__(self):
         self.name = "Unknown"
         self.hostname = None
@@ -511,6 +540,7 @@
 
 
 class RepoFiles(object):
+    """RepoFiles holds config-file content for per-project job config."""
     # When we ask a merger to prepare a future multiple-repo state and
     # collect files so that we can dynamically load our configuration,
     # this class provides easy access to that data.
@@ -532,6 +562,11 @@
 
 
 class BuildSet(object):
+    """Contains the Builds for a Change representing potential future state.
+
+    A BuildSet also holds the UUID used to produce the Zuul Ref that builders
+    check out.
+    """
     # Merge states:
     NEW = 1
     PENDING = 2
@@ -618,7 +653,12 @@
 
 
 class QueueItem(object):
-    """A changish inside of a Pipeline queue"""
+    """Represents the position of a Change in a ChangeQueue.
+
+    All Changes are enqueued into ChangeQueue in a QueueItem. The QueueItem
+    holds the current `BuildSet` as well as all previous `BuildSets` that were
+    produced for this `QueueItem`.
+    """
 
     def __init__(self, queue, change):
         self.pipeline = queue.pipeline
@@ -991,7 +1031,7 @@
 
 
 class Changeish(object):
-    """Something like a change; either a change or a ref"""
+    """Base class for Change and Ref."""
 
     def __init__(self, project):
         self.project = project
@@ -1023,6 +1063,7 @@
 
 
 class Change(Changeish):
+    """A proposed new state for a Project."""
     def __init__(self, project):
         super(Change, self).__init__(project)
         self.branch = None
@@ -1079,6 +1120,7 @@
 
 
 class Ref(Changeish):
+    """An existing state of a Project."""
     def __init__(self, project):
         super(Ref, self).__init__(project)
         self.ref = None
@@ -1134,6 +1176,7 @@
 
 
 class TriggerEvent(object):
+    """Incoming event from an external system."""
     def __init__(self):
         self.data = None
         # common
@@ -1178,6 +1221,7 @@
 
 
 class BaseFilter(object):
+    """Base Class for filtering which Changes and Events to process."""
     def __init__(self, required_approvals=[], reject_approvals=[]):
         self._required_approvals = copy.deepcopy(required_approvals)
         self.required_approvals = self._tidy_approvals(required_approvals)
@@ -1269,6 +1313,7 @@
 
 
 class EventFilter(BaseFilter):
+    """Allows a Pipeline to only respond to certain events."""
     def __init__(self, trigger, types=[], branches=[], refs=[],
                  event_approvals={}, comments=[], emails=[], usernames=[],
                  timespecs=[], required_approvals=[], reject_approvals=[],
@@ -1425,6 +1470,7 @@
 
 
 class ChangeishFilter(BaseFilter):
+    """Allows a Manager to only enqueue Changes that meet certain criteria."""
     def __init__(self, open=None, current_patchset=None,
                  statuses=[], required_approvals=[],
                  reject_approvals=[]):
@@ -1490,8 +1536,11 @@
 
 
 class UnparsedAbideConfig(object):
-    # A collection of yaml lists that has not yet been parsed into
-    # objects.
+    """A collection of yaml lists that has not yet been parsed into objects.
+
+    An Abide is a collection of tenants.
+    """
+
     def __init__(self):
         self.tenants = []
 
@@ -1523,8 +1572,8 @@
 
 
 class UnparsedTenantConfig(object):
-    # A collection of yaml lists that has not yet been parsed into
-    # objects.
+    """A collection of yaml lists that has not yet been parsed into objects."""
+
     def __init__(self):
         self.pipelines = []
         self.jobs = []
@@ -1578,6 +1627,8 @@
 
 
 class Layout(object):
+    """Holds all of the Pipelines."""
+
     def __init__(self):
         self.tenant = None
         self.projects = {}