package org.knowm.xchange.examples; import static org.fest.assertions.api.Assertions.assertThat; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.SocketTimeoutException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; import org.junit.Assume; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.knowm.xchange.Exchange; import org.knowm.xchange.ExchangeFactory; import org.knowm.xchange.currency.Currency; import org.knowm.xchange.currency.CurrencyPair; import org.knowm.xchange.dto.meta.CurrencyMetaData; import org.knowm.xchange.dto.meta.CurrencyPairMetaData; import org.knowm.xchange.dto.meta.ExchangeMetaData; import org.knowm.xchange.exceptions.NotAvailableFromExchangeException; import org.knowm.xchange.exceptions.NotYetImplementedForExchangeException; import org.knowm.xchange.service.marketdata.MarketDataService; import org.knowm.xchange.utils.retries.IPredicate; import org.knowm.xchange.utils.retries.Retries; import org.reflections.Reflections; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @RunWith(Parameterized.class) public class AllIntegration { @Parameterized.Parameters(name = "{index}:{1}") public static Iterable<Object[]> data() { List<Object[]> exchangeClasses = new ArrayList<Object[]>(); // Find every Exchange Reflections reflections = new Reflections("org.knowm.xchange"); for (Class<? extends Exchange> exchangeClass : reflections.getSubTypesOf(Exchange.class)) { if (Modifier.isAbstract(exchangeClass.getModifiers())) { continue; } exchangeClasses.add(new Object[] { exchangeClass, exchangeClass.getSimpleName() }); } return exchangeClasses; } @Parameterized.Parameter(0) public Class<? extends Exchange> exchangeClass; @Parameterized.Parameter(1) public String exchangeName; private Exchange exchange; final static Logger logger = LoggerFactory.getLogger(AllIntegration.class); @Before public void createExchange() { exchange = ExchangeFactory.INSTANCE.createExchange(exchangeClass.getName()); assertThat(exchange).isNotNull(); } @Test public void testGetMetaData() throws IOException { exchange.remoteInit(); ExchangeMetaData exchangeMetaData = exchange.getExchangeMetaData(); assertThat(exchangeMetaData).isNotNull(); Map<CurrencyPair, CurrencyPairMetaData> marketMetaDataMap = exchangeMetaData.getCurrencyPairs(); assertThat(marketMetaDataMap).isNotEmpty(); Map<Currency, CurrencyMetaData> currencyMetaDataMap = exchangeMetaData.getCurrencies(); assertThat(currencyMetaDataMap).isNotNull(); } // Predicate specifies which exceptions indicate to retry the request public static final IPredicate<Exception> RETRYABLE_REQUEST = new IPredicate<Exception>() { @Override public boolean test(Exception e) { return (e.getMessage() != null && e.getMessage().contains("{code=200, message=Too many requests}")) || e instanceof SocketTimeoutException /* * || e instanceof HttpStatusIOException */; } }; // Test some service method for a collection of first arguments, catching for example NotYetImplementedForExchangeException private <R, A> Collection<R> testExchangeMethod(final Object service, final Method method, Collection<A> firstArgumentOptions, Object... restStaticArguments) throws Throwable { Assume.assumeNotNull(service); String methodName = method.getName(); Collection<R> results = new ArrayList<R>(firstArgumentOptions.size()); final ArrayList<Object> arguments = new ArrayList<Object>(restStaticArguments.length + 1); arguments.add(null); arguments.addAll(Arrays.asList(restStaticArguments)); // If one argument throws NotAvailableFromExchange, all must. boolean notAvailableFromExchangeThrown = false; boolean notAvailableFromExchangeNotThrown = false; for (final A firstArgument : firstArgumentOptions) { Callable<R> callMethod = new Callable<R>() { @Override public R call() throws Exception { try { arguments.set(0, firstArgument); return (R) method.invoke(service, arguments.toArray()); } catch (InvocationTargetException invocationTargetException) { throw ((Exception) invocationTargetException.getCause()); } } }; try { R result = Retries.callWithRetries(8, 1, callMethod, RETRYABLE_REQUEST); assertThat(notAvailableFromExchangeThrown).isFalse(); notAvailableFromExchangeNotThrown = true; String logmsg = methodName + "(" + firstArgument + ") -> " + result; if (logmsg.length() > 75) { logmsg = logmsg.substring(0, 75); } logger.debug(logmsg); assertThat(result).isNotNull(); results.add(result); } catch (NotAvailableFromExchangeException e) { assertThat(notAvailableFromExchangeNotThrown).isFalse(); notAvailableFromExchangeThrown = true; } catch (NotYetImplementedForExchangeException e) { logger.warn(methodName + " unimplemented"); } } Assume.assumeFalse(methodName + " not available from exchange", notAvailableFromExchangeThrown); return results; } // Returns collection of currency pairs private Collection<CurrencyPair> getCurrencyPairs() throws IOException { exchange.remoteInit(); Assume.assumeNotNull(exchange.getExchangeMetaData()); Assume.assumeNotNull(exchange.getExchangeMetaData().getCurrencyPairs()); // uncomment to test every single currencypair //return exchange.getMetaData().getMarketMetaDataMap().keySet(); return Collections.singletonList(exchange.getExchangeMetaData().getCurrencyPairs().keySet().iterator().next()); } @Test public void testGetTicker() throws Throwable { Method method = MarketDataService.class.getMethod("getTicker", CurrencyPair.class, Object[].class); testExchangeMethod(exchange.getMarketDataService(), method, getCurrencyPairs(), (Object) new Object[] {}); } @Test public void testGetOrderBook() throws Throwable { Method method = MarketDataService.class.getMethod("getOrderBook", CurrencyPair.class, Object[].class); testExchangeMethod(exchange.getMarketDataService(), method, getCurrencyPairs(), (Object) new Object[] {}); } @Test public void testGetTrades() throws Throwable { Method method = MarketDataService.class.getMethod("getTrades", CurrencyPair.class, Object[].class); testExchangeMethod(exchange.getMarketDataService(), method, getCurrencyPairs(), (Object) new Object[] {}); } }