Skip to content

Commit 2330cf2

Browse files
committed
Add CC::Resolv
1 parent 9aa5fbf commit 2330cf2

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

lib/cc/resolv.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
require "resolv-replace"
2+
3+
module CC
4+
class Resolv
5+
def self.with_fixed_dns(dns = ::Resolv::DNS.new)
6+
::Resolv::DefaultResolver.replace_resolvers([Fixed.new(dns)])
7+
8+
yield if block_given?
9+
ensure
10+
# There's no way to ask what the current values are before we override
11+
# them; hopefully going by the source is good enough.
12+
# https://docs.ruby-lang.org/en/2.0.0/Resolv.html#method-c-new
13+
default_resolvers = [::Resolv::Hosts.new, ::Resolv::DNS.new]
14+
::Resolv::DefaultResolver.replace_resolvers(default_resolvers)
15+
end
16+
17+
class Fixed
18+
def initialize(fallback)
19+
@addresses = {}
20+
@fallback = fallback
21+
end
22+
23+
def each_address(name)
24+
if addresses.key?(name)
25+
yield addresses.fetch(name)
26+
else
27+
fallback.each_address(name) do |address|
28+
addresses[name] ||= address
29+
yield address
30+
end
31+
end
32+
end
33+
34+
private
35+
36+
attr_reader :addresses, :fallback
37+
end
38+
end
39+
end

spec/cc/resolv_spec.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
require "spec_helper"
2+
require "cc/resolv"
3+
4+
module CC
5+
describe Resolv do
6+
describe ".with_fixed_dns" do
7+
it "replaces the default resolver for the duration of the block" do
8+
fallback = double
9+
10+
expect(fallback).to receive(:each_address).
11+
with("google.com").and_yield("overridden")
12+
13+
Resolv.with_fixed_dns(fallback) do
14+
expect(::Resolv.getaddress("google.com")).to eq "overridden"
15+
expect(::Resolv.getaddress("google.com")).to eq "overridden"
16+
end
17+
18+
expect(::Resolv.getaddress("google.com")).not_to eq "overridden"
19+
end
20+
end
21+
22+
describe Resolv::Fixed do
23+
describe "#each_address" do
24+
it "delegates to the fallback resolver and caches the first address" do
25+
fallback = double
26+
fixed = Resolv::Fixed.new(fallback)
27+
28+
allow(fallback).to receive(:each_address).
29+
with("host").once.
30+
and_yield("address-1").
31+
and_yield("address-2")
32+
33+
yielded_1 = []
34+
yielded_2 = []
35+
fixed.each_address("host") { |a| yielded_1 << a }
36+
fixed.each_address("host") { |a| yielded_2 << a }
37+
38+
expect(yielded_1).to eq ["address-1", "address-2"]
39+
expect(yielded_2).to eq ["address-1"]
40+
end
41+
end
42+
end
43+
end
44+
end

spec/support/resolv_helpers.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module ResolvHelpers
2+
def stub_resolv(name, address)
3+
dns = double
4+
allow(::Resolv::DNS).to receive(:new).and_return(dns)
5+
allow(dns).to receive(:each_address).
6+
with(name).and_yield(Resolv::IPv4.create(address))
7+
end
8+
end
9+
10+
RSpec.configure do |conf|
11+
conf.include(ResolvHelpers)
12+
end

0 commit comments

Comments
 (0)