source: src/test/java/geniusweb/runserver/MaxLoadTest.java@ 34

Last change on this file since 34 was 34, checked in by bart, 3 years ago

Reduced memory need of websockets.

File size: 6.5 KB
Line 
1package geniusweb.runserver;
2
3import java.io.BufferedReader;
4import java.io.File;
5import java.io.IOException;
6import java.io.InputStream;
7import java.io.InputStreamReader;
8import java.io.OutputStream;
9import java.lang.management.ManagementFactory;
10import java.lang.management.OperatingSystemMXBean;
11import java.net.HttpURLConnection;
12import java.net.MalformedURLException;
13import java.net.ProtocolException;
14import java.net.URISyntaxException;
15import java.net.URL;
16import java.net.URLConnection;
17import java.nio.charset.StandardCharsets;
18import java.util.Arrays;
19import java.util.List;
20
21import org.junit.After;
22import org.junit.Before;
23import org.junit.Test;
24
25import com.fasterxml.jackson.core.JsonProcessingException;
26import com.fasterxml.jackson.databind.ObjectMapper;
27
28import geniusweb.deadline.Deadline;
29import geniusweb.deadline.DeadlineTime;
30import geniusweb.protocol.session.TeamInfo;
31import geniusweb.protocol.session.saop.SAOPSettings;
32import geniusweb.references.Parameters;
33import geniusweb.references.PartyRef;
34import geniusweb.references.PartyWithParameters;
35import geniusweb.references.PartyWithProfile;
36import geniusweb.references.ProfileRef;
37
38/**
39 * End to end test starts server, plus partyserver plus profilesserver, and then
40 * tries to launch large number of parties and keep them busy. Checks and
41 * reports the average CPU loads. Ensure that you have no other background tasks
42 * when you run this test, to avoid incorrect CPU measurements (we can't measure
43 * java-only CPU loads)
44 *
45 *
46 * <h2>Large tests</h2> Tomcat-embed seems very limited in heap space. Best way
47 * to test this with {@link #NUMBER_SESSIONS}>20 is to run all services on
48 * standard tomcat (not embed). To achieve this, disable the @Before and @After.
49 * Additionally, make sure that server.xml has maxThreads="4500" or some large
50 * number sufficient for your test.
51 */
52public class MaxLoadTest {
53 private static final int NUMBER_SESSIONS = 5;
54 private static final int INTER_LAUNCH_DELAY = 20;
55 private static final int PARTY_RESPONSETIME = 1;
56 // HACK can we get it from maven?
57 private static final String GENIUSWEB_VERSION = "2.0.5";
58 private static final ObjectMapper jackson = new ObjectMapper();
59
60 private static final String HARDLINER = "http://localhost:8080/partiesserver/run/hardliner-"
61 + GENIUSWEB_VERSION;
62 /**
63 * Test takes average load of last minute. It may take also a minute or two
64 * to launch all sessions to start with. The average should be taken AFTER
65 * all sessions were launched.
66 */
67 private static final long TEST_TIME_MS = 3 * 60 * 1000;
68
69 private static final EmbeddedTomcat tomcat = new EmbeddedTomcat();
70 private static final Parameters parameters = new Parameters().with("delay",
71 PARTY_RESPONSETIME);
72 private static final String PROFILE1 = "ws://localhost:8080/profilesserver/websocket/get/7issues/7issues1";
73 private static final String PROFILE2 = "ws://localhost:8080/profilesserver/websocket/get/7issues/7issues2";
74 private static final Deadline deadline = new DeadlineTime(TEST_TIME_MS);
75
76 private final URL url;
77 private final byte[] startcommand;
78
79 public MaxLoadTest() throws MalformedURLException, JsonProcessingException,
80 URISyntaxException {
81 url = new URL("http://localhost:8080/runserver/run");
82 String startsession = jackson.writeValueAsString(getSettings());
83 startcommand = startsession.toString().getBytes(StandardCharsets.UTF_8);
84 }
85
86 /**
87 * Start up embedded tomcat servers (all: parties-, profile- and run-server)
88 *
89 * @throws InterruptedException
90 *
91 * @throws Throwable
92 */
93 @Before
94 public void before() throws InterruptedException {
95 tomcat.start();
96 tomcat.deploy("runserver");
97 tomcat.deployWar("profilesserver", new File(
98 "target/jars/profilesserver-" + GENIUSWEB_VERSION + ".war"));
99 tomcat.deployWar("partiesserver", new File(
100 "target/jars/partiesserver-" + GENIUSWEB_VERSION + ".war"));
101 System.out.println("waiting for server start");
102 Thread.sleep(1500);// HOW do this properly?
103 System.out.println("server started I hope");
104
105 }
106
107 @After
108 public void after() throws InterruptedException {
109 System.setSecurityManager(null);
110 tomcat.stop();
111 Thread.sleep(2000);
112 }
113
114 @Test
115 public void testRunOneSession()
116 throws URISyntaxException, IOException, InterruptedException {
117
118 for (int n = 0; n < NUMBER_SESSIONS; n++) {
119 startSession();
120 Thread.sleep(INTER_LAUNCH_DELAY);
121 }
122
123 System.out.println("Started session. Waiting termination");
124
125 // wait at least 1minute, becaues getLoadAver averages over 1 minute.
126 Thread.sleep(Math.max(TEST_TIME_MS + 100, 60 * 1000));
127 OperatingSystemMXBean operatingSystemMXBean = ManagementFactory
128 .getOperatingSystemMXBean();
129
130 System.out.println("average load in last minute was "
131 + operatingSystemMXBean.getSystemLoadAverage());
132 }
133
134 /**
135 *
136 * @return the response received from the startup request
137 * @throws IOException
138 * @throws ProtocolException
139 * @throws IllegalStateException if party can not be launched.
140 */
141 private void startSession() throws IOException, ProtocolException {
142 URLConnection con = url.openConnection();
143 HttpURLConnection http = (HttpURLConnection) con;
144 http.setRequestMethod("POST"); // PUT is another valid option
145 http.setDoOutput(true);
146
147 http.setFixedLengthStreamingMode(startcommand.length);
148 http.setRequestProperty("Content-Type",
149 "application/json; charset=UTF-8");
150 http.setUseCaches(false);
151 http.setDoOutput(true);
152 http.connect();
153 try (OutputStream os = http.getOutputStream()) {
154 os.write(startcommand);
155 }
156
157 InputStream is = http.getInputStream();
158 BufferedReader rd = new BufferedReader(new InputStreamReader(is));
159 String response = "";
160 String line;
161 while ((line = rd.readLine()) != null) {
162 response += line + "\r";
163 }
164 rd.close();
165 System.out.println("sent request. Response=" + response);
166 if (!(response.startsWith("SAOP")))
167 throw new IllegalStateException(
168 "Failed to start party:" + response);
169 }
170
171 private SAOPSettings getSettings() throws URISyntaxException {
172 PartyRef partyref = new PartyRef(HARDLINER);
173 PartyWithParameters party1 = new PartyWithParameters(partyref,
174 parameters);
175 PartyWithParameters party2 = new PartyWithParameters(partyref,
176 parameters);
177 PartyWithProfile partyprofile1 = new PartyWithProfile(party1,
178 new ProfileRef(PROFILE1));
179 PartyWithProfile partyprofile2 = new PartyWithProfile(party2,
180 new ProfileRef(PROFILE2));
181 TeamInfo team1 = new TeamInfo(Arrays.asList(partyprofile1));
182 TeamInfo team2 = new TeamInfo(Arrays.asList(partyprofile2));
183
184 List<TeamInfo> participants = Arrays.asList(team1, team2);
185 SAOPSettings settings = new SAOPSettings(participants, deadline);
186 return settings;
187 }
188
189}
Note: See TracBrowser for help on using the repository browser.