summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/database_spec.rb
blob: edd01d032c86276e0a633069959a98a2d66c1f78 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
require 'spec_helper'

class MigrationTest
  include Gitlab::Database
end

describe Gitlab::Database, lib: true do
  describe '.adapter_name' do
    it 'returns the name of the adapter' do
      expect(described_class.adapter_name).to be_an_instance_of(String)
    end
  end

  # These are just simple smoke tests to check if the methods work (regardless
  # of what they may return).
  describe '.mysql?' do
    subject { described_class.mysql? }

    it { is_expected.to satisfy { |val| val == true || val == false } }
  end

  describe '.postgresql?' do
    subject { described_class.postgresql? }

    it { is_expected.to satisfy { |val| val == true || val == false } }
  end

  describe '.version' do
    context "on mysql" do
      it "extracts the version number" do
        allow(described_class).to receive(:database_version).
          and_return("5.7.12-standard")

        expect(described_class.version).to eq '5.7.12-standard'
      end
    end

    context "on postgresql" do
      it "extracts the version number" do
        allow(described_class).to receive(:database_version).
          and_return("PostgreSQL 9.4.4 on x86_64-apple-darwin14.3.0")

        expect(described_class.version).to eq '9.4.4'
      end
    end
  end

  describe '.nulls_last_order' do
    context 'when using PostgreSQL' do
      before { expect(described_class).to receive(:postgresql?).and_return(true) }

      it { expect(described_class.nulls_last_order('column', 'ASC')).to eq 'column ASC NULLS LAST'}
      it { expect(described_class.nulls_last_order('column', 'DESC')).to eq 'column DESC NULLS LAST'}
    end

    context 'when using MySQL' do
      before { expect(described_class).to receive(:postgresql?).and_return(false) }

      it { expect(described_class.nulls_last_order('column', 'ASC')).to eq 'column IS NULL, column ASC'}
      it { expect(described_class.nulls_last_order('column', 'DESC')).to eq 'column DESC'}
    end
  end

  describe '.nulls_first_order' do
    context 'when using PostgreSQL' do
      before { expect(described_class).to receive(:postgresql?).and_return(true) }

      it { expect(described_class.nulls_first_order('column', 'ASC')).to eq 'column ASC NULLS FIRST'}
      it { expect(described_class.nulls_first_order('column', 'DESC')).to eq 'column DESC NULLS FIRST'}
    end

    context 'when using MySQL' do
      before { expect(described_class).to receive(:postgresql?).and_return(false) }

      it { expect(described_class.nulls_first_order('column', 'ASC')).to eq 'column ASC'}
      it { expect(described_class.nulls_first_order('column', 'DESC')).to eq 'column IS NULL, column DESC'}
    end
  end

  describe '.with_connection_pool' do
    it 'creates a new connection pool and disconnect it after used' do
      closed_pool = nil

      described_class.with_connection_pool(1) do |pool|
        pool.with_connection do |connection|
          connection.execute('SELECT 1 AS value')
        end

        expect(pool).to be_connected

        closed_pool = pool
      end

      expect(closed_pool).not_to be_connected
    end

    it 'disconnects the pool even an exception was raised' do
      error = Class.new(RuntimeError)
      closed_pool = nil

      begin
        described_class.with_connection_pool(1) do |pool|
          pool.with_connection do |connection|
            connection.execute('SELECT 1 AS value')
          end

          closed_pool = pool

          raise error.new('boom')
        end
      rescue error
      end

      expect(closed_pool).not_to be_connected
    end
  end

  describe '.create_connection_pool' do
    it 'creates a new connection pool with specific pool size' do
      pool = described_class.create_connection_pool(5)

      begin
        expect(pool)
          .to be_kind_of(ActiveRecord::ConnectionAdapters::ConnectionPool)

        expect(pool.spec.config[:pool]).to eq(5)
      ensure
        pool.disconnect!
      end
    end

    it 'allows setting of a custom hostname' do
      pool = described_class.create_connection_pool(5, '127.0.0.1')

      begin
        expect(pool.spec.config[:host]).to eq('127.0.0.1')
      ensure
        pool.disconnect!
      end
    end
  end

  describe '#true_value' do
    it 'returns correct value for PostgreSQL' do
      expect(described_class).to receive(:postgresql?).and_return(true)

      expect(MigrationTest.new.true_value).to eq "'t'"
    end

    it 'returns correct value for MySQL' do
      expect(described_class).to receive(:postgresql?).and_return(false)

      expect(MigrationTest.new.true_value).to eq 1
    end
  end

  describe '#false_value' do
    it 'returns correct value for PostgreSQL' do
      expect(described_class).to receive(:postgresql?).and_return(true)

      expect(MigrationTest.new.false_value).to eq "'f'"
    end

    it 'returns correct value for MySQL' do
      expect(described_class).to receive(:postgresql?).and_return(false)

      expect(MigrationTest.new.false_value).to eq 0
    end
  end
end