unbound 1.0.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 268e920fce264b5a8fb5a60fc0f3b98d2648adde
4
- data.tar.gz: fabfee310e6715df1e05e7ba455ae9fc64ae8f47
3
+ metadata.gz: 3cc064fa99fcaf867d9474ede41d93ad258742e4
4
+ data.tar.gz: dd0dd181466af047705bb39f94db521141eaa752
5
5
  SHA512:
6
- metadata.gz: 634924d61b650aeba4ee82632b34d95040da7aec61ac8a0a632fc3c4b48aeb082c0aca829b0baac77d5647880b933bf711f24f87b88eecc740489f3361dec432
7
- data.tar.gz: 8029d61671926ea5874d9c2c4060cf788e11eae74e8c4d60228b9613263ee4ede4b39b20f04767a2565cea8141eb5291cf1289c55aaebeca75501dd02709560a
6
+ metadata.gz: 51c16931c919a0635208f7ec37f4820f5a7b53e9ec7de05d34f8f0c52d0496dd3e2be8684bf7ac3fedf0cb91565d8c9a14076885b789efd91eda13efbb708f81
7
+ data.tar.gz: b24c0751df53c3e44418db0c85de1b8678c9bd0f0a6180511316ba88adcf39bb17c499a458927661a38b6d5545b8fd9cc0bee76249a37ce59fdbdadbec9e67f1
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.1
1
+ 2.0.0
@@ -71,10 +71,17 @@ module Unbound
71
71
  raise_if_error!(Unbound::Bindings.ub_cancel(@ub_ctx, async_id))
72
72
  end
73
73
 
74
+ # Returns a brand new IO for the file descriptor that can be selected to
75
+ # determine if processing needs to be done.
76
+ # Warning: DO NOT CLOSE THIS IO OBJECT! Use Context#close, instead.
77
+ # @return [FFI::IO] a brand new IO for the context's file descriptor
74
78
  def io
75
- return ::FFI::IO.for_fd(self.fd)
79
+ ret = ::FFI::IO.for_fd(self.fd)
80
+ ret.autoclose = false
81
+ return ret
76
82
  end
77
83
 
84
+ # Returns the number for the file descriptor.
78
85
  def fd
79
86
  check_closed!
80
87
  Unbound::Bindings.ub_fd(@ub_ctx)
@@ -65,6 +65,7 @@ module Unbound
65
65
  private
66
66
  def finish!()
67
67
  @state = STATE_FINISHED
68
+ @async_id = nil
68
69
  @callbacks_finish.call(self)
69
70
  clear_callbacks!
70
71
  end
@@ -20,16 +20,18 @@ module Unbound
20
20
 
21
21
  init_callbacks
22
22
 
23
- on_cancel do |query|
24
- if query.async_id
25
- @ctx.cancel_async_query(query.async_id)
26
- end
27
- end
28
23
  on_finish do |query|
29
24
  @queries.delete_query(query)
30
25
  end
31
26
  end
32
27
 
28
+ # @param [Unbound::Query] query The query that will be canceled
29
+ def cancel_query(query)
30
+ return if query.async_id.nil?
31
+ @ctx.cancel_async_query(query.async_id)
32
+ query.cancel!
33
+ end
34
+
33
35
  # @return [Integer] the number of queries for which we are awaiting reply
34
36
  def outstanding_queries
35
37
  @queries.count
@@ -63,7 +65,7 @@ module Unbound
63
65
  # Cancel all outstanding queries.
64
66
  def cancel_all
65
67
  @queries.each do |query|
66
- query.cancel!
68
+ cancel_query(query)
67
69
  end
68
70
  @queries.clear
69
71
  end
@@ -98,7 +100,8 @@ module Unbound
98
100
  query.on_start(*@callbacks_start) unless @callbacks_start.empty?
99
101
  query.on_answer(*@callbacks_answer) unless @callbacks_answer.empty?
100
102
  query.on_error(*@callbacks_error) unless @callbacks_error.empty?
101
- query.on_cancel(*@callbacks_cancel)
103
+ query.on_cancel(*@callbacks_cancel) unless @callbacks_cancel.empty?
104
+
102
105
  query.on_finish(*@callbacks_finish)
103
106
  ptr = @queries.store(query)
104
107
  async_id = @ctx.resolve_async(
@@ -139,6 +139,33 @@ describe Unbound::Context do
139
139
  end
140
140
  end
141
141
 
142
+ describe "#io" do
143
+ it "should return an IO object" do
144
+ expect(@ctx.io).to be_a(::IO)
145
+ end
146
+
147
+ it "should return a new IO object for each call" do
148
+ expect(@ctx.io).not_to be(@ctx.io)
149
+ end
150
+
151
+ it "should not be set to autoclose" do
152
+ expect(@ctx.io.autoclose?).to be_false
153
+ end
154
+
155
+ it "should not autoclose when garbage collection occurs" do
156
+ do_gc = lambda { ObjectSpace.garbage_collect }
157
+
158
+ if Object.const_defined?(:JRuby)
159
+ # Try to get some GC under JRuby
160
+ do_gc = lambda { java.lang.System.gc() }
161
+ end
162
+ ::IO::select([@ctx.io], nil, nil, 0)
163
+ do_gc.call()
164
+ expect {
165
+ ::IO::select([@ctx.io], nil, nil, 0)
166
+ }.not_to raise_error
167
+ end
168
+ end
142
169
 
143
170
  describe "asynchronous query processing via select/process" do
144
171
  before :each do
@@ -33,6 +33,22 @@ describe Unbound::Query do
33
33
  end
34
34
  end
35
35
 
36
+ describe "#async_id" do
37
+ it "should be nil if the query hasn't been started" do
38
+ expect(@query.async_id).to be_nil
39
+ end
40
+ it "should be the proper value if it has been started" do
41
+ expect(@query.async_id).to be_nil
42
+ @query.start!(1234)
43
+ expect(@query.async_id).to eq(1234)
44
+ end
45
+ it "should be nil if the query has been finished" do
46
+ @query.start!(1234)
47
+ @query.cancel!
48
+ expect(@query.async_id).to be_nil
49
+ end
50
+ end
51
+
36
52
  describe "#start!" do
37
53
  it "should set the async_id" do
38
54
  expect(@query.async_id).to be_nil
@@ -66,6 +82,11 @@ describe Unbound::Query do
66
82
  end
67
83
 
68
84
  describe "#error!" do
85
+ before :each do
86
+ @async_id = 9999
87
+ @query.start!(@async_id)
88
+ end
89
+
69
90
  it "should require an error code as an argument" do
70
91
  expect {
71
92
  @query.error!
@@ -79,9 +100,19 @@ describe Unbound::Query do
79
100
  @query.error!(1234)
80
101
  expect(@query).to be_finished
81
102
  end
103
+
104
+ it "should have set async_id to nil" do
105
+ @query.error!(1234)
106
+ expect(@query.async_id).to be_nil
107
+ end
82
108
  end
83
109
 
84
110
  describe "#answer!" do
111
+ before :each do
112
+ @async_id = 9999
113
+ @query.start!(@async_id)
114
+ end
115
+
85
116
  it "should require a result as an argument" do
86
117
  expect {
87
118
  @query.answer!
@@ -97,9 +128,20 @@ describe Unbound::Query do
97
128
  @query.answer!(result)
98
129
  expect(@query).to be_finished
99
130
  end
131
+
132
+ it "should have set async_id to nil" do
133
+ result = double("Result")
134
+ @query.answer!(result)
135
+ expect(@query.async_id).to be_nil
136
+ end
100
137
  end
101
138
 
102
139
  describe "#cancel!" do
140
+ before :each do
141
+ @async_id = 9999
142
+ @query.start!(@async_id)
143
+ end
144
+
103
145
  it "should require that no arguments be specified" do
104
146
  expect {
105
147
  @query.cancel!(1234)
@@ -113,6 +155,11 @@ describe Unbound::Query do
113
155
  @query.cancel!
114
156
  expect(@query).to be_finished
115
157
  end
158
+
159
+ it "should have set async_id to nil" do
160
+ @query.cancel!
161
+ expect(@query.async_id).to be_nil
162
+ end
116
163
  end
117
164
 
118
165
 
@@ -29,6 +29,20 @@ describe Unbound::QueryStore do
29
29
  end
30
30
  expect(actual_queries).to match_array(expected_queries)
31
31
  end
32
+ it "should not yield deleted queries" do
33
+ q1 = new_query(1)
34
+ q2 = new_query(2)
35
+ q3 = new_query(3)
36
+ query_store.store(q1)
37
+ query_store.store(q2)
38
+ query_store.store(q3)
39
+ query_store.delete_query(q2)
40
+ remaining_queries = []
41
+ query_store.each do |query|
42
+ remaining_queries << query
43
+ end
44
+ expect(remaining_queries).to match_array([q1, q3])
45
+ end
32
46
  end
33
47
  describe "#clear" do
34
48
  it "should cause the count to drop to 0" do
@@ -9,29 +9,71 @@ describe Unbound::Resolver do
9
9
  after :each do
10
10
  @resolver.close unless @resolver.closed?
11
11
  end
12
+
13
+ let(:query) { Unbound::Query.new("localhost", 1, 1) }
12
14
 
13
15
  describe "#cancel_all" do
14
16
  it "should cancel all queries" do
15
- query1 = Unbound::Query.new("localhost", 1, 1)
16
17
  expect { |cb|
17
- query1.on_cancel(cb.to_proc)
18
- @resolver.send_query(query1)
18
+ query.on_cancel(cb.to_proc)
19
+ @resolver.send_query(query)
19
20
  @resolver.cancel_all
20
21
  }.to yield_control
21
22
  end
22
23
  end
23
24
 
24
25
  describe "#outstanding_queries" do
25
- it "should return the number of outstanding queries" do
26
+ it "should be zero if there are no queries" do
26
27
  expect(@resolver.outstanding_queries).to eq(0)
27
- 10.times do
28
- query = Unbound::Query.new("localhost", 1, 1)
29
- @resolver.send_query(query)
30
- end
31
- expect(@resolver.outstanding_queries).to eq(10)
32
- @resolver.cancel_all
28
+ end
29
+
30
+ it "should go up by one for each query added" do
31
+ q1 = Unbound::Query.new("localhost", 1, 1)
32
+ q2 = Unbound::Query.new("localhost", 1, 1)
33
+ q3 = Unbound::Query.new("localhost", 1, 1)
34
+ q4 = Unbound::Query.new("localhost", 1, 1)
35
+ expect(@resolver.outstanding_queries).to eq(0)
36
+ @resolver.send_query(q1)
37
+ expect(@resolver.outstanding_queries).to eq(1)
38
+ @resolver.send_query(q2)
39
+ expect(@resolver.outstanding_queries).to eq(2)
40
+ @resolver.send_query(q3)
41
+ expect(@resolver.outstanding_queries).to eq(3)
42
+ @resolver.send_query(q4)
43
+ expect(@resolver.outstanding_queries).to eq(4)
44
+ end
45
+
46
+ it "should drop by one for each query canceled" do
47
+ q1 = Unbound::Query.new("localhost", 1, 1)
48
+ q2 = Unbound::Query.new("localhost", 1, 1)
49
+ q3 = Unbound::Query.new("localhost", 1, 1)
50
+ q4 = Unbound::Query.new("localhost", 1, 1)
51
+ @resolver.send_query(q1)
52
+ @resolver.send_query(q2)
53
+ @resolver.send_query(q3)
54
+ @resolver.send_query(q4)
55
+ expect(@resolver.outstanding_queries).to eq(4)
56
+ @resolver.cancel_query(q1)
57
+ expect(@resolver.outstanding_queries).to eq(3)
58
+ @resolver.cancel_query(q2)
59
+ expect(@resolver.outstanding_queries).to eq(2)
60
+ @resolver.cancel_query(q3)
61
+ expect(@resolver.outstanding_queries).to eq(1)
62
+ @resolver.cancel_query(q4)
33
63
  expect(@resolver.outstanding_queries).to eq(0)
34
64
  end
65
+
66
+ it "should not reduce the count by more than one if the same query is canceled twice" do
67
+ q1 = Unbound::Query.new("localhost", 1, 1)
68
+ q2 = Unbound::Query.new("localhost", 1, 1)
69
+ @resolver.send_query(q1)
70
+ @resolver.send_query(q2)
71
+ expect(@resolver.outstanding_queries).to eq(2)
72
+ @resolver.cancel_query(q1)
73
+ expect(@resolver.outstanding_queries).to eq(1)
74
+ @resolver.cancel_query(q1)
75
+ expect(@resolver.outstanding_queries).to eq(1)
76
+ end
35
77
  end
36
78
 
37
79
  describe "#outstanding_queries?" do
@@ -40,7 +82,6 @@ describe Unbound::Resolver do
40
82
  end
41
83
 
42
84
  it "should be true if there are any outstanding queries" do
43
- query = Unbound::Query.new("localhost", 1, 1)
44
85
  @resolver.send_query(query)
45
86
  expect(@resolver.outstanding_queries?).to be_true
46
87
  end
@@ -69,17 +110,20 @@ describe Unbound::Resolver do
69
110
  end
70
111
 
71
112
  describe "#io" do
72
- it "should return an IO object" do
73
- expect(@resolver.io).to be_a(::IO)
113
+ it "should pass through to ctx.io" do
114
+ ctx = double("Context")
115
+ resolver = Unbound::Resolver.new(ctx)
116
+ expect(ctx).to receive(:io)
117
+ resolver.io
74
118
  end
119
+
75
120
  end
76
121
 
77
122
  describe "#process" do
78
123
  it "should call our callback" do
79
- query1 = Unbound::Query.new("localhost", 1, 1)
80
124
  expect { |cb|
81
- query1.on_answer(cb.to_proc)
82
- @resolver.send_query(query1)
125
+ query.on_answer(cb.to_proc)
126
+ @resolver.send_query(query)
83
127
  io = @resolver.io
84
128
  expect(::IO.select([io], nil, nil, 5)).to_not be_nil
85
129
  @resolver.process
@@ -87,17 +131,45 @@ describe Unbound::Resolver do
87
131
  end
88
132
  end
89
133
 
134
+ describe "#cancel_query" do
135
+ it "should all context#cancel_async_query" do
136
+ expect(@context).to receive(:cancel_async_query).and_call_original
137
+ @resolver.send_query(query)
138
+ @resolver.cancel_query(query)
139
+ end
140
+
141
+ it "should set query.async_id to nil" do
142
+ @resolver.send_query(query)
143
+ expect(query.async_id).not_to be_nil
144
+ @resolver.cancel_query(query)
145
+ expect(query.async_id).to be_nil
146
+ end
147
+
148
+ it "should call 'query#cancel!' only once" do
149
+ @resolver.send_query(query)
150
+ expect(query).to receive(:cancel!).exactly(1).times.and_call_original
151
+ @resolver.cancel_query(query)
152
+ @resolver.close
153
+ end
154
+
155
+ it "shouldn't try to cancel if the query hasn't been sent" do
156
+ query = double("Query")
157
+ allow(query).to receive(:async_id).and_return(nil)
158
+ ctx = double("Context")
159
+ resolver = Unbound::Resolver.new(ctx)
160
+ resolver.cancel_query(query)
161
+ end
162
+ end
163
+
90
164
  describe "#send_query" do
91
165
  it "should raise an exception if the same query object is submitted twice" do
92
- query1 = Unbound::Query.new("localhost", 1, 1)
93
- @resolver.send_query(query1)
94
- expect {@resolver.send_query(query1)}.to raise_error
166
+ @resolver.send_query(query)
167
+ expect {@resolver.send_query(query)}.to raise_error
95
168
  end
96
169
  end
97
170
 
98
171
  describe "#on_start" do
99
172
  specify "callbacks should be called when send_query is called" do
100
- query = Unbound::Query.new("localhost", 1, 1)
101
173
  expect { |cb|
102
174
  @resolver.on_start(&cb)
103
175
  @resolver.send_query(query)
@@ -107,7 +179,6 @@ describe Unbound::Resolver do
107
179
 
108
180
  describe "#on_answer" do
109
181
  specify "callbacks should be called if the query has been answered" do
110
- query = Unbound::Query.new("localhost", 1, 1)
111
182
  result = double("Result")
112
183
  expect { |cb|
113
184
  @resolver.on_answer(&cb)
@@ -119,7 +190,6 @@ describe Unbound::Resolver do
119
190
 
120
191
  describe "#on_error" do
121
192
  specify "callbacks should be called if the query has an error" do
122
- query = Unbound::Query.new("localhost", 1, 1)
123
193
  result = double("Result")
124
194
  expect { |cb|
125
195
  @resolver.on_error(&cb)
@@ -131,24 +201,22 @@ describe Unbound::Resolver do
131
201
 
132
202
  describe "#on_cancel" do
133
203
  specify "callbacks should be called if the query has been canceled" do
134
- query = Unbound::Query.new("localhost", 1, 1)
135
204
  result = double("Result")
136
205
  expect { |cb|
137
206
  @resolver.on_cancel(&cb)
138
207
  @resolver.send_query(query)
139
- query.cancel!()
208
+ @resolver.cancel_query(query)
140
209
  }.to yield_with_args(query)
141
210
  end
142
211
  end
143
212
 
144
213
  describe "#on_finish" do
145
214
  specify "callbacks should be called if the query is finished for any reason" do
146
- query = Unbound::Query.new("localhost", 1, 1)
147
215
  result = double("Result")
148
216
  expect { |cb|
149
217
  @resolver.on_finish(&cb)
150
218
  @resolver.send_query(query)
151
- query.cancel!()
219
+ @resolver.cancel_query(query)
152
220
  }.to yield_with_args(query)
153
221
  end
154
222
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unbound
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Ryan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-06 00:00:00.000000000 Z
11
+ date: 2014-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi