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
d65c816e
Commit
d65c816e
authored
Mar 31, 2017
by
Shinya Maeda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Brush up
parent
9573bb44
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
80 additions
and
59 deletions
+80
-59
app/models/ci/trigger_schedule.rb
app/models/ci/trigger_schedule.rb
+14
-7
app/workers/trigger_schedule_worker.rb
app/workers/trigger_schedule_worker.rb
+3
-0
lib/ci/cron_parser.rb
lib/ci/cron_parser.rb
+6
-3
spec/factories/ci/trigger_schedules.rb
spec/factories/ci/trigger_schedules.rb
+6
-3
spec/factories/ci/triggers.rb
spec/factories/ci/triggers.rb
+3
-1
spec/lib/ci/cron_parser_spec.rb
spec/lib/ci/cron_parser_spec.rb
+18
-20
spec/models/ci/trigger_schedule_spec.rb
spec/models/ci/trigger_schedule_spec.rb
+19
-12
spec/workers/trigger_schedule_worker_spec.rb
spec/workers/trigger_schedule_worker_spec.rb
+11
-13
No files found.
app/models/ci/trigger_schedule.rb
View file @
d65c816e
...
@@ -18,20 +18,22 @@ module Ci
...
@@ -18,20 +18,22 @@ module Ci
after_create
:schedule_next_run!
after_create
:schedule_next_run!
def
schedule_next_run!
def
schedule_next_run!
puts
"cron:
#{
cron
.
inspect
}
| cron_time_zone:
#{
cron_time_zone
.
inspect
}
"
# puts "cron: #{cron.inspect} | cron_time_zone: #{cron_time_zone.inspect}"
next_time
=
Ci
::
CronParser
.
new
(
cron
,
cron_time_zone
).
next_time_from_now
next_time
=
Ci
::
CronParser
.
new
(
cron
,
cron_time_zone
).
next_time_from
(
Time
.
now
)
if
next_time
.
present?
if
next_time
.
present?
&&
!
less_than_1_hour_from_now?
(
next_time
)
update!
(
next_run_at:
next_time
)
update!
(
next_run_at:
next_time
)
end
end
end
end
def
real_next_run
(
worker_cron:
nil
,
worker_time_zone:
nil
)
def
real_next_run
(
worker_cron:
nil
,
worker_time_zone:
nil
)
puts
"worker_cron:
#{
worker_cron
.
inspect
}
| worker_time_zone:
#{
worker_time_zone
.
inspect
}
"
worker_cron
=
Settings
.
cron_jobs
[
'trigger_schedule_worker'
][
'cron'
]
unless
worker_cron
.
present?
worker_cron
=
Settings
.
cron_jobs
[
'trigger_schedule_worker'
][
'cron'
]
unless
worker_cron
.
present?
worker_time_zone
=
Time
.
zone
.
name
unless
worker_time_zone
.
present?
worker_time_zone
=
Time
.
zone
.
name
unless
worker_time_zone
.
present?
worker_next_time
=
Ci
::
CronParser
.
new
(
worker_cron
,
worker_time_zone
).
next_time_from_now
# puts "real_next_run: worker_cron: #{worker_cron.inspect} | worker_time_zone: #{worker_time_zone.inspect}"
worker_next_time
=
Ci
::
CronParser
.
new
(
worker_cron
,
worker_time_zone
).
next_time_from
(
Time
.
now
)
puts
"
next_run_at:
#{
next_run_at
.
inspect
}
| worker_next_time:
#{
worker_next_time
.
inspect
}
"
# puts "real_next_run:
next_run_at: #{next_run_at.inspect} | worker_next_time: #{worker_next_time.inspect}"
if
next_run_at
>
worker_next_time
if
next_run_at
>
worker_next_time
next_run_at
next_run_at
else
else
...
@@ -41,15 +43,20 @@ module Ci
...
@@ -41,15 +43,20 @@ module Ci
private
private
def
less_than_1_hour_from_now?
(
time
)
((
time
-
Time
.
now
).
abs
<
1
.
hour
)
?
true
:
false
end
def
check_cron
def
check_cron
cron_parser
=
Ci
::
CronParser
.
new
(
cron
,
cron_time_zone
)
cron_parser
=
Ci
::
CronParser
.
new
(
cron
,
cron_time_zone
)
is_valid_cron
,
is_valid_cron_time_zone
=
cron_parser
.
validation
is_valid_cron
,
is_valid_cron_time_zone
=
cron_parser
.
validation
next_time
=
cron_parser
.
next_time_from
(
Time
.
now
)
if
!
is_valid_cron
if
!
is_valid_cron
self
.
errors
.
add
(
:cron
,
" is invalid syntax"
)
self
.
errors
.
add
(
:cron
,
" is invalid syntax"
)
elsif
!
is_valid_cron_time_zone
elsif
!
is_valid_cron_time_zone
self
.
errors
.
add
(
:cron_time_zone
,
" is invalid timezone"
)
self
.
errors
.
add
(
:cron_time_zone
,
" is invalid timezone"
)
elsif
(
cron_parser
.
next_time_from_now
-
Time
.
now
).
abs
<
1
.
hour
elsif
less_than_1_hour_from_now?
(
next_time
)
self
.
errors
.
add
(
:cron
,
" can not be less than 1 hour"
)
self
.
errors
.
add
(
:cron
,
" can not be less than 1 hour"
)
end
end
end
end
...
...
app/workers/trigger_schedule_worker.rb
View file @
d65c816e
...
@@ -4,11 +4,14 @@ class TriggerScheduleWorker
...
@@ -4,11 +4,14 @@ class TriggerScheduleWorker
def
perform
def
perform
Ci
::
TriggerSchedule
.
where
(
"next_run_at < ?"
,
Time
.
now
).
find_each
do
|
trigger_schedule
|
Ci
::
TriggerSchedule
.
where
(
"next_run_at < ?"
,
Time
.
now
).
find_each
do
|
trigger_schedule
|
next
if
Ci
::
Pipeline
.
where
(
project:
trigger_schedule
.
project
,
ref:
trigger_schedule
.
ref
).
running_or_pending
.
count
>
0
begin
begin
Ci
::
CreateTriggerRequestService
.
new
.
execute
(
trigger_schedule
.
project
,
Ci
::
CreateTriggerRequestService
.
new
.
execute
(
trigger_schedule
.
project
,
trigger_schedule
.
trigger
,
trigger_schedule
.
trigger
,
trigger_schedule
.
ref
)
trigger_schedule
.
ref
)
rescue
=>
e
rescue
=>
e
puts
"
#{
trigger_schedule
.
id
}
: Failed to trigger_schedule job:
#{
e
.
message
}
"
# TODO: Remove before merge
Rails
.
logger
.
error
"
#{
trigger_schedule
.
id
}
: Failed to trigger_schedule job:
#{
e
.
message
}
"
Rails
.
logger
.
error
"
#{
trigger_schedule
.
id
}
: Failed to trigger_schedule job:
#{
e
.
message
}
"
ensure
ensure
trigger_schedule
.
schedule_next_run!
trigger_schedule
.
schedule_next_run!
...
...
lib/ci/cron_parser.rb
View file @
d65c816e
...
@@ -8,10 +8,13 @@ module Ci
...
@@ -8,10 +8,13 @@ module Ci
@cron_time_zone
=
cron_time_zone
@cron_time_zone
=
cron_time_zone
end
end
def
next_time_from
_now
def
next_time_from
(
time
)
cronLine
=
try_parse_cron
(
@cron
,
@cron_time_zone
)
cronLine
=
try_parse_cron
(
@cron
,
@cron_time_zone
)
return
nil
unless
cronLine
.
present?
if
cronLine
.
present?
cronLine
.
next_time
cronLine
.
next_time
(
time
)
else
nil
end
end
end
def
validation
def
validation
...
...
spec/factories/ci/trigger_schedules.rb
View file @
d65c816e
FactoryGirl
.
define
do
FactoryGirl
.
define
do
factory
:ci_trigger_schedule
,
class:
Ci
::
TriggerSchedule
do
factory
:ci_trigger_schedule
,
class:
Ci
::
TriggerSchedule
do
project
factory: :project
trigger
factory: :ci_trigger_for_trigger_schedule
trigger
factory: :ci_trigger_with_ref
after
(
:build
)
do
|
trigger_schedule
,
evaluator
|
trigger_schedule
.
update!
(
project:
trigger_schedule
.
trigger
.
project
)
end
trait
:force_triggable
do
trait
:force_triggable
do
after
(
:create
)
do
|
trigger_schedule
,
evaluator
|
after
(
:create
)
do
|
trigger_schedule
,
evaluator
|
trigger_schedule
.
next_run_at
-=
1
.
month
trigger_schedule
.
update!
(
next_run_at:
trigger_schedule
.
next_run_at
-
1
.
year
)
end
end
end
end
...
...
spec/factories/ci/triggers.rb
View file @
d65c816e
...
@@ -3,7 +3,9 @@ FactoryGirl.define do
...
@@ -3,7 +3,9 @@ FactoryGirl.define do
factory
:ci_trigger
do
factory
:ci_trigger
do
token
{
SecureRandom
.
hex
(
15
)
}
token
{
SecureRandom
.
hex
(
15
)
}
factory
:ci_trigger_with_ref
do
factory
:ci_trigger_for_trigger_schedule
do
owner
factory: :user
project
factory: :project
ref
'master'
ref
'master'
end
end
end
end
...
...
spec/lib/ci/cron_parser_spec.rb
View file @
d65c816e
...
@@ -2,8 +2,8 @@ require 'spec_helper'
...
@@ -2,8 +2,8 @@ require 'spec_helper'
module
Ci
module
Ci
describe
CronParser
,
lib:
true
do
describe
CronParser
,
lib:
true
do
describe
'#next_time_from
_now
'
do
describe
'#next_time_from'
do
subject
{
described_class
.
new
(
cron
,
cron_time_zone
).
next_time_from
_now
}
subject
{
described_class
.
new
(
cron
,
cron_time_zone
).
next_time_from
(
Time
.
now
)
}
context
'when cron and cron_time_zone are valid'
do
context
'when cron and cron_time_zone are valid'
do
context
'when specific time'
do
context
'when specific time'
do
...
@@ -65,8 +65,8 @@ module Ci
...
@@ -65,8 +65,8 @@ module Ci
end
end
context
'when cron and cron_time_zone are invalid'
do
context
'when cron and cron_time_zone are invalid'
do
let
(
:cron
)
{
'
hack
'
}
let
(
:cron
)
{
'
invalid_cron
'
}
let
(
:cron_time_zone
)
{
'
hack
'
}
let
(
:cron_time_zone
)
{
'
invalid_cron_time_zone
'
}
it
'returns nil'
do
it
'returns nil'
do
is_expected
.
to
be_nil
is_expected
.
to
be_nil
...
@@ -74,25 +74,23 @@ module Ci
...
@@ -74,25 +74,23 @@ module Ci
end
end
end
end
describe
'#valid_syntax?'
do
describe
'#validation'
do
subject
{
described_class
.
new
(
cron
,
cron_time_zone
).
valid_syntax?
}
it
'returns results'
do
is_valid_cron
,
is_valid_cron_time_zone
=
described_class
.
new
(
'* * * * *'
,
'Europe/Istanbul'
).
validation
context
'when cron and cron_time_zone are valid'
do
expect
(
is_valid_cron
).
to
eq
(
true
)
let
(
:cron
)
{
'* * * * *'
}
expect
(
is_valid_cron_time_zone
).
to
eq
(
true
)
let
(
:cron_time_zone
)
{
'Europe/Istanbul'
}
it
'returns true'
do
is_expected
.
to
eq
(
true
)
end
end
end
context
'when cron and cron_time_zone are invalid'
do
it
'returns results'
do
let
(
:cron
)
{
'hack'
}
is_valid_cron
,
is_valid_cron_time_zone
=
described_class
.
new
(
'*********'
,
'Europe/Istanbul'
).
validation
let
(
:cron_time_zone
)
{
'hack'
}
expect
(
is_valid_cron
).
to
eq
(
false
)
expect
(
is_valid_cron_time_zone
).
to
eq
(
true
)
end
it
'returns false'
do
it
'returns results'
do
is_expected
.
to
eq
(
false
)
is_valid_cron
,
is_valid_cron_time_zone
=
described_class
.
new
(
'* * * * *'
,
'Invalid-zone'
).
validation
end
expect
(
is_valid_cron
).
to
eq
(
true
)
expect
(
is_valid_cron_time_zone
).
to
eq
(
false
)
end
end
end
end
end
end
...
...
spec/models/ci/trigger_schedule_spec.rb
View file @
d65c816e
require
'spec_helper'
require
'spec_helper'
describe
Ci
::
TriggerSchedule
,
models:
true
do
describe
Ci
::
TriggerSchedule
,
models:
true
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:trigger
)
{
create
(
:ci_trigger
,
owner:
user
,
project:
project
,
ref:
'master'
)
}
it
{
is_expected
.
to
belong_to
(
:project
)
}
it
{
is_expected
.
to
belong_to
(
:project
)
}
it
{
is_expected
.
to
belong_to
(
:trigger
)
}
it
{
is_expected
.
to
belong_to
(
:trigger
)
}
...
@@ -11,17 +8,27 @@ describe Ci::TriggerSchedule, models: true do
...
@@ -11,17 +8,27 @@ describe Ci::TriggerSchedule, models: true do
# it { is_expected.to validate_presence_of :cron_time_zone }
# it { is_expected.to validate_presence_of :cron_time_zone }
it
{
is_expected
.
to
respond_to
:ref
}
it
{
is_expected
.
to
respond_to
:ref
}
# describe '#schedule_next_run!' do
it
'should validate less_than_1_hour_from_now'
do
# let(:trigger_schedule) { create(:ci_trigger_schedule, :cron_nightly_build, next_run_at: nil, trigger: trigger) }
trigger_schedule
=
create
(
:ci_trigger_schedule
,
:cron_nightly_build
)
trigger_schedule
.
cron
=
'* * * * *'
trigger_schedule
.
valid?
expect
(
trigger_schedule
.
errors
[
:cron
].
first
).
to
include
(
'can not be less than 1 hour'
)
end
describe
'#schedule_next_run!'
do
context
'when more_than_1_hour_from_now'
do
let
(
:trigger_schedule
)
{
create
(
:ci_trigger_schedule
,
:cron_nightly_build
)
}
#
before do
before
do
#
trigger_schedule.schedule_next_run!
trigger_schedule
.
schedule_next_run!
#
end
end
# it 'updates next_run_at' do
it
'updates next_run_at'
do
# expect(Ci::TriggerSchedule.last.next_run_at).not_to be_nil
next_time
=
Ci
::
CronParser
.
new
(
trigger_schedule
.
cron
,
trigger_schedule
.
cron_time_zone
).
next_time_from
(
Time
.
now
)
# end
expect
(
Ci
::
TriggerSchedule
.
last
.
next_run_at
).
to
eq
(
next_time
)
# end
end
end
end
describe
'#real_next_run'
do
describe
'#real_next_run'
do
subject
{
trigger_schedule
.
real_next_run
(
worker_cron:
worker_cron
,
worker_time_zone:
worker_time_zone
)
}
subject
{
trigger_schedule
.
real_next_run
(
worker_cron:
worker_cron
,
worker_time_zone:
worker_time_zone
)
}
...
...
spec/workers/trigger_schedule_worker_spec.rb
View file @
d65c816e
...
@@ -8,38 +8,36 @@ describe TriggerScheduleWorker do
...
@@ -8,38 +8,36 @@ describe TriggerScheduleWorker do
end
end
context
'when there is a scheduled trigger within next_run_at'
do
context
'when there is a scheduled trigger within next_run_at'
do
let
(
:user
)
{
create
(
:user
)
}
let!
(
:trigger_schedule
)
{
create
(
:ci_trigger_schedule
,
:cron_nightly_build
,
:force_triggable
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:trigger
)
{
create
(
:ci_trigger
,
owner:
user
,
project:
project
,
ref:
'master'
)
}
let!
(
:trigger_schedule
)
{
create
(
:ci_trigger_schedule
,
:cron_nightly_build
,
:force_triggable
,
trigger:
trigger
,
project:
project
)
}
before
do
before
do
worker
.
perform
worker
.
perform
end
end
it
'creates a new trigger request'
do
it
'creates a new trigger request'
do
expect
(
Ci
::
TriggerRequest
.
first
.
trigger_id
).
to
eq
(
trigger
.
id
)
expect
(
trigger_schedule
.
trigger
.
id
).
to
eq
(
Ci
::
TriggerRequest
.
first
.
trigger_
id
)
end
end
it
'creates a new pipeline'
do
it
'creates a new pipeline'
do
expect
(
Ci
::
Pipeline
.
last
.
status
).
to
eq
(
'pending'
)
expect
(
Ci
::
Pipeline
.
last
.
status
).
to
eq
(
'pending'
)
end
end
it
'
schedul
es next_run_at'
do
it
'
updat
es next_run_at'
do
next_time
=
Ci
::
CronParser
.
new
(
'0 1 * * *'
,
'Europe/Istanbul'
).
next_time_from_now
next_time
=
Ci
::
CronParser
.
new
(
trigger_schedule
.
cron
,
trigger_schedule
.
cron_time_zone
).
next_time_from
(
Time
.
now
)
expect
(
Ci
::
TriggerSchedule
.
last
.
next_run_at
).
to
eq
(
next_time
)
expect
(
Ci
::
TriggerSchedule
.
last
.
next_run_at
).
to
eq
(
next_time
)
end
end
end
end
context
'when there
are no scheduled triggers within next_run_at
'
do
context
'when there
is a scheduled trigger within next_run_at and a runnign pipeline
'
do
let!
(
:trigger_schedule
)
{
create
(
:ci_trigger_schedule
,
:cron_nightly_build
)
}
let!
(
:trigger_schedule
)
{
create
(
:ci_trigger_schedule
,
:cron_nightly_build
,
:force_triggable
)
}
before
do
before
do
create
(
:ci_pipeline
,
project:
trigger_schedule
.
project
,
ref:
trigger_schedule
.
ref
,
status:
'running'
)
worker
.
perform
worker
.
perform
end
end
it
'do not create a new pipeline'
do
it
'do not create a new pipeline'
do
expect
(
Ci
::
Pipeline
.
all
).
to
be_empty
expect
(
Ci
::
Pipeline
.
count
).
to
eq
(
1
)
end
end
it
'do not reschedule next_run_at'
do
it
'do not reschedule next_run_at'
do
...
@@ -47,15 +45,15 @@ describe TriggerScheduleWorker do
...
@@ -47,15 +45,15 @@ describe TriggerScheduleWorker do
end
end
end
end
context
'when
next_run_at is nil
'
do
context
'when
there are no scheduled triggers within next_run_at
'
do
let!
(
:trigger_schedule
)
{
create
(
:ci_trigger_schedule
,
:cron_nightly_build
,
next_run_at:
nil
)
}
let!
(
:trigger_schedule
)
{
create
(
:ci_trigger_schedule
,
:cron_nightly_build
)
}
before
do
before
do
worker
.
perform
worker
.
perform
end
end
it
'do not create a new pipeline'
do
it
'do not create a new pipeline'
do
expect
(
Ci
::
Pipeline
.
all
).
to
be_empty
expect
(
Ci
::
Pipeline
.
count
).
to
eq
(
0
)
end
end
it
'do not reschedule next_run_at'
do
it
'do not reschedule next_run_at'
do
...
...
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