Skip to content

Commit

Permalink
Remove mmdb files from test resources (#71)
Browse files Browse the repository at this point in the history
* Do not run tests if maxmind database resources are missing

Add a custom JUnit test runner and a custom condition annotation to
check if the required resources exist.

* Remove mmdb resources and add mmdb files to gitignore
  • Loading branch information
bernd authored and joschi committed Jan 27, 2018
1 parent 80e50fa commit e9b622d
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -13,3 +13,4 @@ node_modules
node
build
cache/
*.mmdb
84 changes: 84 additions & 0 deletions src/test/java/org/graylog/plugins/map/ConditionalRunner.java
@@ -0,0 +1,84 @@
package org.graylog.plugins.map;

import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* JUnit test runner based on {@link BlockJUnit4ClassRunner} that disables tests based on condition annotations.
* <p>
* Supported conditions:
* <ul>
* <li>{@link ResourceExistsCondition} - Disable tests if any given resource doesn't exist
* </ul>
*/
public class ConditionalRunner extends BlockJUnit4ClassRunner {
private static final Logger LOG = LoggerFactory.getLogger(ConditionalRunner.class);

public ConditionalRunner(Class<?> clazz) throws InitializationError {
super(clazz);
}

private List<Class<?>> getClassAndSuperclasses(final Class<?> testClass) {
final List<Class<?>> classes = new ArrayList<>();

Class<?> clazz = testClass;
while (clazz != null) {
classes.add(clazz);
clazz = clazz.getSuperclass();
}

return classes;
}

private Stream<String> missingResourcesStream(final ResourceExistsCondition condition, final Class<?> clazz) {
if (condition == null) {
return Stream.empty();
}

final Stream<String> resources = Arrays.stream(condition.value());

// Return all missing resources
return resources.filter(resource -> clazz.getResource(resource) == null);
}

private Set<String> missingResources(final FrameworkMethod method) {
// Check method class and all its superclasses for annotations
final Stream<String> missingClassResourcesStream = getClassAndSuperclasses(method.getDeclaringClass()).stream()
.flatMap(clazz -> {
final ResourceExistsCondition condition = clazz.getAnnotation(ResourceExistsCondition.class);

return missingResourcesStream(condition, clazz);
});

// Check this method for annotations
final ResourceExistsCondition methodCondition = method.getAnnotation(ResourceExistsCondition.class);

return Stream.concat(
missingClassResourcesStream,
missingResourcesStream(methodCondition, method.getDeclaringClass())
).collect(Collectors.toSet());
}

@Override
protected boolean isIgnored(FrameworkMethod child) {
final Set<String> missingResources = missingResources(child);

if (!missingResources.isEmpty()) {
LOG.warn("Not running test {}#{}() because of missing resources: {}",
child.getDeclaringClass().getCanonicalName(), child.getName(), missingResources);
return true;
}

return super.isIgnored(child);
}
}
29 changes: 29 additions & 0 deletions src/test/java/org/graylog/plugins/map/ResourceExistsCondition.java
@@ -0,0 +1,29 @@
package org.graylog.plugins.map;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Can be used in conjunction with {@link ConditionalRunner} to disable tests if one or more resources doesn't exist.
* <p>
* Example:
* <pre>{@code
* @literal @RunWith(ConditionalRunner.class)
* @literal @ResourceExistsCondition({"/file1.txt", "/file2.txt"})
* public class GeoIpResolverEngineTest {
* @literal @Test
* @literal @ResourceExistsCondition("/file3.txt")
* public void test() {
* }
* }
* }</pre>
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ResourceExistsCondition {
/** List of resources that must exist to run the tests. */
String[] value();
}

Expand Up @@ -21,11 +21,14 @@
import com.eaio.uuid.UUID;
import com.google.common.collect.Maps;
import com.google.common.net.InetAddresses;
import org.graylog.plugins.map.ConditionalRunner;
import org.graylog.plugins.map.ResourceExistsCondition;
import org.graylog.plugins.map.config.GeoIpResolverConfig;
import org.graylog2.plugin.Message;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.net.URISyntaxException;
import java.util.Map;
Expand All @@ -37,7 +40,10 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

@RunWith(ConditionalRunner.class)
@ResourceExistsCondition(GeoIpResolverEngineTest.GEO_LITE2_CITY_MMDB)
public class GeoIpResolverEngineTest {
static final String GEO_LITE2_CITY_MMDB = "/GeoLite2-City.mmdb";

private MetricRegistry metricRegistry;
private GeoIpResolverConfig config;
Expand All @@ -55,7 +61,7 @@ public void tearDown() {
}

private String getTestDatabasePath() throws URISyntaxException {
return this.getClass().getResource("/GeoLite2-City.mmdb").toURI().getPath();
return this.getClass().getResource(GEO_LITE2_CITY_MMDB).toURI().getPath();
}

@Test
Expand Down
Expand Up @@ -5,7 +5,8 @@
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.model.CountryResponse;
import com.maxmind.geoip2.record.City;
import org.graylog.plugins.map.ConditionalRunner;
import org.graylog.plugins.map.ResourceExistsCondition;
import org.graylog.plugins.map.config.DatabaseType;
import org.graylog2.plugin.lookup.LookupResult;
import org.junit.After;
Expand All @@ -29,9 +30,12 @@
MaxmindDataAdapterTest.CountryDatabaseTest.class
})
public class MaxmindDataAdapterTest {
private static final String GEO_LITE2_CITY_MMDB = "/GeoLite2-City.mmdb";
private static final String GEO_LITE2_COUNTRY_MMDB = "/GeoLite2-Country.mmdb";

private static final Map<DatabaseType, String> DB_PATH = ImmutableMap.of(
DatabaseType.MAXMIND_CITY, "/GeoLite2-City.mmdb",
DatabaseType.MAXMIND_COUNTRY, "/GeoLite2-Country.mmdb"
DatabaseType.MAXMIND_CITY, GEO_LITE2_CITY_MMDB,
DatabaseType.MAXMIND_COUNTRY, GEO_LITE2_COUNTRY_MMDB
);

abstract static class Base {
Expand Down Expand Up @@ -99,6 +103,8 @@ public void doGetReturnsEmptyResultForInvalidIPAddress() {
}
}

@RunWith(ConditionalRunner.class)
@ResourceExistsCondition(GEO_LITE2_CITY_MMDB)
public static class CityDatabaseTest extends Base {
public CityDatabaseTest() {
super(DatabaseType.MAXMIND_CITY);
Expand Down Expand Up @@ -138,6 +144,8 @@ public void doGetReturnsResultIfCityResponseFieldsAreNull() throws Exception {
}
}

@RunWith(ConditionalRunner.class)
@ResourceExistsCondition(GEO_LITE2_COUNTRY_MMDB)
public static class CountryDatabaseTest extends Base {
public CountryDatabaseTest() {
super(DatabaseType.MAXMIND_COUNTRY);
Expand Down
Binary file removed src/test/resources/GeoLite2-City.mmdb
Binary file not shown.
Binary file removed src/test/resources/GeoLite2-Country.mmdb
Binary file not shown.

0 comments on commit e9b622d

Please sign in to comment.