-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Worker that is in charge of monitoring Travis for build_failures, and will create BuildFailure records and send messages to gitter as needed.
- Loading branch information
1 parent
69ceb27
commit 51670cf
Showing
2 changed files
with
163 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
require 'travis' | ||
|
||
class TravisBranchMonitor | ||
include Sidekiq::Worker | ||
sidekiq_options :queue => :miq_bot, :retry => false | ||
|
||
include Sidetiq::Schedulable | ||
recurrence { hourly.minute_of_hour(0, 15, 30, 45) } | ||
|
||
include SidekiqWorkerMixin | ||
|
||
class << self | ||
private | ||
|
||
# For this class, sometimes the repo needs to be mapped to a specific | ||
# gitter room, so a hash is required. | ||
# | ||
# This override allows for doing this in the config | ||
# | ||
# travis_branch_monitor: | ||
# included_repos: | ||
# ManageIQ/manageiq-ui-classic: ManageIQ/ui | ||
# ManageIQ/manageiq-gems-pending: ManageIQ/core | ||
# ManageIQ/manageiq: | ||
# ManageIQ/miq_bot: | ||
# | ||
# Which you are allowed to leave the value empty, and the key will be used | ||
# where appropriate (not used in this class). | ||
# | ||
# The result from the above for this method will then be: | ||
# | ||
# [ | ||
# [ | ||
# "ManageIQ/manageiq-ui-classic", | ||
# "ManageIQ/manageiq-gems-pending", | ||
# "ManageIQ/manageiq", | ||
# "ManageIQ/miq_bot" | ||
# ], | ||
# [] | ||
# ] | ||
# | ||
def included_and_excluded_repos | ||
super # just used for error handling... | ||
|
||
[ | ||
settings.included_repos.try(:to_h).try(:stringify_keys).try(:keys), | ||
settings.excluded_repos.try(:to_h).try(:stringify_keys).try(:keys) | ||
] | ||
end | ||
end | ||
|
||
def perform | ||
if !first_unique_worker? | ||
logger.info("#{self.class} is already running, skipping") | ||
else | ||
process_repos | ||
end | ||
end | ||
|
||
def process_repos | ||
enabled_repos.each do |repo| | ||
process_repo(repo) | ||
end | ||
end | ||
|
||
def process_repo(repo) | ||
repo.regular_branch_names.each do |branch_record| | ||
process_branch(repo, branch_record) | ||
end | ||
end | ||
|
||
def process_branch(repo, branch_record) | ||
# If we already have a failure record, call notify with that record | ||
return branch_record.notify_of_failure if branch_record.previously_failing? | ||
|
||
# otherwise, check if any builds exist with a failures, and if so, update | ||
# the branch_record to add the `travis_build_failure_id`. | ||
v3_client = TravisV3Client.new(:repo => Travis::Repository.find(repo.name)) | ||
branch_builds = v3_client.repo_branch_builds(branch_record.name) | ||
|
||
if branch_builds.first.failed? | ||
first_failure = find_first_recent_failure(branch_builds) | ||
branch_record.update(:travis_build_failure_id => first_failure.id) | ||
|
||
branch_record.notify_of_failure | ||
end | ||
end | ||
|
||
private | ||
|
||
def find_first_recent_failure(builds) | ||
builds.take_while(&:failed?).last | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
describe TravisBranchMonitor do | ||
include IncludedReposConfigMethods | ||
|
||
describe ".included_and_excluded_repos (private)" do | ||
it "builds the list from a hash of only keys" do | ||
stub_settings included_repos_keys_only | ||
expected = %w[ManageIQ/manageiq ManageIQ/miq_bot] | ||
|
||
expect(described_class.send(:included_and_excluded_repos)).to eq([expected, nil]) | ||
end | ||
|
||
it "builds the list from a hash of keys with values" do | ||
stub_settings included_repos_keys_and_values | ||
expected = %w[ManageIQ/manageiq-ui-classic ManageIQ/manageiq-gems-pending] | ||
|
||
expect(described_class.send(:included_and_excluded_repos)).to eq([expected, nil]) | ||
end | ||
|
||
it "builds the list from a mixed hash with keys and some values" do | ||
stub_settings included_repos_mixed_keys_with_some_values | ||
expected = %w[ | ||
ManageIQ/manageiq-ui-classic | ||
ManageIQ/manageiq-gems-pending | ||
ManageIQ/manageiq | ||
ManageIQ/miq_bot | ||
] | ||
|
||
expect(described_class.send(:included_and_excluded_repos)).to eq([expected, nil]) | ||
end | ||
end | ||
|
||
describe "#find_first_recent_failure (private)" do | ||
def passed(build_id) | ||
build = Travis::Client::Build.new(nil, build_id) | ||
allow(build).to receive(:inspect_info).and_return("Foo/foo##{build_id}") | ||
build.tap { |b| b.update_attributes(:state => "passed") } | ||
end | ||
|
||
def failed(build_id) | ||
build = Travis::Client::Build.new(nil, build_id) | ||
allow(build).to receive(:inspect_info).and_return("Foo/foo##{build_id}") | ||
build.tap { |b| b.update_attributes(:state => "failed") } | ||
end | ||
|
||
it "returns earliest failure" do | ||
earliest_failure = failed(2) | ||
builds = [ | ||
failed(4), | ||
failed(3), | ||
earliest_failure, | ||
passed(1) | ||
] | ||
|
||
expect(subject.send(:find_first_recent_failure, builds)).to eq(earliest_failure) | ||
end | ||
|
||
it "returns nil if the first build has passed" do | ||
builds = [ | ||
passed(5), | ||
failed(4), | ||
failed(3), | ||
failed(2), | ||
passed(1) | ||
] | ||
|
||
expect(subject.send(:find_first_recent_failure, builds)).to eq(nil) | ||
end | ||
end | ||
end |