unbound 1.0.0 → 1.0.1

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: b9e071138d458da3ab632fd55f7208e686e55679
4
- data.tar.gz: ffebd0663a8fe538b933c21cb35bd9f876ec64eb
3
+ metadata.gz: 268e920fce264b5a8fb5a60fc0f3b98d2648adde
4
+ data.tar.gz: fabfee310e6715df1e05e7ba455ae9fc64ae8f47
5
5
  SHA512:
6
- metadata.gz: 3190a931ff0e491a2c772056b486cad1c35b0e54ade6c6b6cf9429dfdd154157921fac796e62b34d0ea6ae699056a968b02776723179224c337bad716de2809d
7
- data.tar.gz: c539edfe6095cf3dba1c51411782ee6dcfc5f8c73e611270ebcaaa39e855dd61256c650d1f79ca6f058133c3bdadba7f08d4f75271d0317fbf5643d2d71ed15a
6
+ metadata.gz: 634924d61b650aeba4ee82632b34d95040da7aec61ac8a0a632fc3c4b48aeb082c0aca829b0baac77d5647880b933bf711f24f87b88eecc740489f3361dec432
7
+ data.tar.gz: 8029d61671926ea5874d9c2c4060cf788e11eae74e8c4d60228b9613263ee4ede4b39b20f04767a2565cea8141eb5291cf1289c55aaebeca75501dd02709560a
data/Gemfile CHANGED
@@ -5,10 +5,10 @@ gem "ffi"
5
5
 
6
6
  group :development do
7
7
  gem "jeweler"
8
- gem "rake"
9
8
  end
10
9
 
11
10
  group :test do
12
11
  gem "rspec"
13
12
  gem "simplecov"
13
+ gem "rake"
14
14
  end
data/Rakefile CHANGED
@@ -9,28 +9,35 @@ rescue Bundler::BundlerError => e
9
9
  end
10
10
  require 'rake'
11
11
 
12
- require 'jeweler'
13
- Jeweler::Tasks.new do |gem|
14
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
- gem.name = "unbound"
16
- gem.homepage = "http://github.com/justfalter/unbound-ruby"
17
- gem.license = "MIT"
18
- gem.summary = %Q{Unbound DNS resolver bindings for Ruby}
19
- gem.description = %Q{Unbound DNS resolver bindings for Ruby}
20
- gem.email = "falter@gmail.com"
21
- gem.authors = ["Mike Ryan"]
22
- gem.files = Dir.glob("lib/**/*.rb") +
23
- Dir.glob("examples/*") +
24
- Dir.glob("spec/{*.rb}") +
25
- Dir.glob("spec/conf/{*.conf}") +
26
- %w(LICENSE.txt Gemfile README.md Rakefile VERSION)
12
+ begin
13
+ require 'jeweler'
14
+ rescue LoadError
15
+ else
16
+ Jeweler::Tasks.new do |gem|
17
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
18
+ gem.name = "unbound"
19
+ gem.homepage = "http://github.com/justfalter/unbound-ruby"
20
+ gem.license = "MIT"
21
+ gem.summary = %Q{Unbound DNS resolver bindings for Ruby}
22
+ gem.description = %Q{Unbound DNS resolver bindings for Ruby}
23
+ gem.email = "falter@gmail.com"
24
+ gem.authors = ["Mike Ryan"]
25
+ gem.files = Dir.glob("lib/**/*.rb") +
26
+ Dir.glob("examples/*") +
27
+ Dir.glob("spec/{*.rb}") +
28
+ Dir.glob("spec/conf/{*.conf}") +
29
+ %w(LICENSE.txt Gemfile README.md Rakefile VERSION)
27
30
 
31
+ end
32
+ Jeweler::RubygemsDotOrgTasks.new
28
33
  end
29
- Jeweler::RubygemsDotOrgTasks.new
30
34
 
31
- require 'rspec/core'
32
- require 'rspec/core/rake_task'
33
- RSpec::Core::RakeTask.new(:spec) do |spec|
34
- spec.pattern = FileList['spec/**/*_spec.rb']
35
+ begin
36
+ rescue LoadError
37
+ else
38
+ require 'rspec/core'
39
+ require 'rspec/core/rake_task'
40
+ RSpec::Core::RakeTask.new(:spec) do |spec|
41
+ spec.pattern = FileList['spec/**/*_spec.rb']
42
+ end
35
43
  end
36
-
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.0.1
@@ -0,0 +1,54 @@
1
+ require 'ffi'
2
+
3
+ module Unbound
4
+ # Tracks in-flight queries for Resolver
5
+ class QueryStore
6
+ def initialize
7
+ @pointer_to_query_map = {}
8
+ end
9
+
10
+ # Enumerates through each query.
11
+ def each
12
+ @pointer_to_query_map.each_value do |query|
13
+ yield(query)
14
+ end
15
+ end
16
+
17
+ # Clears all queries from the store. No special actions taken.
18
+ def clear
19
+ @pointer_to_query_map.clear
20
+ end
21
+
22
+ # @return [Integer] the number of queries in the store.
23
+ def count
24
+ @pointer_to_query_map.count
25
+ end
26
+
27
+ # Retreives the query from the store via the provided pointer.
28
+ # @param [FFI::Pointer] pointer
29
+ # @return [Unbound::Query, nil] The associated query, otherwise nil.
30
+ def get_by_pointer(pointer)
31
+ return nil if pointer.nil?
32
+ @pointer_to_query_map[pointer.address]
33
+ end
34
+
35
+ # Stores a query object, and returns a pointer suitable for passing through
36
+ # Unbound::Context#resolve_async.
37
+ # @param [Unbound::Query] query
38
+ # @return [FFI::Pointer] the pointer
39
+ def store(query)
40
+ oid_ptr = FFI::Pointer.new query.object_id
41
+ @pointer_to_query_map[oid_ptr.address] = query
42
+ oid_ptr
43
+ end
44
+
45
+ # Deletes a query object from the store, and frees any associated pointer
46
+ # (if nescessary).
47
+ # @param [Unbound::Query] query
48
+ # @return [Unbound::Query] the query, if it was found. Otherwise nil.
49
+ def delete_query(query)
50
+ @pointer_to_query_map.delete(FFI::Pointer.new(query.object_id).address)
51
+ end
52
+ end
53
+ end
54
+
@@ -2,6 +2,7 @@ require 'unbound/bindings'
2
2
  require 'unbound/result'
3
3
  require 'unbound/context'
4
4
  require 'unbound/callbacks_mixin'
5
+ require 'unbound/query_store'
5
6
 
6
7
  module Unbound
7
8
  # A simple asynchronous resolver
@@ -12,7 +13,7 @@ module Unbound
12
13
  # resolver.
13
14
  def initialize(ctx)
14
15
  @ctx = ctx
15
- @queries = {}
16
+ @queries = QueryStore.new
16
17
  @resolve_callback_func = FFI::Function.new(
17
18
  :void, [:pointer, :int, :pointer],
18
19
  self.method(:resolve_callback))
@@ -25,7 +26,7 @@ module Unbound
25
26
  end
26
27
  end
27
28
  on_finish do |query|
28
- @queries.delete(query.object_id)
29
+ @queries.delete_query(query)
29
30
  end
30
31
  end
31
32
 
@@ -41,9 +42,7 @@ module Unbound
41
42
  end
42
43
 
43
44
  def resolve_callback(oid_ptr, err, result_ptr)
44
- return if oid_ptr.nil?
45
- oid = oid_ptr.address
46
- query = @queries[oid]
45
+ query = @queries.get_by_pointer(oid_ptr)
47
46
  return if query.nil?
48
47
 
49
48
  if err == 0
@@ -63,7 +62,7 @@ module Unbound
63
62
 
64
63
  # Cancel all outstanding queries.
65
64
  def cancel_all
66
- @queries.each_value do |query|
65
+ @queries.each do |query|
67
66
  query.cancel!
68
67
  end
69
68
  @queries.clear
@@ -95,20 +94,19 @@ module Unbound
95
94
  if query.started?
96
95
  raise QueryAlreadyStarted.new
97
96
  end
98
- @queries[query.object_id] = query
99
97
  # Add all of our callbacks, if any have been registered.
100
98
  query.on_start(*@callbacks_start) unless @callbacks_start.empty?
101
99
  query.on_answer(*@callbacks_answer) unless @callbacks_answer.empty?
102
100
  query.on_error(*@callbacks_error) unless @callbacks_error.empty?
103
101
  query.on_cancel(*@callbacks_cancel)
104
102
  query.on_finish(*@callbacks_finish)
105
- oid_ptr = FFI::Pointer.new query.object_id
103
+ ptr = @queries.store(query)
106
104
  async_id = @ctx.resolve_async(
107
105
  query.name,
108
106
  query.rrtype,
109
107
  query.rrclass,
110
108
  @resolve_callback_func,
111
- oid_ptr)
109
+ ptr)
112
110
  query.start!(async_id)
113
111
  end
114
112
  end
@@ -0,0 +1,139 @@
1
+ require 'spec_helper'
2
+
3
+ describe Unbound::QueryStore do
4
+ let(:query_store) {
5
+ Unbound::QueryStore.new
6
+ }
7
+
8
+ def new_query(num)
9
+ Unbound::Query.new("somedomain#{num}.com", 1, 1)
10
+ end
11
+
12
+ describe "#each" do
13
+ it "should yield as many times as there are queries in the store" do
14
+ 5.times do |i|
15
+ query_store.store(new_query(i))
16
+ end
17
+ expect {|b| query_store.each(&b)}.to yield_control.exactly(5).times
18
+ end
19
+ it "should yield the set of query objects we put into it" do
20
+ expected_queries = []
21
+ actual_queries = []
22
+ 5.times do |i|
23
+ query = new_query(i)
24
+ expected_queries << query
25
+ query_store.store(query)
26
+ end
27
+ query_store.each do |query|
28
+ actual_queries << query
29
+ end
30
+ expect(actual_queries).to match_array(expected_queries)
31
+ end
32
+ end
33
+ describe "#clear" do
34
+ it "should cause the count to drop to 0" do
35
+ expect(query_store.count).to eq(0)
36
+ 5.times do |i|
37
+ query_store.store(new_query(i))
38
+ end
39
+ expect(query_store.count).to eq(5)
40
+ query_store.clear
41
+ expect(query_store.count).to eq(0)
42
+ end
43
+ it "should remove all queries from the store, making it so they cannot be retreived" do
44
+ queries = {}
45
+ 5.times do |i|
46
+ query = new_query(i)
47
+ ptr = query_store.store(query)
48
+ queries[ptr] = query
49
+ end
50
+
51
+ queries.each_pair do |ptr, query|
52
+ expect(query_store.get_by_pointer(ptr)).to be(query)
53
+ end
54
+
55
+ query_store.clear
56
+ queries.each_pair do |ptr, query|
57
+ expect(query_store.get_by_pointer(ptr)).to be_nil
58
+ end
59
+ end
60
+ end
61
+ describe "#count" do
62
+ it "should be 0 if there's nothing in there" do
63
+ expect(query_store.count).to eq(0)
64
+ end
65
+ it "should be 5 if five distinct queries have been added" do
66
+ 5.times do |i|
67
+ query_store.store(new_query(i))
68
+ end
69
+ expect(query_store.count).to eq(5)
70
+ end
71
+ it "should be 1 if the same query was added 5 times" do
72
+ query = new_query(1)
73
+ 5.times do |i|
74
+ query_store.store(query)
75
+ end
76
+ expect(query_store.count).to eq(1)
77
+ end
78
+ end
79
+ describe "#store" do
80
+ it "should return a pointer" do
81
+ expect(query_store.store(new_query(1))).to be_a(FFI::Pointer)
82
+ end
83
+ it "should increase the count" do
84
+ query = new_query(1)
85
+ expect(query_store.count).to eq(0)
86
+ query_store.store(query)
87
+ expect(query_store.count).to eq(1)
88
+ end
89
+ end
90
+ describe "#get_by_pointer" do
91
+ it "should return the query associated with the provided pointer" do
92
+ query1 = new_query(1)
93
+ query2 = new_query(2)
94
+ query3 = new_query(3)
95
+ query4 = new_query(4)
96
+ query5 = new_query(5)
97
+ ptr1 = query_store.store(query1)
98
+ ptr2 = query_store.store(query2)
99
+ ptr3 = query_store.store(query3)
100
+ ptr4 = query_store.store(query4)
101
+ ptr5 = query_store.store(query5)
102
+ expect(query_store.get_by_pointer(ptr1)).to be(query1)
103
+ expect(query_store.get_by_pointer(ptr2)).to be(query2)
104
+ expect(query_store.get_by_pointer(ptr3)).to be(query3)
105
+ expect(query_store.get_by_pointer(ptr4)).to be(query4)
106
+ expect(query_store.get_by_pointer(ptr5)).to be(query5)
107
+ end
108
+ it "should return nil if the provided pointer is not associated with a query" do
109
+ expect(query_store.get_by_pointer(FFI::Pointer.new(1234))).to be_nil
110
+ end
111
+ end
112
+ describe "#delete_query" do
113
+ it "should make it so the query can no longer be retreived from the store" do
114
+ query1 = new_query(1)
115
+ query2 = new_query(2)
116
+ ptr1 = query_store.store(query1)
117
+ ptr2 = query_store.store(query2)
118
+ expect(query_store.get_by_pointer(ptr1)).to be(query1)
119
+ expect(query_store.get_by_pointer(ptr2)).to be(query2)
120
+ query_store.delete_query(query1)
121
+ expect(query_store.get_by_pointer(ptr1)).to be_nil
122
+ expect(query_store.get_by_pointer(ptr2)).to be(query2)
123
+ query_store.delete_query(query2)
124
+ expect(query_store.get_by_pointer(ptr1)).to be_nil
125
+ expect(query_store.get_by_pointer(ptr2)).to be_nil
126
+ end
127
+ it "should return the query that was deleted" do
128
+ query1 = new_query(1)
129
+ ptr1 = query_store.store(query1)
130
+ expect(query_store.delete_query(query1)).to be(query1)
131
+ end
132
+ it "should return nil if the query was not in the store" do
133
+ query1 = new_query(1)
134
+ expect(query_store.delete_query(query1)).to be_nil
135
+ end
136
+ end
137
+ end
138
+
139
+
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.0
4
+ version: 1.0.1
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-01-31 00:00:00.000000000 Z
11
+ date: 2014-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -38,20 +38,6 @@ dependencies:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: rake
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - '>='
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
41
  description: Unbound DNS resolver bindings for Ruby
56
42
  email: falter@gmail.com
57
43
  executables: []
@@ -73,6 +59,7 @@ files:
73
59
  - lib/unbound/context.rb
74
60
  - lib/unbound/exceptions.rb
75
61
  - lib/unbound/query.rb
62
+ - lib/unbound/query_store.rb
76
63
  - lib/unbound/resolver.rb
77
64
  - lib/unbound/result.rb
78
65
  - spec/callback_array_spec.rb
@@ -80,6 +67,7 @@ files:
80
67
  - spec/conf/test_config.conf
81
68
  - spec/context_spec.rb
82
69
  - spec/query_spec.rb
70
+ - spec/query_store_spec.rb
83
71
  - spec/resolver_spec.rb
84
72
  - spec/result_spec.rb
85
73
  - spec/spec_helper.rb