File: secondary_reads_spec.rb

package info (click to toggle)
ruby-mongo 2.21.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 14,764 kB
  • sloc: ruby: 108,806; makefile: 5; sh: 2
file content (103 lines) | stat: -rw-r--r-- 2,771 bytes parent folder | download
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
# rubocop:todo all
require 'spec_helper'

describe 'Secondary reads' do
  before do
    root_authorized_client.use('sr')['secondary_reads'].drop
    root_authorized_client.use('sr')['secondary_reads'].insert_one(test: 1)
  end

  shared_examples 'performs reads as per read preference' do

    %i(primary primary_preferred).each do |mode|

      context mode.inspect do

        let(:client) do
          root_authorized_client.with(read: {mode: mode}).use('sr')
        end

        it 'reads from primary' do
          start_stats = get_read_counters

          30.times do
            client['secondary_reads'].find.to_a
          end

          end_stats = get_read_counters

          end_stats[:secondary].should be_within(10).of(start_stats[:secondary])
          end_stats[:primary].should >= start_stats[:primary] + 30
        end
      end
    end

    %i(secondary secondary_preferred).each do |mode|

      context mode.inspect do
        let(:client) do
          root_authorized_client.with(read: {mode: mode}).use('sr')
        end

        it 'reads from secondaries' do
          start_stats = get_read_counters

          30.times do
            client['secondary_reads'].find.to_a
          end

          end_stats = get_read_counters

          end_stats[:primary].should be_within(10).of(start_stats[:primary])
          end_stats[:secondary].should >= start_stats[:secondary] + 30
        end
      end
    end
  end

  context 'replica set' do
    require_topology :replica_set

    include_examples 'performs reads as per read preference'
  end

  context 'sharded cluster' do
    require_topology :sharded

    include_examples 'performs reads as per read preference'
  end

  def get_read_counters
    client = ClientRegistry.instance.global_client('root_authorized')
    addresses = []
    if client.cluster.sharded?
      doc = client.use('admin').command(listShards: 1).documents.first
      doc['shards'].each do |shard|
        addresses += shard['host'].split('/').last.split(',')
      end
    else
      client.cluster.servers.each do |server|
        next unless server.primary? || server.secondary?
        addresses << server.address.seed
      end
    end
    stats = Hash.new(0)
    addresses.each do |address|
      ClientRegistry.instance.new_local_client(
        [address],
        SpecConfig.instance.all_test_options.merge(connect: :direct),
      ) do |c|
        server = c.cluster.servers.first
        next unless server.primary? || server.secondary?
        stat = c.command(serverStatus: 1).documents.first
        queries = stat['opcounters']['query']
        if server.primary?
          stats[:primary] += queries
        else
          stats[:secondary] += queries
        end
      end
    end
    stats
  end
end