From d14db1d3fbb5beb39a28a8dc1a416a4cafa3dbd1 Mon Sep 17 00:00:00 2001 From: jendib Date: Mon, 31 Aug 2015 22:53:33 +0200 Subject: [PATCH] #24: Quick & dirty stress tester (slow at 60k docs with mem db) --- docs-stress/pom.xml | 9 +- .../java/com/sismics/docs/stress/Main.java | 115 ++++++++++++++++++ docs-stress/src/main/resources/empty.png | Bin 0 -> 921 bytes 3 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 docs-stress/src/main/resources/empty.png diff --git a/docs-stress/pom.xml b/docs-stress/pom.xml index 68c6bc03..6b7c1efe 100644 --- a/docs-stress/pom.xml +++ b/docs-stress/pom.xml @@ -21,6 +21,13 @@ jersey-client + + + com.sismics.docs + docs-web-common + test-jar + + com.google.guava @@ -47,11 +54,9 @@ jcl-over-slf4j - junit junit - test diff --git a/docs-stress/src/main/java/com/sismics/docs/stress/Main.java b/docs-stress/src/main/java/com/sismics/docs/stress/Main.java index 3e11c534..fa349ed2 100644 --- a/docs-stress/src/main/java/com/sismics/docs/stress/Main.java +++ b/docs-stress/src/main/java/com/sismics/docs/stress/Main.java @@ -1,8 +1,33 @@ package com.sismics.docs.stress; +import java.io.BufferedInputStream; +import java.io.InputStream; +import java.util.Date; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +import javax.ws.rs.core.MediaType; + +import junit.framework.Assert; + +import org.codehaus.jettison.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.sismics.docs.rest.filter.CookieAuthenticationFilter; +import com.sismics.docs.rest.util.ClientUtil; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.ClientResponse.Status; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.core.util.MultivaluedMapImpl; +import com.sun.jersey.multipart.FormDataBodyPart; +import com.sun.jersey.multipart.FormDataMultiPart; + /** * Stress app for Sismics Docs. * @@ -14,6 +39,17 @@ public class Main { */ private static final Logger log = LoggerFactory.getLogger(Main.class); + private static final String API_URL = "http://localhost:9999/docs-web/api/"; + private static final int USER_COUNT = 50; + private static final int DOCUMENT_PER_USER_COUNT = 2000; + private static final int TAG_PER_USER_COUNT = 20; + private static final int FILE_PER_DOCUMENT_COUNT = 0; + + private static Client client = Client.create(); + private static ClientUtil clientUtil; + + private static Set userSet = Sets.newHashSet(); + /** * Entry point. * @@ -21,5 +57,84 @@ public class Main { */ public static void main(String[] args) { log.info("Starting stress test..."); + + WebResource resource = client.resource(API_URL); + clientUtil = new ClientUtil(resource); + + // Create users + for (int i = 0; i < USER_COUNT; i++) { + String username = generateString(); + clientUtil.createUser(username); + userSet.add(new User(username, (clientUtil.login(username)))); + log.info("Created user " + (i + 1) + "/" + USER_COUNT); + } + + // Create tags for each user + int tagCreatedCount = 1; + for (User user : userSet) { + WebResource tagResource = resource.path("/tag"); + tagResource.addFilter(new CookieAuthenticationFilter(user.authToken)); + + for (int j = 0; j < TAG_PER_USER_COUNT; j++) { + MultivaluedMapImpl postParams = new MultivaluedMapImpl(); + String name = generateString(); + postParams.add("name", name); + postParams.add("color", "#ff0000"); + ClientResponse response = tagResource.put(ClientResponse.class, postParams); + JSONObject json = response.getEntity(JSONObject.class); + user.tagList.add(json.optString("id")); + log.info("Created tag " + (tagCreatedCount++) + "/" + TAG_PER_USER_COUNT * USER_COUNT); + } + } + + // Create documents for each user + int documentCreatedCount = 1; + for (User user : userSet) { + for (int i = 0; i < DOCUMENT_PER_USER_COUNT; i++) { + WebResource documentResource = resource.path("/document"); + documentResource.addFilter(new CookieAuthenticationFilter(user.authToken)); + MultivaluedMapImpl postParams = new MultivaluedMapImpl(); + postParams.add("title", generateString()); + postParams.add("description", generateString()); + postParams.add("tags", user.tagList.get(ThreadLocalRandom.current().nextInt(user.tagList.size()))); // Random tag + postParams.add("language", "eng"); + long createDate = new Date().getTime(); + postParams.add("create_date", createDate); + ClientResponse response = documentResource.put(ClientResponse.class, postParams); + JSONObject json = response.getEntity(JSONObject.class); + String documentId = json.optString("id"); + log.info("Created document " + (documentCreatedCount++) + "/" + DOCUMENT_PER_USER_COUNT * USER_COUNT + " for user: " + user.username); + + // Add files for each document + for (int j = 0; j < FILE_PER_DOCUMENT_COUNT; j++) { + WebResource fileResource = resource.path("/file"); + fileResource.addFilter(new CookieAuthenticationFilter(user.authToken)); + FormDataMultiPart form = new FormDataMultiPart(); + InputStream file = Main.class.getResourceAsStream("/empty.png"); + FormDataBodyPart fdp = new FormDataBodyPart("file", + new BufferedInputStream(file), + MediaType.APPLICATION_OCTET_STREAM_TYPE); + form.bodyPart(fdp); + form.field("id", documentId); + response = fileResource.type(MediaType.MULTIPART_FORM_DATA).put(ClientResponse.class, form); + Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); + } + } + } + } + + private static String generateString() { + return UUID.randomUUID().toString().replace("-", ""); + } + + private static class User { + public String username; + public List tagList = Lists.newArrayList(); + public String authToken; + + public User(String username, String authToken) { + this.username = username; + this.authToken = authToken; + } } } diff --git a/docs-stress/src/main/resources/empty.png b/docs-stress/src/main/resources/empty.png new file mode 100644 index 0000000000000000000000000000000000000000..cee8159108c0612fb5980313879099e4e546df96 GIT binary patch literal 921 zcmaJ=%Wl&^6m_XoL8Xc{tVZs##GY|*9FJl`Vka~bj-n(|v&69{jg{JC#uMyhh1hk+ znty;FK!P>Dz=AJ8V$Y_G(>P^8u;h8^oO92;bLV={e{pjB_*jyplis;A6!Ssx-@hlu z_u1%&m>%)YgpcTqXC5O`E1**XdXaZYhQte2ufLIoBprfqJmC}fCH85gcm+nuqeQSJ zsnN_6&tDJ@rsOh=E&12yuQCV&OTN%u=q5Iqhv#cXM(h6AUoU(!kekmyBgaA@BHROc zbQPyKx8#j37VF|zmB9wW7nXc$YT^!nO&I~Y0xLeOK~O^qsy;Og;|b6pf-2Nhq*aiC zs~Uz7Y(H5>Lz2=Z^Tox@PK!_pwi)p_Wn)UO$|?@#l+$!h6JU>Ya1q7<&C(6pb#X6FxflDS z=UB4fD`6PmTDxnYmebN9auDk1by(NUwq13qNDPKuavka~BNFqH8{Bc*d$~m;M2U#( z5Ei~6L6^}8Y!b%delPXCdRuO=-;24Is|qt}ajkz{b9p3sr&#WqR%~`{Ph!#QOf>a_ rpI<(R2l24yw8r`O>F=AH=JU4)($UeObau@@7LTRZ={uj=uipIuIffaM literal 0 HcmV?d00001