Merge branch 'master' into build_list_visibilities

This commit is contained in:
George Vinogradov 2011-12-15 03:29:22 +04:00
commit e3663381db
42 changed files with 491 additions and 140 deletions

2
.rspec
View File

@ -1 +1 @@
--colour --colour --format doc

24
Gemfile
View File

@ -28,6 +28,7 @@ gem 'grack', :git => 'git://github.com/rdblue/grack.git', :require => 'git_http'
gem "grit" gem "grit"
gem 'whenever', :require => false gem 'whenever', :require => false
gem 'delayed_job' gem 'delayed_job'
gem 'highline', '~> 1.6.8'
# XML-RPC support # XML-RPC support
# gem 'actionwebservice' #, :git => 'git://github.com/ywen/actionwebservice.git' # gem 'actionwebservice' #, :git => 'git://github.com/ywen/actionwebservice.git'
@ -39,6 +40,7 @@ gem 'unicorn', '~> 4.1.1'
group :production do group :production do
gem "airbrake", '~> 3.0.5' gem "airbrake", '~> 3.0.5'
# gem 'newrelic_rpm', '~> 3.1.1' # gem 'newrelic_rpm', '~> 3.1.1'
gem 'bluepill', :require => false
end end
group :development do group :development do
@ -72,14 +74,14 @@ group :development, :test do
gem 'rr' gem 'rr'
end end
group :test do # group :test do
# gem 'spork', '>= 0.9.0.rc9' # gem 'spork', '>= 0.9.0.rc9'
# gem 'guard-spork', '~> 0.3.1' # gem 'guard-spork', '~> 0.3.1'
# gem 'guard-rspec', '~> 0.5.0' # gem 'guard-rspec', '~> 0.5.0'
# gem 'guard-bundler', '~> 0.1.3' # gem 'guard-bundler', '~> 0.1.3'
# #
# gem 'rb-fsevent', '>= 0.4.3', :require => false # gem 'rb-fsevent', '>= 0.4.3', :require => false
# gem 'growl', '~> 1.0.3', :require => false # gem 'growl', '~> 1.0.3', :require => false
# gem 'rb-inotify', '>= 0.8.6', :require => false # gem 'rb-inotify', '>= 0.8.6', :require => false
# gem 'libnotify', '~> 0.5.7', :require => false # gem 'libnotify', '~> 0.5.7', :require => false
end # end

View File

@ -41,6 +41,11 @@ GEM
activerecord (>= 2.2.2) activerecord (>= 2.2.2)
arel (2.0.10) arel (2.0.10)
bcrypt-ruby (3.0.1) bcrypt-ruby (3.0.1)
bluepill (0.0.51)
activesupport (>= 3.0.0)
daemons (~> 1.1.0)
i18n (>= 0.5.0)
state_machine (~> 0.9.4)
builder (2.1.2) builder (2.1.2)
cancan (1.6.7) cancan (1.6.7)
cape (1.0.1) cape (1.0.1)
@ -180,6 +185,7 @@ GEM
i18n (>= 0.5.0) i18n (>= 0.5.0)
sexp_processor (3.0.8) sexp_processor (3.0.8)
silent-postgres (0.1.1) silent-postgres (0.1.1)
state_machine (0.9.4)
thor (0.14.6) thor (0.14.6)
treetop (1.4.10) treetop (1.4.10)
polyglot polyglot
@ -204,6 +210,7 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
airbrake (~> 3.0.5) airbrake (~> 3.0.5)
ancestry (~> 1.2.4) ancestry (~> 1.2.4)
bluepill
cancan (~> 1.6.7) cancan (~> 1.6.7)
cape cape
capistrano capistrano
@ -215,6 +222,7 @@ DEPENDENCIES
grack! grack!
grit grit
haml-rails (~> 0.3.4) haml-rails (~> 0.3.4)
highline (~> 1.6.8)
hirb hirb
hpricot hpricot
jammit jammit

View File

@ -78,7 +78,7 @@ class BuildListsController < ApplicationController
end end
def pre_build def pre_build
@build_list.status = BuildList::BUILD_STARTED @build_list.status = BuildServer::BUILD_STARTED
@build_list.notified_at = Time.current @build_list.notified_at = Time.current
@build_list.save @build_list.save

View File

@ -30,7 +30,6 @@ class CollaboratorsController < ApplicationController
def update def update
all_user_ids = [] all_user_ids = []
all_groups_ids = [] all_groups_ids = []
puts params.inspect
Relation::ROLES.each { |r| Relation::ROLES.each { |r|
all_user_ids = all_user_ids | params['user'][r.to_sym].keys if params['user'] && params['user'][r.to_sym] all_user_ids = all_user_ids | params['user'][r.to_sym].keys if params['user'] && params['user'][r.to_sym]
all_groups_ids = all_groups_ids | params['group'][r.to_sym].keys if params['group'] && params['group'][r.to_sym] all_groups_ids = all_groups_ids | params['group'][r.to_sym].keys if params['group'] && params['group'][r.to_sym]
@ -82,6 +81,41 @@ class CollaboratorsController < ApplicationController
def destroy def destroy
end end
def add
# TODO: Here is used Chelyabinsk method to display Flash messages.
member = User.find(params['member_id']) if params['member_id'] && !params['member_id'].empty?
group = Group.find(params['group_id']) if params['group_id'] && !params['group_id'].empty?
flash[:notice], flash[:error], flash[:warning] = [], [], []
[member, group].compact.each do |mem|
if mem and @project.relations.exists?(:object_id => mem.id, :object_type => mem.class.to_s)
flash[:warning] << [t('flash.collaborators.member_already_added'), mem.uname]
end
unless @project.relations.exists?(:object_id => mem.id, :object_type => mem.class.to_s)
rel = @project.relations.build(:role => 'reader')
rel.object = mem
if rel.save
flash[:notice] << [t('flash.collaborators.successfully_added'), mem.uname]
else
flash[:notice] << [t('flash.collaborators.error_in_adding'), mem.uname]
end
end
end
[:notice, :warning, :error].each do |k|
if flash[k].size > 0
flash[k] = flash[k].map{|i| (i.is_a? Array) ? sprintf(i.first, i.last) : i}.join('; ')
else
flash[k] = nil
end
end
flash.delete_if{|k, v| v.nil?}
redirect_to(edit_project_collaborators_path(@project))
end
protected protected
def find_project def find_project
@ -89,10 +123,10 @@ class CollaboratorsController < ApplicationController
end end
def find_users def find_users
@users = User.all @users = @project.collaborators#User.all
end end
def find_groups def find_groups
@groups = Group.all @groups = @project.groups#Group.all
end end
end end

View File

@ -8,6 +8,7 @@ class GroupsController < ApplicationController
before_filter :find_group, :only => [:show, :edit, :update, :destroy] before_filter :find_group, :only => [:show, :edit, :update, :destroy]
load_and_authorize_resource load_and_authorize_resource
autocomplete :group, :uname
def index def index
puts parent.inspect puts parent.inspect

View File

@ -67,10 +67,27 @@ class MembersController < ApplicationController
def destroy def destroy
end end
def add
if params['user_id'] and !params['user_id'].empty?
@user = User.find_by_uname(params['user_id'])
unless parent.objects.exists? :object_id => @user.id, :object_type => 'User'
relation = parent.objects.build(:object_id => @user.id, :object_type => 'User', :role => 'reader')
if relation.save
flash[:notice] = t("flash.members.successfully_added")
else
flash[:error] = t("flash.members.error_in_adding")
end
else
flash[:error] = t("flash.members.already_added")
end
end
redirect_to edit_group_members_path(parent)
end
protected protected
def find_users def find_users
@users = User.all @users = parent.members #User.all
end end
end end

View File

@ -45,18 +45,39 @@ class PlatformsController < ApplicationController
def new def new
@platform = Platform.new @platform = Platform.new
@admin_uname = current_user.uname
@admin_id = current_user.id
end end
def edit def edit
@admin_id = @platform.owner.id
@admin_uname = @platform.owner.uname
end end
def create def create
@platform = Platform.new params[:platform] @platform = Platform.new params[:platform]
@platform.owner = (params[:admin_uname]) ? User.find_by_uname(params[:admin_uname]) : nil @admin_id = params[:admin_id]
@platform.owner ||= get_owner @admin_uname = params[:admin_uname]
@platform.owner = @admin_id.blank? ? get_owner : User.find(@admin_id)
if @platform.save! if @platform.save
# @platform.make_admin_relation(@platform.owner.id) flash[:notice] = I18n.t("flash.platform.saved")
redirect_to @platform
else
flash[:error] = I18n.t("flash.platform.saved_error")
render :action => :new
end
end
def update
@admin_id = params[:admin_id]
@admin_uname = params[:admin_uname]
if @platform.update_attributes(
:owner => @admin_id.blank? ? get_owner : User.find(@admin_id),
:description => params[:platform][:description],
:released => params[:platform][:released]
)
flash[:notice] = I18n.t("flash.platform.saved") flash[:notice] = I18n.t("flash.platform.saved")
redirect_to @platform redirect_to @platform
else else

View File

@ -4,6 +4,7 @@ class UsersController < ApplicationController
before_filter :find_user, :only => [:show, :edit, :update, :destroy] before_filter :find_user, :only => [:show, :edit, :update, :destroy]
load_and_authorize_resource load_and_authorize_resource
autocomplete :user, :uname
def index def index
@users = User.paginate(:page => params[:user_page]) @users = User.paginate(:page => params[:user_page])

View File

@ -44,6 +44,9 @@ class Ability
can :publish, BuildList do |build_list| can :publish, BuildList do |build_list|
build_list.can_published? && build_list.project.relations.exists?(:object_type => 'User', :object_id => user.id) build_list.can_published? && build_list.project.relations.exists?(:object_type => 'User', :object_id => user.id)
end end
can :read, BuildList do |build_list|
build_list.project.public? || build_list.project.relations.exists?(:object_type => 'User', :object_id => user.id)
end
can [:read, :create], PrivateUser, :platform => {:owner_type => 'User', :owner_id => user.id} can [:read, :create], PrivateUser, :platform => {:owner_type => 'User', :owner_id => user.id}
# If rule has multiple conditions CanCan joins them by 'AND' sql operator # If rule has multiple conditions CanCan joins them by 'AND' sql operator
@ -100,6 +103,9 @@ class Ability
can :publish, BuildList do |build_list| can :publish, BuildList do |build_list|
build_list.can_published? && build_list.project.relations.exists?(:object_type => 'Group', :object_id => user.group_ids) build_list.can_published? && build_list.project.relations.exists?(:object_type => 'Group', :object_id => user.group_ids)
end end
can :read, BuildList do |build_list|
build_list.project.public? || build_list.project.relations.exists?(:object_type => 'Group', :object_id => user.group_ids)
end
can :manage_collaborators, Project, projects_in_relations_with(:role => 'admin', :object_type => 'Group', :object_id => user.group_ids) do |project| can :manage_collaborators, Project, projects_in_relations_with(:role => 'admin', :object_type => 'Group', :object_id => user.group_ids) do |project|
project.relations.exists? :object_id => user.group_ids, :object_type => 'Group', :role => 'admin' project.relations.exists? :object_id => user.group_ids, :object_type => 'Group', :role => 'admin'

View File

@ -52,7 +52,7 @@ class BuildList < ActiveRecord::Base
BuildServer::BINARY_TEST_FAILED => :binary_test_failed BuildServer::BINARY_TEST_FAILED => :binary_test_failed
} }
scope :recent, order("updated_at DESC") scope :recent, order("#{table_name}.updated_at DESC")
scope :current, lambda { scope :current, lambda {
outdatable_statuses = [BuildServer::SUCCESS, BuildServer::ERROR, BuildServer::PLATFORM_NOT_FOUND, BuildServer::PLATFORM_PENDING, BuildServer::PROJECT_NOT_FOUND, BuildServer::PROJECT_VERSION_NOT_FOUND] outdatable_statuses = [BuildServer::SUCCESS, BuildServer::ERROR, BuildServer::PLATFORM_NOT_FOUND, BuildServer::PLATFORM_PENDING, BuildServer::PROJECT_NOT_FOUND, BuildServer::PROJECT_VERSION_NOT_FOUND]
where(["status in (?) OR (status in (?) AND notified_at >= ?)", [WAITING_FOR_RESPONSE, BUILD_PENDING, BuildServer::BUILD_STARTED], outdatable_statuses, Time.now - 2.days]) where(["status in (?) OR (status in (?) AND notified_at >= ?)", [WAITING_FOR_RESPONSE, BUILD_PENDING, BuildServer::BUILD_STARTED], outdatable_statuses, Time.now - 2.days])
@ -63,11 +63,11 @@ class BuildList < ActiveRecord::Base
scope :scoped_to_is_circle, lambda {|is_circle| where(:is_circle => is_circle) } scope :scoped_to_is_circle, lambda {|is_circle| where(:is_circle => is_circle) }
scope :for_creation_date_period, lambda{|start_date, end_date| scope :for_creation_date_period, lambda{|start_date, end_date|
if start_date && end_date if start_date && end_date
where(["created_at BETWEEN ? AND ?", start_date, end_date]) where(["#{table_name}.created_at BETWEEN ? AND ?", start_date, end_date])
elsif start_date && !end_date elsif start_date && !end_date
where(["created_at >= ?", start_date]) where(["#{table_name}.created_at >= ?", start_date])
elsif !start_date && end_date elsif !start_date && end_date
where(["created_at <= ?", end_date]) where(["#{table_name}.created_at <= ?", end_date])
end end
} }
scope :for_notified_date_period, lambda{|start_date, end_date| scope :for_notified_date_period, lambda{|start_date, end_date|

View File

@ -12,7 +12,7 @@ class Download < ActiveRecord::Base
def parse_nginx_log def parse_nginx_log
File.open(PREV_LOG_FILE) do |log| File.open(PREV_LOG_FILE) do |log|
while (line = log.gets) while (line = log.gets)
if package = line.match( /GET \/.+\/([\w\d]+)-([\d.]+)-((\d+mdv[\d.]+)|([\d\w]+-mdv[\d.]+))\.([\w\d]+)\.rpm/ ) if package = line.match( /GET \/.+\/([\w\d-]+)-([\d.]+)-((\d+mdv[\d.]+)|([\d\w]+-mdv[\d.]+))\.([\w\d]+)\.rpm/ )
increase( increase(
:name => package[1], :name => package[1],
:version => package[2], :version => package[2],

View File

@ -14,7 +14,9 @@ class Platform < ActiveRecord::Base
has_many :groups, :through => :objects, :source => :object, :source_type => 'Group' has_many :groups, :through => :objects, :source => :object, :source_type => 'Group'
validates :description, :presence => true, :uniqueness => true validates :description, :presence => true, :uniqueness => true
if !Rails.env.development?
validates :name, :uniqueness => true, :presence => true, :format => { :with => /^[a-zA-Z0-9_]+$/ } validates :name, :uniqueness => true, :presence => true, :format => { :with => /^[a-zA-Z0-9_]+$/ }
end
validates :distrib_type, :presence => true, :inclusion => {:in => APP_CONFIG['distr_types']} validates :distrib_type, :presence => true, :inclusion => {:in => APP_CONFIG['distr_types']}
before_create :xml_rpc_create, :unless => lambda {Thread.current[:skip]} before_create :xml_rpc_create, :unless => lambda {Thread.current[:skip]}
@ -22,6 +24,7 @@ class Platform < ActiveRecord::Base
# before_update :check_freezing # before_update :check_freezing
after_create lambda { mount_directory_for_rsync unless hidden? } after_create lambda { mount_directory_for_rsync unless hidden? }
after_destroy lambda { umount_directory_for_rsync unless hidden? } after_destroy lambda { umount_directory_for_rsync unless hidden? }
after_update :update_owner_relation
scope :by_visibilities, lambda {|v| {:conditions => ['visibility in (?)', v.join(',')]}} scope :by_visibilities, lambda {|v| {:conditions => ['visibility in (?)', v.join(',')]}}
scope :open, where(:visibility => 'open') scope :open, where(:visibility => 'open')
@ -60,6 +63,10 @@ class Platform < ActiveRecord::Base
build_path(name) build_path(name)
end end
def mount_path
Rails.root.join("public", "downloads", name)
end
def hidden? def hidden?
visibility == 'hidden' visibility == 'hidden'
end end
@ -106,31 +113,27 @@ class Platform < ActiveRecord::Base
end end
def mount_directory_for_rsync def mount_directory_for_rsync
#FileUtils.rm_rf "#{ Rails.root.join('tmp', 'umount', self.name) }" if File.exist? "#{ Rails.root.join('tmp', 'umount', name) }" # umount_directory_for_rsync # TODO ignore errors
#FileUtils.mkdir_p "#{ Rails.root.join('tmp', 'mount', name) }" system("sudo mkdir -p #{mount_path}")
system("sudo mkdir -p #{ Rails.root.join("public", "downloads") }/#{ name }") system("sudo mount --bind #{path} #{mount_path}")
system("sudo mount --bind /home/share/platforms/#{ name } #{ Rails.root.join("public", "downloads") }/#{ name }")
#system("sudo cp -f /srv/rosa_build/current/tmp/mount/#{ name }/* /home/share/platforms/#{ name }/repository/")
#system("sudo rm -Rf \"/srv/rosa_build/current/tmp/mount/#{ name }\"")
Arch.all.each do |arch| Arch.all.each do |arch|
host = EventLog.current_controller.request.host_with_port rescue ::Rosa::Application.config.action_mailer.default_url_options[:host] host = EventLog.current_controller.request.host_with_port rescue ::Rosa::Application.config.action_mailer.default_url_options[:host]
url = "http://#{host}/downloads/#{name}/repository/" url = "http://#{host}/downloads/#{name}/repository/"
str = "country=Russian Federation,city=Moscow,latitude=52.18,longitude=48.88,bw=1GB,version=2011,arch=#{arch.name},type=distrib,url=#{url}\n" str = "country=Russian Federation,city=Moscow,latitude=52.18,longitude=48.88,bw=1GB,version=2011,arch=#{arch.name},type=distrib,url=#{url}\n"
File.open(Rails.root.join("public", 'downloads', name, "#{name}.#{arch.name}.list"), 'w') {|f| f.write(str) } File.open(File.join(mount_path, "#{name}.#{arch.name}.list"), 'w') {|f| f.write(str) }
end end
end end
def umount_directory_for_rsync def umount_directory_for_rsync
system("sudo umount #{ Rails.root.join("public", "downloads") }/#{ name }") system("sudo umount #{mount_path}")
system("sudo rm -Rf #{ Rails.root.join("public", "downloads") }/#{ name }") system("sudo rm -Rf #{mount_path}")
#system("rm -Rf \"/srv/rosa_build/current/tmp/umount/#{ name }\"")
#FileUtils.rm_rf "#{ Rails.root.join('tmp', 'mount', name) }" if File.exist? "#{ Rails.root.join('tmp', 'mount', name) }"
#FileUtils.mkdir_p "#{ Rails.root.join('tmp', 'umount', name) }"
end end
def make_admin_relation(user_id) def update_owner_relation
r = self.relations.build :object_id => user_id, :object_type => 'User', :role => 'admin' if owner_id_was != owner_id
r.save r = relations.where(:object_id => owner_id_was, :object_type => owner_type_was)[0]
r.update_attributes(:object_id => owner_id, :object_type => owner_type)
end
end end
protected protected

View File

@ -21,28 +21,28 @@
.columns.wat-cf .columns.wat-cf
.column.left .column.left
.group .group
= f.label :status, t("layout.build_lists.created_at_start"), :class => :label = f.label :created_at_start, t("layout.build_lists.created_at_start"), :class => :label
= f.date_select(:created_at_start, :include_blank => true, :selected => @filter.created_at_start) = f.date_select(:created_at_start, :include_blank => true, :selected => @filter.created_at_start)
.group .group
= f.label :status, t("layout.build_lists.notified_at_start"), :class => :label = f.label :notified_at_start, t("layout.build_lists.notified_at_start"), :class => :label
= f.date_select(:notified_at_start, :include_blank => true, :selected => @filter.notified_at_start) = f.date_select(:notified_at_start, :include_blank => true, :selected => @filter.notified_at_start)
.column.right .column.right
.group .group
= f.label :status, t("layout.build_lists.created_at_end"), :class => :label = f.label :created_at_end, t("layout.build_lists.created_at_end"), :class => :label
= f.date_select(:created_at_end, :include_blank => true, :selected => @filter.created_at_end) = f.date_select(:created_at_end, :include_blank => true, :selected => @filter.created_at_end)
.group .group
= f.label :status, t("layout.build_lists.notified_at_end"), :class => :label = f.label :notified_at_end, t("layout.build_lists.notified_at_end"), :class => :label
= f.date_select(:notified_at_end, :include_blank => true, :selected => @filter.notified_at_end) = f.date_select(:notified_at_end, :include_blank => true, :selected => @filter.notified_at_end)
.columns.wat-cf .columns.wat-cf
.column.left .column.left
.group .group
= f.label :status, t("layout.build_lists.bs_id_search"), :class => :label = f.label :project_name, t("layout.build_lists.project_name_search"), :class => :label
= f.text_field :bs_id, :class => :text_field = f.text_field :project_name, :class => :text_field
.column.right .column.right
.group .group
= f.label :status, t("layout.build_lists.project_name"), :class => :label = f.label :bs_id, t("layout.build_lists.bs_id_search"), :class => :label
= f.text_field :project_name, :class => :text_field = f.text_field :bs_id, :class => :text_field
.group.navform.wat-cf .group.navform.wat-cf
%button.button{ :type => "submit" } %button.button{ :type => "submit" }

View File

@ -5,6 +5,26 @@
%li.active= link_to t("layout.collaborators.edit"), edit_project_collaborators_path(@project) %li.active= link_to t("layout.collaborators.edit"), edit_project_collaborators_path(@project)
.content .content
.inner .inner
= form_tag add_project_collaborators_path(@project) do
= javascript_include_tag 'autocomplete-rails.js'
.group
%h2.title= t("layout.collaborators.add")
= label_tag "member_uname", t("layout.collaborators.input_username")
= autocomplete_field_tag 'member_id', params[:member_id], autocomplete_user_uname_users_path, :id_element => '#member_id_field'
&nbsp;
= t('layout.or')
&nbsp;
= label_tag "group_uname", t("layout.collaborators.input_groupname")
= autocomplete_field_tag 'group_id', params[:group_id], autocomplete_group_uname_groups_path, :id_element => '#group_id_field'
= hidden_field_tag 'member_id', nil, :id => 'member_id_field'
= hidden_field_tag 'group_id', nil, :id => 'group_id_field'
%br
.group.navform.wat-cf
%button.button{:type => "submit"}
= image_tag("web-app-theme/icons/tick.png", :alt => t("layout.add"))
= t("layout.add")
= form_tag project_collaborators_path(@project) do = form_tag project_collaborators_path(@project) do
%h2.title= t("layout.users.list_header") %h2.title= t("layout.users.list_header")
%table.table %table.table
@ -31,8 +51,8 @@
%tr %tr
%th.first ID %th.first ID
%th= t("activerecord.attributes.group.name") %th= t("activerecord.attributes.group.name")
%th= t("activerecord.attributes.group.roles")
%th= t("activerecord.attributes.group.uname") %th= t("activerecord.attributes.group.uname")
%th.last= t("layout.collaborators.add")
- @groups.each do |group| - @groups.each do |group|
%tr{:class => cycle("odd", "even")} %tr{:class => cycle("odd", "even")}
%td %td

View File

@ -22,7 +22,7 @@
= link_to user.name, user_path(user) = link_to user.name, user_path(user)
%td %td
- Relation::ROLES.each do |role| - Relation::ROLES.each do |role|
= check_box_tag "#{ role }[#{user.id}]", '1', ((parent.relations.exists? :object_id => user.id, :object_type => 'User', :role => role) ? :checked : nil), {:class => "user_role_chbx"} = check_box_tag "#{ role }[#{user.id}]", '1', ((parent.objects.exists? :object_id => user.id, :object_type => 'User', :role => role) ? :checked : nil), {:class => "user_role_chbx"}
= label_tag "#{ role }[#{user.id}]", t("layout.members.roles.#{ role }") = label_tag "#{ role }[#{user.id}]", t("layout.members.roles.#{ role }")
%td %td
= user.uname = user.uname
@ -33,3 +33,15 @@
%span.text_button_padding= t("layout.or") %span.text_button_padding= t("layout.or")
= link_to t("layout.cancel"), group_path(parent), :class => "text_button_padding link_button" = link_to t("layout.cancel"), group_path(parent), :class => "text_button_padding link_button"
= form_tag add_group_members_path(parent) do
= javascript_include_tag 'autocomplete-rails.js'
.group
%h2.title= t("layout.members.add_member")
= label_tag "", t("layout.members.input_username")
= autocomplete_field_tag 'user_id', params[:user_id], autocomplete_user_uname_users_path
%br
.group.navform.wat-cf
%button.button{:type => "submit"}
= image_tag("web-app-theme/icons/tick.png", :alt => t("layout.add"))
= t("layout.add")

View File

@ -1,6 +1,7 @@
= javascript_include_tag "autocomplete-rails.js" = javascript_include_tag "autocomplete-rails.js"
.group - unless ['edit', 'update'].include? controller.action_name
.group
= f.label :name, :class => :label = f.label :name, :class => :label
= f.text_field :name, :class => 'text_field' = f.text_field :name, :class => 'text_field'
@ -8,11 +9,12 @@
= f.label :description, :class => :label = f.label :description, :class => :label
= f.text_field :description, :class => 'text_field' = f.text_field :description, :class => 'text_field'
.group - unless ['edit', 'update'].include? controller.action_name
.group
= f.label :distrib_type, :class => :label = f.label :distrib_type, :class => :label
= f.select :distrib_type, options_for_select(APP_CONFIG['distr_types']) = f.select :distrib_type, options_for_select(APP_CONFIG['distr_types'])
.group .group
= f.label :parent, :class => :label = f.label :parent, :class => :label
= f.collection_select :parent_platform_id, Platform.all, :id, :description, :include_blank => true = f.collection_select :parent_platform_id, Platform.all, :id, :description, :include_blank => true
@ -21,9 +23,9 @@
= f.check_box :released, :class => 'check_box' = f.check_box :released, :class => 'check_box'
.group .group
= label_tag "admin_uname", t("layout.platforms.admin_uname"), :class => :label = label_tag "", t("layout.platforms.admin_id"), :class => :label
= autocomplete_field_tag 'admin_uname', params[:admin_uname], autocomplete_user_uname_platforms_path = autocomplete_field_tag 'admin_id', @admin_uname, autocomplete_user_uname_platforms_path, :id_element => '#admin_id_field'
=# text_field_tag 'admin_id', '', :id => 'admin_id_field' = hidden_field_tag 'admin_id', @admin_id, :id => 'admin_id_field'
.group.navform.wat-cf .group.navform.wat-cf
%button.button{:type => "submit"} %button.button{:type => "submit"}

View File

@ -64,6 +64,7 @@
= link_to t("layout.platforms.freeze"), freeze_platform_path(@platform), :confirm => I18n.t("layout.platforms.confirm_freeze"), :method => :post, :class => "button" if can? :freeze, @platform = link_to t("layout.platforms.freeze"), freeze_platform_path(@platform), :confirm => I18n.t("layout.platforms.confirm_freeze"), :method => :post, :class => "button" if can? :freeze, @platform
= link_to "Клонировать", clone_platform_path(@platform), :class => "button" if can? :clone, @platform = link_to "Клонировать", clone_platform_path(@platform), :class => "button" if can? :clone, @platform
= link_to t("layout.platforms.build_all"), build_all_platform_path(@platform), :confirm => I18n.t("layout.confirm"), :method => :post, :class => "button" if can? :build_all, @platform = link_to t("layout.platforms.build_all"), build_all_platform_path(@platform), :confirm => I18n.t("layout.confirm"), :method => :post, :class => "button" if can? :build_all, @platform
= link_to t("layout.platforms.edit"), edit_platform_path(@platform), :class => "button" if can? :edit, @platform
%a{ :name => "repositories" } %a{ :name => "repositories" }
.block .block

8
bin/autostart.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/bash
for f in `ls /srv`
do
su -l rosa -c "cd /srv/$f/current && APP_NAME=$f bundle exec bluepill --no-privileged load /srv/$f/current/config/production.pill"
done
/srv/rosa_build/current/bin/mount_downloads.sh

View File

@ -2,8 +2,9 @@
for f in `ls /srv/rosa_build/shared/downloads` for f in `ls /srv/rosa_build/shared/downloads`
do do
if [ -d "/home/share/platforms/$f" ] if [ -d /home/share/platforms/$f ]
then then
mount --bind "/home/share/platforms/$f" "/srv/rosa_build/shared/downloads/$f" sudo umount /srv/rosa_build/shared/downloads/$f 2>&1 >> /dev/null
sudo mount --bind /home/share/platforms/$f /srv/rosa_build/shared/downloads/$f
fi fi
done done

View File

@ -1,9 +0,0 @@
#!/bin/bash
for f in `ls /srv/rosa_build/current/tmp/mount`
do
mkdir -p "/srv/rosa_build/shared/downloads/$f"
mount --bind "/home/share/platforms/$f" "/srv/rosa_build/shared/downloads/$f"
cp -f /srv/rosa_build/current/tmp/mount/$f/* /home/share/platforms/$f/repository/
rm -Rf "/srv/rosa_build/current/tmp/mount/$f"
done

View File

@ -1,6 +0,0 @@
#!/bin/bash
mv /srv/rosa_build/shared/log/nginx.access.log /srv/rosa_build/shared/log/nginx.access.log.0
/etc/init.d/nginx reload
chown rosa /srv/rosa_build/shared/log/nginx.access.log.0
# touch /home/rosa/i_was_launched.txt

View File

@ -1,8 +0,0 @@
#!/bin/bash
for f in `ls /srv/rosa_build/current/tmp/umount`
do
umount "/srv/rosa_build/shared/downloads/$f"
rm -Rf "/srv/rosa_build/shared/downloads/$f"
rm -Rf "/srv/rosa_build/current/tmp/umount/$f"
done

View File

@ -29,6 +29,7 @@ set :scm, "git"
require 'lib/recipes/nginx' require 'lib/recipes/nginx'
require 'lib/recipes/unicorn' require 'lib/recipes/unicorn'
require 'lib/recipes/bluepill'
namespace :deploy do namespace :deploy do
# task :restart, :roles => :app, :except => { :no_release => true } do # task :restart, :roles => :app, :except => { :no_release => true } do
# run "touch #{current_release}/tmp/restart.txt" # run "touch #{current_release}/tmp/restart.txt"
@ -50,17 +51,11 @@ namespace :deploy do
run "mkdir -p #{fetch :shared_path}/downloads" run "mkdir -p #{fetch :shared_path}/downloads"
run "ln -nfs #{fetch :shared_path}/downloads/ #{fetch :release_path}/public/downloads" run "ln -nfs #{fetch :shared_path}/downloads/ #{fetch :release_path}/public/downloads"
run "mkdir -p #{fetch :shared_path}/tmp"
run "ln -nfs #{fetch :shared_path}/pids/ #{fetch :shared_path}/tmp/pids"
run "ln -nfs #{fetch :shared_path}/tmp/ #{fetch :release_path}/tmp"
run "mkdir -p #{fetch :release_path}/tmp/mount"
run "mkdir -p #{fetch :release_path}/tmp/umount"
end end
end end
after "deploy:update_code", "deploy:symlink_all", "deploy:migrate" after "deploy:update_code", "deploy:symlink_all", "deploy:migrate"
after "deploy:restart", "delayed_job:restart", "deploy:cleanup" after "deploy:restart", "delayed_job:restart", "bluepill:restart", "deploy:cleanup"
require 'cape' require 'cape'
namespace :rake_tasks do namespace :rake_tasks do

View File

@ -10,6 +10,6 @@ role :db, domain, :primary => true
set :application, "rosa_build_#{stage}" set :application, "rosa_build_#{stage}"
set :deploy_to, "/srv/#{application}" set :deploy_to, "/srv/#{application}"
set :unicorn_port, 8081 # set :unicorn_port, 8081
before "deploy:restart", "deploy:stub_xml_rpc" before "deploy:restart", "deploy:stub_xml_rpc"

View File

@ -10,6 +10,6 @@ role :db, domain, :primary => true
set :application, "rosa_build_#{stage}" set :application, "rosa_build_#{stage}"
set :deploy_to, "/srv/#{application}" set :deploy_to, "/srv/#{application}"
set :unicorn_port, 8082 # set :unicorn_port, 8082
before "deploy:restart", "deploy:stub_xml_rpc" before "deploy:restart", "deploy:stub_xml_rpc"

View File

@ -25,3 +25,7 @@ Rosa::Application.configure do
end end
require 'stub_xml_rpc' require 'stub_xml_rpc'
Rails.application.config.to_prepare {
Platform.send :include, Modules::Models::RsyncStub
}

View File

@ -94,10 +94,11 @@ ru:
confirm_delete: Вы уверены, что хотите удалить эту категорию? confirm_delete: Вы уверены, что хотите удалить эту категорию?
platforms: platforms:
admin_uname: Владелец admin_id: Владелец
build_all: Собрать все build_all: Собрать все
list: Список list: Список
new: Создать new: Создать
edit: Редактировать
new_header: Новая платформа new_header: Новая платформа
edit_header: Редактировать edit_header: Редактировать
list_header: Платформы list_header: Платформы
@ -222,11 +223,15 @@ ru:
edit_roles: Редактировать роли edit_roles: Редактировать роли
roles_header: Роли для roles_header: Роли для
add_role: Добавить/Удалить роль add_role: Добавить/Удалить роль
input_username: Введите псевдоним пользователя
input_groupname: Введите псевдоним группы
members: members:
back_to_group: Вернуться к группе back_to_group: Вернуться к группе
edit: Редактировать список edit: Редактировать список
roles: Роли roles: Роли
add_member: Добавить участника
input_username: Псевдоним пользователя
groups: groups:
list: Список list: Список
@ -280,7 +285,7 @@ ru:
notified_at_start: "Время последнего обновления от BS с:" notified_at_start: "Время последнего обновления от BS с:"
notified_at_end: "Время последнего обновления от BS по:" notified_at_end: "Время последнего обновления от BS по:"
bs_id_search: 'Поиск по Id' bs_id_search: 'Поиск по Id'
project_name: 'Название проекта' project_name_search: Поиск по названию проекта
bs_id_not_set: Id еще не присвоен bs_id_not_set: Id еще не присвоен
items_header: Элементы сборки items_header: Элементы сборки
no_items_data: Данных нет no_items_data: Данных нет
@ -330,10 +335,17 @@ ru:
collaborators: collaborators:
successfully_changed: Список коллабораторов успешно изменен successfully_changed: Список коллабораторов успешно изменен
error_in_changing: Ошибка изменения списка коллабораторов error_in_changing: Ошибка изменения списка коллабораторов
member_already_added: Участник %s уже добавлен
group_already_added: Группа уже добавлена
successfully_added: Участник %s успешно добавлен
error_in_adding: Ошибка при добавлении участника %s
members: members:
successfully_changed: Список участников успешно изменен successfully_changed: Список участников успешно изменен
error_in_changing: Ошибка изменения списка участников error_in_changing: Ошибка изменения списка участников
successfully_added: Участник успешно добавлен
error_in_adding: Ошибка при добавлении участника
already_added: Пользователь уже добавлен
auto_build_list: auto_build_list:
success: Сборка проекта автоматизорована! success: Сборка проекта автоматизорована!

34
config/production.pill Normal file
View File

@ -0,0 +1,34 @@
#! /usr/bin/env ruby
app_name = ENV['APP_NAME'] || 'rosa_build'
Bluepill.application(app_name) do |app|
app.uid = app.gid = 'rosa'
app.working_dir = "/srv/#{app_name}/current"
app.process("delayed_job") do |process|
process.start_grace_time = 10.seconds
process.stop_grace_time = 10.seconds
process.restart_grace_time = 10.seconds
process.start_command = "/usr/bin/env RAILS_ENV=production script/delayed_job start"
process.stop_command = "/usr/bin/env RAILS_ENV=production script/delayed_job stop"
process.pid_file = File.join(app.working_dir, 'tmp', 'pids', 'delayed_job.pid')
end
app.process("unicorn") do |process|
process.start_grace_time = 8.seconds
process.stop_grace_time = 5.seconds
process.restart_grace_time = 13.seconds
process.start_command = "bundle exec unicorn -l /tmp/#{app_name}_unicorn.sock -E production -c config/unicorn.rb -D"
process.stop_command = "kill -QUIT {{PID}}"
process.restart_command = "kill -USR2 {{PID}}"
process.pid_file = File.join(app.working_dir, 'tmp', 'pids', 'unicorn.pid')
process.monitor_children do |child_process|
child_process.stop_command = "kill -QUIT {{PID}}"
child_process.checks :mem_usage, :every => 10.seconds, :below => 150.megabytes, :times => [3,4], :fires => :stop
child_process.checks :cpu_usage, :every => 10.seconds, :below => 20, :times => [3,4], :fires => :stop
end
end
end

View File

@ -8,6 +8,7 @@ Rosa::Application.routes.draw do
resources :users do resources :users do
resources :groups, :only => [:new, :create, :index] resources :groups, :only => [:new, :create, :index]
get :autocomplete_user_uname, :on => :collection
end end
resources :event_logs, :only => :index resources :event_logs, :only => :index
@ -78,10 +79,11 @@ Rosa::Application.routes.draw do
end end
end end
resources :collaborators, :only => [:index, :edit, :update] do resources :collaborators, :only => [:index, :edit, :update, :add] do
collection do collection do
get :edit get :edit
post :update post :update
post :add
end end
member do member do
post :update post :update
@ -108,9 +110,11 @@ Rosa::Application.routes.draw do
end end
resources :groups do resources :groups do
resources :members, :only => [:index, :edit, :update] do get :autocomplete_group_uname, :on => :collection
resources :members, :only => [:index, :edit, :update, :add] do
collection do collection do
get :edit get :edit
post :add
post :update post :update
end end
member do member do

View File

@ -1,11 +1,10 @@
base_path = File.expand_path(File.join File.dirname(__FILE__), '..')
rails_env = ENV['RAILS_ENV'] || 'production' rails_env = ENV['RAILS_ENV'] || 'production'
worker_processes 4 worker_processes 4
working_directory base_path # available in 0.94.0+
preload_app true # listen File.join(base_path, 'tmp', 'pids', 'unicorn.sock')
working_directory File.expand_path(File.join(File.dirname(__FILE__), "..")) # available in 0.94.0+
# listen '/tmp/rosa_build.sock', :backlog => 2048
# listen "/tmp/.sock", :backlog => 64 # listen "/tmp/.sock", :backlog => 64
# listen 8080, :tcp_nopush => true # listen 8080, :tcp_nopush => true
@ -13,7 +12,7 @@ working_directory File.expand_path(File.join(File.dirname(__FILE__), "..")) # a
timeout 600 timeout 600
# feel free to point this anywhere accessible on the filesystem # feel free to point this anywhere accessible on the filesystem
pid File.expand_path(File.join(File.dirname(__FILE__), "..")) + '/tmp/pids/unicorn.pid' pid File.join(base_path, 'tmp', 'pids', 'unicorn.pid')
# REE # REE
# http://www.rubyenterpriseedition.com/faq.html#adapt_apps_for_cow # http://www.rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
@ -24,8 +23,8 @@ end
# By default, the Unicorn logger will write to stderr. # By default, the Unicorn logger will write to stderr.
# Additionally, ome applications/frameworks log to stderr or stdout, # Additionally, ome applications/frameworks log to stderr or stdout,
# so prevent them from going to /dev/null when daemonized here: # so prevent them from going to /dev/null when daemonized here:
stderr_path File.expand_path(File.join(File.dirname(__FILE__), "..")) + "/log/unicorn.stderr.log" stderr_path File.join(base_path, 'log', 'unicorn.stderr.log')
stdout_path File.expand_path(File.join(File.dirname(__FILE__), "..")) + "/log/unicorn.stdout.log" stdout_path File.join(base_path, 'log', 'unicorn.stdout.log')
# combine REE with "preload_app true" for memory savings # combine REE with "preload_app true" for memory savings
# http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow # http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
@ -42,7 +41,7 @@ before_fork do |server, worker|
# we send it a QUIT. # we send it a QUIT.
# #
# Using this method we get 0 downtime deploys. # Using this method we get 0 downtime deploys.
old_pid = File.expand_path(File.join(File.dirname(__FILE__), "..")) + '/tmp/pids/unicorn.pid.oldbin' old_pid = File.join(base_path, 'tmp', 'pids', '/unicorn.pid.oldbin')
if File.exists?(old_pid) && server.pid != old_pid if File.exists?(old_pid) && server.pid != old_pid
begin begin
Process.kill("QUIT", File.read(old_pid).to_i) Process.kill("QUIT", File.read(old_pid).to_i)

View File

@ -1,3 +1,8 @@
=== Basic bootstrap === Basic bootstrap
* rake db:drop db:setup * rake db:drop db:setup
== ==
=== Setup autostart
Add to /etc/rc.d/rc.local following /srv/rosa_build/current/bin/autostart.sh
==

View File

@ -0,0 +1,23 @@
module Modules
module Models
module RsyncStub
extend ActiveSupport::Concern
included do
def mount_directory_for_rsync
true
end
def umount_directory_for_rsync
true
end
end
module InstanceMethods
end
module ClassMethods
end
end
end
end

30
lib/recipes/bluepill.rb Normal file
View File

@ -0,0 +1,30 @@
Capistrano::Configuration.instance(:must_exist).load do
namespace :bluepill do
set(:bluepill_binary) {"bundle exec bluepill --no-privileged"}
desc "Load bluepill configuration and start it"
task :start, :roles => [:app] do
run "cd #{fetch :current_path} && #{try_sudo} APP_NAME=#{fetch :application} #{bluepill_binary} load config/production.pill"
end
desc "Stop processes that bluepill is monitoring"
task :stop, :roles => [:app], :on_error => :continue do
run "cd #{fetch :current_path} && #{try_sudo} #{bluepill_binary} #{fetch :application} stop"
end
task :restart, :roles => [:app] do
# run "cd #{fetch :current_path} && #{try_sudo} #{bluepill_binary} #{fetch :application} restart"
stop; quit; start
end
desc "Stop processes that bluepill is monitoring and quit bluepill"
task :quit, :roles => [:app] do
run "cd #{fetch :current_path} && #{try_sudo} #{bluepill_binary} #{fetch :application} quit"
end
desc "Prints bluepills monitored processes statuses"
task :status, :roles => [:app] do
run "cd #{fetch :current_path} && #{try_sudo} #{bluepill_binary} #{fetch :application} status"
end
end
end

View File

@ -8,7 +8,8 @@ Capistrano::Configuration.instance(:must_exist).load do
task :generate_configuration, :roles => :web, :except => { :no_release => true } do task :generate_configuration, :roles => :web, :except => { :no_release => true } do
config = %Q{ config = %Q{
upstream #{application}_backend { upstream #{application}_backend {
server 127.0.0.1:#{unicorn_port}; # server 127.0.0.1:#{unicorn_port rescue 8080};
server unix:/tmp/#{fetch :application}_unicorn.sock;
} }
server { server {

View File

@ -1,12 +1,11 @@
Capistrano::Configuration.instance(:must_exist).load do Capistrano::Configuration.instance(:must_exist).load do
namespace :deploy do namespace :deploy do
set :unicorn_binary, "bundle exec unicorn" set :unicorn_binary, "bundle exec unicorn"
set(:unicorn_config) { "#{fetch :current_path}/config/unicorn.rb" }
set(:unicorn_pid) { "#{fetch :shared_path}/tmp/pids/unicorn.pid" } set(:unicorn_pid) { "#{fetch :shared_path}/tmp/pids/unicorn.pid" }
set :unicorn_port, 8080 # set :unicorn_port, 8080
task :start, :roles => :app, :except => { :no_release => true } do task :start, :roles => :app, :except => { :no_release => true } do
run "cd #{fetch :current_path} && #{try_sudo} #{unicorn_binary} -c #{unicorn_config} -p #{unicorn_port} -E #{rails_env} -D" run "cd #{fetch :current_path} && #{try_sudo} #{unicorn_binary} -l /tmp/#{fetch :application}_unicorn.sock -E #{rails_env} -c config/unicorn.rb -D" # -p #{unicorn_port}
end end
task :stop, :roles => :app, :except => { :no_release => true } do task :stop, :roles => :app, :except => { :no_release => true } do
run "#{try_sudo} kill `cat #{unicorn_pid}`" rescue warn 'deploy:stop FAILED' run "#{try_sudo} kill `cat #{unicorn_pid}`" rescue warn 'deploy:stop FAILED'
@ -18,9 +17,8 @@ Capistrano::Configuration.instance(:must_exist).load do
run "#{try_sudo} kill -s USR2 `cat #{unicorn_pid}`" rescue warn 'deploy:reload FAILED' run "#{try_sudo} kill -s USR2 `cat #{unicorn_pid}`" rescue warn 'deploy:reload FAILED'
end end
task :restart, :roles => :app, :except => { :no_release => true } do task :restart, :roles => :app, :except => { :no_release => true } do
# reload
stop stop
start start # blue pill will do it?
end end
end end
end end

View File

@ -1,17 +1,27 @@
require 'highline/import'
require 'open-uri' require 'open-uri'
namespace :import do namespace :import do
desc "Load projects" desc "Load projects"
task :projects => :environment do task :projects => :environment do
open('http://dl.dropbox.com/u/984976/package_list.txt').readlines.each do |name| source = ENV['SOURCE'] || 'http://dl.dropbox.com/u/984976/package_list.txt'
owner = User.find_by_uname(ENV['OWNER_UNAME']) || Group.find_by_uname(ENV['OWNER_UNAME']) || User.first
platform = Platform.find_by_name(ENV['PLATFORM_NAME']) # 'mandriva2011'
repo = platform.repositories.first rescue nil
say "START import projects from '#{source}' for '#{owner.uname}'.#{repo ? " To repo '#{platform.name}/#{repo.name}'." : ''}"
ask 'Press enter to continue'
open(source).readlines.each do |name|
name.chomp!; name.strip! #; name.downcase! name.chomp!; name.strip! #; name.downcase!
# name = name.match(/^([a-z\d_\-\+\.]+?)-(\d[a-z\d\-\.]+)\.src\.rpm$/)[1] # parse # name = name.match(/^([a-z\d_\-\+\.]+?)-(\d[a-z\d\-\.]+)\.src\.rpm$/)[1] # parse
print "Import #{name}..." print "Import '#{name}'..."
owner = User.find(1) # I am p = Project.find_or_create_by_name_and_owner_type_and_owner_id(name, owner.class.to_s, owner.id)
# owner = Group.find(1) # Core Team print p.persisted? ? "Ok!" : "Fail!"
p = Project.find_or_create_by_name(name) {|p| p.owner = owner} if repo
puts p.persisted? ? "Ok!" : "Fail!" print " Add to repo '#{platform.name}/#{repo.name}'."
repo.projects << p rescue print ' Fail!'
end end
puts 'DONE' puts
end
say 'DONE'
end end
end end

View File

@ -1,6 +1,21 @@
require 'spec_helper' require 'spec_helper'
describe BuildListsController do describe BuildListsController do
shared_examples_for 'show build list' do
it 'should be able to perform show action' do
get :show, @show_params
response.should be_success
end
end
shared_examples_for 'not show build list' do
it 'should not be able to perform show action' do
get :show, @show_params
response.should redirect_to(forbidden_url)
end
end
context 'crud' do context 'crud' do
context 'for guest' do context 'for guest' do
it 'should not be able to perform all action' do it 'should not be able to perform all action' do
@ -10,12 +25,58 @@ describe BuildListsController do
end end
context 'for user' do context 'for user' do
before(:each) { set_session_for Factory(:user) } before(:each) do
stub_rsync_methods
@build_list = Factory(:build_list_core)
@project = @build_list.project
@owner_user = @project.owner
@member_user = Factory(:user)
rel = @project.relations.build(:role => 'reader')
rel.object = @member_user
rel.save
@user = Factory(:user)
set_session_for(@user)
@show_params = {:project_id => @project.id, :id => @build_list.id}
end
it 'should not be able to perform all action' do it 'should not be able to perform all action' do
get :all get :all
response.should redirect_to(forbidden_url) response.should redirect_to(forbidden_url)
end end
context 'for open project' do
it_should_behave_like 'show build list'
context 'if user is project owner' do
before(:each) {set_session_for(@owner_user)}
it_should_behave_like 'show build list'
end
context 'if user is project owner' do
before(:each) {set_session_for(@member_user)}
it_should_behave_like 'show build list'
end
end
context 'for hidden project' do
before(:each) do
@project.visibility = 'hidden'
@project.save
end
it_should_behave_like 'not show build list'
context 'if user is project owner' do
before(:each) {set_session_for(@owner_user)}
it_should_behave_like 'show build list'
end
context 'if user is project owner' do
before(:each) {set_session_for(@member_user)}
it_should_behave_like 'show build list'
end
end
end end
context 'for admin' do context 'for admin' do
@ -35,10 +96,25 @@ describe BuildListsController do
end end
context 'filter' do context 'filter' do
before(:each) do
stub_rsync_methods
set_session_for Factory(:admin)
end
let(:build_list1) { Factory(:build_list_core) } let(:build_list1) { Factory(:build_list_core) }
let(:build_list2) { Factory(:build_list_core) } let(:build_list2) { Factory(:build_list_core) }
let(:build_list3) { Factory(:build_list_core) } let(:build_list3) { Factory(:build_list_core) }
before(:each) { set_session_for Factory(:admin) } let(:build_list4) do
b = Factory(:build_list_core)
b.created_at = b.created_at - 1.day
b.project = build_list3.project
b.pl = build_list3.pl
b.arch = build_list3.arch
b.save
b
end
before(:each) { set_session_for Factory(:admin); stub_rsync_methods; }
it 'should filter by bs_id' do it 'should filter by bs_id' do
get :all, :filter => {:bs_id => build_list1.bs_id, :project_name => 'fdsfdf', :any_other_field => 'do not matter'} get :all, :filter => {:bs_id => build_list1.bs_id, :project_name => 'fdsfdf', :any_other_field => 'do not matter'}
@ -54,6 +130,18 @@ describe BuildListsController do
assigns[:build_lists].should include(build_list2) assigns[:build_lists].should include(build_list2)
assigns[:build_lists].should_not include(build_list3) assigns[:build_lists].should_not include(build_list3)
end end
it 'should filter by project_name and start_date' do
get :all, :filter => {:project_name => build_list3.project.name,
"created_at_start(1i)"=>build_list3.created_at.year.to_s,
"created_at_start(2i)"=>build_list3.created_at.month.to_s,
"created_at_start(3i)"=>build_list3.created_at.day.to_s}
assigns[:build_lists].should_not include(build_list1)
assigns[:build_lists].should_not include(build_list2)
assigns[:build_lists].should include(build_list3)
assigns[:build_lists].should_not include(build_list4)
# response.should be_success
end
end end
context 'callbacks' do context 'callbacks' do

View File

@ -36,12 +36,30 @@ describe CollaboratorsController do
@user = Factory(:user) @user = Factory(:user)
@user.relations @user.relations
set_session_for(@user) set_session_for(@user)
@group = Factory(:group)
@project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'reader') @project.relations.create!(:object_type => 'User', :object_id => @user.id, :role => 'reader')
end end
it_should_behave_like 'show collaborators list' it_should_behave_like 'show collaborators list'
it_should_behave_like 'update collaborators' it_should_behave_like 'update collaborators'
it_should_behave_like 'update collaborator relation' it_should_behave_like 'update collaborator relation'
it 'should add new collaborator with reader role' do
@params = {:member_id => @another_user.id.to_s, :project_id => @project.id.to_s}
post :add, @params
@project.relations.exists?(:object_type => 'User', :object_id => @another_user.id, :role => 'reader').should be_true
end
it 'should add new group with reader role' do
@params = {:group_id => @group.id.to_s, :project_id => @project.id.to_s}
post :add, @params
@project.relations.exists?(:object_type => 'Group', :object_id => @group.id, :role => 'reader').should be_true
end
it_should_behave_like 'show collaborators list'
it_should_behave_like 'update collaborators'
it_should_behave_like 'update collaborator relation'
end end
context 'for owner user' do context 'for owner user' do

View File

@ -1,5 +1,24 @@
require 'spec_helper' require 'spec_helper'
describe MembersController do describe MembersController do
before(:each) do
@group = Factory(:group)
@user = @group.owner
set_session_for @user
@another_user = Factory(:user)
@add_params = {:group_id => @group.id, :user_id => @another_user.uname}
end
context 'for owner user' do
it 'should add member to group' do
post :add, @add_params
response.should redirect_to(edit_group_members_path(@group))
Relation.by_target(@group).by_object(@another_user).count.should eql(1)
end
it 'should add reader member to group' do
post :add, @add_params
Relation.by_target(@group).by_object(@another_user).first.role.should eql('reader')
end
end
end end

View File

@ -42,11 +42,6 @@ describe PlatformsController do
@admin = Factory(:admin) @admin = Factory(:admin)
@user = Factory(:user) @user = Factory(:user)
set_session_for(@admin) set_session_for(@admin)
any_instance_of(Platform) do |plat|
stub(plat).mount_directory_for_rsync {|args| true}
stub(plat).umount_directory_for_rsync {|args| true}
end
# any_instance_of(Platform).umount_directory_for_rsync{true}
end end
it_should_behave_like 'able_to_perform_index#platforms' it_should_behave_like 'able_to_perform_index#platforms'
@ -69,13 +64,15 @@ describe PlatformsController do
it_should_behave_like 'change_objects_count_on_destroy_success' it_should_behave_like 'change_objects_count_on_destroy_success'
it_should_behave_like 'not_be_able_to_destroy_personal_platform' it_should_behave_like 'not_be_able_to_destroy_personal_platform'
context 'when owner uname present' do
it 'should create platform with mentioned owner' do it 'should create platform with mentioned owner if owner id present' do
post :create, @create_params.merge({:admin_uname => @user.uname}) post :create, @create_params.merge({:admin_id => @user.id})
Platform.last.owner.id.should eql(@user.id) Platform.last.owner.id.should eql(@user.id)
end end
it 'should create platform with current user as owner if owner id not present' do
post :create, @create_params
Platform.last.owner.id.should eql(@admin.id)
end end
end end

View File

@ -213,7 +213,7 @@ describe CanCan do
end end
[:manage, :add_project, :remove_project, :change_visibility, :settings].each do |action| [:manage, :add_project, :remove_project, :change_visibility, :settings].each do |action|
it 'should be able to #{ action } repository' do it "should be able to #{ action } repository" do
@ability.should be_able_to(action, @repository) @ability.should be_able_to(action, @repository)
end end
end end