|
15 | 15 |
|
16 | 16 | import org.apache.lucene.util.Constants; |
17 | 17 | import org.elasticsearch.common.network.NetworkAddress; |
18 | | -import org.elasticsearch.common.settings.Settings; |
19 | | -import org.elasticsearch.common.util.set.Sets; |
20 | 18 | import org.elasticsearch.core.IOUtils; |
21 | 19 | import org.elasticsearch.core.SuppressForbidden; |
22 | | -import org.elasticsearch.core.TimeValue; |
23 | 20 | import org.elasticsearch.test.ESTestCase; |
24 | | -import org.elasticsearch.threadpool.TestThreadPool; |
25 | | -import org.elasticsearch.threadpool.ThreadPool; |
26 | | -import org.elasticsearch.watcher.ResourceWatcherService; |
27 | 21 | import org.junit.After; |
28 | 22 | import org.junit.Before; |
29 | 23 |
|
|
41 | 35 | import static org.elasticsearch.ingest.geoip.IpinfoIpDataLookups.parseBoolean; |
42 | 36 | import static org.elasticsearch.ingest.geoip.IpinfoIpDataLookups.parseLocationDouble; |
43 | 37 | import static org.hamcrest.Matchers.anyOf; |
44 | | -import static org.hamcrest.Matchers.empty; |
| 38 | +import static org.hamcrest.Matchers.containsInAnyOrder; |
45 | 39 | import static org.hamcrest.Matchers.equalTo; |
46 | | -import static org.hamcrest.Matchers.is; |
47 | 40 | import static org.hamcrest.Matchers.notNullValue; |
48 | 41 | import static org.hamcrest.Matchers.nullValue; |
49 | 42 | import static org.hamcrest.Matchers.startsWith; |
50 | 43 |
|
51 | 44 | public class IpinfoIpDataLookupsTests extends ESTestCase { |
52 | 45 |
|
53 | | - private ThreadPool threadPool; |
54 | | - private ResourceWatcherService resourceWatcherService; |
55 | | - |
56 | 46 | // a temporary directory that mmdb files can be copied to and read from |
57 | 47 | private Path tmpDir; |
58 | 48 |
|
59 | 49 | @Before |
60 | 50 | public void setup() { |
61 | | - threadPool = new TestThreadPool(ConfigDatabases.class.getSimpleName()); |
62 | | - Settings settings = Settings.builder().put("resource.reload.interval.high", TimeValue.timeValueMillis(100)).build(); |
63 | | - resourceWatcherService = new ResourceWatcherService(settings, threadPool); |
64 | 51 | tmpDir = createTempDir(); |
65 | 52 | } |
66 | 53 |
|
67 | 54 | @After |
68 | 55 | public void cleanup() throws IOException { |
69 | | - resourceWatcherService.close(); |
70 | | - threadPool.shutdownNow(); |
71 | 56 | IOUtils.rm(tmpDir); |
72 | 57 | } |
73 | 58 |
|
74 | | - public void testDatabasePropertyInvariants() { |
75 | | - // the second ASN variant database is like a specialization of the ASN database |
76 | | - assertThat(Sets.difference(Database.Asn.properties(), Database.AsnV2.properties()), is(empty())); |
77 | | - assertThat(Database.Asn.defaultProperties(), equalTo(Database.AsnV2.defaultProperties())); |
78 | | - |
79 | | - // the second City variant database is like a version of the ordinary City database but lacking many fields |
80 | | - assertThat(Sets.difference(Database.CityV2.properties(), Database.City.properties()), is(empty())); |
81 | | - assertThat(Sets.difference(Database.CityV2.defaultProperties(), Database.City.defaultProperties()), is(empty())); |
82 | | - |
83 | | - // the second Country variant database is like a version of the ordinary Country database but lacking come fields |
84 | | - assertThat(Sets.difference(Database.CountryV2.properties(), Database.CountryV2.properties()), is(empty())); |
85 | | - assertThat(Database.CountryV2.defaultProperties(), equalTo(Database.Country.defaultProperties())); |
86 | | - } |
87 | | - |
88 | 59 | public void testParseAsn() { |
89 | 60 | // expected case: "AS123" is 123 |
90 | 61 | assertThat(parseAsn("AS123"), equalTo(123L)); |
@@ -126,53 +97,42 @@ public void testParseLocationDouble() { |
126 | 97 | assertThat(parseLocationDouble("anythingelse"), nullValue()); |
127 | 98 | } |
128 | 99 |
|
129 | | - public void testAsn() throws IOException { |
| 100 | + public void testAsnFree() { |
130 | 101 | assumeFalse("https://github.com/elastic/elasticsearch/issues/114266", Constants.WINDOWS); |
131 | | - Path configDir = tmpDir; |
132 | | - copyDatabase("ipinfo/ip_asn_sample.mmdb", configDir.resolve("ip_asn_sample.mmdb")); |
133 | | - copyDatabase("ipinfo/asn_sample.mmdb", configDir.resolve("asn_sample.mmdb")); |
134 | | - |
135 | | - GeoIpCache cache = new GeoIpCache(1000); // real cache to test purging of entries upon a reload |
136 | | - ConfigDatabases configDatabases = new ConfigDatabases(configDir, cache); |
137 | | - configDatabases.initialize(resourceWatcherService); |
138 | | - |
139 | | - // this is the 'free' ASN database (sample) |
140 | | - try (DatabaseReaderLazyLoader loader = configDatabases.getDatabase("ip_asn_sample.mmdb")) { |
141 | | - IpDataLookup lookup = new IpinfoIpDataLookups.Asn(Database.AsnV2.properties()); |
142 | | - Map<String, Object> data = lookup.getData(loader, "5.182.109.0"); |
143 | | - assertThat( |
144 | | - data, |
145 | | - equalTo( |
146 | | - Map.ofEntries( |
147 | | - entry("ip", "5.182.109.0"), |
148 | | - entry("organization_name", "M247 Europe SRL"), |
149 | | - entry("asn", 9009L), |
150 | | - entry("network", "5.182.109.0/24"), |
151 | | - entry("domain", "m247.com") |
152 | | - ) |
153 | | - ) |
154 | | - ); |
155 | | - } |
| 102 | + String databaseName = "ip_asn_sample.mmdb"; |
| 103 | + String ip = "5.182.109.0"; |
| 104 | + assertExpectedLookupResults( |
| 105 | + databaseName, |
| 106 | + ip, |
| 107 | + new IpinfoIpDataLookups.Asn(Database.AsnV2.properties()), |
| 108 | + Map.ofEntries( |
| 109 | + entry("ip", ip), |
| 110 | + entry("organization_name", "M247 Europe SRL"), |
| 111 | + entry("asn", 9009L), |
| 112 | + entry("network", "5.182.109.0/24"), |
| 113 | + entry("domain", "m247.com") |
| 114 | + ) |
| 115 | + ); |
| 116 | + } |
156 | 117 |
|
157 | | - // this is the non-free or 'standard' ASN database (sample) |
158 | | - try (DatabaseReaderLazyLoader loader = configDatabases.getDatabase("asn_sample.mmdb")) { |
159 | | - IpDataLookup lookup = new IpinfoIpDataLookups.Asn(Database.AsnV2.properties()); |
160 | | - Map<String, Object> data = lookup.getData(loader, "23.53.116.0"); |
161 | | - assertThat( |
162 | | - data, |
163 | | - equalTo( |
164 | | - Map.ofEntries( |
165 | | - entry("ip", "23.53.116.0"), |
166 | | - entry("organization_name", "Akamai Technologies, Inc."), |
167 | | - entry("asn", 32787L), |
168 | | - entry("network", "23.53.116.0/24"), |
169 | | - entry("domain", "akamai.com"), |
170 | | - entry("type", "hosting"), |
171 | | - entry("country_iso_code", "US") |
172 | | - ) |
173 | | - ) |
174 | | - ); |
175 | | - } |
| 118 | + public void testAsnStandard() { |
| 119 | + assumeFalse("https://github.com/elastic/elasticsearch/issues/114266", Constants.WINDOWS); |
| 120 | + String databaseName = "asn_sample.mmdb"; |
| 121 | + String ip = "23.53.116.0"; |
| 122 | + assertExpectedLookupResults( |
| 123 | + databaseName, |
| 124 | + ip, |
| 125 | + new IpinfoIpDataLookups.Asn(Database.AsnV2.properties()), |
| 126 | + Map.ofEntries( |
| 127 | + entry("ip", ip), |
| 128 | + entry("organization_name", "Akamai Technologies, Inc."), |
| 129 | + entry("asn", 32787L), |
| 130 | + entry("network", "23.53.116.0/24"), |
| 131 | + entry("domain", "akamai.com"), |
| 132 | + entry("type", "hosting"), |
| 133 | + entry("country_iso_code", "US") |
| 134 | + ) |
| 135 | + ); |
176 | 136 | } |
177 | 137 |
|
178 | 138 | public void testAsnInvariants() { |
@@ -212,62 +172,42 @@ public void testAsnInvariants() { |
212 | 172 | } |
213 | 173 | } |
214 | 174 |
|
215 | | - public void testCountry() throws IOException { |
| 175 | + public void testCountryFree() { |
216 | 176 | assumeFalse("https://github.com/elastic/elasticsearch/issues/114266", Constants.WINDOWS); |
217 | | - Path configDir = tmpDir; |
218 | | - copyDatabase("ipinfo/ip_country_sample.mmdb", configDir.resolve("ip_country_sample.mmdb")); |
219 | | - |
220 | | - GeoIpCache cache = new GeoIpCache(1000); // real cache to test purging of entries upon a reload |
221 | | - ConfigDatabases configDatabases = new ConfigDatabases(configDir, cache); |
222 | | - configDatabases.initialize(resourceWatcherService); |
223 | | - |
224 | | - // this is the 'free' Country database (sample) |
225 | | - try (DatabaseReaderLazyLoader loader = configDatabases.getDatabase("ip_country_sample.mmdb")) { |
226 | | - IpDataLookup lookup = new IpinfoIpDataLookups.Country(Database.CountryV2.properties()); |
227 | | - Map<String, Object> data = lookup.getData(loader, "4.221.143.168"); |
228 | | - assertThat( |
229 | | - data, |
230 | | - equalTo( |
231 | | - Map.ofEntries( |
232 | | - entry("ip", "4.221.143.168"), |
233 | | - entry("country_name", "South Africa"), |
234 | | - entry("country_iso_code", "ZA"), |
235 | | - entry("continent_name", "Africa"), |
236 | | - entry("continent_code", "AF") |
237 | | - ) |
238 | | - ) |
239 | | - ); |
240 | | - } |
| 177 | + String databaseName = "ip_country_sample.mmdb"; |
| 178 | + String ip = "4.221.143.168"; |
| 179 | + assertExpectedLookupResults( |
| 180 | + databaseName, |
| 181 | + ip, |
| 182 | + new IpinfoIpDataLookups.Country(Database.CountryV2.properties()), |
| 183 | + Map.ofEntries( |
| 184 | + entry("ip", ip), |
| 185 | + entry("country_name", "South Africa"), |
| 186 | + entry("country_iso_code", "ZA"), |
| 187 | + entry("continent_name", "Africa"), |
| 188 | + entry("continent_code", "AF") |
| 189 | + ) |
| 190 | + ); |
241 | 191 | } |
242 | 192 |
|
243 | | - public void testGeolocation() throws IOException { |
| 193 | + public void testGeolocationStandard() { |
244 | 194 | assumeFalse("https://github.com/elastic/elasticsearch/issues/114266", Constants.WINDOWS); |
245 | | - Path configDir = tmpDir; |
246 | | - copyDatabase("ipinfo/ip_geolocation_sample.mmdb", configDir.resolve("ip_geolocation_sample.mmdb")); |
247 | | - |
248 | | - GeoIpCache cache = new GeoIpCache(1000); // real cache to test purging of entries upon a reload |
249 | | - ConfigDatabases configDatabases = new ConfigDatabases(configDir, cache); |
250 | | - configDatabases.initialize(resourceWatcherService); |
251 | | - |
252 | | - // this is the non-free or 'standard' Geolocation database (sample) |
253 | | - try (DatabaseReaderLazyLoader loader = configDatabases.getDatabase("ip_geolocation_sample.mmdb")) { |
254 | | - IpDataLookup lookup = new IpinfoIpDataLookups.Geolocation(Database.CityV2.properties()); |
255 | | - Map<String, Object> data = lookup.getData(loader, "2.124.90.182"); |
256 | | - assertThat( |
257 | | - data, |
258 | | - equalTo( |
259 | | - Map.ofEntries( |
260 | | - entry("ip", "2.124.90.182"), |
261 | | - entry("country_iso_code", "GB"), |
262 | | - entry("region_name", "England"), |
263 | | - entry("city_name", "London"), |
264 | | - entry("timezone", "Europe/London"), |
265 | | - entry("postal_code", "E1W"), |
266 | | - entry("location", Map.of("lat", 51.50853, "lon", -0.12574)) |
267 | | - ) |
268 | | - ) |
269 | | - ); |
270 | | - } |
| 195 | + String databaseName = "ip_geolocation_sample.mmdb"; |
| 196 | + String ip = "2.124.90.182"; |
| 197 | + assertExpectedLookupResults( |
| 198 | + databaseName, |
| 199 | + ip, |
| 200 | + new IpinfoIpDataLookups.Geolocation(Database.CityV2.properties()), |
| 201 | + Map.ofEntries( |
| 202 | + entry("ip", ip), |
| 203 | + entry("country_iso_code", "GB"), |
| 204 | + entry("region_name", "England"), |
| 205 | + entry("city_name", "London"), |
| 206 | + entry("timezone", "Europe/London"), |
| 207 | + entry("postal_code", "E1W"), |
| 208 | + entry("location", Map.of("lat", 51.50853, "lon", -0.12574)) |
| 209 | + ) |
| 210 | + ); |
271 | 211 | } |
272 | 212 |
|
273 | 213 | public void testGeolocationInvariants() { |
@@ -308,53 +248,43 @@ public void testGeolocationInvariants() { |
308 | 248 | } |
309 | 249 | } |
310 | 250 |
|
311 | | - public void testPrivacyDetection() throws IOException { |
| 251 | + public void testPrivacyDetectionStandard() { |
312 | 252 | assumeFalse("https://github.com/elastic/elasticsearch/issues/114266", Constants.WINDOWS); |
313 | | - Path configDir = tmpDir; |
314 | | - copyDatabase("ipinfo/privacy_detection_sample.mmdb", configDir.resolve("privacy_detection_sample.mmdb")); |
315 | | - |
316 | | - GeoIpCache cache = new GeoIpCache(1000); // real cache to test purging of entries upon a reload |
317 | | - ConfigDatabases configDatabases = new ConfigDatabases(configDir, cache); |
318 | | - configDatabases.initialize(resourceWatcherService); |
319 | | - |
320 | | - // testing the first row in the sample database |
321 | | - try (DatabaseReaderLazyLoader loader = configDatabases.getDatabase("privacy_detection_sample.mmdb")) { |
322 | | - IpDataLookup lookup = new IpinfoIpDataLookups.PrivacyDetection(Database.PrivacyDetection.properties()); |
323 | | - Map<String, Object> data = lookup.getData(loader, "1.53.59.33"); |
324 | | - assertThat( |
325 | | - data, |
326 | | - equalTo( |
327 | | - Map.ofEntries( |
328 | | - entry("ip", "1.53.59.33"), |
329 | | - entry("hosting", false), |
330 | | - entry("proxy", false), |
331 | | - entry("relay", false), |
332 | | - entry("tor", false), |
333 | | - entry("vpn", true) |
334 | | - ) |
335 | | - ) |
336 | | - ); |
337 | | - } |
| 253 | + String databaseName = "privacy_detection_sample.mmdb"; |
| 254 | + String ip = "1.53.59.33"; |
| 255 | + assertExpectedLookupResults( |
| 256 | + databaseName, |
| 257 | + ip, |
| 258 | + new IpinfoIpDataLookups.PrivacyDetection(Database.PrivacyDetection.properties()), |
| 259 | + Map.ofEntries( |
| 260 | + entry("ip", ip), |
| 261 | + entry("hosting", false), |
| 262 | + entry("proxy", false), |
| 263 | + entry("relay", false), |
| 264 | + entry("tor", false), |
| 265 | + entry("vpn", true) |
| 266 | + ) |
| 267 | + ); |
| 268 | + } |
338 | 269 |
|
339 | | - // testing a row with a non-empty service in the sample database |
340 | | - try (DatabaseReaderLazyLoader loader = configDatabases.getDatabase("privacy_detection_sample.mmdb")) { |
341 | | - IpDataLookup lookup = new IpinfoIpDataLookups.PrivacyDetection(Database.PrivacyDetection.properties()); |
342 | | - Map<String, Object> data = lookup.getData(loader, "216.131.74.65"); |
343 | | - assertThat( |
344 | | - data, |
345 | | - equalTo( |
346 | | - Map.ofEntries( |
347 | | - entry("ip", "216.131.74.65"), |
348 | | - entry("hosting", true), |
349 | | - entry("proxy", false), |
350 | | - entry("service", "FastVPN"), |
351 | | - entry("relay", false), |
352 | | - entry("tor", false), |
353 | | - entry("vpn", true) |
354 | | - ) |
355 | | - ) |
356 | | - ); |
357 | | - } |
| 270 | + public void testPrivacyDetectionStandardNonEmptyService() { |
| 271 | + assumeFalse("https://github.com/elastic/elasticsearch/issues/114266", Constants.WINDOWS); |
| 272 | + String databaseName = "privacy_detection_sample.mmdb"; |
| 273 | + String ip = "216.131.74.65"; |
| 274 | + assertExpectedLookupResults( |
| 275 | + databaseName, |
| 276 | + ip, |
| 277 | + new IpinfoIpDataLookups.PrivacyDetection(Database.PrivacyDetection.properties()), |
| 278 | + Map.ofEntries( |
| 279 | + entry("ip", ip), |
| 280 | + entry("hosting", true), |
| 281 | + entry("proxy", false), |
| 282 | + entry("service", "FastVPN"), |
| 283 | + entry("relay", false), |
| 284 | + entry("tor", false), |
| 285 | + entry("vpn", true) |
| 286 | + ) |
| 287 | + ); |
358 | 288 | } |
359 | 289 |
|
360 | 290 | public void testPrivacyDetectionInvariants() { |
@@ -403,4 +333,29 @@ private static void assertDatabaseInvariants(final Path databasePath, final BiCo |
403 | 333 | private static File pathToFile(Path databasePath) { |
404 | 334 | return databasePath.toFile(); |
405 | 335 | } |
| 336 | + |
| 337 | + private void assertExpectedLookupResults(String databaseName, String ip, IpDataLookup lookup, Map<String, Object> expected) { |
| 338 | + try (DatabaseReaderLazyLoader loader = loader(databaseName)) { |
| 339 | + Map<String, Object> actual = lookup.getData(loader, ip); |
| 340 | + assertThat( |
| 341 | + "The set of keys in the result are not the same as the set of expected keys", |
| 342 | + actual.keySet(), |
| 343 | + containsInAnyOrder(expected.keySet().toArray(new String[0])) |
| 344 | + ); |
| 345 | + for (Map.Entry<String, Object> entry : expected.entrySet()) { |
| 346 | + assertThat("Unexpected value for key [" + entry.getKey() + "]", actual.get(entry.getKey()), equalTo(entry.getValue())); |
| 347 | + } |
| 348 | + } catch (AssertionError e) { |
| 349 | + fail(e, "Assert failed for database [%s] with address [%s]", databaseName, ip); |
| 350 | + } catch (Exception e) { |
| 351 | + fail(e, "Exception for database [%s] with address [%s]", databaseName, ip); |
| 352 | + } |
| 353 | + } |
| 354 | + |
| 355 | + private DatabaseReaderLazyLoader loader(final String databaseName) { |
| 356 | + Path path = tmpDir.resolve(databaseName); |
| 357 | + copyDatabase("ipinfo/" + databaseName, path); // the ipinfo databases are prefixed on the test classpath |
| 358 | + final GeoIpCache cache = new GeoIpCache(1000); |
| 359 | + return new DatabaseReaderLazyLoader(cache, path, null); |
| 360 | + } |
406 | 361 | } |
0 commit comments