Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZeger-Jan van de Weg <zegerjan@gitlab.com>2018-01-04 15:37:30 +0300
committerZeger-Jan van de Weg <zegerjan@gitlab.com>2018-01-04 15:37:30 +0300
commit31c8ac664e83563db72604ed4277ea2e46b16e5e (patch)
tree074d953393aa105dc8b0ebaf0448cfcbe5d140f3
parent041babfa3775e3e48a490cf2b1dd59b489916f09 (diff)
parentd724550940072bd01233d3c2d9488347f9600dee (diff)
Merge branch 'rspec-tests' into 'master'
Add rspec unit and integration tests Closes #832 See merge request gitlab-org/gitaly!504
-rw-r--r--.gitignore2
-rw-r--r--Makefile17
-rw-r--r--ruby/Gemfile1
-rw-r--r--ruby/Gemfile.lock14
-rw-r--r--ruby/README.md17
-rw-r--r--ruby/spec/gitaly/ref_service_spec.rb31
-rw-r--r--ruby/spec/gitaly/repository_service_spec.rb22
-rw-r--r--ruby/spec/integration_helper.rb47
-rw-r--r--ruby/spec/lib/gitlab/config_spec.rb20
-rw-r--r--ruby/spec/spec_helper.rb2
-rw-r--r--ruby/spec/test_repo_helper.rb46
11 files changed, 212 insertions, 7 deletions
diff --git a/.gitignore b/.gitignore
index 6fd3edea3..4b01bfbd4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,5 @@
/.ruby-bundle
/ruby/vendor/bundle
/ruby/.bundle
+/ruby/tmp
+*.socket
diff --git a/Makefile b/Makefile
index dd7ca208d..ba49d801f 100644
--- a/Makefile
+++ b/Makefile
@@ -72,10 +72,16 @@ force-ruby-bundle:
# Assembles all runtime components into a directory
# Used by the GDK: run `make assemble ASSEMBLY_ROOT=.../gitaly`
.PHONY: assemble
-assemble: force-ruby-bundle build
+assemble: force-ruby-bundle build assemble-internal
+
+# assemble-internal does not force 'bundle install' to run again
+.PHONY: assemble-internal
+assemble-internal: build
rm -rf $(ASSEMBLY_ROOT)/bin $(ASSEMBLY_ROOT)/ruby
mkdir -p $(ASSEMBLY_ROOT)/bin
+ rm -rf ruby/tmp
cp -r ruby $(ASSEMBLY_ROOT)/ruby
+ rm -rf $(ASSEMBLY_ROOT)/ruby/spec
install $(foreach cmd,$(COMMANDS),$(BIN_BUILD_DIR)/$(cmd)) $(ASSEMBLY_ROOT)/bin
binaries: assemble
@@ -109,9 +115,16 @@ $(TEST_REPO):
prepare-tests: $(TARGET_SETUP) $(TEST_REPO) .ruby-bundle
.PHONY: test
-test: prepare-tests
+test: test-go rspec
+
+.PHONY: test-go
+test-go: prepare-tests
@go test $(LOCAL_PACKAGES)
+.PHONY: rspec
+rspec: assemble-internal prepare-tests
+ cd ruby && bundle exec rspec
+
.PHONY: test-changes
test-changes: prepare-tests
cd $(PKG_BUILD_DIR) && go test $(CHANGED_LOCAL_GO_PACKAGES)
diff --git a/ruby/Gemfile b/ruby/Gemfile
index 4276c25a5..95bf6367f 100644
--- a/ruby/Gemfile
+++ b/ruby/Gemfile
@@ -9,4 +9,5 @@ gem 'gollum-rugged_adapter', '~> 0.4.4', require: false
group :development, :test do
gem 'gitlab-styles', '~> 2.0.0', require: false
+ gem 'rspec', require: false
end
diff --git a/ruby/Gemfile.lock b/ruby/Gemfile.lock
index 6a6019b14..d8976893f 100644
--- a/ruby/Gemfile.lock
+++ b/ruby/Gemfile.lock
@@ -89,6 +89,19 @@ GEM
rake (12.1.0)
rdoc (4.3.0)
rouge (2.2.1)
+ rspec (3.6.0)
+ rspec-core (~> 3.6.0)
+ rspec-expectations (~> 3.6.0)
+ rspec-mocks (~> 3.6.0)
+ rspec-core (3.6.0)
+ rspec-support (~> 3.6.0)
+ rspec-expectations (3.6.0)
+ diff-lcs (>= 1.2.0, < 2.0)
+ rspec-support (~> 3.6.0)
+ rspec-mocks (3.6.0)
+ diff-lcs (>= 1.2.0, < 2.0)
+ rspec-support (~> 3.6.0)
+ rspec-support (3.6.0)
rubocop (0.50.0)
parallel (~> 1.10)
parser (>= 2.3.3.1, < 3.0)
@@ -126,6 +139,7 @@ DEPENDENCIES
gollum-lib (~> 4.2)
gollum-rugged_adapter (~> 0.4.4)
rdoc (~> 4.2)
+ rspec
BUNDLED WITH
1.16.0
diff --git a/ruby/README.md b/ruby/README.md
index 8125f97bf..7a8dc3cfa 100644
--- a/ruby/README.md
+++ b/ruby/README.md
@@ -22,11 +22,18 @@ mode 0700. It runs as the same user as the Gitaly parent process.
## Testing
-All tests for code in Gitaly-ruby go through the parent Gitaly process
-for two reasons. Firstly, testing through the parent proves that the
-Ruby code under test is reachable. Secondly, testing through the
-parent will make it easier to create a Go implementation in the parent
-if we ever want to do that.
+There are three sets of test that exercise gitaly-ruby:
+
+- Top-level Go integration tests
+- Rspec integration tests (`spec/gitaly`)
+- Rspec unit tests (`spec/lib`)
+
+If you are working on the Ruby code and you want to run the Rspec
+tests only, without recompiling the Go parts then do the following:
+
+- run `make rspec` at the top level at least once, to compile Go binaries and get the test repo;
+- edit code under the current directory (`ruby`);
+- run `bundle exec rspec` in the current directory.
## Vendored copy of Gitlab::Git
diff --git a/ruby/spec/gitaly/ref_service_spec.rb b/ruby/spec/gitaly/ref_service_spec.rb
new file mode 100644
index 000000000..96a648639
--- /dev/null
+++ b/ruby/spec/gitaly/ref_service_spec.rb
@@ -0,0 +1,31 @@
+require 'integration_helper'
+require 'securerandom'
+
+describe Gitaly::RefService do
+ include IntegrationClient
+ include TestRepo
+
+ let(:service_stub) { gitaly_stub(:RefService) }
+
+ describe 'CreateBranch' do
+ it 'can create a branch' do
+ repo = new_mutable_test_repo
+ branch_name = 'branch-' + SecureRandom.hex(10)
+ request = Gitaly::CreateBranchRequest.new(
+ repository: repo,
+ name: branch_name,
+ start_point: 'master'
+ )
+
+ response = service_stub.create_branch(request)
+
+ expect(response.status).to eq(:OK)
+
+ # Intentionally instatiate this Rugged::Repository after we performed
+ # the RPC, to ensure we don't see stale repository state.
+ rugged = rugged_from_gitaly(repo)
+
+ expect(response.branch.target_commit.id).to eq(rugged.branches[branch_name].target_id)
+ end
+ end
+end
diff --git a/ruby/spec/gitaly/repository_service_spec.rb b/ruby/spec/gitaly/repository_service_spec.rb
new file mode 100644
index 000000000..e66458ab5
--- /dev/null
+++ b/ruby/spec/gitaly/repository_service_spec.rb
@@ -0,0 +1,22 @@
+require 'integration_helper'
+
+describe Gitaly::RepositoryService do
+ include IntegrationClient
+ include TestRepo
+
+ subject { gitaly_stub(:RepositoryService) }
+
+ describe 'RepositoryExists' do
+ it 'returns false if the repository does not exist' do
+ request = Gitaly::RepositoryExistsRequest.new(repository: gitaly_repo('default', 'foobar.git'))
+ response = subject.repository_exists(request)
+ expect(response.exists).to eq(false)
+ end
+
+ it 'returns true if the repository exists' do
+ request = Gitaly::RepositoryExistsRequest.new(repository: test_repo_read_only)
+ response = subject.repository_exists(request)
+ expect(response.exists).to eq(true)
+ end
+ end
+end
diff --git a/ruby/spec/integration_helper.rb b/ruby/spec/integration_helper.rb
new file mode 100644
index 000000000..0186d0514
--- /dev/null
+++ b/ruby/spec/integration_helper.rb
@@ -0,0 +1,47 @@
+require 'gitaly'
+require 'test_repo_helper'
+
+SOCKET_PATH = 'gitaly.socket'.freeze
+TMP_DIR = File.expand_path('../../tmp', __FILE__)
+
+module IntegrationClient
+ def gitaly_stub(service)
+ klass = Gitaly.const_get(service).const_get(:Stub)
+ klass.new("unix:tmp/#{SOCKET_PATH}", :this_channel_is_insecure)
+ end
+
+ def gitaly_repo(storage, relative_path)
+ Gitaly::Repository.new(storage_name: storage, relative_path: relative_path)
+ end
+end
+
+def start_gitaly
+ build_dir = File.expand_path('../../../_build', __FILE__)
+ gitlab_shell_dir = File.join(TMP_DIR, 'gitlab-shell')
+
+ FileUtils.mkdir_p([TMP_DIR, File.join(gitlab_shell_dir, 'hooks')])
+
+ config_toml = <<~CONFIG
+ socket_path = "#{SOCKET_PATH}"
+ bin_dir = "#{build_dir}/bin"
+
+ [gitlab-shell]
+ dir = "#{gitlab_shell_dir}"
+
+ [gitaly-ruby]
+ dir = "#{build_dir}/assembly/ruby"
+
+ [[storage]]
+ name = "#{DEFAULT_STORAGE_NAME}"
+ path = "#{DEFAULT_STORAGE_DIR}"
+ CONFIG
+ config_path = File.join(TMP_DIR, 'gitaly-rspec-config.toml')
+ File.write(config_path, config_toml)
+
+ test_log = File.join(TMP_DIR, 'gitaly-rspec-test.log')
+ options = { out: test_log, err: test_log, chdir: TMP_DIR }
+ gitaly_pid = spawn(File.join(build_dir, 'bin/gitaly'), config_path, options)
+ at_exit { Process.kill('KILL', gitaly_pid) }
+end
+
+start_gitaly
diff --git a/ruby/spec/lib/gitlab/config_spec.rb b/ruby/spec/lib/gitlab/config_spec.rb
new file mode 100644
index 000000000..bd2aaaede
--- /dev/null
+++ b/ruby/spec/lib/gitlab/config_spec.rb
@@ -0,0 +1,20 @@
+require 'spec_helper'
+
+describe Gitlab::Config do
+ describe '#gitlab_shell' do
+ subject { described_class.new.gitlab_shell }
+
+ let(:gitlab_shell_path) { '/foo/bar/gitlab-shell' }
+
+ before do
+ ENV['GITALY_RUBY_GITLAB_SHELL_PATH'] = gitlab_shell_path
+ end
+
+ after do
+ ENV.delete('GITALY_RUBY_GITLAB_SHELL_PATH')
+ end
+
+ it { expect(subject.path).to eq(gitlab_shell_path) }
+ it { expect(subject.hooks_path).to eq(File.join(gitlab_shell_path, 'hooks')) }
+ end
+end
diff --git a/ruby/spec/spec_helper.rb b/ruby/spec/spec_helper.rb
new file mode 100644
index 000000000..2480c77c7
--- /dev/null
+++ b/ruby/spec/spec_helper.rb
@@ -0,0 +1,2 @@
+require_relative '../lib/gitlab/git.rb'
+require 'test_repo_helper'
diff --git a/ruby/spec/test_repo_helper.rb b/ruby/spec/test_repo_helper.rb
new file mode 100644
index 000000000..53cdfe536
--- /dev/null
+++ b/ruby/spec/test_repo_helper.rb
@@ -0,0 +1,46 @@
+require 'fileutils'
+require 'securerandom'
+require 'gitaly'
+require 'rugged'
+
+DEFAULT_STORAGE_DIR = File.expand_path('../../tmp/repositories', __FILE__)
+DEFAULT_STORAGE_NAME = 'default'.freeze
+TEST_REPO_PATH = File.join(DEFAULT_STORAGE_DIR, 'gitlab-test.git')
+TEST_REPO_ORIGIN = '../internal/testhelper/testdata/data/gitlab-test.git'.freeze
+
+module TestRepo
+ def self.prepare_test_repository
+ FileUtils.rm_rf(Dir["#{DEFAULT_STORAGE_DIR}/mutable-*"])
+ return if File.directory?(TEST_REPO_PATH)
+
+ FileUtils.mkdir_p(DEFAULT_STORAGE_DIR)
+ clone_new_repo!(TEST_REPO_PATH)
+ end
+
+ def test_repo_read_only
+ Gitaly::Repository.new(storage_name: DEFAULT_STORAGE_NAME, relative_path: File.basename(TEST_REPO_PATH))
+ end
+
+ def new_mutable_test_repo
+ relative_path = "mutable-#{SecureRandom.hex(6)}.git"
+ TestRepo.clone_new_repo!(File.join(DEFAULT_STORAGE_DIR, relative_path))
+ Gitaly::Repository.new(storage_name: DEFAULT_STORAGE_NAME, relative_path: relative_path)
+ end
+
+ def rugged_from_gitaly(gitaly_repo)
+ Rugged::Repository.new(repo_path_from_gitaly(gitaly_repo))
+ end
+
+ def repo_path_from_gitaly(gitaly_repo)
+ storage_name = gitaly_repo.storage_name
+ raise "this helper does not know storage #{storage_name.inspect}" unless storage_name == DEFAULT_STORAGE_NAME
+ File.join(DEFAULT_STORAGE_DIR, gitaly_repo.relative_path)
+ end
+
+ def self.clone_new_repo!(destination)
+ return if system(*%W[git clone --quiet --bare #{TEST_REPO_ORIGIN} #{destination}])
+ abort "Failed to clone test repo. Try running 'make prepare-tests' and try again."
+ end
+end
+
+TestRepo.prepare_test_repository