File: server_block_spec.rb

package info (click to toggle)
ruby-sequel 5.41.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 9,548 kB
  • sloc: ruby: 104,241; makefile: 3
file content (135 lines) | stat: -rw-r--r-- 4,772 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
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
require_relative "spec_helper"

with_server_specs = shared_description do
  it "should set the default server to use in the block" do
    @db.with_server(:a){@db[:t].all}
    @db.sqls.must_equal ["SELECT * FROM t -- a"]
    @db.with_server(:b){@db[:t].all}
    @db.sqls.must_equal ["SELECT * FROM t -- b"]
  end

  it "should set the default server to use in the block" do
    @db.with_server(:a, :b){@db[:t].all}
    @db.sqls.must_equal ["SELECT * FROM t -- b"]
    @db.with_server(:a, :b){@db[:t].insert}
    @db.sqls.must_equal ["INSERT INTO t DEFAULT VALUES -- a"]
  end

  it "should have no affect after the block" do
    @db.with_server(:a){@db[:t].all}
    @db.sqls.must_equal ["SELECT * FROM t -- a"]
    @db[:t].all
    @db.sqls.must_equal ["SELECT * FROM t"]
  end

  it "should not override specific server inside the block" do
    @db.with_server(:a){@db[:t].server(:b).all}
    @db.sqls.must_equal ["SELECT * FROM t -- b"]
  end

  it "should work correctly when blocks are nested" do
    @db[:t].all
    @db.with_server(:a) do
      @db[:t].all
      @db.with_server(:b){@db[:t].all}
      @db[:t].all
    end
    @db[:t].all
    @db.sqls.must_equal ["SELECT * FROM t", "SELECT * FROM t -- a", "SELECT * FROM t -- b", "SELECT * FROM t -- a", "SELECT * FROM t"]
  end

  it "should work correctly for inserts/updates/deletes" do
    @db.with_server(:a) do
      @db[:t].insert
      @db[:t].update(:a=>1)
      @db[:t].delete
    end
    @db.sqls.must_equal ["INSERT INTO t DEFAULT VALUES -- a", "UPDATE t SET a = 1 -- a", "DELETE FROM t -- a"]
  end
end

describe "Database#with_server single threaded" do
  before do
    @db = Sequel.mock(:single_threaded=>true, :servers=>{:a=>{}, :b=>{}})
    @db.extension :server_block
  end

  include with_server_specs
end

describe "Database#with_server multi threaded" do
  before do
    @db = Sequel.mock(:servers=>{:a=>{}, :b=>{}, :c=>{}, :d=>{}})
    @db.extension :server_block
  end

  include with_server_specs

  it "should respect multithreaded access" do
    q, q1 = Queue.new, Queue.new
    
    t = nil
    @db[:t].all
    @db.with_server(:a) do
      @db[:t].all
      t = Thread.new do
        @db[:t].all
        @db.with_server(:c) do
          @db[:t].all
          @db.with_server(:d){@db[:t].all}
          q.push nil
          q1.pop
          @db[:t].all
        end
        @db[:t].all
      end
      q.pop
      @db.with_server(:b){@db[:t].all}
      @db[:t].all
    end
    @db[:t].all
    q1.push nil
    t.join
    @db.sqls.must_equal ["SELECT * FROM t", "SELECT * FROM t -- a", "SELECT * FROM t", "SELECT * FROM t -- c", "SELECT * FROM t -- d",
      "SELECT * FROM t -- b", "SELECT * FROM t -- a", "SELECT * FROM t", "SELECT * FROM t -- c", "SELECT * FROM t"]
  end
end

describe "Database#with_server with invalid servers" do
  def sqls(server)
    @db.with_server(server) do
      @db[:t].all
      @db[:t].insert
      @db[:t].update(:a=>1)
      @db[:t].delete
    end
    @db.sqls
  end

  it "when single threaded and no servers_hash" do
    @db = Sequel.mock(:single_threaded=>true, :servers=>{:a=>{}}).extension(:server_block)
    sqls(:a).must_equal ["SELECT * FROM t -- a", "INSERT INTO t DEFAULT VALUES -- a", "UPDATE t SET a = 1 -- a", "DELETE FROM t -- a"]
    sqls(:c).must_equal ["SELECT * FROM t", "INSERT INTO t DEFAULT VALUES", "UPDATE t SET a = 1", "DELETE FROM t"]
  end

  it "when multi-threaded and no servers_hash" do
    @db = Sequel.mock(:servers=>{:a=>{}}).extension(:server_block)
    sqls(:a).must_equal ["SELECT * FROM t -- a", "INSERT INTO t DEFAULT VALUES -- a", "UPDATE t SET a = 1 -- a", "DELETE FROM t -- a"]
    sqls(:c).must_equal ["SELECT * FROM t", "INSERT INTO t DEFAULT VALUES", "UPDATE t SET a = 1", "DELETE FROM t"]
  end

  it "when single threaded and servers_hash" do
    @db = Sequel.mock(:single_threaded=>true, :servers=>{:a=>{}, :b=>{}}, :servers_hash=>Hash.new{|_,k| raise}.merge!(:c=>:b)).extension(:server_block)
    sqls(:a).must_equal ["SELECT * FROM t -- a", "INSERT INTO t DEFAULT VALUES -- a", "UPDATE t SET a = 1 -- a", "DELETE FROM t -- a"]
    sqls(:c).must_equal ["SELECT * FROM t -- b", "INSERT INTO t DEFAULT VALUES -- b", "UPDATE t SET a = 1 -- b", "DELETE FROM t -- b"]
    proc{sqls(:d)}.must_raise(RuntimeError)
  end

  it "when multi-threaded and servers_hash" do
    @db = Sequel.mock(:servers=>{:a=>{}, :b=>{}}, :servers_hash=>Hash.new{|_,k| raise}.merge!(:c=>:b)).extension(:server_block)
    sqls(:a).must_equal ["SELECT * FROM t -- a", "INSERT INTO t DEFAULT VALUES -- a", "UPDATE t SET a = 1 -- a", "DELETE FROM t -- a"]
    sqls(:c).must_equal ["SELECT * FROM t -- b", "INSERT INTO t DEFAULT VALUES -- b", "UPDATE t SET a = 1 -- b", "DELETE FROM t -- b"]
    proc{sqls(:d)}.must_raise(RuntimeError)
  end
end