1require 'socket' 2require 'spec_helper' 3 4SOCKET_PATH = 'gitaly.socket'.freeze 5 6module GitalyConfig 7 def self.set_dynamic_ports 8 tcp_sock = Socket.new(:INET, :STREAM) 9 tls_sock = Socket.new(:INET, :STREAM) 10 tcp_sock.bind(Addrinfo.tcp('127.0.0.1', 0)) 11 tls_sock.bind(Addrinfo.tcp('127.0.0.1', 0)) 12 13 @dynamic_tcp_port = tcp_sock.local_address.ip_port 14 @dynamic_tls_port = tls_sock.local_address.ip_port 15 ensure 16 tcp_sock.close 17 tls_sock.close 18 end 19 20 def self.dynamic_port(type) 21 set_dynamic_ports unless @dynamic_tcp_port && @dynamic_tls_port 22 23 case type 24 when 'tcp' 25 @dynamic_tcp_port 26 when 'tls' 27 @dynamic_tls_port 28 end 29 end 30end 31 32module IntegrationClient 33 def gitaly_stub(service, type = 'unix') 34 klass = Gitaly.const_get(service).const_get(:Stub) 35 addr = case type 36 when 'unix' 37 "unix:#{File.join(TMP_DIR_NAME, SOCKET_PATH)}" 38 when 'tcp', 'tls' 39 "#{type}://localhost:#{GitalyConfig.dynamic_port(type)}" 40 end 41 klass.new(addr, creds) 42 end 43 44 def creds 45 :this_channel_is_insecure 46 end 47 48 def gitaly_repo(storage, relative_path) 49 Gitaly::Repository.new(storage_name: storage, relative_path: relative_path) 50 end 51 52 def get_client(addr) 53 servers = Base64.strict_encode64({ 54 default: { 55 address: addr, 56 token: 'the-secret-token' 57 } 58 }.to_json) 59 60 call = double(metadata: { 'gitaly-servers' => servers }) 61 Gitlab::Git::GitalyRemoteRepository.new(repository.gitaly_repository, call) 62 end 63end 64 65def start_gitaly 66 build_dir = File.expand_path(File.join(GITALY_RUBY_DIR, '../_build')) 67 cert_path = File.join(File.dirname(__FILE__), "/certs") 68 69 FileUtils.mkdir_p([TMP_DIR, File.join(GITLAB_SHELL_DIR, 'hooks')]) 70 File.write(File.join(GITLAB_SHELL_DIR, '.gitlab_shell_secret'), 'test_gitlab_shell_token') 71 72 config_toml = <<~CONFIG 73 socket_path = "#{SOCKET_PATH}" 74 listen_addr = "localhost:#{GitalyConfig.dynamic_port('tcp')}" 75 tls_listen_addr = "localhost:#{GitalyConfig.dynamic_port('tls')}" 76 bin_dir = "#{build_dir}/bin" 77 78 [tls] 79 certificate_path = "#{cert_path}/gitalycert.pem" 80 key_path = "#{cert_path}/gitalykey.pem" 81 82 [gitlab-shell] 83 dir = "#{GITLAB_SHELL_DIR}" 84 85 [gitlab] 86 url = 'http://gitlab_url' 87 88 [gitaly-ruby] 89 dir = "#{GITALY_RUBY_DIR}" 90 91 [[storage]] 92 name = "#{DEFAULT_STORAGE_NAME}" 93 path = "#{DEFAULT_STORAGE_DIR}" 94 CONFIG 95 config_path = File.join(TMP_DIR, 'gitaly-rspec-config.toml') 96 File.write(config_path, config_toml) 97 98 test_log = File.join(TMP_DIR, 'gitaly-rspec-test.log') 99 options = { out: test_log, err: test_log, chdir: TMP_DIR } 100 101 gitaly_pid = spawn(File.join(build_dir, 'bin/gitaly'), config_path, options) 102 at_exit { Process.kill('KILL', gitaly_pid) } 103 104 wait_ready!(File.join(TMP_DIR_NAME, SOCKET_PATH)) 105end 106 107def wait_ready!(socket) 108 last_exception = StandardError.new('wait_ready! has not made any connection attempts') 109 110 print('Booting gitaly for integration tests') 111 100.times do |_i| 112 sleep 0.1 113 printf('.') 114 begin 115 UNIXSocket.new(socket).close 116 puts ' ok' 117 return 118 rescue => ex 119 last_exception = ex 120 end 121 end 122 123 puts 124 raise last_exception 125end 126 127start_gitaly 128