Merge pull request #415 from abf/rosa-build:405-smart-build-scenarios-3

#405: Smart build scenarios 3
This commit is contained in:
avokhmin 2014-07-10 23:37:42 +04:00
commit 88a852b4c8
8 changed files with 161 additions and 4 deletions

View File

@ -0,0 +1,30 @@
class RunExtraMassBuildsJob
@queue = :low
def self.perform
RunExtraMassBuildsJob.new.perform
end
def perform
MassBuild.where(status: MassBuild::BUILD_PENDING).find_each do |mb|
next if mb.extra_mass_builds.blank?
emb = MassBuild.where(status: MassBuild::SUCCESS, id: mb.extra_mass_builds).to_a
next if emb.size != mb.extra_mass_builds.size
next if emb.find{ |mb| not_ready?(mb) }
mb.build_all
end
end
private
# Returns true if mass build has not published packages or packages without container
def not_ready?(mb)
mb.build_lists.count != mb.build_lists.where(
'status = ? OR container_status = ?',
BuildList::BUILD_PUBLISHED,
BuildList::BUILD_PUBLISHED
).count
end
end

View File

@ -15,7 +15,7 @@ class BuildList < ActiveRecord::Base
belongs_to :builder, class_name: 'User'
belongs_to :publisher, class_name: 'User'
belongs_to :advisory
belongs_to :mass_build, counter_cache: true, touch: true
belongs_to :mass_build, counter_cache: true
has_many :items, class_name: '::BuildList::Item', dependent: :destroy
has_many :packages, class_name: '::BuildList::Package', dependent: :destroy
has_many :source_packages, -> { where(package_type: 'source') }, class_name: '::BuildList::Package'
@ -172,7 +172,7 @@ class BuildList < ActiveRecord::Base
end
after_transition on: :published,
do: [:set_version_and_tag, :actualize_packages]
do: %i(set_version_and_tag actualize_packages)
after_transition on: :publish, do: :set_publisher
after_transition(on: :publish) do |build_list, transition|
if transition.from == BUILD_PUBLISHED_INTO_TESTING

View File

@ -2,6 +2,34 @@ class MassBuild < ActiveRecord::Base
AUTO_PUBLISH_STATUSES = %w(none default testing)
STATUSES, HUMAN_STATUSES = [], {}
[
%w(SUCCESS 0),
%w(BUILD_STARTED 3000),
%w(BUILD_PENDING 2000),
].each do |kind, value|
value = value.to_i
const_set kind, value
STATUSES << value
HUMAN_STATUSES[value] = kind.downcase.to_sym
end
STATUSES.freeze
HUMAN_STATUSES.freeze
state_machine :status, initial: :build_pending do
event :start do
transition build_pending: :build_started
end
event :done do
transition build_started: :success
end
HUMAN_STATUSES.each do |code,name|
state name, value: code
end
end
belongs_to :build_for_platform, -> { where(platform_type: 'main') }, class_name: 'Platform'
belongs_to :save_to_platform, class_name: 'Platform'
belongs_to :user
@ -43,7 +71,7 @@ class MassBuild < ActiveRecord::Base
:use_extra_tests,
inclusion: { in: [true, false] }
after_commit :build_all, on: :create
after_commit :build_all, on: :create, if: Proc.new { |mb| mb.extra_mass_builds.blank? }
before_validation :set_data, on: :create
COUNT_STATUSES = %i(
@ -58,6 +86,7 @@ class MassBuild < ActiveRecord::Base
)
def build_all
return unless start
# later with resque
arches_list = arch_names ? Arch.where(name: arch_names.split(', ')) : Arch.all
@ -82,6 +111,7 @@ class MassBuild < ActiveRecord::Base
update_column :missed_projects_list, list
end
end
done
end
later :build_all, queue: :low

View File

@ -26,6 +26,13 @@ clean_api_defender_statistics:
queue: low
description: 'Cleans ApiDefender statistics'
run_extra_mass_builds:
every:
- '5m'
class: 'RunExtraMassBuildsJob'
queue: low
description: 'Run mass builds with relations'
restart_nodes:
every:
- '5m'

View File

@ -0,0 +1,13 @@
class AddStatusToMassBuilds < ActiveRecord::Migration
def up
# Sets SUCCESS for all current builds
add_column :mass_builds, :status, :integer, null: false, default: 0 # SUCCESS
# Sets BUILD_PENDING for all new builds
change_column :mass_builds, :status, :integer, null: false, default: 2000 # BUILD_PENDING
end
def down
remove_column :mass_builds, :status
end
end

View File

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20140701172739) do
ActiveRecord::Schema.define(version: 20140709194335) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -331,6 +331,7 @@ ActiveRecord::Schema.define(version: 20140701172739) do
t.text "extra_mass_builds"
t.boolean "include_testing_subrepository", default: false, null: false
t.boolean "auto_create_container", default: false, null: false
t.integer "status", default: 2000, null: false
end
create_table "users", force: true do |t|

View File

@ -0,0 +1,49 @@
require 'spec_helper'
describe RunExtraMassBuildsJob do
let(:mass_build1) { FactoryGirl.build(:mass_build, id: 123) }
let(:mass_build2) { FactoryGirl.build(:mass_build, id: 234, extra_mass_builds: [mass_build1.id]) }
let(:build_list) { FactoryGirl.build(:build_list, id: 345, mass_build: mass_build) }
let(:job) { RunExtraMassBuildsJob.new }
before do
stub_symlink_methods
MassBuild.stub_chain(:where, :find_each).and_yield(mass_build2)
MassBuild.stub_chain(:where, :to_a).and_return([mass_build1])
allow(job).to receive(:not_ready?).with(mass_build1).and_return(false)
allow(mass_build2).to receive(:build_all)
end
it 'ensures that not raises error' do
expect do
job.perform
end.to_not raise_exception
end
it 'ensures that calls #build_all' do
expect(mass_build2).to receive(:build_all)
job.perform
end
it 'ensures that do nothing when no extra_mass_builds' do
mass_build2.extra_mass_builds = []
expect(mass_build2).to_not receive(:build_all)
job.perform
end
it 'ensures that do nothing when extra mass build not ready' do
allow(job).to receive(:not_ready?).with(mass_build1).and_return(true)
expect(mass_build2).to_not receive(:build_all)
job.perform
end
it 'ensures that do nothing when some extra mass builds have no status SUCCESS' do
mass_build0 = FactoryGirl.build(:mass_build, id: 1)
mass_build2.extra_mass_builds = [mass_build0, mass_build1]
MassBuild.stub_chain(:where, :to_a).and_return([mass_build1])
expect(mass_build2).to_not receive(:build_all)
job.perform
end
end

View File

@ -77,4 +77,31 @@ describe MassBuild do
mb.send(:publish, user, [])
end
it 'ensures that calls #build_all on create' do
mass_build = FactoryGirl.build(:mass_build)
expect(mass_build).to receive(:build_all)
mass_build.save
end
it 'ensures that does not call #build_all on create if attached extra mass builds' do
mass_build = FactoryGirl.build(:mass_build, extra_mass_builds: [1])
expect(mass_build).to_not receive(:build_all)
mass_build.save
end
context '#build_all' do
let(:mass_build) { FactoryGirl.create(:mass_build, extra_mass_builds: [1]) }
it 'ensures that do nothing when build has status build_started' do
mass_build.start
expect(mass_build).to_not receive(:projects_list)
mass_build.build_all
end
it 'ensures that works when build has status build_pending' do
expect(mass_build).to receive(:projects_list).at_least(:once)
mass_build.build_all
end
end
end