dns_mock 0.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.codeclimate.yml +1 -1
- data/.reek.yml +13 -0
- data/.rubocop.yml +16 -1
- data/CHANGELOG.md +155 -0
- data/Gemfile.lock +9 -9
- data/README.md +134 -18
- data/dns_mock.gemspec +2 -2
- data/lib/dns_mock.rb +2 -2
- data/lib/dns_mock/core.rb +3 -1
- data/lib/dns_mock/record/builder/mx.rb +12 -1
- data/lib/dns_mock/record/builder/ptr.rb +9 -0
- data/lib/dns_mock/record/factory/ptr.rb +15 -0
- data/lib/dns_mock/response/answer.rb +5 -4
- data/lib/dns_mock/response/message.rb +8 -2
- data/lib/dns_mock/server.rb +5 -3
- data/lib/dns_mock/server/records_dictionary_builder.rb +14 -1
- data/lib/dns_mock/test_framework/rspec.rb +12 -0
- data/lib/dns_mock/test_framework/rspec/helper.rb +15 -0
- data/lib/dns_mock/test_framework/rspec/interface.rb +35 -0
- data/lib/dns_mock/version.rb +1 -1
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da8634cd856df1f65afef1ba6f87f3b6118fc54525d00843da76c7b0e415dfc0
|
4
|
+
data.tar.gz: 45d0c5f55c9460d3d555ed26ae474fe7a7f30d614e172ec22d430d531f941c61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4c7c08f00e98916c5d10580961bfa8518455d3323718327ca87767f699a78d4ceda1d2ea039150a8e05eec88dd50659519a46dadaf27c8f8c2504590951703c
|
7
|
+
data.tar.gz: 8fc55743a9ff129c5add8e1592b257046150c4267a621afc9bc0257901bfd3e72f4ac658fba03cde7f5608c1683584ebdf0e422af419e94f914eedcc465ed9e6
|
data/.codeclimate.yml
CHANGED
data/.reek.yml
CHANGED
@@ -20,6 +20,9 @@ detectors:
|
|
20
20
|
- DnsMock::RecordsDictionaryHelper#create_records_dictionary_by_records
|
21
21
|
- DnsMock::ServerHelper#start_random_server
|
22
22
|
- DnsMock::ServerHelper#stop_all_running_servers
|
23
|
+
- DnsMock::Server::RecordsDictionaryBuilder#rdns_lookup_prefix
|
24
|
+
- DnsMock::ContextGeneratorHelper#random_port_number
|
25
|
+
- DnsMock::TestFramework::RSpec::Helper#dns_mock_server
|
23
26
|
|
24
27
|
ControlParameter:
|
25
28
|
exclude:
|
@@ -44,3 +47,13 @@ detectors:
|
|
44
47
|
LongParameterList:
|
45
48
|
exclude:
|
46
49
|
- DnsMock::Server#initialize
|
50
|
+
- DnsMock#start_server
|
51
|
+
|
52
|
+
BooleanParameter:
|
53
|
+
exclude:
|
54
|
+
- DnsMock::Server#initialize
|
55
|
+
- DnsMock#start_server
|
56
|
+
|
57
|
+
NilCheck:
|
58
|
+
exclude:
|
59
|
+
- DnsMock::Record::Builder::Mx#build
|
data/.rubocop.yml
CHANGED
@@ -118,8 +118,11 @@ Style/EndlessMethod:
|
|
118
118
|
Style/HashExcept:
|
119
119
|
Enabled: true
|
120
120
|
|
121
|
+
Style/IfWithBooleanLiteralBranches:
|
122
|
+
Enabled: true
|
123
|
+
|
121
124
|
Layout/LineLength:
|
122
|
-
Max:
|
125
|
+
Max: 150
|
123
126
|
|
124
127
|
Layout/EmptyLinesAroundAttributeAccessor:
|
125
128
|
Enabled: true
|
@@ -203,6 +206,18 @@ Lint/RedundantDirGlobSort:
|
|
203
206
|
Lint/UnmodifiedReduceAccumulator:
|
204
207
|
Enabled: true
|
205
208
|
|
209
|
+
Lint/NumberedParameterAssignment:
|
210
|
+
Enabled: true
|
211
|
+
|
212
|
+
Lint/OrAssignmentToConstant:
|
213
|
+
Enabled: true
|
214
|
+
|
215
|
+
Lint/SymbolConversion:
|
216
|
+
Enabled: true
|
217
|
+
|
218
|
+
Lint/TripleQuotes:
|
219
|
+
Enabled: true
|
220
|
+
|
206
221
|
Performance/AncestorsInclude:
|
207
222
|
Enabled: true
|
208
223
|
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,161 @@
|
|
2
2
|
|
3
3
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
4
4
|
|
5
|
+
## [1.2.0] - 2021-02-04
|
6
|
+
|
7
|
+
### Ability to specify MX record priority
|
8
|
+
|
9
|
+
Added ability to specify custom priority of MX record if it needed. Now it impossible to define null or backup MX records. Please note, if you haven't specified a priority of MX record, it will be assigned automatically. MX records builder is assigning priority with step 10 from first item of defined MX records array.
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
records = {
|
13
|
+
'example.com' => {
|
14
|
+
mx: %w[.:0 mx1.domain.com:10 mx2.domain.com:10 mx3.domain.com]
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
DnsMock.start_server(records: records)
|
19
|
+
```
|
20
|
+
|
21
|
+
```bash
|
22
|
+
dig @localhost -p 5300 MX example.com
|
23
|
+
```
|
24
|
+
|
25
|
+
```
|
26
|
+
; <<>> DiG 9.10.6 <<>> @localhost -p 5300 MX example.com
|
27
|
+
|
28
|
+
;; ANSWER SECTION:
|
29
|
+
example.com. 1 IN MX 0 .
|
30
|
+
example.com. 1 IN MX 10 mx1.domain.com.
|
31
|
+
example.com. 1 IN MX 10 mx2.domain.com.
|
32
|
+
example.com. 1 IN MX 40 mx3.domain.com.
|
33
|
+
|
34
|
+
;; Query time: 0 msec
|
35
|
+
;; SERVER: 127.0.0.1#5300(127.0.0.1)
|
36
|
+
;; WHEN: Wed Feb 03 20:19:51 EET 2021
|
37
|
+
;; MSG SIZE rcvd: 102
|
38
|
+
```
|
39
|
+
|
40
|
+
## [1.1.0] - 2021-02-01
|
41
|
+
|
42
|
+
### RSpec native support
|
43
|
+
|
44
|
+
Added DnsMock helper which can simplify integration with RSpec.
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
# spec/support/config/dns_mock.rb
|
48
|
+
require 'dns_mock/test_framework/rspec'
|
49
|
+
|
50
|
+
RSpec.configure do |config|
|
51
|
+
config.include DnsMock::TestFramework::RSpec::Helper
|
52
|
+
end
|
53
|
+
|
54
|
+
# your awesome first_a_record_spec.rb
|
55
|
+
RSpec.describe FirstARecord do
|
56
|
+
subject(:service) do
|
57
|
+
described_class.call(
|
58
|
+
hostname,
|
59
|
+
dns_gateway_host: 'localhost',
|
60
|
+
dns_gateway_port: dns_mock_server.port
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
let(:hostname) { 'example.com' }
|
65
|
+
let(:first_a_record) { '1.2.3.4' }
|
66
|
+
let(:records) { { hostname => { a: [first_a_record] } } }
|
67
|
+
|
68
|
+
before { dns_mock_server.assign_mocks(records) }
|
69
|
+
|
70
|
+
it { is_expected.to eq(first_a_record) }
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
## [1.0.0] - 2021-01-29
|
75
|
+
|
76
|
+
### Configurable record not found behaviour
|
77
|
+
|
78
|
+
Added configurable strategy for record not found case. By default it won't raise an exception when DNS record not found in mocked records dictionary:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
DnsMock.start_server(port: 5300)
|
82
|
+
```
|
83
|
+
|
84
|
+
```bash
|
85
|
+
dig @localhost -p 5300 A example.com
|
86
|
+
```
|
87
|
+
|
88
|
+
```
|
89
|
+
; <<>> DiG 9.10.6 <<>> @localhost -p 5300 A example.com
|
90
|
+
;; Got answer:
|
91
|
+
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38632
|
92
|
+
;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
|
93
|
+
;; WARNING: recursion requested but not available
|
94
|
+
|
95
|
+
;; OPT PSEUDOSECTION:
|
96
|
+
; EDNS: version: 0, flags:; udp: 4096
|
97
|
+
;; QUESTION SECTION:
|
98
|
+
;example.com. IN A
|
99
|
+
|
100
|
+
;; Query time: 0 msec
|
101
|
+
;; SERVER: 127.0.0.1#5300(127.0.0.1)
|
102
|
+
;; WHEN: Fri Jan 29 08:21:30 EET 2021
|
103
|
+
;; MSG SIZE rcvd: 40
|
104
|
+
```
|
105
|
+
|
106
|
+
If you want raise an exception when record not found, just start `DnsMock` with `exception_if_not_found: true` option:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
DnsMock.start_server(exception_if_not_found: true)
|
110
|
+
```
|
111
|
+
|
112
|
+
### Changed
|
113
|
+
|
114
|
+
- Updated `DnsMock.start_server`
|
115
|
+
- Updated `DnsMock::Server`
|
116
|
+
- Updated `DnsMock::Response::Message`
|
117
|
+
- Updated `DnsMock::Response::Answer`
|
118
|
+
- Updated gem version, readme
|
119
|
+
|
120
|
+
## [0.2.1] - 2021-01-27
|
121
|
+
|
122
|
+
### Fixed RDNS lookup representation
|
123
|
+
|
124
|
+
Fixed RDNS lookup representatin for IP address in PTR record feature.
|
125
|
+
|
126
|
+
## [0.2.0] - 2021-01-26
|
127
|
+
|
128
|
+
### PTR record support
|
129
|
+
|
130
|
+
Added ability to mock PTR records. Please note, you can define host address without RDNS lookup prefix (`.in-addr.arpa`). `DnsMock` will do it for you.
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
records = {
|
134
|
+
'1.1.1.1' => {
|
135
|
+
ptr: %w[domain_1.com domain_2.com]
|
136
|
+
}
|
137
|
+
}
|
138
|
+
|
139
|
+
DnsMock.start_server(records: records)
|
140
|
+
```
|
141
|
+
|
142
|
+
```bash
|
143
|
+
dig @localhost -p 5300 -x 1.1.1.1
|
144
|
+
```
|
145
|
+
|
146
|
+
```
|
147
|
+
; <<>> DiG 9.10.6 <<>> @localhost -p 5300 -x 1.1.1.1
|
148
|
+
; (2 servers found)
|
149
|
+
|
150
|
+
;; ANSWER SECTION:
|
151
|
+
1.1.1.1.in-addr.arpa. 1 IN PTR domain_1.com.
|
152
|
+
1.1.1.1.in-addr.arpa. 1 IN PTR domain_2.com.
|
153
|
+
|
154
|
+
;; Query time: 0 msec
|
155
|
+
;; SERVER: 127.0.0.1#5300(127.0.0.1)
|
156
|
+
;; WHEN: Mon Jan 25 19:58:39 EET 2021
|
157
|
+
;; MSG SIZE rcvd: 98
|
158
|
+
```
|
159
|
+
|
5
160
|
## [0.1.0] - 2021-01-19
|
6
161
|
|
7
162
|
### First release
|
data/Gemfile.lock
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
dns_mock (
|
4
|
+
dns_mock (1.2.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
ast (2.4.
|
9
|
+
ast (2.4.2)
|
10
10
|
bundler-audit (0.7.0.1)
|
11
11
|
bundler (>= 1.2.0, < 3)
|
12
12
|
thor (>= 0.18, < 2)
|
@@ -14,7 +14,7 @@ GEM
|
|
14
14
|
childprocess (4.0.0)
|
15
15
|
coderay (1.1.3)
|
16
16
|
colorize (0.8.1)
|
17
|
-
concurrent-ruby (1.1.
|
17
|
+
concurrent-ruby (1.1.8)
|
18
18
|
diff-lcs (1.4.4)
|
19
19
|
dnsruby (1.61.5)
|
20
20
|
simpleidn (~> 0.1)
|
@@ -65,11 +65,11 @@ GEM
|
|
65
65
|
rspec-expectations (3.10.1)
|
66
66
|
diff-lcs (>= 1.2.0, < 2.0)
|
67
67
|
rspec-support (~> 3.10.0)
|
68
|
-
rspec-mocks (3.10.
|
68
|
+
rspec-mocks (3.10.2)
|
69
69
|
diff-lcs (>= 1.2.0, < 2.0)
|
70
70
|
rspec-support (~> 3.10.0)
|
71
|
-
rspec-support (3.10.
|
72
|
-
rubocop (1.
|
71
|
+
rspec-support (3.10.2)
|
72
|
+
rubocop (1.9.0)
|
73
73
|
parallel (~> 1.10)
|
74
74
|
parser (>= 3.0.0.0)
|
75
75
|
rainbow (>= 2.2.2, < 4.0)
|
@@ -78,7 +78,7 @@ GEM
|
|
78
78
|
rubocop-ast (>= 1.2.0, < 2.0)
|
79
79
|
ruby-progressbar (~> 1.7)
|
80
80
|
unicode-display_width (>= 1.4.0, < 3.0)
|
81
|
-
rubocop-ast (1.4.
|
81
|
+
rubocop-ast (1.4.1)
|
82
82
|
parser (>= 2.7.1.5)
|
83
83
|
rubocop-performance (1.9.2)
|
84
84
|
rubocop (>= 0.90.0, < 2.0)
|
@@ -97,7 +97,7 @@ GEM
|
|
97
97
|
simplecov-html (0.10.2)
|
98
98
|
simpleidn (0.2.1)
|
99
99
|
unf (~> 0.1.4)
|
100
|
-
thor (1.0
|
100
|
+
thor (1.1.0)
|
101
101
|
unf (0.1.4)
|
102
102
|
unf_ext
|
103
103
|
unf_ext (0.0.7.7)
|
@@ -118,7 +118,7 @@ DEPENDENCIES
|
|
118
118
|
reek (~> 6.0, >= 6.0.3)
|
119
119
|
rspec (~> 3.10)
|
120
120
|
rspec-dns (~> 0.1.8)
|
121
|
-
rubocop (~> 1.
|
121
|
+
rubocop (~> 1.9)
|
122
122
|
rubocop-performance (~> 1.9, >= 1.9.2)
|
123
123
|
rubocop-rspec (~> 2.1)
|
124
124
|
simplecov (~> 0.17.1)
|
data/README.md
CHANGED
@@ -1,27 +1,40 @@
|
|
1
1
|
# Ruby DnsMock
|
2
2
|
|
3
|
-
[](https://codeclimate.com/github/mocktools/ruby-dns-mock/maintainability)
|
4
|
+
[](https://codeclimate.com/github/mocktools/ruby-dns-mock/test_coverage)
|
5
|
+
[](https://circleci.com/gh/mocktools/ruby-dns-mock/tree/master)
|
4
6
|
[](https://badge.fury.io/rb/dns_mock)
|
5
7
|
[](https://rubygems.org/gems/dns_mock)
|
6
8
|
[](LICENSE.txt)
|
7
9
|
[](CODE_OF_CONDUCT.md)
|
8
10
|
|
11
|
+
💎 Ruby DNS mock. Mimic any DNS records for your test environment and even more.
|
12
|
+
|
9
13
|
## Table of Contents
|
10
14
|
|
11
15
|
- [Features](#features)
|
12
16
|
- [Requirements](#requirements)
|
13
17
|
- [Installation](#installation)
|
14
18
|
- [Usage](#usage)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
+
- [RSpec](#rspec)
|
20
|
+
- [Contributing](#contributing)
|
21
|
+
- [License](#license)
|
22
|
+
- [Code of Conduct](#code-of-conduct)
|
23
|
+
- [Credits](#credits)
|
24
|
+
- [Versioning](#versioning)
|
25
|
+
- [Changelog](CHANGELOG.md)
|
19
26
|
|
20
27
|
## Features
|
21
28
|
|
22
|
-
- Ability to mimic any DNS records
|
29
|
+
- Ability to mimic any DNS records (`A`, `AAAA`, `CNAME`, `MX`, `NS`, `PTR`, `SOA` and `TXT`)
|
23
30
|
- Zero runtime dependencies
|
24
|
-
-
|
31
|
+
- Lightweight UDP DNS mock server with dynamic/manual port assignment
|
32
|
+
- Test framework agnostic (it's PORO, so you can use it outside of `RSpec`, `Test::Unit` or `MiniTest`)
|
33
|
+
- Simple and intuitive DSL
|
34
|
+
|
35
|
+
## Requirements
|
36
|
+
|
37
|
+
Ruby MRI 2.5.0+
|
25
38
|
|
26
39
|
## Installation
|
27
40
|
|
@@ -44,13 +57,13 @@ Or install it yourself as:
|
|
44
57
|
## Usage
|
45
58
|
|
46
59
|
```ruby
|
47
|
-
# Example of mocked DNS records
|
60
|
+
# Example of mocked DNS records, please follow this data structure
|
48
61
|
records = {
|
49
62
|
'example.com' => {
|
50
|
-
a: %w[1.1.1.1
|
63
|
+
a: %w[1.1.1.1 2.2.2.2],
|
51
64
|
aaaa: %w[2a00:1450:4001:81e::200e],
|
52
65
|
ns: %w[ns1.domain.com ns2.domain.com],
|
53
|
-
mx: %w[mx1.domain.com mx2.domain.com],
|
66
|
+
mx: %w[mx1.domain.com mx2.domain.com:50], # you can specify host(s) or host(s) with priority
|
54
67
|
txt: %w[txt_record_1 txt_record_2],
|
55
68
|
cname: 'some.domain.com',
|
56
69
|
soa: [
|
@@ -64,16 +77,119 @@ records = {
|
|
64
77
|
minimum: 3_600
|
65
78
|
}
|
66
79
|
]
|
80
|
+
},
|
81
|
+
'1.2.3.4' => {
|
82
|
+
ptr: %w[domain_1.com domain_2.com]
|
67
83
|
}
|
68
84
|
}
|
69
85
|
|
70
|
-
# Main DnsMock interface
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
86
|
+
# Main DnsMock interface
|
87
|
+
# records:Hash, port:Integer, exception_if_not_found:Boolean
|
88
|
+
# are optional params. By default creates dns mock server with
|
89
|
+
# empty records. A free port for server will be randomly assigned
|
90
|
+
# in the range from 49152 to 65535, if record not found exception
|
91
|
+
# won't raises. Returns current dns mock server
|
92
|
+
dns_mock_server = DnsMock.start_server(records: records) # => DnsMock::Server instance
|
93
|
+
|
94
|
+
# returns current dns mock server port
|
95
|
+
dns_mock_server.port # => 49322
|
96
|
+
|
97
|
+
# interface to setup mock records.
|
98
|
+
# Available only in case when server mocked records is empty
|
99
|
+
dns_mock_server.assign_mocks(records) # => true/nil
|
100
|
+
|
101
|
+
# interface to reset current mocked records
|
102
|
+
dns_mock_server.reset_mocks! # => true
|
103
|
+
|
104
|
+
# interface to stop current dns mock server
|
105
|
+
dns_mock_server.stop! # => true
|
76
106
|
|
77
|
-
|
78
|
-
DnsMock.
|
107
|
+
# returns list of running dns mock servers
|
108
|
+
DnsMock.running_servers # => [DnsMock::Server instance]
|
109
|
+
|
110
|
+
# interface to stop all running dns mock servers
|
111
|
+
DnsMock.stop_running_servers! # => true
|
112
|
+
```
|
113
|
+
|
114
|
+
### RSpec
|
115
|
+
|
116
|
+
Require this either in your Gemfile or in RSpec's support scripts. So either:
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
# Gemfile
|
120
|
+
group :test do
|
121
|
+
gem 'rspec'
|
122
|
+
gem 'dns_mock', require: 'dns_mock/test_framework/rspec'
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
126
|
+
or
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
# spec/support/config/dns_mock.rb
|
130
|
+
require 'dns_mock/test_framework/rspec'
|
79
131
|
```
|
132
|
+
|
133
|
+
#### DnsMock RSpec helper
|
134
|
+
|
135
|
+
Just add `DnsMock::TestFramework::RSpec::Helper` if you wanna use shortcut `dns_mock_server` for DnsMock server instance into your `RSpec.describe` blocks:
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
# spec/support/config/dns_mock.rb
|
139
|
+
RSpec.configure do |config|
|
140
|
+
config.include DnsMock::TestFramework::RSpec::Helper
|
141
|
+
end
|
142
|
+
```
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
# your awesome first_a_record_spec.rb
|
146
|
+
RSpec.describe FirstARecord do
|
147
|
+
subject(:service) do
|
148
|
+
described_class.call(
|
149
|
+
hostname,
|
150
|
+
dns_gateway_host: 'localhost',
|
151
|
+
dns_gateway_port: dns_mock_server.port
|
152
|
+
)
|
153
|
+
end
|
154
|
+
|
155
|
+
let(:hostname) { 'example.com' }
|
156
|
+
let(:first_a_record) { '1.2.3.4' }
|
157
|
+
let(:records) { { hostname => { a: [first_a_record] } } }
|
158
|
+
|
159
|
+
before { dns_mock_server.assign_mocks(records) }
|
160
|
+
|
161
|
+
it { is_expected.to eq(first_a_record) }
|
162
|
+
end
|
163
|
+
```
|
164
|
+
|
165
|
+
#### DnsMock RSpec interface
|
166
|
+
|
167
|
+
If you won't use `DnsMock::TestFramework::RSpec::Helper` you can use `DnsMock::TestFramework::RSpec::Interface` directly instead:
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
DnsMock::TestFramework::RSpec::Interface.start_server # creates and runs DnsMock server instance
|
171
|
+
DnsMock::TestFramework::RSpec::Interface.stop_server! # stops current DnsMock server instance
|
172
|
+
DnsMock::TestFramework::RSpec::Interface.reset_mocks! # resets mocks in current DnsMock server instance
|
173
|
+
DnsMock::TestFramework::RSpec::Interface.clear_server! # stops and clears current DnsMock server instance
|
174
|
+
```
|
175
|
+
|
176
|
+
## Contributing
|
177
|
+
|
178
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/mocktools/ruby-dns-mock. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. Please check the [open tikets](https://github.com/mocktools/ruby-dns-mock/issues). Be shure to follow Contributor Code of Conduct below and our [Contributing Guidelines](CONTRIBUTING.md).
|
179
|
+
|
180
|
+
## License
|
181
|
+
|
182
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
183
|
+
|
184
|
+
## Code of Conduct
|
185
|
+
|
186
|
+
Everyone interacting in the DnsMock project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](CODE_OF_CONDUCT.md).
|
187
|
+
|
188
|
+
## Credits
|
189
|
+
|
190
|
+
- [The Contributors](https://github.com/mocktools/ruby-dns-mock/graphs/contributors) for code and awesome suggestions
|
191
|
+
- [The Stargazers](https://github.com/mocktools/ruby-dns-mock/stargazers) for showing their support
|
192
|
+
|
193
|
+
## Versioning
|
194
|
+
|
195
|
+
DnsMock uses [Semantic Versioning 2.0.0](https://semver.org)
|
data/dns_mock.gemspec
CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.email = ['admin@bestweb.com.ua']
|
12
12
|
|
13
13
|
spec.summary = %(dns_mock)
|
14
|
-
spec.description = %(Ruby DNS mock)
|
14
|
+
spec.description = %(💎 Ruby DNS mock. Mimic any DNS records for your test environment and even more.)
|
15
15
|
|
16
16
|
spec.homepage = 'https://github.com/mocktools/ruby-dns-mock'
|
17
17
|
spec.license = 'MIT'
|
@@ -41,7 +41,7 @@ Gem::Specification.new do |spec|
|
|
41
41
|
spec.add_development_dependency 'reek', '~> 6.0', '>= 6.0.3'
|
42
42
|
spec.add_development_dependency 'rspec', '~> 3.10'
|
43
43
|
spec.add_development_dependency 'rspec-dns', '~> 0.1.8'
|
44
|
-
spec.add_development_dependency 'rubocop', '~> 1.
|
44
|
+
spec.add_development_dependency 'rubocop', '~> 1.9'
|
45
45
|
spec.add_development_dependency 'rubocop-performance', '~> 1.9', '>= 1.9.2'
|
46
46
|
spec.add_development_dependency 'rubocop-rspec', '~> 2.1'
|
47
47
|
spec.add_development_dependency 'simplecov', '~> 0.17.1'
|
data/lib/dns_mock.rb
CHANGED
@@ -4,8 +4,8 @@ require_relative 'dns_mock/core'
|
|
4
4
|
|
5
5
|
module DnsMock
|
6
6
|
class << self
|
7
|
-
def start_server(server = DnsMock::Server, records: {}, port: nil)
|
8
|
-
server.new(records: records, port: port)
|
7
|
+
def start_server(server = DnsMock::Server, records: {}, port: nil, exception_if_not_found: false)
|
8
|
+
server.new(records: records, port: port, exception_if_not_found: exception_if_not_found)
|
9
9
|
end
|
10
10
|
|
11
11
|
def running_servers
|
data/lib/dns_mock/core.rb
CHANGED
@@ -4,7 +4,7 @@ require 'resolv'
|
|
4
4
|
require 'socket'
|
5
5
|
|
6
6
|
module DnsMock
|
7
|
-
AVAILABLE_DNS_RECORD_TYPES = %i[a aaaa cname mx ns soa txt].freeze
|
7
|
+
AVAILABLE_DNS_RECORD_TYPES = %i[a aaaa cname mx ns ptr soa txt].freeze
|
8
8
|
|
9
9
|
module Error
|
10
10
|
require_relative '../dns_mock/error/argument_type'
|
@@ -26,6 +26,7 @@ module DnsMock
|
|
26
26
|
require_relative '../dns_mock/record/factory/cname'
|
27
27
|
require_relative '../dns_mock/record/factory/mx'
|
28
28
|
require_relative '../dns_mock/record/factory/ns'
|
29
|
+
require_relative '../dns_mock/record/factory/ptr'
|
29
30
|
require_relative '../dns_mock/record/factory/soa'
|
30
31
|
require_relative '../dns_mock/record/factory/txt'
|
31
32
|
end
|
@@ -39,6 +40,7 @@ module DnsMock
|
|
39
40
|
require_relative '../dns_mock/record/builder/cname'
|
40
41
|
require_relative '../dns_mock/record/builder/mx'
|
41
42
|
require_relative '../dns_mock/record/builder/ns'
|
43
|
+
require_relative '../dns_mock/record/builder/ptr'
|
42
44
|
require_relative '../dns_mock/record/builder/soa'
|
43
45
|
require_relative '../dns_mock/record/builder/txt'
|
44
46
|
end
|
@@ -4,18 +4,29 @@ module DnsMock
|
|
4
4
|
module Record
|
5
5
|
module Builder
|
6
6
|
class Mx < DnsMock::Record::Builder::Base
|
7
|
+
include DnsMock::Error::Helper
|
8
|
+
|
9
|
+
MX_RECORD_REGEX_PATTERN = /\A(.+):(\d+)|(.+)\z/.freeze
|
7
10
|
RECORD_PREFERENCE_STEP = 10
|
8
11
|
|
9
12
|
def build
|
10
13
|
records_data.map.with_index(1) do |record_data, record_preference|
|
14
|
+
record_data, custom_record_preference = parse_mx_record_data(record_data)
|
11
15
|
target_factory.new(
|
12
16
|
record_data: [
|
13
|
-
record_preference * DnsMock::Record::Builder::Mx::RECORD_PREFERENCE_STEP,
|
17
|
+
custom_record_preference&.to_i || record_preference * DnsMock::Record::Builder::Mx::RECORD_PREFERENCE_STEP,
|
14
18
|
record_data
|
15
19
|
]
|
16
20
|
).create
|
17
21
|
end
|
18
22
|
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def parse_mx_record_data(record_data)
|
27
|
+
raise_record_context_type_error(:mx, record_data, ::String)
|
28
|
+
record_data.scan(DnsMock::Record::Builder::Mx::MX_RECORD_REGEX_PATTERN).flatten.compact
|
29
|
+
end
|
19
30
|
end
|
20
31
|
end
|
21
32
|
end
|
@@ -8,8 +8,9 @@ module DnsMock
|
|
8
8
|
hash[::Resolv::DNS::Resource::IN.const_get(record_type.upcase)] = record_type
|
9
9
|
end.freeze
|
10
10
|
|
11
|
-
def initialize(records)
|
11
|
+
def initialize(records, exception_if_not_found)
|
12
12
|
@records = records
|
13
|
+
@exception_if_not_found = exception_if_not_found
|
13
14
|
end
|
14
15
|
|
15
16
|
def build(hostname, record_class)
|
@@ -19,13 +20,13 @@ module DnsMock
|
|
19
20
|
|
20
21
|
private
|
21
22
|
|
22
|
-
attr_reader :records, :hostname
|
23
|
+
attr_reader :records, :exception_if_not_found, :hostname
|
23
24
|
|
24
25
|
def record_by_type(record_class)
|
25
26
|
record_type = DnsMock::Response::Answer::REVERSE_TYPE_MAPPER[record_class]
|
26
27
|
found_records = records.dig(hostname.to_s, record_type)
|
27
|
-
raise DnsMock::Error::RecordNotFound.new(record_type, hostname) unless found_records
|
28
|
-
found_records
|
28
|
+
raise DnsMock::Error::RecordNotFound.new(record_type, hostname) unless found_records || !exception_if_not_found
|
29
|
+
Array(found_records)
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
@@ -3,8 +3,14 @@
|
|
3
3
|
module DnsMock
|
4
4
|
module Response
|
5
5
|
class Message
|
6
|
-
def initialize(
|
7
|
-
|
6
|
+
def initialize(
|
7
|
+
packet,
|
8
|
+
records,
|
9
|
+
exception_if_not_found,
|
10
|
+
dns_answer = DnsMock::Response::Answer,
|
11
|
+
dns_message = ::Resolv::DNS::Message
|
12
|
+
)
|
13
|
+
@dns_answer = dns_answer.new(records, exception_if_not_found)
|
8
14
|
@dns_message = dns_message.decode(packet)
|
9
15
|
end
|
10
16
|
|
data/lib/dns_mock/server.rb
CHANGED
@@ -15,13 +15,15 @@ module DnsMock
|
|
15
15
|
random_available_port = DnsMock::Server::RandomAvailablePort,
|
16
16
|
thread_class = ::Thread,
|
17
17
|
records: nil,
|
18
|
-
port: nil
|
18
|
+
port: nil,
|
19
|
+
exception_if_not_found: false
|
19
20
|
)
|
20
21
|
@socket = socket
|
21
22
|
@records_dictionary_builder = records_dictionary_builder
|
22
23
|
@thread_class = thread_class
|
23
24
|
@records = records_dictionary_builder.call(records || {})
|
24
25
|
@port = port || random_available_port.call
|
26
|
+
@exception_if_not_found = exception_if_not_found
|
25
27
|
prepare_server_thread
|
26
28
|
end
|
27
29
|
|
@@ -34,7 +36,7 @@ module DnsMock
|
|
34
36
|
break if packet.size.zero?
|
35
37
|
|
36
38
|
address, port = addr.values_at(3, 1)
|
37
|
-
socket.send(DnsMock::Response::Message.new(packet, records).as_binary_string, 0, address, port)
|
39
|
+
socket.send(DnsMock::Response::Message.new(packet, records, exception_if_not_found).as_binary_string, 0, address, port)
|
38
40
|
end
|
39
41
|
ensure
|
40
42
|
socket.close
|
@@ -63,7 +65,7 @@ module DnsMock
|
|
63
65
|
|
64
66
|
private
|
65
67
|
|
66
|
-
attr_reader :socket, :records_dictionary_builder, :thread_class
|
68
|
+
attr_reader :socket, :records_dictionary_builder, :thread_class, :exception_if_not_found
|
67
69
|
attr_accessor :records, :thread
|
68
70
|
|
69
71
|
def prepare_socket_for_session
|
@@ -5,6 +5,9 @@ module DnsMock
|
|
5
5
|
class RecordsDictionaryBuilder
|
6
6
|
include DnsMock::Error::Helper
|
7
7
|
|
8
|
+
IP_ADDRESS_PATTERN = /\A((1\d|[1-9]|2[0-4])?\d|25[0-5])(\.\g<1>){3}\z/.freeze
|
9
|
+
IP_OCTET_GROUPS = /(\d+).(\d+).(\d+).(\d+)/.freeze
|
10
|
+
RDNS_LOOKUP_REPRESENTATION = '\4.\3.\2.\1.in-addr.arpa'
|
8
11
|
TYPE_MAPPER = DnsMock::AVAILABLE_DNS_RECORD_TYPES.zip(
|
9
12
|
[
|
10
13
|
[DnsMock::Record::Builder::A, DnsMock::Record::Factory::A, ::Array],
|
@@ -12,6 +15,7 @@ module DnsMock
|
|
12
15
|
[DnsMock::Record::Builder::Cname, DnsMock::Record::Factory::Cname, ::String],
|
13
16
|
[DnsMock::Record::Builder::Mx, DnsMock::Record::Factory::Mx, ::Array],
|
14
17
|
[DnsMock::Record::Builder::Ns, DnsMock::Record::Factory::Ns, ::Array],
|
18
|
+
[DnsMock::Record::Builder::Ptr, DnsMock::Record::Factory::Ptr, ::Array],
|
15
19
|
[DnsMock::Record::Builder::Soa, DnsMock::Record::Factory::Soa, ::Array],
|
16
20
|
[DnsMock::Record::Builder::Txt, DnsMock::Record::Factory::Txt, ::Array]
|
17
21
|
]
|
@@ -31,7 +35,7 @@ module DnsMock
|
|
31
35
|
raise_unless(DnsMock::Error::ArgumentType.new(records_to_build.class), records_to_build.is_a?(::Hash))
|
32
36
|
records_to_build.each do |hostname, dns_records|
|
33
37
|
raise_unless(DnsMock::Error::RecordHostType.new(hostname, hostname.class), hostname.is_a?(::String))
|
34
|
-
records[hostname] = dns_records.each_with_object({}) do |(record_type, records_data), records_instances_by_type|
|
38
|
+
records[rdns_lookup_prefix(hostname)] = dns_records.each_with_object({}) do |(record_type, records_data), records_instances_by_type|
|
35
39
|
records_instances_by_type[record_type] = build_records_instances_by_type(record_type, records_data)
|
36
40
|
end
|
37
41
|
end
|
@@ -41,6 +45,15 @@ module DnsMock
|
|
41
45
|
|
42
46
|
private
|
43
47
|
|
48
|
+
def rdns_lookup_prefix(hostname)
|
49
|
+
return hostname unless hostname[DnsMock::Server::RecordsDictionaryBuilder::IP_ADDRESS_PATTERN]
|
50
|
+
|
51
|
+
hostname.gsub(
|
52
|
+
DnsMock::Server::RecordsDictionaryBuilder::IP_OCTET_GROUPS,
|
53
|
+
DnsMock::Server::RecordsDictionaryBuilder::RDNS_LOOKUP_REPRESENTATION
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
44
57
|
def build_records_instances_by_type(record_type, records_to_build)
|
45
58
|
target_builder, target_factory, expected_type = DnsMock::Server::RecordsDictionaryBuilder::TYPE_MAPPER[record_type]
|
46
59
|
raise_record_type_error(record_type, target_builder)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rspec/core'
|
4
|
+
require_relative '../../dns_mock'
|
5
|
+
require_relative './rspec/interface'
|
6
|
+
require_relative './rspec/helper'
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.before(:suite) { DnsMock::TestFramework::RSpec::Interface.start_server }
|
10
|
+
config.after(:suite) { DnsMock::TestFramework::RSpec::Interface.stop_server! }
|
11
|
+
config.after { DnsMock::TestFramework::RSpec::Interface.reset_mocks! }
|
12
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './interface'
|
4
|
+
|
5
|
+
module DnsMock
|
6
|
+
module TestFramework
|
7
|
+
module RSpec
|
8
|
+
module Helper
|
9
|
+
def dns_mock_server(**options)
|
10
|
+
DnsMock::TestFramework::RSpec::Interface.start_server(**options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DnsMock
|
4
|
+
module TestFramework
|
5
|
+
module RSpec
|
6
|
+
module Interface
|
7
|
+
class << self
|
8
|
+
def start_server(**options)
|
9
|
+
@dns_mock_server ||= DnsMock.start_server(**options) # rubocop:disable Naming/MemoizedInstanceVariableName
|
10
|
+
end
|
11
|
+
|
12
|
+
def stop_server!
|
13
|
+
return unless dns_mock_server
|
14
|
+
|
15
|
+
dns_mock_server.stop!
|
16
|
+
end
|
17
|
+
|
18
|
+
def reset_mocks!
|
19
|
+
return unless dns_mock_server
|
20
|
+
|
21
|
+
dns_mock_server.reset_mocks!
|
22
|
+
end
|
23
|
+
|
24
|
+
def clear_server!
|
25
|
+
@dns_mock_server = nil
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :dns_mock_server
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/dns_mock/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dns_mock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladislav Trotsenko
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-02-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -174,20 +174,14 @@ dependencies:
|
|
174
174
|
requirements:
|
175
175
|
- - "~>"
|
176
176
|
- !ruby/object:Gem::Version
|
177
|
-
version: '1.
|
178
|
-
- - ">="
|
179
|
-
- !ruby/object:Gem::Version
|
180
|
-
version: 1.8.1
|
177
|
+
version: '1.9'
|
181
178
|
type: :development
|
182
179
|
prerelease: false
|
183
180
|
version_requirements: !ruby/object:Gem::Requirement
|
184
181
|
requirements:
|
185
182
|
- - "~>"
|
186
183
|
- !ruby/object:Gem::Version
|
187
|
-
version: '1.
|
188
|
-
- - ">="
|
189
|
-
- !ruby/object:Gem::Version
|
190
|
-
version: 1.8.1
|
184
|
+
version: '1.9'
|
191
185
|
- !ruby/object:Gem::Dependency
|
192
186
|
name: rubocop-performance
|
193
187
|
requirement: !ruby/object:Gem::Requirement
|
@@ -236,7 +230,8 @@ dependencies:
|
|
236
230
|
- - "~>"
|
237
231
|
- !ruby/object:Gem::Version
|
238
232
|
version: 0.17.1
|
239
|
-
description: Ruby DNS mock
|
233
|
+
description: "\U0001F48E Ruby DNS mock. Mimic any DNS records for your test environment
|
234
|
+
and even more."
|
240
235
|
email:
|
241
236
|
- admin@bestweb.com.ua
|
242
237
|
executables: []
|
@@ -286,6 +281,7 @@ files:
|
|
286
281
|
- lib/dns_mock/record/builder/cname.rb
|
287
282
|
- lib/dns_mock/record/builder/mx.rb
|
288
283
|
- lib/dns_mock/record/builder/ns.rb
|
284
|
+
- lib/dns_mock/record/builder/ptr.rb
|
289
285
|
- lib/dns_mock/record/builder/soa.rb
|
290
286
|
- lib/dns_mock/record/builder/txt.rb
|
291
287
|
- lib/dns_mock/record/factory/a.rb
|
@@ -294,6 +290,7 @@ files:
|
|
294
290
|
- lib/dns_mock/record/factory/cname.rb
|
295
291
|
- lib/dns_mock/record/factory/mx.rb
|
296
292
|
- lib/dns_mock/record/factory/ns.rb
|
293
|
+
- lib/dns_mock/record/factory/ptr.rb
|
297
294
|
- lib/dns_mock/record/factory/soa.rb
|
298
295
|
- lib/dns_mock/record/factory/txt.rb
|
299
296
|
- lib/dns_mock/response/answer.rb
|
@@ -301,6 +298,9 @@ files:
|
|
301
298
|
- lib/dns_mock/server.rb
|
302
299
|
- lib/dns_mock/server/random_available_port.rb
|
303
300
|
- lib/dns_mock/server/records_dictionary_builder.rb
|
301
|
+
- lib/dns_mock/test_framework/rspec.rb
|
302
|
+
- lib/dns_mock/test_framework/rspec/helper.rb
|
303
|
+
- lib/dns_mock/test_framework/rspec/interface.rb
|
304
304
|
- lib/dns_mock/version.rb
|
305
305
|
homepage: https://github.com/mocktools/ruby-dns-mock
|
306
306
|
licenses:
|