package org.infinispan.server.router.profiling; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; import org.infinispan.client.hotrod.RemoteCacheManager; import org.infinispan.commons.test.annotations.Profiling; import org.infinispan.server.hotrod.HotRodServer; import org.infinispan.server.router.MultiTenantRouter; import org.infinispan.server.router.routes.Route; import org.infinispan.server.router.routes.RouteDestination; import org.infinispan.server.router.routes.RouteSource; import org.junit.Test; import org.junit.experimental.categories.Category; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.TearDown; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.JdkLoggerFactory; /** * This class is responsible for performance tests against the router. It tests 3 configurations: <ul> <li>No SSL at * all</li> <li>HotRod with SSL only</li> <li>Multi tenant router with SSL+SNI</li> </ul> * <p> * <p> Note that this class is not triggered by Surefire by default (it doesn't end with "test"). We want to do * performance test on demand only. </p> */ public class RouterPerfTest { private static final int MEASUREMENT_ITERATIONS_COUNT = 1; private static final int WARMUP_ITERATIONS_COUNT = 1; @Test @Category(Profiling.class) public void performRouterBenchmark() throws Exception { Options opt = new OptionsBuilder() .include(this.getClass().getName() + ".*") .mode(Mode.AverageTime) .mode(Mode.SingleShotTime) .timeUnit(TimeUnit.MILLISECONDS) .warmupIterations(WARMUP_ITERATIONS_COUNT) .measurementIterations(MEASUREMENT_ITERATIONS_COUNT) .threads(1) .forks(1) .shouldFailOnError(true) .shouldDoGC(true) .build(); new Runner(opt).run(); } @State(Scope.Thread) public static class BenchmarkState { @Param({ "org.infinispan.server.router.performance.configuration.SingleServerNoSsl", "org.infinispan.server.router.performance.configuration.SingleServerWithSsl", "org.infinispan.server.router.performance.configuration.TwoServersWithSslSni" }) public String configurationClassName; private List<HotRodServer> hotRodServers; private Optional<Set<Route<? extends RouteSource, ? extends RouteDestination>>> routes; private RemoteCacheManager preloadedClient; private Optional<MultiTenantRouter> router; private PerfTestConfiguration configuration; @Setup public void setup() throws Exception { //Netty uses SLF and SLF can redirect to all other logging frameworks. //Just to make sure we know what we are testing against - let's enforce one of them InternalLoggerFactory.setDefaultFactory(JdkLoggerFactory.INSTANCE); //Temporary to make the test equal System.setProperty("infinispan.server.channel.epoll", "false"); configuration = (PerfTestConfiguration) Class.forName(configurationClassName).getDeclaredConstructor(null).newInstance(null); hotRodServers = configuration.initServers(); routes = configuration.initRoutes(hotRodServers); router = configuration.initRouter(routes); preloadedClient = configuration.initClient(router, routes, hotRodServers); } @TearDown public void tearDown() { preloadedClient.stop(); configuration.shutdown(hotRodServers, router); } @Benchmark public void initConnectionOnly() { RemoteCacheManager client = configuration.initClient(router, routes, hotRodServers); client.stop(); } @Benchmark public void initConnectionAndPerform10Puts() { RemoteCacheManager client = configuration.initClient(router, routes, hotRodServers); configuration.performLoadTesting(client, 10); client.stop(); } @Benchmark public void initConnectionAndPerform10KPuts() { RemoteCacheManager client = configuration.initClient(router, routes, hotRodServers); configuration.performLoadTesting(client, 10_000); client.stop(); } @Benchmark public void perform10KPuts() { configuration.performLoadTesting(preloadedClient, 10_000); } } }