/*******************************************************************************
* Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2015-2019)
*
* contact.vitam@culture.gouv.fr
*
* This software is a computer program whose purpose is to implement a digital archiving back-office system managing
* high volumetry securely and efficiently.
*
* This software is governed by the CeCILL 2.1 license under French law and abiding by the rules of distribution of free
* software. You can use, modify and/ or redistribute the software under the terms of the CeCILL 2.1 license as
* circulated by CEA, CNRS and INRIA at the following URL "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license,
* users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the
* successive licensors have only limited liability.
*
* In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or
* developing or reproducing the software by the user in light of its specific status of free software, that may mean
* that it is complicated to manipulate, and that also therefore means that it is reserved for developers and
* experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the
* software's suitability as regards their requirements in conditions enabling the security of their systems and/or data
* to be ensured and, more generally, to use and operate it in the same conditions as regards security.
*
* The fact that you are presently reading this means that you have had knowledge of the CeCILL 2.1 license and that you
* accept its terms.
*******************************************************************************/
package fr.gouv.vitam.common.server.benchmark;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.HttpMethod;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import fr.gouv.vitam.common.exception.VitamApplicationServerException;
import fr.gouv.vitam.common.exception.VitamClientException;
import fr.gouv.vitam.common.junit.JunitHelper;
import fr.gouv.vitam.common.logging.SysErrLogger;
import fr.gouv.vitam.common.logging.VitamLogger;
import fr.gouv.vitam.common.logging.VitamLoggerFactory;
public class BenchmarkResourceManual {
private static final int SLEEP_STARTUP = 5000;
private static final int SLEEP_INTERMEDIARY = 100;
private static final int START_SIZE = SLEEP_INTERMEDIARY;
private static final int FACTOR_STEP = 10;
private static final long MAX_SIZE = 100000000L;
private static final VitamLogger LOGGER = VitamLoggerFactory.getInstance(BenchmarkResourceManual.class);
private static int serverPort = 8889;
public static void main(String[] args) {
BenchmarkClientFactory.setConfiguration(serverPort);
final BenchmarkResourceManual test = new BenchmarkResourceManual();
test.testVariousConnector();
test.testThreadedMode();
}
@BeforeClass
public static void setUpBeforeClass() {
BenchmarkClientFactory.setConfiguration(serverPort);
}
@AfterClass
public static void tearDownAfterClass() {
LOGGER.debug("Ending tests");
}
private static void checkSizeLimit(BenchmarkClientRest client, String method, long size, List<Long> list) {
final long start = System.nanoTime();
final long receivedSize = client.upload(method, size);
if (receivedSize != size) {
LOGGER.error(method + ":" + size + " = " + receivedSize);
}
assertEquals(size, receivedSize);
final long stop = System.nanoTime();
list.add((stop - start) / size);
LOGGER.info("Size: " + size + " Time: " + (stop - start) / size + " ns/bytes");
}
private static void printFinalResul(List<List<Long>> globalTests, long maxSize) {
final StringBuilder builder = new StringBuilder("CONNECTOR ; ");
long size = START_SIZE;
builder.append("Status").append(HttpMethod.GET).append(" ; ");
builder.append("Status").append(HttpMethod.HEAD).append(" ; ");
builder.append("Status").append(HttpMethod.OPTIONS).append(" ; ");
builder.append(HttpMethod.POST).append(size).append(" ; ");
for (; size <= maxSize; size *= FACTOR_STEP) {
builder.append(HttpMethod.POST).append(size).append(" ; ")
.append(HttpMethod.GET).append(size).append(" ; ")
.append(HttpMethod.DELETE).append(size).append(" ; ")
.append(HttpMethod.PUT).append(size).append(" ; ");
}
builder.append(" MEMORY_UZED\n");
int i = 0;
for (final BenchmarkConnectorProvider mode : BenchmarkConnectorProvider.values()) {
if (mode == BenchmarkConnectorProvider.STANDARD || mode == BenchmarkConnectorProvider.APACHE_NOCHECK) {
continue;
}
builder.append(mode.name());
final List<Long> list = globalTests.get(i);
for (final Long info : list) {
builder.append(" ; ").append(info);
}
builder.append("\n");
i++;
}
LOGGER.warn(builder.toString());
}
public final void testVariousConnector() {
final List<List<Long>> globalTests = new ArrayList<>();
for (final BenchmarkConnectorProvider mode : BenchmarkConnectorProvider.values()) {
if (mode == BenchmarkConnectorProvider.STANDARD || mode == BenchmarkConnectorProvider.APACHE_NOCHECK) {
continue;
}
final List<Long> testList = new ArrayList<>();
JunitHelper.awaitFullGc();
try {
Thread.sleep(10000);
} catch (final InterruptedException e) {}
final long available = Runtime.getRuntime().freeMemory();
BenchmarkClientFactory.getInstance().mode(mode);
LOGGER.warn("START " + mode.name());
testBenchmark(globalTests, testList);
final long availableEnd = Runtime.getRuntime().freeMemory();
final long used = available - availableEnd;
testList.add(used);
globalTests.add(testList);
}
printFinalResul(globalTests, MAX_SIZE);
}
public final void testBenchmark(List<List<Long>> globalTests, List<Long> list) {
try (final BenchmarkClientRest client =
BenchmarkClientFactory.getInstance().getClient()) {
long start = System.nanoTime();
client.checkStatus();
long stop = System.nanoTime();
list.add(stop - start);
start = System.nanoTime();
assertTrue(client.getStatus(HttpMethod.HEAD));
stop = System.nanoTime();
list.add(stop - start);
start = System.nanoTime();
assertTrue(client.getStatus(HttpMethod.OPTIONS));
stop = System.nanoTime();
list.add(stop - start);
long size = START_SIZE;
checkSizeLimit(client, HttpMethod.POST, size, list);
try {
Thread.sleep(SLEEP_STARTUP);
} catch (final InterruptedException e) {}
for (; size <= MAX_SIZE; size *= FACTOR_STEP) {
checkSizeLimit(client, HttpMethod.POST, size, list);
try {
Thread.sleep(SLEEP_INTERMEDIARY);
} catch (final InterruptedException e) {}
if (BenchmarkClientFactory.getInstance().getMode() != BenchmarkConnectorProvider.STANDARD) {
checkSizeLimit(client, HttpMethod.GET, size, list);
try {
Thread.sleep(SLEEP_INTERMEDIARY);
} catch (final InterruptedException e) {}
} else {
list.add(-1L);
}
checkSizeLimit(client, HttpMethod.DELETE, size, list);
try {
Thread.sleep(SLEEP_INTERMEDIARY);
} catch (final InterruptedException e) {}
checkSizeLimit(client, HttpMethod.PUT, size, list);
try {
Thread.sleep(SLEEP_INTERMEDIARY);
} catch (final InterruptedException e) {}
}
} catch (final VitamApplicationServerException | VitamClientException e1) {
list.add(-2L);
globalTests.add(list);
printFinalResul(globalTests, MAX_SIZE);
fail("Cannot connect to server");
}
}
public final void testThreadedMode() {
final List<List<Long>> globalTests = new ArrayList<>();
for (final BenchmarkConnectorProvider mode : BenchmarkConnectorProvider.values()) {
if (mode == BenchmarkConnectorProvider.STANDARD || mode == BenchmarkConnectorProvider.APACHE_NOCHECK) {
continue;
}
final List<Long> testList = new ArrayList<>();
JunitHelper.awaitFullGc();
try {
Thread.sleep(10000);
} catch (final InterruptedException e) {}
final ExecutorService executorService = Executors.newCachedThreadPool();
final long available = Runtime.getRuntime().freeMemory();
BenchmarkClientFactory.getInstance().mode(mode);
LOGGER.warn("START " + mode.name());
final long start = System.nanoTime();
for (int i = 0; i < FACTOR_STEP; i++) {
final BenchmarkThread thread = new BenchmarkThread();
thread.globalTests = globalTests;
thread.testList = testList;
executorService.execute(thread);
}
executorService.shutdown();
try {
while (!executorService.awaitTermination(SLEEP_STARTUP, TimeUnit.MILLISECONDS)) {
}
} catch (final InterruptedException e) {
SysErrLogger.FAKE_LOGGER.ignoreLog(e);
}
final long stop = System.nanoTime();
testList.add(stop - start);
final long availableEnd = Runtime.getRuntime().freeMemory();
final long used = available - availableEnd;
testList.add(used);
globalTests.add(testList);
}
printFinalResul(globalTests, MAX_SIZE);
}
private static class BenchmarkThread implements Runnable {
List<List<Long>> globalTests;
List<Long> testList;
@Override
public void run() {
try (final BenchmarkClientRest client =
BenchmarkClientFactory.getInstance().getClient()) {
client.checkStatus();
checkSizeLimit(client, HttpMethod.POST, MAX_SIZE / 10, testList);
} catch (final VitamApplicationServerException e1) {
testList.add(-2L);
globalTests.add(testList);
printFinalResul(globalTests, MAX_SIZE / 100);
fail("Cannot connect to server");
}
}
}
}