Fix exception calculating run time for lost builds.

When a build is reported as lost, it has no start_time, so the
code that calculated the run-time for statsd threw an exception.

Correct that by only calculating the run time for jobs that have
really completed.

Add debug lines to onBuild* that would have helped diagnose this.

Keep track of the throwaway threads that are used to report LOST
builds so that the test suite can more correctly know when the
system is settled.

Add a test case for a single non-existent post job.

Add STATSD_* env variables in tox to make sure that the statsd
code paths are executed by tests.

Change-Id: I339443cbad7b0858d70e9180d63dfb701b8eaee9
Reviewed-on: https://review.openstack.org/18792
Reviewed-by: Clark Boylan <clark.boylan@gmail.com>
Approved: Jeremy Stanley <fungi@yuggoth.org>
Reviewed-by: Jeremy Stanley <fungi@yuggoth.org>
Tested-by: Jenkins
diff --git a/tests/test_scheduler.py b/tests/test_scheduler.py
index cbc006e..c199345 100644
--- a/tests/test_scheduler.py
+++ b/tests/test_scheduler.py
@@ -696,6 +696,7 @@
             if (self.sched.trigger_event_queue.empty() and
                 self.sched.result_event_queue.empty() and
                 self.fake_gerrit.event_queue.empty() and
+                len(self.jenkins.lost_threads) == 0 and
                 self.fake_jenkins.fakeAllWaiting()):
                 self.sched.queue_lock.release()
                 self.log.debug("...settled.")
@@ -712,7 +713,8 @@
         for pipeline in self.sched.pipelines.values():
             for queue in pipeline.queues:
                 if len(queue.queue) != 0:
-                    print 'queue', queue.queue
+                    print 'pipeline %s queue %s contents %s' % (
+                        pipeline.name, queue.name, queue.queue)
                 assert len(queue.queue) == 0
                 if len(queue.severed_heads) != 0:
                     print 'heads', queue.severed_heads
@@ -1635,3 +1637,27 @@
         assert A.data['status'] == 'MERGED'
         assert A.reported == 2
         self.assertEmptyQueues()
+
+    def test_single_nonexistent_post_job(self):
+        "Test launching a single post job that doesn't exist"
+        self.fake_jenkins.nonexistent_jobs.append('project-post')
+        self.jenkins.launch_retry_timeout = 0.1
+
+        e = {
+            "type": "ref-updated",
+            "submitter": {
+                "name": "User Name",
+            },
+            "refUpdate": {
+                "oldRev": "90f173846e3af9154517b88543ffbd1691f31366",
+                "newRev": "d479a0bfcb34da57a31adb2a595c0cf687812543",
+                "refName": "master",
+                "project": "org/project",
+            }
+        }
+        self.fake_gerrit.addEvent(e)
+        self.waitUntilSettled()
+
+        jobs = self.fake_jenkins.job_history
+        assert len(jobs) == 0
+        self.assertEmptyQueues()