From ebd5ced7eb296ce10160021d8999d21b36b24da9 Mon Sep 17 00:00:00 2001
From: James Lopez <james@jameslopez.es>
Date: Thu, 20 Oct 2016 16:20:04 +0200
Subject: [PATCH] Added test events specs and logic. Also fixed some SQL and
 refactored the pipeline worker spec.

---
 app/models/merge_request.rb                   |  2 +-
 lib/gitlab/cycle_analytics/events.rb          |  7 ++++++
 lib/gitlab/cycle_analytics/events_fetcher.rb  | 14 ++++++++++-
 .../lib/gitlab/cycle_analytics/events_spec.rb | 24 ++++++++++++++++++-
 spec/workers/pipeline_metrics_worker_spec.rb  | 18 ++++++++------
 5 files changed, 55 insertions(+), 10 deletions(-)

diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index a3eb815dd34..d76feb9680e 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -232,7 +232,7 @@ class MergeRequest < ActiveRecord::Base
   end
 
   def diff_head_commit
-    if persisted?diff_head_commit
+    if persisted?
       merge_request_diff.head_commit
     else
       source_branch_head
diff --git a/lib/gitlab/cycle_analytics/events.rb b/lib/gitlab/cycle_analytics/events.rb
index ea8e78d7ab7..739c8772080 100644
--- a/lib/gitlab/cycle_analytics/events.rb
+++ b/lib/gitlab/cycle_analytics/events.rb
@@ -34,6 +34,13 @@ module Gitlab
         end
       end
 
+      def test_events
+        @fetcher.fetch_test_events.each do |event|
+          event['total_time'] = distance_of_time_in_words(event['total_time'].to_f)
+          event['pipeline'] = ::Ci::Pipeline.find_by_id(event['ci_commit_id']) # we may not have a pipeline
+        end
+      end
+
       private
 
       def first_time_reference_commit(commits, event)
diff --git a/lib/gitlab/cycle_analytics/events_fetcher.rb b/lib/gitlab/cycle_analytics/events_fetcher.rb
index cb61cda200d..d12161be0d3 100644
--- a/lib/gitlab/cycle_analytics/events_fetcher.rb
+++ b/lib/gitlab/cycle_analytics/events_fetcher.rb
@@ -36,7 +36,7 @@ module Gitlab
         base_query = base_query_for(:code)
         diff_fn = subtract_datetimes_diff(base_query,
                                           issue_metrics_table[:first_mentioned_in_commit_at],
-                                          issue_table[:created_at])
+                                          mr_table[:created_at])
 
         query = base_query.join(user_table).on(issue_table[:author_id].eq(user_table[:id])).
           project(extract_epoch(diff_fn).as('total_time'), *code_projections).
@@ -45,6 +45,18 @@ module Gitlab
         execute(query)
       end
 
+      def fetch_test_events
+        base_query = base_query_for(:code)
+        diff_fn = subtract_datetimes_diff(base_query,
+                                          mr_metrics_table[:latest_build_started_at],
+                                          mr_metrics_table[:latest_build_finished_at])
+
+        query = base_query.project(extract_epoch(diff_fn).as('total_time'), mr_metrics_table[:ci_commit_id]).
+          order(mr_table[:created_at].desc)
+
+        execute(query)
+      end
+
       private
 
       def issue_attributes
diff --git a/spec/lib/gitlab/cycle_analytics/events_spec.rb b/spec/lib/gitlab/cycle_analytics/events_spec.rb
index 4a329737c7e..404d9e6912c 100644
--- a/spec/lib/gitlab/cycle_analytics/events_spec.rb
+++ b/spec/lib/gitlab/cycle_analytics/events_spec.rb
@@ -55,7 +55,7 @@ describe Gitlab::CycleAnalytics::Events do
     end
 
     it 'has the total time' do
-      expect(subject.code_events.first['total_time']).to eq('2 days')
+      expect(subject.code_events.first['total_time']).to eq('less than a minute')
     end
 
     it 'has a title' do
@@ -75,6 +75,28 @@ describe Gitlab::CycleAnalytics::Events do
     end
   end
 
+  describe '#test_events' do
+    let!(:context) { create(:issue, project: project, created_at: 2.days.ago) }
+    let(:merge_request) { MergeRequest.first }
+    let!(:pipeline) { create(:ci_pipeline,
+                             ref: merge_request.source_branch,
+                             sha: merge_request.diff_head_sha,
+                             project: context.project) }
+
+    before do
+      pipeline.run!
+      pipeline.succeed!
+    end
+
+    it 'has the build info as a pipeline' do
+      expect(subject.test_events.first['pipeline']).to eq(pipeline)
+    end
+
+    it 'has the total time' do
+      expect(subject.test_events.first['total_time']).to eq('less than a minute')
+    end
+  end
+
   def setup(context)
     milestone = create(:milestone, project: project)
     context.update(milestone: milestone)
diff --git a/spec/workers/pipeline_metrics_worker_spec.rb b/spec/workers/pipeline_metrics_worker_spec.rb
index 2c9e7c2cd02..2d47d93acec 100644
--- a/spec/workers/pipeline_metrics_worker_spec.rb
+++ b/spec/workers/pipeline_metrics_worker_spec.rb
@@ -15,32 +15,36 @@ describe PipelineMetricsWorker do
   end
 
   describe '#perform' do
-    subject { described_class.new.perform(pipeline.id) }
+    before do
+      described_class.new.perform(pipeline.id)
+    end
 
     context 'when pipeline is running' do
       let(:status) { 'running' }
 
       it 'records the build start time' do
-        subject
-
         expect(merge_request.reload.metrics.latest_build_started_at).to be_like_time(pipeline.started_at)
       end
 
       it 'clears the build end time' do
-        subject
-
         expect(merge_request.reload.metrics.latest_build_finished_at).to be_nil
       end
+
+      it 'records the pipeline' do
+        expect(merge_request.reload.metrics.pipeline).to eq(pipeline)
+      end
     end
 
     context 'when pipeline succeeded' do
       let(:status) { 'success' }
 
       it 'records the build end time' do
-        subject
-
         expect(merge_request.reload.metrics.latest_build_finished_at).to be_like_time(pipeline.finished_at)
       end
+
+      it 'records the pipeline' do
+        expect(merge_request.reload.metrics.pipeline).to eq(pipeline)
+      end
     end
   end
 end
-- 
GitLab