/* * Copyright Siemens AG, 2015. Part of the SW360 Portal Project. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.eclipse.sw360.datahandler; import com.google.common.collect.ImmutableList; import com.google.common.collect.Ordering; import com.google.common.base.Optional; import org.eclipse.sw360.datahandler.common.DatabaseSettings; import org.eclipse.sw360.datahandler.couchdb.DatabaseInstance; import org.eclipse.sw360.datahandler.couchdb.DatabaseInstanceTracker; import org.eclipse.sw360.datahandler.thrift.users.User; import org.eclipse.sw360.datahandler.thrift.users.UserGroup; import org.apache.thrift.TBase; import org.apache.thrift.TFieldIdEnum; import org.ektorp.http.HttpClient; import org.hamcrest.*; import org.hamcrest.collection.IsEmptyCollection; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import java.io.IOException; import java.net.MalformedURLException; import java.net.NetworkInterface; import java.net.SocketException; import java.net.URL; import java.util.*; import java.util.function.Supplier; import static com.google.common.base.Predicates.instanceOf; import static com.google.common.base.Predicates.not; import static com.google.common.base.Strings.isNullOrEmpty; import static com.google.common.collect.Iterables.tryFind; import static com.google.common.collect.Ordering.usingToString; import static java.lang.String.format; import static java.util.Collections.sort; import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import static org.junit.Assume.assumeNoException; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; /** * @author daniele.fognini@tngtech.com */ public class TestUtils { public static final String BLACK_HOLE_ADDRESS = "192.0.2.0"; private static final List<String> dbNames = ImmutableList.of( DatabaseSettings.COUCH_DB_DATABASE, DatabaseSettings.COUCH_DB_ATTACHMENTS, DatabaseSettings.COUCH_DB_FOSSOLOGY, DatabaseSettings.COUCH_DB_USERS); static { assertTestDbNames(); } public static void assertTestDbNames() { for (String dbName : dbNames) { assertTestString(dbName); } } public static void deleteAllDatabases() throws MalformedURLException { for (String dbName : dbNames) { deleteDatabase(DatabaseSettings.getConfiguredHttpClient(), dbName); } } public static void assertTestString(String testString) { assertThat(testString, containsString("test")); } public static Answer failOnUnexpectedMethod() { return new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { fail(format("unexpected call on this mock to <%s>", invocation.getMethod())); return null; } }; } public static <T> T failingMock(Class<T> clazz) { final T mock = mock(clazz, failOnUnexpectedMethod()); @SuppressWarnings("unused") final String toString = doReturn("failing mock for " + clazz).when(mock).toString(); return mock; } public static User getAdminUser(Class caller) { User user = failingMock(User.class); doReturn(true).when(user).isSetUserGroup(); doReturn(UserGroup.ADMIN).when(user).getUserGroup(); doReturn(true).when(user).isSetEmail(); doReturn(caller.getSimpleName() + "@tngtech.com").when(user).getEmail(); doReturn(true).when(user).isSetDepartment(); doReturn(caller.getPackage().getName()).when(user).getDepartment(); return user; } public static void deleteDatabase(Supplier<HttpClient> httpClient, String dbName) throws MalformedURLException { assertTestString(dbName); DatabaseInstance instance = new DatabaseInstance(httpClient.get()); if (instance.checkIfDbExists(dbName)) instance.deleteDatabase(dbName); DatabaseInstanceTracker.destroy(); } public static void createDatabase(Supplier<HttpClient> httpClient, String dbName) throws MalformedURLException { createDatabase(httpClient.get(), dbName); } public static void createDatabase(HttpClient httpClient, String dbName) throws MalformedURLException { assertTestString(dbName); DatabaseInstance instance = new DatabaseInstance(httpClient); if (instance.checkIfDbExists(dbName)) instance.deleteDatabase(dbName); instance.createDatabase(dbName); DatabaseInstanceTracker.destroy(); } public static <T extends TBase<T, F>, F extends TFieldIdEnum> Comparator<T> orderByField(final F field) { return orderByField(field, usingToString()); } public static <T extends TBase<T, F>, F extends TFieldIdEnum> Ordering<T> orderByField(final F field, final Comparator<Object> fieldComparator) { return Ordering.from(new Comparator<T>() { @Override public int compare(T o1, T o2) { Object fieldValue1 = o1.getFieldValue(field); Object fieldValue2 = o2.getFieldValue(field); return fieldComparator.compare(fieldValue1, fieldValue2); } }); } public static <T extends TBase<T, F>, F extends TFieldIdEnum> void sortByField(List<T> list, F field) { Comparator<T> comparator = orderByField(field); sort(list, comparator); } public static Matcher<String> nullOrEmpty() { return new TypeSafeMatcher<String>() { @Override protected boolean matchesSafely(String item) { return isNullOrEmpty(item); } @Override public void describeTo(Description description) { description.appendText("not an empty string"); } }; } public static <T> Matcher<Collection<? extends T>> emptyOrNullCollectionOf(final Class<T> clazz) { return new EmptyOrNullCollectionMatcher<>(clazz); } public static NetworkInterface getAvailableNetworkInterface() { try { Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces(); while (networkInterfaces.hasMoreElements()) { NetworkInterface networkInterface = networkInterfaces.nextElement(); if (networkInterface.isLoopback()) continue; if (networkInterface.isUp()) return networkInterface; } return null; } catch (SocketException e) { return null; } } public static Matcher<NetworkInterface> isAvailable() { return new TypeSafeMatcher<NetworkInterface>() { @Override protected boolean matchesSafely(NetworkInterface item) { try { if (item != null && item.isUp()) return true; } catch (SocketException ignored) { } return false; } @Override public void describeTo(Description description) { description.appendText("an available network interface"); } }; } @SafeVarargs public static <F> F[] restrictedToFields(F... fields) { return fields; } @SafeVarargs public static <T extends TBase<T, F>, F extends TFieldIdEnum> Matcher<? super T> equalTo(final T expected, final F... fields) { if (fields.length == 0) { return CoreMatchers.equalTo(expected); } return new TypeSafeDiagnosingMatcher<T>() { @Override protected boolean matchesSafely(T item, Description mismatchDescription) { for (F field : fields) { Object fieldValue = item.getFieldValue(field); Object expectedFieldValue = expected.getFieldValue(field); if (!Objects.equals(fieldValue, expectedFieldValue)) { mismatchDescription.appendText("field " + field + " does not match, it was :"); mismatchDescription.appendValue(fieldValue); return false; } } return true; } @Override public void describeTo(Description description) { description.appendText("object with fields: "); description.appendValueList("{", ",", "}", Arrays.asList(fields)); description.appendText(" same as object: "); description.appendValue(expected); } }; } public static void assumeCanConnectTo(String url) { try { new URL(url).openConnection().getInputStream().close(); } catch (IOException e) { assumeNoException(e); } } private static class EmptyOrNullCollectionMatcher<T> extends TypeSafeCollectionMatcher<T> { public EmptyOrNullCollectionMatcher(Class<T> expectedType) { super(expectedType); } protected boolean matchesSafely(Collection<? extends T> item) { return IsEmptyCollection.<T>empty().matches(item); } @Override protected boolean nullMatches() { return true; } @Override public void describeTo(Description description) { description.appendText("an empty collection or null"); } } private static abstract class TypeSafeCollectionMatcher<T> extends DiagnosingMatcher<Collection<? extends T>> { private final Class<T> expectedType; public TypeSafeCollectionMatcher(Class<T> expectedType) { this.expectedType = expectedType; } protected boolean nullMatches() { return false; } @Override public boolean matches(Object item, Description mismatchDescription) { if (item == null) { return nullMatches(); } if (item instanceof Collection) { Collection<?> collection = (Collection<?>) item; Optional<?> find = tryFind(collection, not(instanceOf(expectedType))); if (!find.isPresent()) { @SuppressWarnings("unchecked") Collection<? extends T> safeItem = (Collection<? extends T>) collection; return matchesSafely(safeItem); } else { mismatchDescription.appendText("element '"); mismatchDescription.appendValue(find.get()); mismatchDescription.appendText("' is not an instance of " + expectedType.getCanonicalName()); return false; } } else { return false; } } protected abstract boolean matchesSafely(Collection<? extends T> safeItem); } }