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

partition_creator_spec.rb « partitioning « database « gitlab « lib « spec - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 563999416628f422bcb106fe8cc0f6b7f4bdb539 (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
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Gitlab::Database::Partitioning::PartitionCreator do
  include PartitioningHelpers
  include ExclusiveLeaseHelpers

  describe '.register' do
    let(:model) { double(partitioning_strategy: nil) }

    it 'remembers registered models' do
      expect { described_class.register(model) }.to change { described_class.models }.to include(model)
    end
  end

  describe '#create_partitions (mocked)' do
    subject { described_class.new(models).create_partitions }

    let(:models) { [model] }
    let(:model) { double(partitioning_strategy: partitioning_strategy, table_name: table) }
    let(:partitioning_strategy) { double(missing_partitions: partitions) }
    let(:table) { "some_table" }

    before do
      allow(ActiveRecord::Base.connection).to receive(:table_exists?).and_call_original
      allow(ActiveRecord::Base.connection).to receive(:table_exists?).with(table).and_return(true)
      allow(ActiveRecord::Base.connection).to receive(:execute).and_call_original

      stub_exclusive_lease(described_class::LEASE_KEY % table, timeout: described_class::LEASE_TIMEOUT)
    end

    let(:partitions) do
      [
        instance_double(Gitlab::Database::Partitioning::TimePartition, table: 'bar', partition_name: 'foo', to_sql: "SELECT 1"),
        instance_double(Gitlab::Database::Partitioning::TimePartition, table: 'bar', partition_name: 'foo2', to_sql: "SELECT 2")
      ]
    end

    it 'creates the partition' do
      expect(ActiveRecord::Base.connection).to receive(:execute).with(partitions.first.to_sql)
      expect(ActiveRecord::Base.connection).to receive(:execute).with(partitions.second.to_sql)

      subject
    end

    context 'error handling with 2 models' do
      let(:models) do
        [
          double(partitioning_strategy: strategy1, table_name: table),
          double(partitioning_strategy: strategy2, table_name: table)
        ]
      end

      let(:strategy1) { double('strategy1', missing_partitions: nil) }
      let(:strategy2) { double('strategy2', missing_partitions: partitions) }

      it 'still creates partitions for the second table' do
        expect(strategy1).to receive(:missing_partitions).and_raise('this should never happen (tm)')
        expect(ActiveRecord::Base.connection).to receive(:execute).with(partitions.first.to_sql)
        expect(ActiveRecord::Base.connection).to receive(:execute).with(partitions.second.to_sql)

        subject
      end
    end
  end

  describe '#create_partitions' do
    subject { described_class.new([my_model]).create_partitions }

    let(:connection) { ActiveRecord::Base.connection }
    let(:my_model) do
      Class.new(ApplicationRecord) do
        include PartitionedTable

        self.table_name = 'my_model_example_table'

        partitioned_by :created_at, strategy: :monthly
      end
    end

    before do
      connection.execute(<<~SQL)
        CREATE TABLE my_model_example_table
        (id serial not null, created_at timestamptz not null, primary key (id, created_at))
        PARTITION BY RANGE (created_at);
      SQL
    end

    it 'creates partitions' do
      expect { subject }.to change { find_partitions(my_model.table_name, schema: Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA).size }.from(0)

      subject
    end
  end
end