Commit eae636ed authored by Robert Speicher's avatar Robert Speicher

Merge branch 'wall-clock-time-for-showing-pipeline' into 'master'

Show wall-clock time when showing pipeline

## What does this MR do?

Show wall-clock time when showing pipeline instead of cumulative builds time.

Closes #17007

See merge request !5734
parents 66eb0185 c627dbc8
......@@ -39,6 +39,7 @@ v 8.11.0 (unreleased)
- API: Add deployment endpoints
- API: Add Play endpoint on Builds
- Fix of 'Commits being passed to custom hooks are already reachable when using the UI'
- Show wall clock time when showing a pipeline. !5734
- Show member roles to all users on members page
- Project.visible_to_user is instrumented again
- Fix awardable button mutuality loading spinners (ClemMakesApps)
......
......@@ -15,20 +15,9 @@ module TimeHelper
"#{from.to_s(:short)} - #{to.to_s(:short)}"
end
def duration_in_numbers(finished_at, started_at)
interval = interval_in_seconds(started_at, finished_at)
time_format = interval < 1.hour ? "%M:%S" : "%H:%M:%S"
def duration_in_numbers(duration)
time_format = duration < 1.hour ? "%M:%S" : "%H:%M:%S"
Time.at(interval).utc.strftime(time_format)
end
private
def interval_in_seconds(started_at, finished_at = nil)
if started_at && finished_at
finished_at.to_i - started_at.to_i
elsif started_at
Time.now.to_i - started_at.to_i
end
Time.at(duration).utc.strftime(time_format)
end
end
......@@ -78,6 +78,10 @@ module Ci
CommitStatus.where(pipeline: pluck(:id)).stages
end
def self.total_duration
where.not(duration: nil).sum(:duration)
end
def stages_with_latest_statuses
statuses.latest.order(:stage_idx).group_by(&:stage)
end
......@@ -250,7 +254,7 @@ module Ci
end
def update_duration
self.duration = statuses.latest.duration
self.duration = calculate_duration
end
def execute_hooks
......
......@@ -21,6 +21,7 @@ class CommitStatus < ActiveRecord::Base
where(id: max_id.group(:name, :commit_id))
end
scope :retried, -> { where.not(id: latest) }
scope :ordered, -> { order(:name) }
scope :ignored, -> { where(allow_failure: true, status: [:failed, :canceled]) }
......@@ -107,13 +108,7 @@ class CommitStatus < ActiveRecord::Base
end
def duration
duration =
if started_at && finished_at
finished_at - started_at
elsif started_at
Time.now - started_at
end
duration
calculate_duration
end
def stuck?
......
......@@ -35,11 +35,6 @@ module Statuseable
all.pluck(self.status_sql).first
end
def duration
duration_array = all.map(&:duration).compact
duration_array.reduce(:+)
end
def started_at
all.minimum(:started_at)
end
......@@ -85,4 +80,14 @@ module Statuseable
def complete?
COMPLETED_STATUSES.include?(status)
end
private
def calculate_duration
if started_at && finished_at
finished_at - started_at
elsif started_at
Time.now - started_at
end
end
end
......@@ -51,7 +51,7 @@
- if build.duration
%p.duration
= custom_icon("icon_timer")
= duration_in_numbers(build.finished_at, build.started_at)
= duration_in_numbers(build.duration)
- if build.finished_at
%p.finished-at
......
......@@ -63,7 +63,7 @@
- if build.duration
%p.duration
= custom_icon("icon_timer")
= duration_in_numbers(build.finished_at, build.started_at)
= duration_in_numbers(build.duration)
- if build.finished_at
%p.finished-at
= icon("calendar")
......
......@@ -48,10 +48,10 @@
\-
%td
- if pipeline.started_at && pipeline.finished_at
- if pipeline.duration
%p.duration
= custom_icon("icon_timer")
= duration_in_numbers(pipeline.finished_at, pipeline.started_at)
= duration_in_numbers(pipeline.duration)
- if pipeline.finished_at
%p.finished-at
= icon("calendar")
......
......@@ -58,9 +58,8 @@
= ci_icon_for_status(@commit.status)
%span.ci-status-label
= ci_label_for_status(@commit.status)
- if @commit.pipelines.duration
in
= time_interval_in_words @commit.pipelines.duration
= time_interval_in_words @commit.pipelines.total_duration
.commit-box.content-block
%h3.commit-title
......
......@@ -9,7 +9,7 @@
= link_to @pipeline.ref, namespace_project_commits_path(@project.namespace, @project, @pipeline.ref), class: "monospace"
- if @pipeline.duration
in
= time_interval_in_words @pipeline.duration
= time_interval_in_words(@pipeline.duration)
.pull-right
= link_to namespace_project_pipeline_path(@project.namespace, @project, @pipeline), class: "ci-status ci-#{@pipeline.status}" do
......
......@@ -7,7 +7,7 @@ module Gitlab
# @param cmd [Array<String>]
# @return [Boolean]
def system_silent(cmd)
Popen::popen(cmd).last.zero?
Popen.popen(cmd).last.zero?
end
def force_utf8(str)
......
......@@ -19,16 +19,16 @@ describe TimeHelper do
describe "#duration_in_numbers" do
it "returns minutes and seconds" do
duration_in_numbers = {
[100, 0] => "01:40",
[121, 0] => "02:01",
[3721, 0] => "01:02:01",
[0, 0] => "00:00",
[nil, Time.now.to_i - 42] => "00:42"
durations_and_expectations = {
100 => "01:40",
121 => "02:01",
3721 => "01:02:01",
0 => "00:00",
42 => "00:42"
}
duration_in_numbers.each do |interval, expectation|
expect(duration_in_numbers(*interval)).to eq(expectation)
durations_and_expectations.each do |duration, expectation|
expect(duration_in_numbers(duration)).to eq(expectation)
end
end
end
......
require 'spec_helper'
describe BroadcastMessage, models: true do
include ActiveSupport::Testing::TimeHelpers
subject { create(:broadcast_message) }
it { is_expected.to be_valid }
......
......@@ -124,17 +124,21 @@ describe Ci::Pipeline, models: true do
describe 'state machine' do
let(:current) { Time.now.change(usec: 0) }
let(:build) { create :ci_build, name: 'build1', pipeline: pipeline, started_at: current - 60, finished_at: current }
let(:build2) { create :ci_build, name: 'build2', pipeline: pipeline, started_at: current - 60, finished_at: current }
let(:build) { create :ci_build, name: 'build1', pipeline: pipeline }
describe '#duration' do
before do
build.skip
build2.skip
travel_to(current - 120) do
pipeline.run
end
travel_to(current) do
pipeline.succeed
end
end
it 'matches sum of builds duration' do
expect(pipeline.reload.duration).to eq(build.duration + build2.duration)
expect(pipeline.reload.duration).to eq(120)
end
end
......
......@@ -33,6 +33,7 @@ RSpec.configure do |config|
config.include EmailHelpers
config.include TestEnv
config.include ActiveJob::TestHelper
config.include ActiveSupport::Testing::TimeHelpers
config.include StubGitlabCalls
config.include StubGitlabData
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment