Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
gitlab-ce
Commits
69ecd951
Commit
69ecd951
authored
Dec 01, 2016
by
James Lopez
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor fetcher and fixed specs
parent
b8056669
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
49 additions
and
67 deletions
+49
-67
app/controllers/projects/cycle_analytics/events_controller.rb
...controllers/projects/cycle_analytics/events_controller.rb
+1
-1
lib/gitlab/cycle_analytics/base_event.rb
lib/gitlab/cycle_analytics/base_event.rb
+2
-2
lib/gitlab/cycle_analytics/events_query.rb
lib/gitlab/cycle_analytics/events_query.rb
+0
-32
lib/gitlab/cycle_analytics/metrics_fetcher.rb
lib/gitlab/cycle_analytics/metrics_fetcher.rb
+15
-0
lib/gitlab/database/median.rb
lib/gitlab/database/median.rb
+5
-0
spec/models/cycle_analytics/code_spec.rb
spec/models/cycle_analytics/code_spec.rb
+3
-3
spec/models/cycle_analytics/issue_spec.rb
spec/models/cycle_analytics/issue_spec.rb
+2
-2
spec/models/cycle_analytics/plan_spec.rb
spec/models/cycle_analytics/plan_spec.rb
+2
-2
spec/models/cycle_analytics/production_spec.rb
spec/models/cycle_analytics/production_spec.rb
+3
-3
spec/models/cycle_analytics/review_spec.rb
spec/models/cycle_analytics/review_spec.rb
+2
-2
spec/models/cycle_analytics/staging_spec.rb
spec/models/cycle_analytics/staging_spec.rb
+3
-3
spec/models/cycle_analytics/test_spec.rb
spec/models/cycle_analytics/test_spec.rb
+5
-5
spec/support/cycle_analytics_helpers/test_generation.rb
spec/support/cycle_analytics_helpers/test_generation.rb
+6
-12
No files found.
app/controllers/projects/cycle_analytics/events_controller.rb
View file @
69ecd951
...
@@ -48,7 +48,7 @@ module Projects
...
@@ -48,7 +48,7 @@ module Projects
end
end
def
cycle_analytics
def
cycle_analytics
@cycle_analytics
||=
::
CycleAnalytics
.
new
(
project
,
options
:
options
(
events_params
))
@cycle_analytics
||=
::
CycleAnalytics
.
new
(
project
,
options
(
events_params
))
end
end
def
events_params
def
events_params
...
...
lib/gitlab/cycle_analytics/base_event.rb
View file @
69ecd951
...
@@ -7,7 +7,7 @@ module Gitlab
...
@@ -7,7 +7,7 @@ module Gitlab
attr_reader
:start_time_attrs
,
:end_time_attrs
,
:projections
,
:query
attr_reader
:start_time_attrs
,
:end_time_attrs
,
:projections
,
:query
def
initialize
(
fetcher
:,
options
:)
def
initialize
(
fetcher
:,
options
:)
@
query
=
EventsQuery
.
new
(
fetcher:
fetcher
)
@
fetcher
=
fetcher
@project
=
fetcher
.
project
@project
=
fetcher
.
project
@options
=
options
@options
=
options
end
end
...
@@ -39,7 +39,7 @@ module Gitlab
...
@@ -39,7 +39,7 @@ module Gitlab
end
end
def
event_result
def
event_result
@event_result
||=
@
query
.
execute
(
self
).
to_a
@event_result
||=
@
fetcher
.
events
(
self
).
to_a
end
end
def
serialize
(
_event
)
def
serialize
(
_event
)
...
...
lib/gitlab/cycle_analytics/events_query.rb
deleted
100644 → 0
View file @
b8056669
module
Gitlab
module
CycleAnalytics
class
EventsQuery
def
initialize
(
fetcher
:)
@fetcher
=
fetcher
end
def
execute
(
stage_class
)
@stage_class
=
stage_class
ActiveRecord
::
Base
.
connection
.
exec_query
(
query
.
to_sql
)
end
private
def
query
base_query
=
@fetcher
.
base_query_for
(
@stage_class
.
stage
)
diff_fn
=
@fetcher
.
subtract_datetimes_diff
(
base_query
,
@stage_class
.
start_time_attrs
,
@stage_class
.
end_time_attrs
)
@stage_class
.
custom_query
(
base_query
)
base_query
.
project
(
extract_epoch
(
diff_fn
).
as
(
'total_time'
),
*
@stage_class
.
projections
).
order
(
@stage_class
.
order
.
desc
)
end
def
extract_epoch
(
arel_attribute
)
return
arel_attribute
unless
Gitlab
::
Database
.
postgresql?
Arel
.
sql
(
%Q{EXTRACT(EPOCH FROM (
#{
arel_attribute
.
to_sql
}
))}
)
end
end
end
end
lib/gitlab/cycle_analytics/metrics_fetcher.rb
View file @
69ecd951
...
@@ -29,6 +29,21 @@ module Gitlab
...
@@ -29,6 +29,21 @@ module Gitlab
median_datetime
(
cte_table
,
interval_query
,
name
)
median_datetime
(
cte_table
,
interval_query
,
name
)
end
end
def
events
(
stage_class
)
ActiveRecord
::
Base
.
connection
.
exec_query
(
events_query
(
stage_class
).
to_sql
)
end
private
def
events_query
(
stage_class
)
base_query
=
base_query_for
(
stage_class
.
stage
)
diff_fn
=
subtract_datetimes_diff
(
base_query
,
stage_class
.
start_time_attrs
,
stage_class
.
end_time_attrs
)
stage_class
.
custom_query
(
base_query
)
base_query
.
project
(
extract_diff_epoch
(
diff_fn
).
as
(
'total_time'
),
*
stage_class
.
projections
).
order
(
stage_class
.
order
.
desc
)
end
# Join table with a row for every <issue,merge_request> pair (where the merge request
# Join table with a row for every <issue,merge_request> pair (where the merge request
# closes the given issue) with issue and merge request metrics included. The metrics
# closes the given issue) with issue and merge request metrics included. The metrics
# are loaded with an inner join, so issues / merge requests without metrics are
# are loaded with an inner join, so issues / merge requests without metrics are
...
...
lib/gitlab/database/median.rb
View file @
69ecd951
...
@@ -103,6 +103,11 @@ module Gitlab
...
@@ -103,6 +103,11 @@ module Gitlab
Arel
.
sql
(
%Q{EXTRACT(EPOCH FROM "
#{
arel_attribute
.
relation
.
name
}
"."
#{
arel_attribute
.
name
}
")}
)
Arel
.
sql
(
%Q{EXTRACT(EPOCH FROM "
#{
arel_attribute
.
relation
.
name
}
"."
#{
arel_attribute
.
name
}
")}
)
end
end
def
extract_diff_epoch
(
diff
)
return
diff
unless
Gitlab
::
Database
.
postgresql?
Arel
.
sql
(
%Q{EXTRACT(EPOCH FROM (
#{
diff
.
to_sql
}
))}
)
end
# Need to cast '0' to an INTERVAL before we can check if the interval is positive
# Need to cast '0' to an INTERVAL before we can check if the interval is positive
def
zero_interval
def
zero_interval
Arel
::
Nodes
::
NamedFunction
.
new
(
"CAST"
,
[
Arel
.
sql
(
"'0' AS INTERVAL"
)])
Arel
::
Nodes
::
NamedFunction
.
new
(
"CAST"
,
[
Arel
.
sql
(
"'0' AS INTERVAL"
)])
...
...
spec/models/cycle_analytics/code_spec.rb
View file @
69ecd951
...
@@ -6,7 +6,7 @@ describe 'CycleAnalytics#code', feature: true do
...
@@ -6,7 +6,7 @@ describe 'CycleAnalytics#code', feature: true do
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:from_date
)
{
10
.
days
.
ago
}
let
(
:from_date
)
{
10
.
days
.
ago
}
let
(
:user
)
{
create
(
:user
,
:admin
)
}
let
(
:user
)
{
create
(
:user
,
:admin
)
}
subject
{
CycleAnalytics
Test
.
new
(
project
,
options:
{
from:
from_date
}
)
}
subject
{
CycleAnalytics
.
new
(
project
,
from:
from_date
)
}
context
'with deployment'
do
context
'with deployment'
do
generate_cycle_analytics_spec
(
generate_cycle_analytics_spec
(
...
@@ -37,7 +37,7 @@ describe 'CycleAnalytics#code', feature: true do
...
@@ -37,7 +37,7 @@ describe 'CycleAnalytics#code', feature: true do
deploy_master
deploy_master
end
end
expect
(
subject
.
code
).
to
be_nil
expect
(
subject
[
:code
].
median
).
to
be_nil
end
end
end
end
end
end
...
@@ -69,7 +69,7 @@ describe 'CycleAnalytics#code', feature: true do
...
@@ -69,7 +69,7 @@ describe 'CycleAnalytics#code', feature: true do
merge_merge_requests_closing_issue
(
issue
)
merge_merge_requests_closing_issue
(
issue
)
end
end
expect
(
subject
.
code
).
to
be_nil
expect
(
subject
[
:code
].
median
).
to
be_nil
end
end
end
end
end
end
...
...
spec/models/cycle_analytics/issue_spec.rb
View file @
69ecd951
...
@@ -6,7 +6,7 @@ describe 'CycleAnalytics#issue', models: true do
...
@@ -6,7 +6,7 @@ describe 'CycleAnalytics#issue', models: true do
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:from_date
)
{
10
.
days
.
ago
}
let
(
:from_date
)
{
10
.
days
.
ago
}
let
(
:user
)
{
create
(
:user
,
:admin
)
}
let
(
:user
)
{
create
(
:user
,
:admin
)
}
subject
{
CycleAnalytics
Test
.
new
(
project
,
options:
{
from:
from_date
}
)
}
subject
{
CycleAnalytics
.
new
(
project
,
from:
from_date
)
}
generate_cycle_analytics_spec
(
generate_cycle_analytics_spec
(
phase: :issue
,
phase: :issue
,
...
@@ -42,7 +42,7 @@ describe 'CycleAnalytics#issue', models: true do
...
@@ -42,7 +42,7 @@ describe 'CycleAnalytics#issue', models: true do
merge_merge_requests_closing_issue
(
issue
)
merge_merge_requests_closing_issue
(
issue
)
end
end
expect
(
subject
.
issue
).
to
be_nil
expect
(
subject
[
:issue
].
median
).
to
be_nil
end
end
end
end
end
end
spec/models/cycle_analytics/plan_spec.rb
View file @
69ecd951
...
@@ -6,7 +6,7 @@ describe 'CycleAnalytics#plan', feature: true do
...
@@ -6,7 +6,7 @@ describe 'CycleAnalytics#plan', feature: true do
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:from_date
)
{
10
.
days
.
ago
}
let
(
:from_date
)
{
10
.
days
.
ago
}
let
(
:user
)
{
create
(
:user
,
:admin
)
}
let
(
:user
)
{
create
(
:user
,
:admin
)
}
subject
{
CycleAnalytics
Test
.
new
(
project
,
options:
{
from:
from_date
}
)
}
subject
{
CycleAnalytics
.
new
(
project
,
from:
from_date
)
}
generate_cycle_analytics_spec
(
generate_cycle_analytics_spec
(
phase: :plan
,
phase: :plan
,
...
@@ -44,7 +44,7 @@ describe 'CycleAnalytics#plan', feature: true do
...
@@ -44,7 +44,7 @@ describe 'CycleAnalytics#plan', feature: true do
create_merge_request_closing_issue
(
issue
,
source_branch:
branch_name
)
create_merge_request_closing_issue
(
issue
,
source_branch:
branch_name
)
merge_merge_requests_closing_issue
(
issue
)
merge_merge_requests_closing_issue
(
issue
)
expect
(
subject
.
issue
).
to
be_nil
expect
(
subject
[
:issue
].
median
).
to
be_nil
end
end
end
end
end
end
spec/models/cycle_analytics/production_spec.rb
View file @
69ecd951
...
@@ -6,7 +6,7 @@ describe 'CycleAnalytics#production', feature: true do
...
@@ -6,7 +6,7 @@ describe 'CycleAnalytics#production', feature: true do
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:from_date
)
{
10
.
days
.
ago
}
let
(
:from_date
)
{
10
.
days
.
ago
}
let
(
:user
)
{
create
(
:user
,
:admin
)
}
let
(
:user
)
{
create
(
:user
,
:admin
)
}
subject
{
CycleAnalytics
Test
.
new
(
project
,
options:
{
from:
from_date
}
)
}
subject
{
CycleAnalytics
.
new
(
project
,
from:
from_date
)
}
generate_cycle_analytics_spec
(
generate_cycle_analytics_spec
(
phase: :production
,
phase: :production
,
...
@@ -35,7 +35,7 @@ describe 'CycleAnalytics#production', feature: true do
...
@@ -35,7 +35,7 @@ describe 'CycleAnalytics#production', feature: true do
deploy_master
deploy_master
end
end
expect
(
subject
.
productio
n
).
to
be_nil
expect
(
subject
[
:production
].
media
n
).
to
be_nil
end
end
end
end
...
@@ -48,7 +48,7 @@ describe 'CycleAnalytics#production', feature: true do
...
@@ -48,7 +48,7 @@ describe 'CycleAnalytics#production', feature: true do
deploy_master
(
environment:
'staging'
)
deploy_master
(
environment:
'staging'
)
end
end
expect
(
subject
.
productio
n
).
to
be_nil
expect
(
subject
[
:production
].
media
n
).
to
be_nil
end
end
end
end
end
end
spec/models/cycle_analytics/review_spec.rb
View file @
69ecd951
...
@@ -6,7 +6,7 @@ describe 'CycleAnalytics#review', feature: true do
...
@@ -6,7 +6,7 @@ describe 'CycleAnalytics#review', feature: true do
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:from_date
)
{
10
.
days
.
ago
}
let
(
:from_date
)
{
10
.
days
.
ago
}
let
(
:user
)
{
create
(
:user
,
:admin
)
}
let
(
:user
)
{
create
(
:user
,
:admin
)
}
subject
{
CycleAnalytics
Test
.
new
(
project
,
options:
{
from:
from_date
}
)
}
subject
{
CycleAnalytics
.
new
(
project
,
from:
from_date
)
}
generate_cycle_analytics_spec
(
generate_cycle_analytics_spec
(
phase: :review
,
phase: :review
,
...
@@ -27,7 +27,7 @@ describe 'CycleAnalytics#review', feature: true do
...
@@ -27,7 +27,7 @@ describe 'CycleAnalytics#review', feature: true do
MergeRequests
::
MergeService
.
new
(
project
,
user
).
execute
(
create
(
:merge_request
))
MergeRequests
::
MergeService
.
new
(
project
,
user
).
execute
(
create
(
:merge_request
))
end
end
expect
(
subject
.
review
).
to
be_nil
expect
(
subject
[
:review
].
median
).
to
be_nil
end
end
end
end
end
end
spec/models/cycle_analytics/staging_spec.rb
View file @
69ecd951
...
@@ -6,7 +6,7 @@ describe 'CycleAnalytics#staging', feature: true do
...
@@ -6,7 +6,7 @@ describe 'CycleAnalytics#staging', feature: true do
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:from_date
)
{
10
.
days
.
ago
}
let
(
:from_date
)
{
10
.
days
.
ago
}
let
(
:user
)
{
create
(
:user
,
:admin
)
}
let
(
:user
)
{
create
(
:user
,
:admin
)
}
subject
{
CycleAnalytics
Test
.
new
(
project
,
options:
{
from:
from_date
}
)
}
subject
{
CycleAnalytics
.
new
(
project
,
from:
from_date
)
}
generate_cycle_analytics_spec
(
generate_cycle_analytics_spec
(
phase: :staging
,
phase: :staging
,
...
@@ -45,7 +45,7 @@ describe 'CycleAnalytics#staging', feature: true do
...
@@ -45,7 +45,7 @@ describe 'CycleAnalytics#staging', feature: true do
deploy_master
deploy_master
end
end
expect
(
subject
.
staging
).
to
be_nil
expect
(
subject
[
:staging
].
median
).
to
be_nil
end
end
end
end
...
@@ -58,7 +58,7 @@ describe 'CycleAnalytics#staging', feature: true do
...
@@ -58,7 +58,7 @@ describe 'CycleAnalytics#staging', feature: true do
deploy_master
(
environment:
'staging'
)
deploy_master
(
environment:
'staging'
)
end
end
expect
(
subject
.
staging
).
to
be_nil
expect
(
subject
[
:staging
].
median
).
to
be_nil
end
end
end
end
end
end
spec/models/cycle_analytics/test_spec.rb
View file @
69ecd951
...
@@ -6,7 +6,7 @@ describe 'CycleAnalytics#test', feature: true do
...
@@ -6,7 +6,7 @@ describe 'CycleAnalytics#test', feature: true do
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:from_date
)
{
10
.
days
.
ago
}
let
(
:from_date
)
{
10
.
days
.
ago
}
let
(
:user
)
{
create
(
:user
,
:admin
)
}
let
(
:user
)
{
create
(
:user
,
:admin
)
}
subject
{
CycleAnalytics
Test
.
new
(
project
,
options:
{
from:
from_date
}
)
}
subject
{
CycleAnalytics
.
new
(
project
,
from:
from_date
)
}
generate_cycle_analytics_spec
(
generate_cycle_analytics_spec
(
phase: :test
,
phase: :test
,
...
@@ -35,7 +35,7 @@ describe 'CycleAnalytics#test', feature: true do
...
@@ -35,7 +35,7 @@ describe 'CycleAnalytics#test', feature: true do
merge_merge_requests_closing_issue
(
issue
)
merge_merge_requests_closing_issue
(
issue
)
end
end
expect
(
subject
.
test
).
to
be_nil
expect
(
subject
[
:test
].
median
).
to
be_nil
end
end
end
end
...
@@ -48,7 +48,7 @@ describe 'CycleAnalytics#test', feature: true do
...
@@ -48,7 +48,7 @@ describe 'CycleAnalytics#test', feature: true do
pipeline
.
succeed!
pipeline
.
succeed!
end
end
expect
(
subject
.
test
).
to
be_nil
expect
(
subject
[
:test
].
median
).
to
be_nil
end
end
end
end
...
@@ -65,7 +65,7 @@ describe 'CycleAnalytics#test', feature: true do
...
@@ -65,7 +65,7 @@ describe 'CycleAnalytics#test', feature: true do
merge_merge_requests_closing_issue
(
issue
)
merge_merge_requests_closing_issue
(
issue
)
end
end
expect
(
subject
.
test
).
to
be_nil
expect
(
subject
[
:test
].
median
).
to
be_nil
end
end
end
end
...
@@ -82,7 +82,7 @@ describe 'CycleAnalytics#test', feature: true do
...
@@ -82,7 +82,7 @@ describe 'CycleAnalytics#test', feature: true do
merge_merge_requests_closing_issue
(
issue
)
merge_merge_requests_closing_issue
(
issue
)
end
end
expect
(
subject
.
test
).
to
be_nil
expect
(
subject
[
:test
].
median
).
to
be_nil
end
end
end
end
end
end
spec/support/cycle_analytics_helpers/test_generation.rb
View file @
69ecd951
class
CycleAnalyticsTest
<
CycleAnalytics
def
method_missing
(
method_sym
,
*
arguments
,
&
block
)
classify_stage
(
method_sym
).
new
(
project:
@project
,
options:
@options
,
stage:
method_sym
).
median
end
end
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/AbcSize
# Note: The ABC size is large here because we have a method generating test cases with
# Note: The ABC size is large here because we have a method generating test cases with
...
@@ -56,7 +50,7 @@ module CycleAnalyticsHelpers
...
@@ -56,7 +50,7 @@ module CycleAnalyticsHelpers
end
end
median_time_difference
=
time_differences
.
sort
[
2
]
median_time_difference
=
time_differences
.
sort
[
2
]
expect
(
subject
.
public_send
(
phase
)
).
to
be_within
(
5
).
of
(
median_time_difference
)
expect
(
subject
[
phase
].
median
).
to
be_within
(
5
).
of
(
median_time_difference
)
end
end
context
"when the data belongs to another project"
do
context
"when the data belongs to another project"
do
...
@@ -88,7 +82,7 @@ module CycleAnalyticsHelpers
...
@@ -88,7 +82,7 @@ module CycleAnalyticsHelpers
# Turn off the stub before checking assertions
# Turn off the stub before checking assertions
allow
(
self
).
to
receive
(
:project
).
and_call_original
allow
(
self
).
to
receive
(
:project
).
and_call_original
expect
(
subject
.
public_send
(
phase
)
).
to
be_nil
expect
(
subject
[
phase
].
median
).
to
be_nil
end
end
end
end
...
@@ -111,7 +105,7 @@ module CycleAnalyticsHelpers
...
@@ -111,7 +105,7 @@ module CycleAnalyticsHelpers
Timecop
.
freeze
(
end_time
+
1
.
day
)
{
post_fn
[
self
,
data
]
}
if
post_fn
Timecop
.
freeze
(
end_time
+
1
.
day
)
{
post_fn
[
self
,
data
]
}
if
post_fn
expect
(
subject
.
public_send
(
phase
)
).
to
be_nil
expect
(
subject
[
phase
].
median
).
to
be_nil
end
end
end
end
end
end
...
@@ -131,7 +125,7 @@ module CycleAnalyticsHelpers
...
@@ -131,7 +125,7 @@ module CycleAnalyticsHelpers
Timecop
.
freeze
(
end_time
+
1
.
day
)
{
post_fn
[
self
,
data
]
}
if
post_fn
Timecop
.
freeze
(
end_time
+
1
.
day
)
{
post_fn
[
self
,
data
]
}
if
post_fn
end
end
expect
(
subject
.
public_send
(
phase
)
).
to
be_nil
expect
(
subject
[
phase
].
median
).
to
be_nil
end
end
end
end
end
end
...
@@ -150,7 +144,7 @@ module CycleAnalyticsHelpers
...
@@ -150,7 +144,7 @@ module CycleAnalyticsHelpers
post_fn
[
self
,
data
]
if
post_fn
post_fn
[
self
,
data
]
if
post_fn
end
end
expect
(
subject
.
public_send
(
phase
)
).
to
be_nil
expect
(
subject
[
phase
].
median
).
to
be_nil
end
end
end
end
end
end
...
@@ -158,7 +152,7 @@ module CycleAnalyticsHelpers
...
@@ -158,7 +152,7 @@ module CycleAnalyticsHelpers
context
"when none of the start / end conditions are matched"
do
context
"when none of the start / end conditions are matched"
do
it
"returns nil"
do
it
"returns nil"
do
expect
(
subject
.
public_send
(
phase
)
).
to
be_nil
expect
(
subject
[
phase
].
median
).
to
be_nil
end
end
end
end
end
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment