|
17 | 17 |
|
18 | 18 | package org.apache.jmeter.protocol.http.control |
19 | 19 |
|
| 20 | +import org.junit.jupiter.api.Assertions.assertEquals |
| 21 | +import org.junit.jupiter.api.Assertions.assertNotNull |
| 22 | +import org.junit.jupiter.api.Assertions.assertNull |
| 23 | +import org.junit.jupiter.api.Assertions.assertTrue |
| 24 | +import org.junit.jupiter.api.Assumptions.assumeTrue |
| 25 | +import org.junit.jupiter.api.Test |
| 26 | +import org.junit.jupiter.api.assertThrows |
| 27 | +import org.junit.jupiter.api.condition.DisabledIfSystemProperty |
| 28 | +import org.junit.jupiter.api.fail |
20 | 29 | import org.xbill.DNS.ExtendedResolver |
21 | 30 | import org.xbill.DNS.ResolverConfig |
| 31 | +import java.net.InetAddress |
| 32 | +import java.net.UnknownHostException |
22 | 33 |
|
23 | | -import spock.lang.IgnoreIf |
24 | | -import spock.lang.Requires |
25 | | -import spock.lang.Specification |
| 34 | +class DNSCacheManagerTest { |
26 | 35 |
|
27 | | -class DNSCacheManagerSpec extends Specification { |
28 | | - |
29 | | - private static final String[] VALID_DNS_SERVERS = ResolverConfig.getCurrentConfig().servers() |
30 | | - private static final String INVALID_DNS_SERVER = "512.1.1.1" |
31 | | - private static final String VALID_HOSTNAME = "jmeter.apache.org" |
| 36 | + companion object { |
| 37 | + val VALID_DNS_SERVERS = ResolverConfig.getCurrentConfig().servers() |
| 38 | + val INVALID_DNS_SERVER = "512.1.1.1" |
| 39 | + val VALID_HOSTNAME = "jmeter.apache.org" |
| 40 | + } |
32 | 41 |
|
33 | | - private static final boolean localDNSResolverOK = { |
| 42 | + private val localDNSResolverOK = |
34 | 43 | try { |
35 | 44 | if (VALID_DNS_SERVERS == null) { |
36 | | - return false |
| 45 | + false |
| 46 | + } else { |
| 47 | + DNSCacheManager().resolve("apache.org") |
| 48 | + true |
37 | 49 | } |
38 | | - new DNSCacheManager().resolve("apache.org") |
39 | | - return true |
40 | | - } catch (UnknownHostException uhe) { |
41 | | - return false |
| 50 | + } catch (uhe: UnknownHostException) { |
| 51 | + false |
42 | 52 | } |
43 | | - }.call() // <-- this avoids automatic casting of Closure to boolean which yields true in Groovy |
44 | 53 |
|
45 | | - def sut = new DNSCacheManager() |
| 54 | + val sut = DNSCacheManager() |
46 | 55 |
|
47 | | - def "A custom resolver with one host will resolve that host"() { |
48 | | - given: |
49 | | - sut.setCustomResolver(true) |
50 | | - sut.addHost("jmeter.example.org", "127.0.0.1") |
51 | | - expect: |
52 | | - sut.resolve("jmeter.example.org") == [InetAddress.getByName("127.0.0.1")].toArray() |
| 56 | + private fun assumeLocalDnsResolverOK() { |
| 57 | + assumeTrue(localDNSResolverOK, "Local DNS resolver is needed for the test") |
53 | 58 | } |
54 | 59 |
|
55 | | - def "A custom resolver with one host and an invalid DNS server will still resolve that host"() { |
56 | | - given: |
57 | | - sut.setCustomResolver(true) |
58 | | - sut.addServer(INVALID_DNS_SERVER) |
59 | | - sut.addHost("localhost", "127.0.0.1") |
60 | | - expect: |
61 | | - sut.resolve("localhost") == [InetAddress.getByName("127.0.0.1")].toArray() |
| 60 | + @Test |
| 61 | + fun `A custom resolver with one host will resolve that host`() { |
| 62 | + sut.isCustomResolver = true |
| 63 | + sut.addHost("jmeter.example.org", "127.0.0.1") |
| 64 | + |
| 65 | + assertEquals(listOf(InetAddress.getByName("127.0.0.1")), sut.resolve("jmeter.example.org").toList()) |
62 | 66 | } |
63 | 67 |
|
64 | | - def "A custom resolver with one host with many addresses will resolve all addresses for that host"() { |
65 | | - given: |
66 | | - sut.setCustomResolver(true) |
67 | | - sut.addHost("jmeter.example.org", "127.0.0.1, 1.2.3.4") |
68 | | - expect: |
69 | | - sut.resolve("jmeter.example.org") == |
70 | | - [InetAddress.getByName("127.0.0.1"), |
71 | | - InetAddress.getByName("1.2.3.4")].toArray() |
| 68 | + @Test |
| 69 | + fun `A custom resolver with one host and an invalid DNS server will still resolve that host`() { |
| 70 | + sut.isCustomResolver = true |
| 71 | + sut.addServer(INVALID_DNS_SERVER) |
| 72 | + sut.addHost("localhost", "127.0.0.1") |
| 73 | + |
| 74 | + assertEquals(listOf(InetAddress.getByName("127.0.0.1")), sut.resolve("localhost").toList()) |
72 | 75 | } |
73 | 76 |
|
74 | | - @Requires({ localDNSResolverOK }) |
75 | | - def "Clear removes custom resolver status and any added hosts"() { |
76 | | - given: |
77 | | - sut.setCustomResolver(true) |
78 | | - sut.addHost(VALID_HOSTNAME, "127.0.0.1") |
79 | | - sut.clear() |
80 | | - expect: |
81 | | - // uses real DNS server |
82 | | - sut.resolve(VALID_HOSTNAME).contains(InetAddress.getByName(VALID_HOSTNAME)) |
83 | | - !sut.resolve(VALID_HOSTNAME).contains(InetAddress.getByName("127.0.0.1")) |
| 77 | + @Test |
| 78 | + fun `A custom resolver with one host with many addresses will resolve all addresses for that host`() { |
| 79 | + sut.isCustomResolver = true |
| 80 | + sut.addHost("jmeter.example.org", "127.0.0.1, 1.2.3.4") |
| 81 | + assertEquals( |
| 82 | + listOf(InetAddress.getByName("127.0.0.1"), InetAddress.getByName("1.2.3.4")), |
| 83 | + sut.resolve("jmeter.example.org").toList() |
| 84 | + ) |
84 | 85 | } |
85 | 86 |
|
86 | | - @Requires({ localDNSResolverOK }) |
87 | | - def "A custom resolver with a host entry will still fall back to system lookup"() { |
88 | | - given: |
89 | | - sut.setCustomResolver(true) |
90 | | - sut.addHost("jmeter.example.org", "127.0.0.1") |
91 | | - expect: |
92 | | - // uses real DNS server |
93 | | - sut.resolve(VALID_HOSTNAME).contains(InetAddress.getByName(VALID_HOSTNAME)) |
| 87 | + @Test |
| 88 | + fun `Clear removes custom resolver status and any added hosts`() { |
| 89 | + assumeLocalDnsResolverOK() |
| 90 | + sut.isCustomResolver = true |
| 91 | + sut.addHost(VALID_HOSTNAME, "127.0.0.1") |
| 92 | + sut.clear() |
| 93 | + // uses real DNS server |
| 94 | + sut.resolve(VALID_HOSTNAME).contains(InetAddress.getByName(VALID_HOSTNAME)) |
| 95 | + !sut.resolve(VALID_HOSTNAME).contains(InetAddress.getByName("127.0.0.1")) |
94 | 96 | } |
95 | 97 |
|
96 | | - def "If using an invalid server resolve throws UnknownHostException"() { |
97 | | - given: |
98 | | - sut.addServer(INVALID_DNS_SERVER) |
99 | | - sut.setCustomResolver(true) |
100 | | - when: |
101 | | - sut.resolve(VALID_HOSTNAME) |
102 | | - then: |
103 | | - thrown(UnknownHostException) |
104 | | - sut.resolver == null |
105 | | - sut.initFailed |
| 98 | + @Test |
| 99 | + fun `A custom resolver with a host entry will still fall back to system lookup`() { |
| 100 | + assumeLocalDnsResolverOK() |
| 101 | + sut.isCustomResolver = true |
| 102 | + sut.addHost("jmeter.example.org", "127.0.0.1") |
| 103 | + // uses real DNS server |
| 104 | + sut.resolve(VALID_HOSTNAME).contains(InetAddress.getByName(VALID_HOSTNAME)) |
106 | 105 | } |
107 | 106 |
|
108 | | - @IgnoreIf({ Boolean.getBoolean("skip.test_TestDNSCacheManager.testWithCustomResolverAnd1Server") }) |
109 | | - @Requires({ localDNSResolverOK }) |
110 | | - def "Valid DNS resolves and caches with custom resolve true"() { |
111 | | - given: |
112 | | - for (dns in VALID_DNS_SERVERS) { |
113 | | - sut.addServer(dns) |
114 | | - } |
115 | | - sut.setCustomResolver(true) |
116 | | - sut.setTimeoutMs(5000) |
117 | | - when: |
| 107 | + @Test |
| 108 | + fun `If using an invalid server resolve throws UnknownHostException`() { |
| 109 | + sut.addServer(INVALID_DNS_SERVER) |
| 110 | + sut.isCustomResolver = true |
| 111 | + assertThrows<UnknownHostException> { |
118 | 112 | sut.resolve(VALID_HOSTNAME) |
119 | | - then: |
120 | | - sut.resolver != null |
121 | | - ((ExtendedResolver) sut.resolver).getResolvers().length == VALID_DNS_SERVERS.length |
122 | | - sut.cache.size() == 1 |
| 113 | + } |
| 114 | + assertNull(sut.resolver, ".resolver") |
| 115 | + assertTrue(sut.initFailed, ".initFailed") |
123 | 116 | } |
124 | 117 |
|
125 | | - def "Cache should be used where entries exist"() { |
126 | | - given: |
127 | | - for (dns in VALID_DNS_SERVERS) { |
128 | | - sut.addServer(dns) |
129 | | - } |
130 | | - sut.setCustomResolver(true) |
131 | | - sut.setTimeoutMs(5000) |
132 | | - when: |
133 | | - sut.cache.put(VALID_HOSTNAME, new InetAddress[0]) |
134 | | - then: |
135 | | - sut.resolve(VALID_HOSTNAME) == new InetAddress[0] |
136 | | - |
137 | | - when: |
138 | | - sut.cache.put(VALID_HOSTNAME, null) |
139 | | - then: |
140 | | - sut.resolve(VALID_HOSTNAME) == null |
| 118 | + @Test |
| 119 | + @DisabledIfSystemProperty(named = "skip.test_TestDNSCacheManager.testWithCustomResolverAnd1Server", matches = "true") |
| 120 | + fun `Valid DNS resolves and caches with custom resolve true`() { |
| 121 | + assumeLocalDnsResolverOK() |
| 122 | + for (dns in VALID_DNS_SERVERS) { |
| 123 | + sut.addServer(dns) |
| 124 | + } |
| 125 | + sut.isCustomResolver = true |
| 126 | + sut.timeoutMs = 5000 |
| 127 | + sut.resolve(VALID_HOSTNAME) |
| 128 | + assertNotNull(sut.resolver, ".resolver") |
| 129 | + assertEquals(VALID_DNS_SERVERS.size, (sut.resolver as ExtendedResolver).resolvers.size, ".resolver.resolvers.size") |
| 130 | + assertEquals(1, sut.cache.size, ".cache.size") |
141 | 131 | } |
142 | 132 |
|
143 | | - @Requires({ localDNSResolverOK }) |
144 | | - def "set custom resolver but without an address should use system resolver"() { |
145 | | - given: |
146 | | - sut.setCustomResolver(true) |
147 | | - sut.setTimeoutMs(5000) |
148 | | - when: |
149 | | - sut.resolve(VALID_HOSTNAME) |
150 | | - then: |
151 | | - sut.resolver != null |
152 | | - ((ExtendedResolver) sut.resolver).getResolvers().length == 0 |
| 133 | + @Test |
| 134 | + fun `Cache should be used where entries exist`() { |
| 135 | + assumeLocalDnsResolverOK() |
| 136 | + for (dns in VALID_DNS_SERVERS) { |
| 137 | + sut.addServer(dns) |
| 138 | + } |
| 139 | + sut.isCustomResolver = true |
| 140 | + sut.timeoutMs = 5000 |
| 141 | + val cached = arrayOf(InetAddress.getByAddress(byteArrayOf(10, 20, 30, 40))) |
| 142 | + sut.cache[VALID_HOSTNAME] = cached |
| 143 | + assertEquals(cached, sut.resolve(VALID_HOSTNAME), ".resolve($VALID_HOSTNAME) should return cached results") |
| 144 | + |
| 145 | + sut.cache[VALID_HOSTNAME] = null |
| 146 | + assertNull(sut.resolve(VALID_HOSTNAME)) { |
| 147 | + ".resolve($VALID_HOSTNAME) after removing entry from the cache" |
| 148 | + } |
| 149 | + } |
| 150 | + |
| 151 | + @Test |
| 152 | + fun `set custom resolver but without an address should use system resolver`() { |
| 153 | + assumeLocalDnsResolverOK() |
| 154 | + sut.isCustomResolver = true |
| 155 | + sut.timeoutMs = 5000 |
| 156 | + sut.resolve(VALID_HOSTNAME) |
| 157 | + assertNotNull(sut.resolver, ".resolver") |
| 158 | + assertEquals(0, (sut.resolver as ExtendedResolver).resolvers.size, ".resolver.resolvers.size") |
153 | 159 | } |
154 | 160 |
|
155 | | - def "Clones retain custom resolve and server info"() { |
156 | | - given: |
157 | | - sut.setCustomResolver(true) |
158 | | - sut.addServer(INVALID_DNS_SERVER) |
159 | | - DNSCacheManager clone = (DNSCacheManager) sut.clone() |
160 | | - clone.setTimeoutMs(5000) |
161 | | - when: |
| 161 | + @Test |
| 162 | + fun `Clones retain custom resolve and server info`() { |
| 163 | + sut.isCustomResolver = true |
| 164 | + sut.addServer(INVALID_DNS_SERVER) |
| 165 | + val clone = sut.clone() as DNSCacheManager |
| 166 | + clone.timeoutMs = 5000 |
| 167 | + assertThrows<UnknownHostException> { |
162 | 168 | clone.resolve(VALID_HOSTNAME) |
163 | | - then: |
164 | | - thrown(UnknownHostException) |
165 | | - clone.resolver == sut.resolver |
| 169 | + } |
| 170 | + assertEquals(sut.resolver, clone.resolver, "Cloned DNSCacheManager should share the resolver") |
166 | 171 | } |
167 | 172 |
|
168 | | - @Requires({ localDNSResolverOK }) |
169 | | - def "Resolve Existing Host With System Default DNS Server"() { |
170 | | - given: |
171 | | - sut.setCustomResolver(false) |
172 | | - when: |
173 | | - InetAddress[] result = sut.resolve("www.example.org") |
174 | | - then: |
175 | | - sut.resolver == null |
176 | | - result != null |
177 | | - result.length > 0 // IPv4 and/or IPv6 |
| 173 | + @Test |
| 174 | + fun `Resolve Existing Host With System Default DNS Server`() { |
| 175 | + assumeLocalDnsResolverOK() |
| 176 | + sut.isCustomResolver = false |
| 177 | + |
| 178 | + val result = sut.resolve("www.example.org") |
| 179 | + assertNull(sut.resolver, ".resolver") |
| 180 | + if (result == null || result.isEmpty()) { |
| 181 | + fail("Resolution result should be non-empty, got ${result.contentDeepToString()}") |
| 182 | + } |
178 | 183 | } |
179 | 184 |
|
180 | | - def "Resolve Non-existing Host With System Default DNS Server"() { |
181 | | - given: |
182 | | - sut.setCustomResolver(false) |
183 | | - when: |
| 185 | + @Test |
| 186 | + fun `Resolve Non-existing Host With System Default DNS Server`() { |
| 187 | + sut.isCustomResolver = false |
| 188 | + assertThrows<UnknownHostException> { |
184 | 189 | sut.resolve("jmeterxxx.apache.org") |
185 | | - then: |
186 | | - thrown(UnknownHostException) |
187 | | - sut.resolver == null |
| 190 | + } |
| 191 | + assertNull(sut.resolver, ".resolver") |
188 | 192 | } |
189 | 193 | } |
0 commit comments