From 3d7194f0112da12e8732df9ffe8b34fe7d0a9f6b Mon Sep 17 00:00:00 2001 From: Izaak Alpert Date: Thu, 25 Apr 2013 10:15:33 -0400 Subject: Merge Request on forked projects The good: - You can do a merge request for a forked commit and it will merge properly (i.e. it does work). - Push events take into account merge requests on forked projects - Tests around merge_actions now present, spinach, and other rspec tests - Satellites now clean themselves up rather then recreate The questionable: - Events only know about target projects - Project's merge requests only hold on to MR's where they are the target - All operations performed in the satellite The bad: - Duplication between project's repositories and satellites (e.g. commits_between) (for reference: http://feedback.gitlab.com/forums/176466-general/suggestions/3456722-merge-requests-between-projects-repos) Fixes: Make test repos/satellites only create when needed -Spinach/Rspec now only initialize test directory, and setup stubs (things that are relatively cheap) -project_with_code, source_project_with_code, and target_project_with_code now create/destroy their repos individually -fixed remote removal -How to merge renders properly -Update emails to show project/branches -Edit MR doesn't set target branch -Fix some failures on editing/creating merge requests, added a test -Added back a test around merge request observer -Clean up project_transfer_spec, Remove duplicate enable/disable observers -Ensure satellite lock files are cleaned up, Attempted to add some testing around these as well -Signifant speed ups for tests -Update formatting ordering in notes_on_merge_requests -Remove wiki schema update Fixes for search/search results -Search results was using by_project for a list of projects, updated this to use in_projects -updated search results to reference the correct (target) project -udpated search results to print both sides of the merge request Change-Id: I19407990a0950945cc95d62089cbcc6262dab1a8 --- spec/lib/gitlab/satellite/action_spec.rb | 131 ++++++++++++++++++++++++ spec/lib/gitlab/satellite/merge_action_spec.rb | 136 +++++++++++++++++++++++++ 2 files changed, 267 insertions(+) create mode 100644 spec/lib/gitlab/satellite/action_spec.rb create mode 100644 spec/lib/gitlab/satellite/merge_action_spec.rb (limited to 'spec/lib') diff --git a/spec/lib/gitlab/satellite/action_spec.rb b/spec/lib/gitlab/satellite/action_spec.rb new file mode 100644 index 00000000000..3a2dd0bf6d3 --- /dev/null +++ b/spec/lib/gitlab/satellite/action_spec.rb @@ -0,0 +1,131 @@ +require 'spec_helper' + +describe 'Gitlab::Satellite::Action' do + + + let(:project) { create(:project_with_code) } + let(:user) { create(:user) } + + + describe '#prepare_satellite!' do + + it 'create a repository with a parking branch and one remote: origin' do + repo = project.satellite.repo + + #now lets dirty it up + + starting_remote_count = repo.git.list_remotes.size + starting_remote_count.should >= 1 + #kind of hookey way to add a second remote + origin_uri = repo.git.remote({v: true}).split(" ")[1] + begin + repo.git.remote({raise: true}, 'add', 'another-remote', origin_uri) + repo.git.branch({raise: true}, 'a-new-branch') + + repo.heads.size.should > (starting_remote_count) + repo.git.remote().split(" ").size.should > (starting_remote_count) + rescue + end + + repo.git.config({}, "user.name", "#{user.name} -- foo") + repo.git.config({}, "user.email", "#{user.email} -- foo") + repo.config['user.name'].should =="#{user.name} -- foo" + repo.config['user.email'].should =="#{user.email} -- foo" + + + #These must happen in the context of the satellite directory... + satellite_action = Gitlab::Satellite::Action.new(user, project) + project.satellite.lock { + #Now clean it up, use send to get around prepare_satellite! being protected + satellite_action.send(:prepare_satellite!, repo) + } + + #verify it's clean + heads = repo.heads.map(&:name) + heads.size.should == 1 + heads.include?(Gitlab::Satellite::Satellite::PARKING_BRANCH).should == true + remotes = repo.git.remote().split(' ') + remotes.size.should == 1 + remotes.include?('origin').should == true + repo.config['user.name'].should ==user.name + repo.config['user.email'].should ==user.email + end + + + end + + + describe '#in_locked_and_timed_satellite' do + + it 'should make use of a lockfile' do + repo = project.satellite.repo + called = false + + #set assumptions + File.rm(project.satellite.lock_file) unless !File.exists? project.satellite.lock_file + + File.exists?(project.satellite.lock_file).should be_false + + satellite_action = Gitlab::Satellite::Action.new(user, project) + satellite_action.send(:in_locked_and_timed_satellite) do |sat_repo| + repo.should == sat_repo + (File.exists? project.satellite.lock_file).should be_true + called = true + end + + called.should be_true + + end + + it 'should be able to use the satellite after locking' do + pending "can't test this, doesn't seem to be a way to the the flock status on a file, throwing piles of processes at it seems lousy too" + repo = project.satellite.repo + first_call = false + + (File.exists? project.satellite.lock_file).should be_false + + test_file = ->(called) { + File.exists?(project.satellite.lock_file).should be_true + called.should be_true + File.readlines.should == "some test code" + File.truncate(project.satellite.lock, 0) + File.readlines.should == "" + } + + write_file = ->(called, checker) { + if (File.exists?(project.satellite.lock_file)) + file = File.open(project.satellite.lock, '+w') + file.write("some test code") + file.close + checker.call(called) + end + } + + + satellite_action = Gitlab::Satellite::Action.new(user, project) + satellite_action.send(:in_locked_and_timed_satellite) do |sat_repo| + write_file.call(first_call, test_file) + first_call = true + repo.should == sat_repo + (File.exists? project.satellite.lock_file).should be_true + + end + + first_call.should be_true + puts File.stat(project.satellite.lock_file).inspect + + second_call = false + satellite_action.send(:in_locked_and_timed_satellite) do |sat_repo| + write_file.call(second_call, test_file) + second_call = true + repo.should == sat_repo + (File.exists? project.satellite.lock_file).should be_true + end + + second_call.should be_true + (File.exists? project.satellite.lock_file).should be_true + end + + end +end + diff --git a/spec/lib/gitlab/satellite/merge_action_spec.rb b/spec/lib/gitlab/satellite/merge_action_spec.rb new file mode 100644 index 00000000000..36e6b3c7973 --- /dev/null +++ b/spec/lib/gitlab/satellite/merge_action_spec.rb @@ -0,0 +1,136 @@ +require 'spec_helper' + +describe 'Gitlab::Satellite::MergeAction' do + before(:each) do +# TestEnv.init(mailer: false, init_repos: true, repos: true) + @master = ['master', 'bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a'] + @one_after_stable = ['stable', '6ea87c47f0f8a24ae031c3fff17bc913889ecd00'] #this commit sha is one after stable + @wiki_branch = ['wiki', '635d3e09b72232b6e92a38de6cc184147e5bcb41'] #this is the commit sha where the wiki branch goes off from master + @conflicting_metior = ['metior', '313d96e42b313a0af5ab50fa233bf43e27118b3f'] #this branch conflicts with the wiki branch + + #these commits are quite close together, itended to make string diffs/format patches small + @close_commit1 = ['2_3_notes_fix', '8470d70da67355c9c009e4401746b1d5410af2e3'] + @close_commit2 = ['scss_refactoring', 'f0f14c8eaba69ebddd766498a9d0b0e79becd633'] + + end + + let(:project) { create(:project_with_code) } + let(:merge_request) { create(:merge_request, source_project: project, target_project: project) } + let(:merge_request_fork) { create(:merge_request) } + describe '#commits_between' do + context 'on fork' do + it 'should get proper commits between' do + merge_request_fork.target_branch = @one_after_stable[0] + merge_request_fork.source_branch = @master[0] + commits = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).commits_between + commits.first.id.should == @one_after_stable[1] + commits.last.id.should == @master[1] + + merge_request_fork.target_branch = @wiki_branch[0] + merge_request_fork.source_branch = @master[0] + commits = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).commits_between + commits.first.id.should == @wiki_branch[1] + commits.last.id.should == @master[1] + end + end + + context 'between branches' do + it 'should get proper commits between' do + merge_request.target_branch = @one_after_stable[0] + merge_request.source_branch = @master[0] + commits = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).commits_between + commits.first.id.should == @one_after_stable[1] + commits.last.id.should == @master[1] + + merge_request.target_branch = @wiki_branch[0] + merge_request.source_branch = @master[0] + commits = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).commits_between + commits.first.id.should == @wiki_branch[1] + commits.last.id.should == @master[1] + end + end + end + + + describe '#format_patch' do + context 'on fork' do + it 'should build a format patch' do + merge_request_fork.target_branch = @close_commit1[0] + merge_request_fork.source_branch = @close_commit2[0] + patch = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).format_patch + (patch.include? "From #{@close_commit2[1]}").should be_true + (patch.include? "From #{@close_commit1[1]}").should be_true + end + end + + context 'between branches' do + it 'should build a format patch' do + merge_request.target_branch = @close_commit1[0] + merge_request.source_branch = @close_commit2[0] + patch = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).format_patch + (patch.include? "From #{@close_commit2[1]}").should be_true + (patch.include? "From #{@close_commit1[1]}").should be_true + end + end + end + + + describe '#diffs_between_satellite tested against diff_in_satellite' do + context 'on fork' do + it 'should get proper diffs' do + merge_request_fork.target_branch = @close_commit1[0] + merge_request_fork.source_branch = @master[0] + diffs = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).diffs_between_satellite + + merge_request_fork.target_branch = @close_commit1[0] + merge_request_fork.source_branch = @master[0] + diff = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request_fork).diffs_between_satellite + + diffs.each {|a_diff| (diff.include? a_diff.diff).should be_true} + end + end + + context 'between branches' do + it 'should get proper diffs' do + merge_request.target_branch = @close_commit1[0] + merge_request.source_branch = @wiki_branch[0] + diffs = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).diffs_between_satellite + + + merge_request.target_branch = @close_commit1[0] + merge_request.source_branch = @master[0] + diff = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).diffs_between_satellite + + diffs.each {|a_diff| (diff.include? a_diff.diff).should be_true} + end + end + end + + + describe '#can_be_merged?' do + context 'on fork' do + it 'return true or false depending on if something is mergable' do + merge_request_fork.target_branch = @one_after_stable[0] + merge_request_fork.source_branch = @master[0] + Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).can_be_merged?.should be_true + + merge_request_fork.target_branch = @conflicting_metior[0] + merge_request_fork.source_branch = @wiki_branch[0] + Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).can_be_merged?.should be_false + end + end + + context 'between branches' do + it 'return true or false depending on if something is mergable' do + merge_request.target_branch = @one_after_stable[0] + merge_request.source_branch = @master[0] + Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).can_be_merged?.should be_true + + merge_request.target_branch = @conflicting_metior[0] + merge_request.source_branch = @wiki_branch[0] + Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).can_be_merged?.should be_false + end + end + end + +end \ No newline at end of file -- cgit v1.2.3