├── .gitignore
├── LICENSE.txt
├── README.md
├── pom.xml
└── src
├── main
├── java
│ └── net
│ │ └── unit8
│ │ └── jmeter
│ │ └── protocol
│ │ └── websocket
│ │ ├── control
│ │ └── gui
│ │ │ └── WebSocketSamplerGui.java
│ │ └── sampler
│ │ └── WebSocketSampler.java
└── resources
│ └── net
│ └── unit8
│ └── jmeter
│ └── protocol
│ └── websocket
│ └── sampler
│ ├── WebSocketSamplerResources.properties
│ └── WebSocketSamplerResources_ja.properties
└── test
├── java
└── net
│ └── unit8
│ └── jmeter
│ └── protocol
│ └── websocket
│ └── sampler
│ └── WebSocketSamplerTest.java
├── resources
├── jmeter.properties
├── saveservice.properties
└── users.csv
└── scripts
└── chat.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | node_modules
3 | target
4 | *.iml
5 | *.class
6 | *.log
7 | *-log
8 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright 2013 kawasima1016@gmail.com
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ApacheJmeter websocket
2 | ======================
3 |
4 | This is the jmeter plugin for WebSocket protocol.
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | net.unit8.jmeter
8 | ApacheJmeter_websocket
9 | 0.1.0-SNAPSHOT
10 | ApacheJmeter_websocket
11 |
12 |
13 | 2.9
14 | 8.1.9.v20130131
15 |
16 |
17 |
18 |
19 |
20 | org.apache.maven.plugins
21 | maven-shade-plugin
22 | 2.0
23 |
24 | target/${project.name}-dist-${project.version}.jar
25 |
26 |
27 |
28 | package
29 |
30 | shade
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | org.apache.jmeter
41 | ApacheJMeter
42 | ${jmeterVersion}
43 | provided
44 |
45 |
46 | org.apache.jmeter
47 | ApacheJMeter_http
48 | ${jmeterVersion}
49 | provided
50 |
51 |
52 | org.apache.jmeter
53 | ApacheJMeter_functions
54 | ${jmeterVersion}
55 | provided
56 |
57 |
58 | org.eclipse.jetty
59 | jetty-websocket
60 | ${jettyVersion}
61 |
62 |
63 | junit
64 | junit
65 | 4.11
66 | test
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/src/main/java/net/unit8/jmeter/protocol/websocket/control/gui/WebSocketSamplerGui.java:
--------------------------------------------------------------------------------
1 | package net.unit8.jmeter.protocol.websocket.control.gui;
2 |
3 | import net.unit8.jmeter.protocol.websocket.sampler.WebSocketSampler;
4 | import org.apache.jmeter.config.Arguments;
5 | import org.apache.jmeter.gui.util.HorizontalPanel;
6 | import org.apache.jmeter.gui.util.VerticalPanel;
7 | import org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel;
8 | import org.apache.jmeter.protocol.http.util.HTTPArgument;
9 | import org.apache.jmeter.samplers.gui.AbstractSamplerGui;
10 | import org.apache.jmeter.testelement.TestElement;
11 | import org.apache.jmeter.testelement.property.TestElementProperty;
12 | import org.apache.jmeter.util.JMeterUtils;
13 | import org.apache.jorphan.logging.LoggingManager;
14 | import org.apache.log.Logger;
15 |
16 | import javax.swing.*;
17 | import java.awt.*;
18 | import java.util.Locale;
19 | import java.util.MissingResourceException;
20 | import java.util.ResourceBundle;
21 |
22 | /**
23 | * GUI for WebSocetSampler
24 | *
25 | * @author kawasima
26 | */
27 | public class WebSocketSamplerGui extends AbstractSamplerGui {
28 | private static final Logger log = LoggingManager.getLoggerForClass();
29 |
30 | private JTextField domain;
31 | private JTextField port;
32 | private JTextField protocol;
33 | private JTextField contentEncoding;
34 | private JTextField path;
35 | private JTextArea sendMessage;
36 | private JTextArea recvMessage;
37 | private HTTPArgumentsPanel argsPanel;
38 |
39 | private boolean displayName = true;
40 | private static final ResourceBundle resources;
41 |
42 | static {
43 | Locale loc = JMeterUtils.getLocale();
44 | resources = ResourceBundle.getBundle(WebSocketSampler.class.getName() + "Resources", loc);
45 | log.info("Resource " + WebSocketSampler.class.getName() + //$NON-NLS-1$
46 | " is loaded for locale " + loc); //$NON-NLS-1$
47 | }
48 |
49 | public WebSocketSamplerGui() {
50 | this(true);
51 | }
52 |
53 | public WebSocketSamplerGui(boolean displayName) {
54 | this.displayName = displayName;
55 | init();
56 | }
57 |
58 | @Override
59 | public String getLabelResource() {
60 | throw new IllegalStateException("This shouldn't be called"); //$NON-NLS-1$
61 | }
62 |
63 | @Override
64 | public String getStaticLabel() {
65 | return getResString("websocket_testing_title"); //$NON-NLS-1$
66 | }
67 | @Override
68 | public void configure(TestElement element) {
69 | super.configure(element);
70 | domain.setText(element.getPropertyAsString(WebSocketSampler.DOMAIN));
71 | port.setText(element.getPropertyAsString(WebSocketSampler.PORT));
72 | protocol.setText(element.getPropertyAsString(WebSocketSampler.PROTOCOL));
73 | path.setText(element.getPropertyAsString(WebSocketSampler.PATH));
74 | contentEncoding.setText(element.getPropertyAsString(WebSocketSampler.CONTENT_ENCODING));
75 |
76 | Arguments arguments = (Arguments) element.getProperty(WebSocketSampler.ARGUMENTS).getObjectValue();
77 | argsPanel.configure(arguments);
78 |
79 | sendMessage.setText(element.getPropertyAsString(WebSocketSampler.SEND_MESSAGE));
80 | recvMessage.setText(element.getPropertyAsString(WebSocketSampler.RECV_MESSAGE));
81 | }
82 |
83 | @Override
84 | public TestElement createTestElement() {
85 | WebSocketSampler element = new WebSocketSampler();
86 |
87 | element.setName(getName());
88 | element.setProperty(TestElement.GUI_CLASS, this.getClass().getName());
89 | element.setProperty(TestElement.TEST_CLASS, element.getClass().getName());
90 |
91 | modifyTestElement(element);
92 | return element;
93 | }
94 |
95 | @Override
96 | public void modifyTestElement(TestElement element) {
97 | configureTestElement(element);
98 | element.setProperty(WebSocketSampler.DOMAIN, domain.getText());
99 | element.setProperty(WebSocketSampler.PATH, path.getText());
100 | element.setProperty(WebSocketSampler.PORT, port.getText());
101 | element.setProperty(WebSocketSampler.PROTOCOL, protocol.getText());
102 | element.setProperty(WebSocketSampler.CONTENT_ENCODING, contentEncoding.getText());
103 |
104 | Arguments args = (Arguments) argsPanel.createTestElement();
105 | HTTPArgument.convertArgumentsToHTTP(args);
106 | element.setProperty(new TestElementProperty(WebSocketSampler.ARGUMENTS, args));
107 |
108 | element.setProperty(WebSocketSampler.SEND_MESSAGE, sendMessage.getText());
109 | element.setProperty(WebSocketSampler.RECV_MESSAGE, recvMessage.getText());
110 | }
111 |
112 | private JPanel getDomainPanel() {
113 | domain = new JTextField(20);
114 |
115 | JLabel label = new JLabel(JMeterUtils.getResString("web_server_domain")); // $NON-NLS-1$
116 | label.setLabelFor(domain);
117 |
118 | JPanel panel = new JPanel(new BorderLayout(5, 0));
119 | panel.add(label, BorderLayout.WEST);
120 | panel.add(domain, BorderLayout.CENTER);
121 | return panel;
122 | }
123 |
124 | private JPanel getPortPanel() {
125 | port = new JTextField(4);
126 |
127 | JLabel label = new JLabel(JMeterUtils.getResString("web_server_port")); // $NON-NLS-1$
128 | label.setLabelFor(port);
129 |
130 | JPanel panel = new JPanel(new BorderLayout(5, 0));
131 | panel.add(label, BorderLayout.WEST);
132 | panel.add(port, BorderLayout.CENTER);
133 |
134 | return panel;
135 | }
136 |
137 | protected Component getProtocolAndPathPanel() {
138 | // PATH
139 | path = new JTextField(15);
140 | JLabel pathLabel = new JLabel(JMeterUtils.getResString("path")); //$NON-NLS-1$
141 | pathLabel.setLabelFor(path);
142 |
143 | // PROTOCOL
144 | protocol = new JTextField(4);
145 | JLabel protocolLabel = new JLabel(JMeterUtils.getResString("protocol")); // $NON-NLS-1$
146 | protocolLabel.setLabelFor(protocol);
147 |
148 | // CONTENT_ENCODING
149 | contentEncoding = new JTextField(10);
150 | JLabel contentEncodingLabel = new JLabel(JMeterUtils.getResString("content_encoding")); // $NON-NLS-1$
151 | contentEncodingLabel.setLabelFor(contentEncoding);
152 |
153 | JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
154 | panel.add(pathLabel);
155 | panel.add(path);
156 | panel.add(Box.createHorizontalStrut(5));
157 |
158 | panel.add(protocolLabel);
159 | panel.add(protocol);
160 | panel.add(Box.createHorizontalStrut(5));
161 |
162 | panel.add(contentEncodingLabel);
163 | panel.add(contentEncoding);
164 | panel.setMinimumSize(panel.getPreferredSize());
165 |
166 | return panel;
167 | }
168 |
169 | private JPanel getSendMessagePanel() {
170 | JLabel sendMessageLabel = new JLabel(getResString("websocket_send_message")); // $NON-NLS-1$
171 | sendMessage = new JTextArea(3, 0);
172 | sendMessage.setLineWrap(true);
173 | sendMessageLabel.setLabelFor(sendMessage);
174 |
175 | JPanel sendMessagePanel = new JPanel(new BorderLayout(5, 0));
176 | sendMessagePanel.add(sendMessageLabel, BorderLayout.WEST);
177 | sendMessagePanel.add(sendMessage, BorderLayout.CENTER);
178 | return sendMessagePanel;
179 | }
180 |
181 | private JPanel getRecvMessagePanel() {
182 | JLabel recvMessageLabel = new JLabel(getResString("websocket_recv_message")); // $NON-NLS-1$
183 | recvMessage = new JTextArea(3, 0);
184 | recvMessage.setLineWrap(true);
185 | recvMessageLabel.setLabelFor(recvMessage);
186 |
187 | JPanel recvMessagePanel = new JPanel(new BorderLayout(5, 0));
188 | recvMessagePanel.add(recvMessageLabel, BorderLayout.WEST);
189 | recvMessagePanel.add(recvMessage, BorderLayout.CENTER);
190 | return recvMessagePanel;
191 | }
192 |
193 | private void init() {
194 | setLayout(new BorderLayout(0, 5));
195 |
196 | if (displayName) {
197 | setBorder(makeBorder());
198 | add(makeTitlePanel(), BorderLayout.NORTH);
199 | }
200 |
201 | // MAIN PANEL
202 | VerticalPanel mainPanel = new VerticalPanel();
203 | JPanel webRequestPanel = new HorizontalPanel();
204 | JPanel serverPanel = new JPanel();
205 | serverPanel.setLayout(new BoxLayout(serverPanel, BoxLayout.X_AXIS));
206 | serverPanel.add(getDomainPanel());
207 | serverPanel.add(getPortPanel());
208 |
209 | webRequestPanel.add(serverPanel, BorderLayout.NORTH);
210 | JPanel northPanel = new JPanel();
211 | northPanel.setLayout(new BoxLayout(northPanel, BoxLayout.Y_AXIS));
212 | northPanel.add(getProtocolAndPathPanel());
213 |
214 | webRequestPanel.add(northPanel, BorderLayout.CENTER);
215 | argsPanel = new HTTPArgumentsPanel();
216 | webRequestPanel.add(argsPanel, BorderLayout.SOUTH);
217 |
218 | mainPanel.add(webRequestPanel);
219 | mainPanel.add(getSendMessagePanel());
220 | mainPanel.add(getRecvMessagePanel());
221 | add(mainPanel, BorderLayout.CENTER);
222 | }
223 |
224 | /**
225 | * Gets the resource string for this key.
226 | *
227 | * If the resource is not found, a warning is logged
228 | *
229 | * @param key
230 | * the key in the resource file
231 | * @return the resource string if the key is found; otherwise, return
232 | * "[res_key="+key+"]"
233 | */
234 | public static String getResString(String key) {
235 | return getResStringDefault(key, RES_KEY_PFX + key + "]"); //$NON-NLS-1$
236 | }
237 |
238 | public static final String RES_KEY_PFX = "[res_key="; //$NON-NLS-1$
239 |
240 | /*
241 | * Helper method to do the actual work of fetching resources; allows
242 | * getResString(S,S) to be deprecated without affecting getResString(S);
243 | */
244 | private static String getResStringDefault(String key, String defaultValue) {
245 | if (key == null) {
246 | return null;
247 | }
248 | // Resource keys cannot contain spaces
249 | key = key.replace(' ', '_'); // $NON-NLS-1$ // $NON-NLS-2$
250 | key = key.toLowerCase(java.util.Locale.ENGLISH);
251 | String resString = null;
252 | try {
253 | resString = resources.getString(key);
254 | } catch (MissingResourceException mre) {
255 | log.warn("ERROR! Resource string not found: [" + //$NON-NLS-1$
256 | key + "]", mre); //$NON-NLS-1$
257 | resString = defaultValue;
258 | }
259 | return resString;
260 | }
261 | }
262 |
--------------------------------------------------------------------------------
/src/main/java/net/unit8/jmeter/protocol/websocket/sampler/WebSocketSampler.java:
--------------------------------------------------------------------------------
1 | package net.unit8.jmeter.protocol.websocket.sampler;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 | import org.apache.jmeter.config.Argument;
5 | import org.apache.jmeter.config.Arguments;
6 | import org.apache.jmeter.config.ConfigTestElement;
7 | import org.apache.jmeter.protocol.http.util.EncoderCache;
8 | import org.apache.jmeter.protocol.http.util.HTTPArgument;
9 | import org.apache.jmeter.protocol.http.util.HTTPConstants;
10 | import org.apache.jmeter.samplers.AbstractSampler;
11 | import org.apache.jmeter.samplers.Entry;
12 | import org.apache.jmeter.samplers.SampleResult;
13 | import org.apache.jmeter.testelement.TestElement;
14 | import org.apache.jmeter.testelement.TestStateListener;
15 | import org.apache.jmeter.testelement.property.*;
16 | import org.apache.jmeter.threads.JMeterContextService;
17 | import org.apache.jorphan.logging.LoggingManager;
18 | import org.apache.jorphan.util.JOrphanUtils;
19 | import org.apache.log.Logger;
20 | import org.eclipse.jetty.util.ConcurrentHashSet;
21 | import org.eclipse.jetty.websocket.WebSocket;
22 | import org.eclipse.jetty.websocket.WebSocketClient;
23 | import org.eclipse.jetty.websocket.WebSocketClientFactory;
24 |
25 | import java.io.UnsupportedEncodingException;
26 | import java.net.URI;
27 | import java.net.URISyntaxException;
28 | import java.util.Arrays;
29 | import java.util.HashSet;
30 | import java.util.Set;
31 | import java.util.concurrent.Future;
32 | import java.util.concurrent.TimeoutException;
33 | import java.util.regex.Pattern;
34 |
35 | /**
36 | * The sampler for WebSocket.
37 |
38 | * @author kawasima
39 | */
40 | public class WebSocketSampler extends AbstractSampler implements TestStateListener {
41 |
42 | private static final Logger log = LoggingManager.getLoggerForClass();
43 |
44 | private static final Set APPLIABLE_CONFIG_CLASSES = new HashSet(
45 | Arrays.asList(new String[]{
46 | "net.unit8.jmeter.protocol.websocket.control.gui.WebSocketSamplerGui",
47 | "org.apache.jmeter.config.gui.SimpleConfigGui"}));
48 |
49 | private static final String ARG_VAL_SEP = "="; // $NON-NLS-1$
50 | private static final String QRY_SEP = "&"; // $NON-NLS-1$
51 | private static final String QRY_PFX = "?"; // $NON-NLS-1$
52 |
53 | private static final String WS_PREFIX = "ws://"; // $NON-NLS-1$
54 | private static final String WSS_PREFIX = "wss://"; // $NON-NLS-1$
55 | private static final String DEFAULT_PROTOCOL = "ws";
56 | private static final int UNSPECIFIED_PORT = 0;
57 | private static final String UNSPECIFIED_PORT_AS_STRING = "0"; // $NON-NLS-1$
58 | private static final int URL_UNSPECIFIED_PORT = -1;
59 |
60 |
61 | private WebSocket.Connection connection = null;
62 | private static final ConcurrentHashSet samplerConnections
63 | = new ConcurrentHashSet();
64 |
65 | private boolean initialized = false;
66 | private String responseMessage;
67 |
68 | public static final String DOMAIN = "WebSocketSampler.domain";
69 | public static final String PORT = "WebSocketSampler.port";
70 | public static final String PATH = "WebSocketSampler.path";
71 | public static final String PROTOCOL = "WebSocketSampler.protocol";
72 | public static final String CONTENT_ENCODING = "WebSocketSampler.contentEncoding";
73 | public static final String ARGUMENTS = "WebSocketSampler.arguments";
74 | public static final String SEND_MESSAGE = "WebSocketSampler.sendMessage";
75 | public static final String RECV_MESSAGE = "WebSocketSampler.recvMessage";
76 | public static final String RECV_TIMEOUT = "WebSocketSampler.recvTimeout";
77 |
78 | private static WebSocketClientFactory webSocketClientFactory = new WebSocketClientFactory();
79 |
80 |
81 | public WebSocketSampler() {
82 | setArguments(new Arguments());
83 | }
84 |
85 | public void initialize() throws Exception {
86 | URI uri = getUri();
87 | WebSocketClient webSocketClient = webSocketClientFactory.newWebSocketClient();
88 | final WebSocketSampler parent = this;
89 | final String threadName = JMeterContextService.getContext().getThread().getThreadName();
90 | final Pattern regex = (getRecvMessage() != null) ? Pattern.compile(getRecvMessage()) : null;
91 | Future futureConnection = webSocketClient.open(uri, new WebSocket.OnTextMessage() {
92 |
93 | @Override
94 | public void onMessage(String s) {
95 | synchronized (parent) {
96 | if (regex == null || regex.matcher(s).find()) {
97 | responseMessage = s;
98 | parent.notify();
99 | }
100 | }
101 | }
102 |
103 | @Override
104 | public void onOpen(Connection connection) {
105 | log.debug("Connect " + threadName);
106 | }
107 |
108 | @Override
109 | public void onClose(int i, String s) {
110 | log.debug("Disconnect " + threadName);
111 | }
112 | });
113 | connection = futureConnection.get();
114 | samplerConnections.add(connection);
115 | initialized = true;
116 | }
117 | @Override
118 | public SampleResult sample(Entry entry) {
119 | SampleResult res = new SampleResult();
120 | res.setSampleLabel(getName());
121 |
122 | boolean isOK = false;
123 | if (!initialized) {
124 | try {
125 | initialize();
126 | } catch (Exception e) {
127 | res.setResponseMessage(e.getMessage());
128 | res.setSuccessful(false);
129 | return res;
130 | }
131 | }
132 | String message = getPropertyAsString(SEND_MESSAGE, "default message");
133 | res.setSamplerData(message);
134 | res.sampleStart();
135 | try {
136 | if (connection.isOpen()) {
137 | res.setDataEncoding(getContentEncoding());
138 | connection.sendMessage(message);
139 | } else {
140 | initialize();
141 | }
142 | synchronized (this) {
143 | wait(getRecvTimeout());
144 | }
145 | if (responseMessage == null) {
146 | res.setResponseCode("204");
147 | throw new TimeoutException("No content (probably timeout).");
148 | }
149 | res.setResponseCodeOK();
150 | res.setResponseData(responseMessage, getContentEncoding());
151 | isOK = true;
152 | } catch (Exception e) {
153 | log.debug(e.getMessage());
154 | res.setResponseMessage(e.getMessage());
155 | }
156 | res.sampleEnd();
157 | res.setSuccessful(isOK);
158 |
159 | return res;
160 | }
161 |
162 |
163 | @Override
164 | public void setName(String name) {
165 | if (name != null)
166 | setProperty(TestElement.NAME, name);
167 | }
168 |
169 | @Override
170 | public String getName() {
171 | return getPropertyAsString(TestElement.NAME);
172 | }
173 |
174 | @Override
175 | public void setComment(String comment){
176 | setProperty(new StringProperty(TestElement.COMMENTS, comment));
177 | }
178 |
179 | @Override
180 | public String getComment(){
181 | return getProperty(TestElement.COMMENTS).getStringValue();
182 | }
183 |
184 | public URI getUri() throws URISyntaxException {
185 | String path = this.getPath();
186 | // Hack to allow entire URL to be provided in host field
187 | if (path.startsWith(WS_PREFIX)
188 | || path.startsWith(WSS_PREFIX)){
189 | return new URI(path);
190 | }
191 | String domain = getDomain();
192 | String protocol = getProtocol();
193 | // HTTP URLs must be absolute, allow file to be relative
194 | if (!path.startsWith("/")){ // $NON-NLS-1$
195 | path = "/" + path; // $NON-NLS-1$
196 | }
197 |
198 | String queryString = getQueryString(getContentEncoding());
199 | if(isProtocolDefaultPort()) {
200 | return new URI(protocol, null, domain, -1, path, queryString, null);
201 | }
202 | return new URI(protocol, null, domain, getPort(), path, queryString, null);
203 | }
204 |
205 | public void setPath(String path, String contentEncoding) {
206 | boolean fullUrl = path.startsWith(WS_PREFIX) || path.startsWith(WSS_PREFIX);
207 | if (!fullUrl) {
208 | int index = path.indexOf(QRY_PFX);
209 | if (index > -1) {
210 | setProperty(PATH, path.substring(0, index));
211 | // Parse the arguments in querystring, assuming specified encoding for values
212 | parseArguments(path.substring(index + 1), contentEncoding);
213 | } else {
214 | setProperty(PATH, path);
215 | }
216 | } else {
217 | setProperty(PATH, path);
218 | }
219 | }
220 |
221 | public String getPath() {
222 | String p = getPropertyAsString(PATH);
223 | return encodeSpaces(p);
224 | }
225 |
226 | public void setPort(int value) {
227 | setProperty(new IntegerProperty(PORT, value));
228 | }
229 |
230 | public static int getDefaultPort(String protocol,int port){
231 | if (port==URL_UNSPECIFIED_PORT){
232 | return
233 | protocol.equalsIgnoreCase(HTTPConstants.PROTOCOL_HTTP) ? HTTPConstants.DEFAULT_HTTP_PORT :
234 | protocol.equalsIgnoreCase(HTTPConstants.PROTOCOL_HTTPS) ? HTTPConstants.DEFAULT_HTTPS_PORT :
235 | port;
236 | }
237 | return port;
238 | }
239 |
240 | /**
241 | * Get the port number from the port string, allowing for trailing blanks.
242 | *
243 | * @return port number or UNSPECIFIED_PORT (== 0)
244 | */
245 | public int getPortIfSpecified() {
246 | String port_s = getPropertyAsString(PORT, UNSPECIFIED_PORT_AS_STRING);
247 | try {
248 | return Integer.parseInt(port_s.trim());
249 | } catch (NumberFormatException e) {
250 | return UNSPECIFIED_PORT;
251 | }
252 | }
253 |
254 | /**
255 | * Tell whether the default port for the specified protocol is used
256 | *
257 | * @return true if the default port number for the protocol is used, false otherwise
258 | */
259 | public boolean isProtocolDefaultPort() {
260 | final int port = getPortIfSpecified();
261 | final String protocol = getProtocol();
262 | return port == UNSPECIFIED_PORT ||
263 | ("ws".equalsIgnoreCase(protocol) && port == HTTPConstants.DEFAULT_HTTP_PORT) ||
264 | ("wss".equalsIgnoreCase(protocol) && port == HTTPConstants.DEFAULT_HTTPS_PORT);
265 | }
266 |
267 | public int getPort() {
268 | final int port = getPortIfSpecified();
269 | if (port == UNSPECIFIED_PORT) {
270 | String prot = getProtocol();
271 | if ("wss".equalsIgnoreCase(prot)) {
272 | return HTTPConstants.DEFAULT_HTTPS_PORT;
273 | }
274 | if (!"ws".equalsIgnoreCase(prot)) {
275 | log.warn("Unexpected protocol: "+prot);
276 | // TODO - should this return something else?
277 | }
278 | return HTTPConstants.DEFAULT_HTTP_PORT;
279 | }
280 | return port;
281 | }
282 |
283 |
284 | public void setDomain(String value) {
285 | setProperty(DOMAIN, value);
286 | }
287 |
288 | public String getDomain() {
289 | return getPropertyAsString(DOMAIN);
290 | }
291 | public void setProtocol(String value) {
292 | setProperty(PROTOCOL, value.toLowerCase(java.util.Locale.ENGLISH));
293 | }
294 |
295 | public String getProtocol() {
296 | String protocol = getPropertyAsString(PROTOCOL);
297 | if (protocol == null || protocol.length() == 0 ) {
298 | return DEFAULT_PROTOCOL;
299 | }
300 | return protocol;
301 | }
302 |
303 | public void setContentEncoding(String charsetName) {
304 | setProperty(CONTENT_ENCODING, charsetName);
305 | }
306 | public String getContentEncoding() {
307 | return getPropertyAsString(CONTENT_ENCODING);
308 | }
309 |
310 | public String getQueryString(String contentEncoding) {
311 | // Check if the sampler has a specified content encoding
312 | if(JOrphanUtils.isBlank(contentEncoding)) {
313 | // We use the encoding which should be used according to the HTTP spec, which is UTF-8
314 | contentEncoding = EncoderCache.URL_ARGUMENT_ENCODING;
315 | }
316 | StringBuilder buf = new StringBuilder();
317 | PropertyIterator iter = getArguments().iterator();
318 | boolean first = true;
319 | while (iter.hasNext()) {
320 | HTTPArgument item = null;
321 | Object objectValue = iter.next().getObjectValue();
322 | try {
323 | item = (HTTPArgument) objectValue;
324 | } catch (ClassCastException e) {
325 | item = new HTTPArgument((Argument) objectValue);
326 | }
327 | final String encodedName = item.getEncodedName();
328 | if (encodedName.length() == 0) {
329 | continue; // Skip parameters with a blank name (allows use of optional variables in parameter lists)
330 | }
331 | if (!first) {
332 | buf.append(QRY_SEP);
333 | } else {
334 | first = false;
335 | }
336 | buf.append(encodedName);
337 | if (item.getMetaData() == null) {
338 | buf.append(ARG_VAL_SEP);
339 | } else {
340 | buf.append(item.getMetaData());
341 | }
342 |
343 | // Encode the parameter value in the specified content encoding
344 | try {
345 | buf.append(item.getEncodedValue(contentEncoding));
346 | }
347 | catch(UnsupportedEncodingException e) {
348 | log.warn("Unable to encode parameter in encoding " + contentEncoding + ", parameter value not included in query string");
349 | }
350 | }
351 | return buf.toString();
352 | }
353 |
354 | public void setSendMessage(String value) {
355 | setProperty(SEND_MESSAGE, value);
356 | }
357 |
358 | public String getSendMessage() {
359 | return getPropertyAsString(SEND_MESSAGE);
360 | }
361 |
362 | public void setRecvMessage(String value) {
363 | setProperty(RECV_MESSAGE, value);
364 | }
365 |
366 | public String getRecvMessage() {
367 | return getPropertyAsString(RECV_MESSAGE);
368 | }
369 |
370 | public void setRecvTimeout(long value) {
371 | setProperty(new LongProperty(RECV_TIMEOUT, value));
372 | }
373 |
374 | public long getRecvTimeout() {
375 | return getPropertyAsLong(RECV_TIMEOUT, 20000L);
376 | }
377 |
378 | public void setArguments(Arguments value) {
379 | setProperty(new TestElementProperty(ARGUMENTS, value));
380 | }
381 |
382 |
383 | public Arguments getArguments() {
384 | return (Arguments) getProperty(ARGUMENTS).getObjectValue();
385 | }
386 |
387 | protected String encodeSpaces(String path) {
388 | return JOrphanUtils.replaceAllChars(path, ' ', "%20"); // $NON-NLS-1$
389 | }
390 |
391 | public void parseArguments(String queryString, String contentEncoding) {
392 | String[] args = JOrphanUtils.split(queryString, QRY_SEP);
393 | for (int i = 0; i < args.length; i++) {
394 | // need to handle four cases:
395 | // - string contains name=value
396 | // - string contains name=
397 | // - string contains name
398 | // - empty string
399 |
400 | String metaData; // records the existance of an equal sign
401 | String name;
402 | String value;
403 | int length = args[i].length();
404 | int endOfNameIndex = args[i].indexOf(ARG_VAL_SEP);
405 | if (endOfNameIndex != -1) {// is there a separator?
406 | // case of name=value, name=
407 | metaData = ARG_VAL_SEP;
408 | name = args[i].substring(0, endOfNameIndex);
409 | value = args[i].substring(endOfNameIndex + 1, length);
410 | } else {
411 | metaData = "";
412 | name=args[i];
413 | value="";
414 | }
415 | if (name.length() > 0) {
416 | // If we know the encoding, we can decode the argument value,
417 | // to make it easier to read for the user
418 | if(!StringUtils.isEmpty(contentEncoding)) {
419 | addEncodedArgument(name, value, metaData, contentEncoding);
420 | }
421 | else {
422 | // If we do not know the encoding, we just use the encoded value
423 | // The browser has already done the encoding, so save the values as is
424 | addNonEncodedArgument(name, value, metaData);
425 | }
426 | }
427 | }
428 | }
429 | public void addEncodedArgument(String name, String value, String metaData, String contentEncoding) {
430 | if (log.isDebugEnabled()){
431 | log.debug("adding argument: name: " + name + " value: " + value + " metaData: " + metaData + " contentEncoding: " + contentEncoding);
432 | }
433 |
434 | HTTPArgument arg = null;
435 | final boolean nonEmptyEncoding = !StringUtils.isEmpty(contentEncoding);
436 | if(nonEmptyEncoding) {
437 | arg = new HTTPArgument(name, value, metaData, true, contentEncoding);
438 | }
439 | else {
440 | arg = new HTTPArgument(name, value, metaData, true);
441 | }
442 |
443 | // Check if there are any difference between name and value and their encoded name and value
444 | String valueEncoded = null;
445 | if(nonEmptyEncoding) {
446 | try {
447 | valueEncoded = arg.getEncodedValue(contentEncoding);
448 | }
449 | catch (UnsupportedEncodingException e) {
450 | log.warn("Unable to get encoded value using encoding " + contentEncoding);
451 | valueEncoded = arg.getEncodedValue();
452 | }
453 | }
454 | else {
455 | valueEncoded = arg.getEncodedValue();
456 | }
457 | // If there is no difference, we mark it as not needing encoding
458 | if (arg.getName().equals(arg.getEncodedName()) && arg.getValue().equals(valueEncoded)) {
459 | arg.setAlwaysEncoded(false);
460 | }
461 | this.getArguments().addArgument(arg);
462 | }
463 |
464 | public void addEncodedArgument(String name, String value, String metaData) {
465 | this.addEncodedArgument(name, value, metaData, null);
466 | }
467 |
468 | public void addNonEncodedArgument(String name, String value, String metadata) {
469 | HTTPArgument arg = new HTTPArgument(name, value, metadata, false);
470 | arg.setAlwaysEncoded(false);
471 | this.getArguments().addArgument(arg);
472 | }
473 |
474 | public void addArgument(String name, String value) {
475 | this.getArguments().addArgument(new HTTPArgument(name, value));
476 | }
477 |
478 | public void addArgument(String name, String value, String metadata) {
479 | this.getArguments().addArgument(new HTTPArgument(name, value, metadata));
480 | }
481 |
482 | public boolean hasArguments() {
483 | return getArguments().getArgumentCount() > 0;
484 | }
485 |
486 | @Override
487 | public void testStarted() {
488 | testStarted("");
489 | }
490 |
491 | @Override
492 | public void testStarted(String host) {
493 | try {
494 | webSocketClientFactory.start();
495 | } catch(Exception e) {
496 | log.error("Can't start WebSocketClientFactory", e);
497 | }
498 | }
499 |
500 | @Override
501 | public void testEnded() {
502 | testEnded("");
503 | }
504 |
505 | @Override
506 | public void testEnded(String host) {
507 | try {
508 | for(WebSocket.Connection connection : samplerConnections) {
509 | connection.close();
510 | }
511 | webSocketClientFactory.stop();
512 | } catch (Exception e) {
513 | log.error("sampler error when close.", e);
514 | }
515 | }
516 |
517 | /**
518 | * @see org.apache.jmeter.samplers.AbstractSampler#applies(org.apache.jmeter.config.ConfigTestElement)
519 | */
520 | @Override
521 | public boolean applies(ConfigTestElement configElement) {
522 | String guiClass = configElement.getProperty(TestElement.GUI_CLASS).getStringValue();
523 | return APPLIABLE_CONFIG_CLASSES.contains(guiClass);
524 | }
525 |
526 | }
527 |
--------------------------------------------------------------------------------
/src/main/resources/net/unit8/jmeter/protocol/websocket/sampler/WebSocketSamplerResources.properties:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one or more
2 | # contributor license agreements. See the NOTICE file distributed with
3 | # this work for additional information regarding copyright ownership.
4 | # The ASF licenses this file to You under the Apache License, Version 2.0
5 | # (the "License"); you may not use this file except in compliance with
6 | # the License. You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | displayName=WebSocket Sampler
17 | websocket_sample_title=WebSocket Sampler
18 | websocket_testing_title=WebSocket Sampler
19 | websocket_send_message=Send message
20 | websocket_recv_message=Received message
21 |
--------------------------------------------------------------------------------
/src/main/resources/net/unit8/jmeter/protocol/websocket/sampler/WebSocketSamplerResources_ja.properties:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one or more
2 | # contributor license agreements. See the NOTICE file distributed with
3 | # this work for additional information regarding copyright ownership.
4 | # The ASF licenses this file to You under the Apache License, Version 2.0
5 | # (the "License"); you may not use this file except in compliance with
6 | # the License. You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | displayName=WebSocket Sampler
17 | websocket_testing_title=WebSocket\u30B5\u30F3\u30D7\u30E9
18 | websocket_send_message=\u9001\u4FE1\u30E1\u30C3\u30BB\u30FC\u30B8
19 | websocket_recv_message=\u53D7\u4FE1\u30E1\u30C3\u30BB\u30FC\u30B8
20 | websocket_sample_title=WebSocket\u30B5\u30F3\u30D7\u30E9\u30FC
21 |
--------------------------------------------------------------------------------
/src/test/java/net/unit8/jmeter/protocol/websocket/sampler/WebSocketSamplerTest.java:
--------------------------------------------------------------------------------
1 | package net.unit8.jmeter.protocol.websocket.sampler;
2 |
3 | import net.unit8.jmeter.protocol.websocket.sampler.WebSocketSampler;
4 | import org.apache.jmeter.config.Arguments;
5 | import org.apache.jmeter.config.CSVDataSet;
6 | import org.apache.jmeter.control.LoopController;
7 | import org.apache.jmeter.control.OnceOnlyController;
8 | import org.apache.jmeter.control.ReplaceableController;
9 | import org.apache.jmeter.control.gui.TestPlanGui;
10 | import org.apache.jmeter.engine.JMeterEngine;
11 | import org.apache.jmeter.engine.StandardJMeterEngine;
12 | import org.apache.jmeter.gui.tree.JMeterTreeModel;
13 | import org.apache.jmeter.gui.tree.JMeterTreeNode;
14 | import org.apache.jmeter.reporters.ResultCollector;
15 | import org.apache.jmeter.reporters.Summariser;
16 | import org.apache.jmeter.testelement.TestElement;
17 | import org.apache.jmeter.testelement.TestPlan;
18 | import org.apache.jmeter.testelement.property.BooleanProperty;
19 | import org.apache.jmeter.testelement.property.StringProperty;
20 | import org.apache.jmeter.testelement.property.TestElementProperty;
21 | import org.apache.jmeter.threads.ThreadGroup;
22 | import org.apache.jmeter.timers.UniformRandomTimer;
23 | import org.apache.jmeter.util.JMeterUtils;
24 | import org.apache.jorphan.collections.HashTree;
25 | import org.apache.jorphan.collections.ListedHashTree;
26 | import org.apache.jorphan.logging.LoggingManager;
27 | import org.apache.jorphan.util.HeapDumper;
28 | import org.apache.log.Logger;
29 |
30 | import javax.xml.transform.Result;
31 | import java.net.DatagramPacket;
32 | import java.net.DatagramSocket;
33 | import java.net.InetAddress;
34 | import java.net.SocketException;
35 | import java.util.ArrayList;
36 | import java.util.LinkedList;
37 | import java.util.List;
38 | import java.util.Locale;
39 |
40 | /**
41 | * Tests of WebSocketSampler
42 | *
43 | * @author kawasima
44 | */
45 | public class WebSocketSamplerTest {
46 | private static final Logger log = LoggingManager.getLoggerForClass();
47 |
48 | public static void main(String[] args) throws Exception {
49 | JMeterUtils.setJMeterHome("src/test/resources/");
50 | JMeterUtils.loadJMeterProperties("src/test/resources/jmeter.properties");
51 | JMeterUtils.setProperty("saveservice_properties", "saveservice.properties");
52 | JMeterUtils.setProperty("search_paths", "ApacheJMeter_functions-2.9.jar");
53 | JMeterUtils.setLocale(Locale.JAPAN);
54 |
55 | JMeterEngine engine = new StandardJMeterEngine();
56 | HashTree config = new ListedHashTree();
57 | TestPlan testPlan = new TestPlan("websocket test");
58 | testPlan.setFunctionalMode(false);
59 | testPlan.setSerialized(false);
60 | testPlan.setProperty(new BooleanProperty(TestElement.ENABLED, true));
61 | testPlan.setUserDefinedVariables(new Arguments());
62 |
63 | ThreadGroup threadGroup = new ThreadGroup();
64 | threadGroup.setNumThreads(300);
65 | threadGroup.setRampUp(20);
66 | threadGroup.setDelay(0);
67 | threadGroup.setDuration(0);
68 | threadGroup.setProperty(new StringProperty(ThreadGroup.ON_SAMPLE_ERROR, "continue"));
69 | threadGroup.setScheduler(false);
70 | threadGroup.setName("Group1");
71 | threadGroup.setProperty(new BooleanProperty(TestElement.ENABLED, true));
72 |
73 | LoopController controller = new LoopController();
74 | controller.setLoops(10);
75 | controller.setContinueForever(false);
76 | controller.setProperty(new BooleanProperty(TestElement.ENABLED, true));
77 | threadGroup.setProperty(new TestElementProperty(ThreadGroup.MAIN_CONTROLLER, controller));
78 |
79 | CSVDataSet csvDataSet = new CSVDataSet();
80 | csvDataSet.setProperty(new StringProperty("filename", "src/test/resources/users.csv"));
81 | csvDataSet.setProperty(new StringProperty("variableNames", "USER_NAME"));
82 | csvDataSet.setProperty(new StringProperty("delimiter", ","));
83 | csvDataSet.setProperty(new StringProperty("shareMode", "shareMode.all"));
84 | csvDataSet.setProperty("quoted", false);
85 | csvDataSet.setProperty("recycle", true);
86 | csvDataSet.setProperty("stopThread", false);
87 |
88 | WebSocketSampler sampler = new WebSocketSampler();
89 | sampler.setName("WebSocket Test");
90 | sampler.setProperty(new BooleanProperty(TestElement.ENABLED, true));
91 | sampler.addNonEncodedArgument("name", "${USER_NAME}", "=");
92 | sampler.setContentEncoding("UTF-8");
93 | sampler.setProtocol("ws");
94 | sampler.setDomain("localhost");
95 | sampler.setPort(9090);
96 | sampler.setPath("/", "UTF-8");
97 | sampler.setSendMessage("${__RandomString(50,ABCDEFGHIJKLMNOPQRSTUVWXYZ)}");
98 | sampler.setRecvMessage("\"name\":\"${USER_NAME}\"");
99 |
100 | OnceOnlyController onceOnlyController = new OnceOnlyController();
101 |
102 | Summariser summariser = new Summariser();
103 |
104 | HashTree tpConfig = config.add(testPlan);
105 | HashTree tgConfig = tpConfig.add(threadGroup);
106 | HashTree oocConfig = tgConfig.add(onceOnlyController);
107 | oocConfig.add(csvDataSet);
108 |
109 | UniformRandomTimer randomTimer = new UniformRandomTimer();
110 | randomTimer.setRange(3000);
111 | HashTree samplerConfig = tgConfig.add(sampler);
112 | samplerConfig.add(summariser);
113 | tgConfig.add(randomTimer);
114 |
115 | engine.configure(config);
116 | engine.runTest();
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/src/test/resources/jmeter.properties:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # Apache JMeter Property file
3 | ################################################################################
4 |
5 | ## Licensed to the Apache Software Foundation (ASF) under one or more
6 | ## contributor license agreements. See the NOTICE file distributed with
7 | ## this work for additional information regarding copyright ownership.
8 | ## The ASF licenses this file to You under the Apache License, Version 2.0
9 | ## (the "License"); you may not use this file except in compliance with
10 | ## the License. You may obtain a copy of the License at
11 | ##
12 | ## http://www.apache.org/licenses/LICENSE-2.0
13 | ##
14 | ## Unless required by applicable law or agreed to in writing, software
15 | ## distributed under the License is distributed on an "AS IS" BASIS,
16 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 | ## See the License for the specific language governing permissions and
18 | ## limitations under the License.
19 |
20 |
21 | #Preferred GUI language. Comment out to use the JVM default locale's language.
22 | #language=en
23 |
24 | # Additional locale(s) to add to the displayed list.
25 | # The current default list is: en, fr, de, no, es, tr, ja, zh_CN, zh_TW, pl, pt_BR
26 | # [see JMeterMenuBar#makeLanguageMenu()]
27 | # The entries are a comma-separated list of language names
28 | #locales.add=zu
29 |
30 | # Netscape HTTP Cookie file
31 | cookies=cookies
32 |
33 | #---------------------------------------------------------------------------
34 | # File format configuration for JMX and JTL files
35 | #---------------------------------------------------------------------------
36 |
37 | # Properties:
38 | # file_format - affects both JMX and JTL files
39 | # file_format.testplan - affects JMX files only
40 | # file_format.testlog - affects JTL files only
41 | #
42 | # Possible values are:
43 | # 2.1 - initial format using XStream
44 | # 2.2 - updated format using XStream, with shorter names
45 |
46 | # N.B. format 2.0 (Avalon) is no longer supported
47 |
48 | #---------------------------------------------------------------------------
49 | # XML Parser
50 | #---------------------------------------------------------------------------
51 |
52 | # XML Reader(Parser) - Must implement SAX 2 specs
53 | xml.parser=org.apache.xerces.parsers.SAXParser
54 |
55 | # Path to a Properties file containing Namespace mapping in the form
56 | # prefix=Namespace
57 | # Example:
58 | # ns=http://biz.aol.com/schema/2006-12-18
59 | #xpath.namespace.config=
60 |
61 | #---------------------------------------------------------------------------
62 | # SSL configuration
63 | #---------------------------------------------------------------------------
64 |
65 | ## SSL System properties are now in system.properties
66 |
67 | # JMeter no longer converts javax.xxx property entries in this file into System properties.
68 | # These must now be defined in the system.properties file or on the command-line.
69 | # The system.properties file gives more flexibility.
70 |
71 | # By default, SSL session contexts are now created per-thread, rather than being shared.
72 | # The original behaviour can be enabled by setting the JMeter property:
73 | #https.sessioncontext.shared=true
74 |
75 | # Default HTTPS protocol level:
76 | #https.default.protocol=TLS
77 | # This may need to be changed here (or in user.properties) to:
78 | #https.default.protocol=SSLv3
79 |
80 | # List of protocols to enable (unlikely to be needed):
81 | #https.socket.protocols=SSLv2Hello SSLv3 TLSv1
82 |
83 | # Control if we allow reuse of cached SSL context between iterations
84 | # set the value to 'false' to reset the SSL context each iteration
85 | #https.use.cached.ssl.context=true
86 |
87 | # Start and end index to be used with keystores with many entries
88 | # The default is to use entry 0, i.e. the first
89 | #https.keyStoreStartIndex=0
90 | #https.keyStoreEndIndex=0
91 |
92 | #---------------------------------------------------------------------------
93 | # Look and Feel configuration
94 | #---------------------------------------------------------------------------
95 |
96 | #Classname of the Swing default UI
97 | #
98 | # The LAF classnames that are available are now displayed as ToolTip text
99 | # when hovering over the Options/Look and Feel selection list.
100 | #
101 | # You can either use a full class name, as shown above,
102 | # or one of the strings "System" or "CrossPlatform" which means
103 | # JMeter will use the corresponding string returned by UIManager.getLookAndFeelClassName()
104 |
105 | # LAF can be overridden by os.name (lowercased, spaces replaced by '_')
106 | # Sample os.name LAF:
107 | #jmeter.laf.windows_xp=javax.swing.plaf.metal.MetalLookAndFeel
108 |
109 | # Failing that, the OS family = os.name, but only up to first space:
110 | # Sample OS family LAF:
111 | #jmeter.laf.windows=com.sun.java.swing.plaf.windows.WindowsLookAndFeel
112 |
113 | # Mac apparently looks better with the System LAF
114 | jmeter.laf.mac=System
115 |
116 | # Failing that, the JMeter default laf can be defined:
117 | #jmeter.laf=System
118 |
119 | # If none of the above jmeter.laf properties are defined, JMeter uses the CrossPlatform LAF.
120 | # This is because the CrossPlatform LAF generally looks better than the System LAF.
121 | # See https://issues.apache.org/bugzilla/show_bug.cgi?id=52026 for details
122 | # N.B. the laf can be defined in user.properties.
123 |
124 | # LoggerPanel display
125 | # default to false
126 | #jmeter.loggerpanel.display=false
127 |
128 | # Error/Fatal Log count display
129 | # defaults to true
130 | #jmeter.errorscounter.display=true
131 |
132 | # Max characters kept in LoggerPanel, default to 80000 chars
133 | # O means no limit
134 | #jmeter.loggerpanel.maxlength=80000
135 |
136 | # Toolbar display
137 | # default:
138 | #jmeter.toolbar.display=true
139 | # Toolbar icon definitions
140 | #jmeter.toolbar.icons=org/apache/jmeter/images/toolbar/icons-toolbar.properties
141 | # Toolbar list
142 | #jmeter.toolbar=new,open,close,save,save_as_testplan,|,cut,copy,paste,|,expand,collapse,toggle,|,test_start,test_stop,test_shutdown,|,test_start_remote_all,test_stop_remote_all,test_shutdown_remote_all,|,test_clear,test_clear_all,|,search,search_reset,|,function_helper,help
143 |
144 | # Icon definitions
145 | # default:
146 | #jmeter.icons=org/apache/jmeter/images/icon.properties
147 | # alternate:
148 | #jmeter.icons=org/apache/jmeter/images/icon_1.properties
149 |
150 | #Components to not display in JMeter GUI (GUI class name or static label)
151 | # These elements are deprecated: HTML Parameter Mask,HTTP User Parameter Modifier
152 | not_in_menu=HTML Parameter Mask,HTTP User Parameter Modifier
153 |
154 | #---------------------------------------------------------------------------
155 | # Remote hosts and RMI configuration
156 | #---------------------------------------------------------------------------
157 |
158 | # Remote Hosts - comma delimited
159 | remote_hosts=127.0.0.1
160 | #remote_hosts=localhost:1099,localhost:2010
161 |
162 | # RMI port to be used by the server (must start rmiregistry with same port)
163 | #server_port=1099
164 |
165 | # To change the port to (say) 1234:
166 | # On the server(s)
167 | # - set server_port=1234
168 | # - start rmiregistry with port 1234
169 | # On Windows this can be done by:
170 | # SET SERVER_PORT=1234
171 | # JMETER-SERVER
172 | #
173 | # On Unix:
174 | # SERVER_PORT=1234 jmeter-server
175 | #
176 | # On the client:
177 | # - set remote_hosts=server:1234
178 |
179 | # Parameter that controls the RMI port used by the RemoteSampleListenerImpl
180 | # Default value is 0 which means port is randomly assigned
181 | #client.rmi.localport=0
182 |
183 | # To change the default port (1099) used to access the server:
184 | #server.rmi.port=1234
185 |
186 | # To use a specific port for the JMeter server engine, define
187 | # the following property before starting the server:
188 | #server.rmi.localport=4000
189 |
190 | # From JMeter 2.3.1, the jmeter server creates the RMI registry as part of the server process.
191 | # To stop the server creating the RMI registry:
192 | #server.rmi.create=false
193 |
194 | # From JMeter 2.3.1, define the following property to cause JMeter to exit after the first test
195 | #server.exitaftertest=true
196 |
197 | # Prefix used by IncludeController when building file name
198 | #includecontroller.prefix=
199 |
200 | #---------------------------------------------------------------------------
201 | # Logging Configuration
202 | #---------------------------------------------------------------------------
203 |
204 | # Note: JMeter uses Avalon (Excalibur) LogKit
205 |
206 | # Logging Format
207 | # see http://excalibur.apache.org/apidocs/org/apache/log/format/PatternFormatter.html
208 |
209 | #
210 | # Default format:
211 | #log_format=%{time:yyyy/MM/dd HH:mm:ss} %5.5{priority} - %{category}: %{message} %{throwable}
212 | # \n is automatically added to the end of the string
213 | #
214 | # Predefined formats in the JMeter LoggingManager:
215 | #log_format_type=default
216 | #log_format_type=thread_prefix
217 | #log_format_type=thread_suffix
218 | # default is as above
219 | # thread_prefix adds the thread name as a prefix to the category
220 | # thread_suffix adds the thread name as a suffix to the category
221 | # Note that thread name is not included by default, as it requires extra processing.
222 | #
223 | # To change the logging format, define either log_format_type or log_format
224 | # If both are defined, the type takes precedence
225 | # Note that these properties cannot be defined using the -J or -D JMeter
226 | # command-line flags, as the format will have already been determined by then
227 | # However, they can be defined as JVM properties
228 |
229 | #Logging levels for the logging categories in JMeter. Correct values are FATAL_ERROR, ERROR, WARN, INFO, and DEBUG
230 | # To set the log level for a package or individual class, use:
231 | # log_level.[package_name].[classname]=[PRIORITY_LEVEL]
232 | # But omit "org.apache" from the package name. The classname is optional. Further examples below.
233 |
234 | log_level.jmeter=INFO
235 | log_level.jmeter.junit=DEBUG
236 | #log_level.jmeter.control=DEBUG
237 | #log_level.jmeter.testbeans=DEBUG
238 | #log_level.jmeter.engine=DEBUG
239 | #log_level.jmeter.threads=DEBUG
240 | #log_level.jmeter.gui=WARN
241 | #log_level.jmeter.testelement=DEBUG
242 | #log_level.jmeter.util=WARN
243 | #log_level.jmeter.util.classfinder=WARN
244 | #log_level.jmeter.test=DEBUG
245 | #log_level.jmeter.protocol.http=DEBUG
246 | # For CookieManager, AuthManager etc:
247 | #log_level.jmeter.protocol.http.control=DEBUG
248 | #log_level.jmeter.protocol.ftp=WARN
249 | #log_level.jmeter.protocol.jdbc=DEBUG
250 | #log_level.jmeter.protocol.java=WARN
251 | #log_level.jmeter.testelements.property=DEBUG
252 | log_level.jorphan=INFO
253 |
254 |
255 | #Log file for log messages.
256 | # You can specify a different log file for different categories via:
257 | # log_file.[category]=[filename]
258 | # category is equivalent to the package/class names described above
259 |
260 | # Combined log file (for jmeter and jorphan)
261 | #log_file=jmeter.log
262 | # To redirect logging to standard output, try the following:
263 | # (it will probably report an error, but output will be to stdout)
264 | #log_file=
265 |
266 | # Or define separate logs if required:
267 | #log_file.jorphan=jorphan.log
268 | #log_file.jmeter=jmeter.log
269 |
270 | # If the filename contains paired single-quotes, then the name is processed
271 | # as a SimpleDateFormat format applied to the current date, for example:
272 | #log_file='jmeter_'yyyyMMddHHmmss'.tmp'
273 |
274 | # N.B. When JMeter starts, it sets the system property:
275 | # org.apache.commons.logging.Log
276 | # to
277 | # org.apache.commons.logging.impl.LogKitLogger
278 | # if not already set. This causes Apache and Commons HttpClient to use the same logging as JMeter
279 |
280 | # Further logging configuration
281 | # Excalibur logging provides the facility to configure logging using
282 | # configuration files written in XML. This allows for such features as
283 | # log file rotation which are not supported directly by JMeter.
284 | #
285 | # If such a file specified, it will be applied to the current logging
286 | # hierarchy when that has been created.
287 | #
288 | #log_config=logkit.xml
289 |
290 | #---------------------------------------------------------------------------
291 | # HTTP Java configuration
292 | #---------------------------------------------------------------------------
293 |
294 | # Number of connection retries performed by HTTP Java sampler before giving up
295 | #http.java.sampler.retries=10
296 | # 0 now means don't retry connection (in 2.3 and before it meant no tries at all!)
297 |
298 | #---------------------------------------------------------------------------
299 | # Commons HTTPClient configuration
300 | #---------------------------------------------------------------------------
301 |
302 | # define a properties file for overriding Commons HttpClient parameters
303 | # See: http://hc.apache.org/httpclient-3.x/preference-api.html
304 | #httpclient.parameters.file=httpclient.parameters
305 |
306 |
307 | # define a properties file for overriding Apache HttpClient parameters
308 | # See: TBA
309 | #hc.parameters.file=hc.parameters
310 |
311 | # Following properties apply to both Commons and Apache HttpClient
312 |
313 | # set the socket timeout (or use the parameter http.socket.timeout)
314 | # Value is in milliseconds
315 | #httpclient.timeout=0
316 | # 0 == no timeout
317 |
318 | # Set the http version (defaults to 1.1)
319 | #httpclient.version=1.0 (or use the parameter http.protocol.version)
320 |
321 | # Define characters per second > 0 to emulate slow connections
322 | #httpclient.socket.http.cps=0
323 | #httpclient.socket.https.cps=0
324 |
325 | #Enable loopback protocol
326 | #httpclient.loopback=true
327 |
328 | # Define the local host address to be used for multi-homed hosts
329 | #httpclient.localaddress=1.2.3.4
330 |
331 | # Sample logging levels for Commons HttpClient
332 | #
333 | # Commons HttpClient Logging information can be found at:
334 | # http://hc.apache.org/httpclient-3.x/logging.html
335 |
336 | # Note that full category names are used, i.e. must include the org.apache.
337 | # Info level produces no output:
338 | #log_level.org.apache.commons.httpclient=debug
339 | # Might be useful:
340 | #log_level.org.apache.commons.httpclient.Authenticator=trace
341 |
342 | # Show headers only
343 | #log_level.httpclient.wire.header=debug
344 |
345 | # Full wire debug produces a lot of output; consider using separate file:
346 | #log_level.httpclient.wire=debug
347 | #log_file.httpclient=httpclient.log
348 |
349 |
350 | # Apache Commons HttpClient logging examples
351 | #
352 | # Enable header wire + context logging - Best for Debugging
353 | #log_level.org.apache.http=DEBUG
354 | #log_level.org.apache.http.wire=ERROR
355 |
356 | # Enable full wire + context logging
357 | #log_level.org.apache.http=DEBUG
358 |
359 | # Enable context logging for connection management
360 | #log_level.org.apache.http.impl.conn=DEBUG
361 |
362 | # Enable context logging for connection management / request execution
363 | #log_level.org.apache.http.impl.conn=DEBUG
364 | #log_level.org.apache.http.impl.client=DEBUG
365 | #log_level.org.apache.http.client=DEBUG
366 |
367 | #---------------------------------------------------------------------------
368 | # Apache HttpComponents HTTPClient configuration (HTTPClient4)
369 | #---------------------------------------------------------------------------
370 |
371 | # Number of retries to attempt (default 1)
372 | #httpclient4.retrycount=1
373 |
374 | # Number of retries to attempt (default 1)
375 | #httpclient3.retrycount=1
376 |
377 | #---------------------------------------------------------------------------
378 | # Results file configuration
379 | #---------------------------------------------------------------------------
380 |
381 | # This section helps determine how result data will be saved.
382 | # The commented out values are the defaults.
383 |
384 | # legitimate values: xml, csv, db. Only xml and csv are currently supported.
385 | #jmeter.save.saveservice.output_format=csv
386 |
387 |
388 | # true when field should be saved; false otherwise
389 |
390 | # assertion_results_failure_message only affects CSV output
391 | #jmeter.save.saveservice.assertion_results_failure_message=false
392 | #
393 | # legitimate values: none, first, all
394 | #jmeter.save.saveservice.assertion_results=none
395 | #
396 | #jmeter.save.saveservice.data_type=true
397 | #jmeter.save.saveservice.label=true
398 | #jmeter.save.saveservice.response_code=true
399 | # response_data is not currently supported for CSV output
400 | #jmeter.save.saveservice.response_data=false
401 | # Save ResponseData for failed samples
402 | #jmeter.save.saveservice.response_data.on_error=false
403 | #jmeter.save.saveservice.response_message=true
404 | #jmeter.save.saveservice.successful=true
405 | #jmeter.save.saveservice.thread_name=true
406 | #jmeter.save.saveservice.time=true
407 | #jmeter.save.saveservice.subresults=true
408 | #jmeter.save.saveservice.assertions=true
409 | #jmeter.save.saveservice.latency=true
410 | #jmeter.save.saveservice.samplerData=false
411 | #jmeter.save.saveservice.responseHeaders=false
412 | #jmeter.save.saveservice.requestHeaders=false
413 | #jmeter.save.saveservice.encoding=false
414 | #jmeter.save.saveservice.bytes=true
415 | #jmeter.save.saveservice.url=false
416 | #jmeter.save.saveservice.filename=false
417 | #jmeter.save.saveservice.hostname=false
418 | #jmeter.save.saveservice.thread_counts=false
419 | #jmeter.save.saveservice.sample_count=false
420 | #jmeter.save.saveservice.idle_time=false
421 |
422 | # Timestamp format - this only affects CSV output files
423 | # legitimate values: none, ms, or a format suitable for SimpleDateFormat
424 | #jmeter.save.saveservice.timestamp_format=ms
425 | #jmeter.save.saveservice.timestamp_format=yyyy/MM/dd HH:mm:ss.SSS
426 |
427 | # For use with Comma-separated value (CSV) files or other formats
428 | # where the fields' values are separated by specified delimiters.
429 | # Default:
430 | #jmeter.save.saveservice.default_delimiter=,
431 | # For TAB, since JMeter 2.3 one can use:
432 | #jmeter.save.saveservice.default_delimiter=\t
433 |
434 | # Only applies to CSV format files:
435 | #jmeter.save.saveservice.print_field_names=false
436 |
437 | # Optional list of JMeter variable names whose values are to be saved in the result data files.
438 | # Use commas to separate the names. For example:
439 | #sample_variables=SESSION_ID,REFERENCE
440 | # N.B. The current implementation saves the values in XML as attributes,
441 | # so the names must be valid XML names.
442 | # Versions of JMeter after 2.3.2 send the variable to all servers
443 | # to ensure that the correct data is available at the client.
444 |
445 | # Optional xml processing instruction for line 2 of the file:
446 | #jmeter.save.saveservice.xml_pi=
447 |
448 | # Prefix used to identify filenames that are relative to the current base
449 | #jmeter.save.saveservice.base_prefix=~/
450 |
451 | #---------------------------------------------------------------------------
452 | # Settings that affect SampleResults
453 | #---------------------------------------------------------------------------
454 |
455 | # Save the start time stamp instead of the end
456 | # This also affects the timestamp stored in result files
457 | sampleresult.timestamp.start=true
458 |
459 | # Whether to use System.nanoTime() - otherwise only use System.currentTimeMillis()
460 | #sampleresult.useNanoTime=true
461 |
462 | # Use a background thread to calculate the nanoTime offset
463 | # Set this to <= 0 to disable the background thread
464 | #sampleresult.nanoThreadSleep=5000
465 |
466 | #---------------------------------------------------------------------------
467 | # Upgrade property
468 | #---------------------------------------------------------------------------
469 |
470 | # File that holds a record of name changes for backward compatibility issues
471 | upgrade_properties=/bin/upgrade.properties
472 |
473 | #---------------------------------------------------------------------------
474 | # JMeter Proxy recorder configuration
475 | #---------------------------------------------------------------------------
476 |
477 | # If the proxy detects a gap of at least 1s (default) between HTTP requests,
478 | # it assumes that the user has clicked a new URL
479 | #proxy.pause=1000
480 |
481 | # Add numeric prefix to Sampler names (default false)
482 | #proxy.number.requests=true
483 |
484 | # List of URL patterns that will be added to URL Patterns to exclude in Proxy
485 | #proxy.excludes.suggested=.*\\.js;.*\\.css;.*\\.swf;.*\\.gif;.*\\.png;.*\\.jpg;.*\\.bmp
486 |
487 | # Change the default HTTP Sampler (currently HttpClient4)
488 | # Java:
489 | #jmeter.httpsampler=HTTPSampler
490 | #or
491 | #jmeter.httpsampler=Java
492 | #
493 | # Apache HTTPClient:
494 | #jmeter.httpsampler=HTTPSampler2
495 | #or
496 | #jmeter.httpsampler=HttpClient3.1
497 | #
498 | # HttpClient4.x
499 | #jmeter.httpsampler=HttpClient4
500 |
501 | # Default content-type include filter to use
502 | #proxy.content_type_include=text/html|text/plain|text/xml
503 | # Default content-type exclude filter to use
504 | #proxy.content_type_exclude=image/.*|text/css|application/.*
505 |
506 | # Default headers to remove from Header Manager elements
507 | # (Cookie and Authorization are always removed)
508 | #proxy.headers.remove=If-Modified-Since,If-None-Match,Host
509 |
510 | # Binary content-type handling
511 | # These content-types will be handled by saving the request in a file:
512 | #proxy.binary.types=application/x-amf,application/x-java-serialized-object
513 | # The files will be saved in this directory:
514 | #proxy.binary.directory=user.dir
515 | # The files will be created with this file filesuffix:
516 | #proxy.binary.filesuffix=.binary
517 |
518 | #---------------------------------------------------------------------------
519 | # JMeter Proxy configuration
520 | #---------------------------------------------------------------------------
521 | # use command-line flags for user-name and password
522 | #http.proxyDomain=NTLM domain, if required by HTTPClient sampler
523 |
524 | # SSL configuration
525 | #proxy.cert.directory=.
526 | #proxy.cert.file=proxyserver.jks
527 | #proxy.cert.type=JKS
528 | #proxy.cert.keystorepass=password
529 | #proxy.cert.keypassword=password
530 | #proxy.cert.factory=SunX509
531 | #proxy.ssl.protocol=SSLv3
532 |
533 | #---------------------------------------------------------------------------
534 | # HTTPSampleResponse Parser configuration
535 | #---------------------------------------------------------------------------
536 |
537 | # Space-separated list of parser groups
538 | HTTPResponse.parsers=htmlParser wmlParser
539 | # for each parser, there should be a parser.types and a parser.className property
540 |
541 | #---------------------------------------------------------------------------
542 | # HTML Parser configuration
543 | #---------------------------------------------------------------------------
544 |
545 | # Define the HTML parser to be used.
546 | # Default parser:
547 | #htmlParser.className=org.apache.jmeter.protocol.http.parser.HtmlParserHTMLParser
548 | # Other parsers:
549 | #htmlParser.className=org.apache.jmeter.protocol.http.parser.JTidyHTMLParser
550 | #htmlParser.className=org.apache.jmeter.protocol.http.parser.RegexpHTMLParser
551 | #
552 |
553 | htmlParser.types=text/html application/xhtml+xml application/xml text/xml
554 |
555 | #---------------------------------------------------------------------------
556 | # WML Parser configuration
557 | #---------------------------------------------------------------------------
558 |
559 | wmlParser.className=org.apache.jmeter.protocol.http.parser.RegexpHTMLParser
560 |
561 | wmlParser.types=text/vnd.wap.wml
562 |
563 | #---------------------------------------------------------------------------
564 | # Remote batching configuration
565 | #---------------------------------------------------------------------------
566 | # How is Sample sender implementations configured:
567 | # - true (default) means client configuration will be used
568 | # - false means server configuration will be used
569 | #sample_sender_client_configured=true
570 |
571 | # Remote batching support
572 | # Since JMeter 2.9, default is MODE_STRIPPED_BATCH, which returns samples in
573 | # batch mode (every 100 samples or every minute by default)
574 | # Note also that MODE_STRIPPED_BATCH strips response data from SampleResult, so if you need it change to
575 | # another mode
576 | # Hold retains samples until end of test (may need lots of memory)
577 | # Batch returns samples in batches
578 | # Statistical returns sample summary statistics
579 | # hold_samples was originally defined as a separate property,
580 | # but can now also be defined using mode=Hold
581 | # mode can also be the class name of an implementation of org.apache.jmeter.samplers.SampleSender
582 | #mode=Standard
583 | #mode=Batch
584 | #mode=Hold
585 | #mode=Statistical
586 | #Set to true to key statistical samples on threadName rather than threadGroup
587 | #key_on_threadname=false
588 | #mode=Stripped
589 | #mode=StrippedBatch
590 | #mode=org.example.load.MySampleSender
591 | #hold_samples=true
592 | #
593 | #num_sample_threshold=100
594 | # Value is in milliseconds
595 | #time_threshold=60000
596 | #
597 | # Asynchronous sender; uses a queue and background worker process to return the samples
598 | #mode=Asynch
599 | # default queue size
600 | #asynch.batch.queue.size=100
601 | #
602 | # DiskStore: as for Hold mode, but serialises the samples to disk, rather than saving in memory
603 | #mode=DiskStore
604 |
605 | # Note: the mode is currently resolved on the client;
606 | # other properties (e.g. time_threshold) are resolved on the server.
607 |
608 | # To set the Monitor Health Visualiser buffer size, enter the desired value
609 | # monitor.buffer.size=800
610 |
611 | #---------------------------------------------------------------------------
612 | # TCP Sampler configuration
613 | #---------------------------------------------------------------------------
614 |
615 | # The default handler class
616 | #tcp.handler=TCPClientImpl
617 | #
618 | # eolByte = byte value for end of line
619 | # set this to a value outside the range -128 to +127 to skip eol checking
620 | #tcp.eolByte=1000
621 | #
622 | # TCP Charset, used by org.apache.jmeter.protocol.tcp.sampler.TCPClientImpl
623 | # default to Platform defaults charset as returned by Charset.defaultCharset().name()
624 | #tcp.charset=
625 | #
626 | # status.prefix and suffix = strings that enclose the status response code
627 | #tcp.status.prefix=Status=
628 | #tcp.status.suffix=.
629 | #
630 | # status.properties = property file to convert codes to messages
631 | #tcp.status.properties=mytestfiles/tcpstatus.properties
632 |
633 | # The length prefix used by LengthPrefixedBinaryTCPClientImpl implementation
634 | # defaults to 2 bytes.
635 | #tcp.binarylength.prefix.length=2
636 |
637 | #---------------------------------------------------------------------------
638 | # Summariser - Generate Summary Results - configuration (mainly applies to non-GUI mode)
639 | #---------------------------------------------------------------------------
640 | #
641 | # Define the following property to automatically start a summariser with that name
642 | # (applies to non-GUI mode only)
643 | #summariser.name=summary
644 | #
645 | # interval between summaries (in seconds) default 3 minutes
646 | #summariser.interval=180
647 | #
648 | # Write messages to log file
649 | #summariser.log=true
650 | #
651 | # Write messages to System.out
652 | #summariser.out=true
653 |
654 | #---------------------------------------------------------------------------
655 | # BeanShell configuration
656 | #---------------------------------------------------------------------------
657 |
658 | # BeanShell Server properties
659 | #
660 | # Define the port number as non-zero to start the http server on that port
661 | #beanshell.server.port=9000
662 | # The telnet server will be started on the next port
663 |
664 | #
665 | # Define the server initialisation file
666 | beanshell.server.file=../extras/startup.bsh
667 |
668 | #
669 | # Define a file to be processed at startup
670 | # This is processed using its own interpreter.
671 | #beanshell.init.file=
672 |
673 | #
674 | # Define the intialisation files for BeanShell Sampler, Function and other BeanShell elements
675 | # N.B. Beanshell test elements do not share interpreters.
676 | # Each element in each thread has its own interpreter.
677 | # This is retained between samples.
678 | #beanshell.sampler.init=BeanShellSampler.bshrc
679 | #beanshell.function.init=BeanShellFunction.bshrc
680 | #beanshell.assertion.init=BeanShellAssertion.bshrc
681 | #beanshell.listener.init=etc
682 | #beanshell.postprocessor.init=etc
683 | #beanshell.preprocessor.init=etc
684 | #beanshell.timer.init=etc
685 |
686 | # The file BeanShellListeners.bshrc contains sample definitions
687 | # of Test and Thread Listeners.
688 |
689 | #---------------------------------------------------------------------------
690 | # MailerModel configuration
691 | #---------------------------------------------------------------------------
692 |
693 | # Number of successful samples before a message is sent
694 | #mailer.successlimit=2
695 | #
696 | # Number of failed samples before a message is sent
697 | #mailer.failurelimit=2
698 |
699 | #---------------------------------------------------------------------------
700 | # CSVRead configuration
701 | #---------------------------------------------------------------------------
702 |
703 | # CSVRead delimiter setting (default ",")
704 | # Make sure that there are no trailing spaces or tabs after the delimiter
705 | # characters, or these will be included in the list of valid delimiters
706 | #csvread.delimiter=,
707 | #csvread.delimiter=;
708 | #csvread.delimiter=!
709 | #csvread.delimiter=~
710 | # The following line has a tab after the =
711 | #csvread.delimiter=
712 |
713 | #---------------------------------------------------------------------------
714 | # __time() function configuration
715 | #
716 | # The properties below can be used to redefine the default formats
717 | #---------------------------------------------------------------------------
718 | #time.YMD=yyyyMMdd
719 | #time.HMS=HHmmss
720 | #time.YMDHMS=yyyyMMdd-HHmmss
721 | #time.USER1=
722 | #time.USER2=
723 |
724 | #---------------------------------------------------------------------------
725 | # CSV DataSet configuration
726 | #---------------------------------------------------------------------------
727 |
728 | # String to return at EOF (if recycle not used)
729 | #csvdataset.eofstring=
730 |
731 | #---------------------------------------------------------------------------
732 | # LDAP Sampler configuration
733 | #---------------------------------------------------------------------------
734 | # Maximum number of search results returned by a search that will be sorted
735 | # to guarantee a stable ordering (if more results then this limit are retruned
736 | # then no sorting is done). Set to 0 to turn off all sorting, in which case
737 | # "Equals" response assertions will be very likely to fail against search results.
738 | #
739 | #ldapsampler.max_sorted_results=1000
740 |
741 | # Number of characters to log for each of three sections (starting matching section, diff section,
742 | # ending matching section where not all sections will appear for all diffs) diff display when an Equals
743 | # assertion fails. So a value of 100 means a maximum of 300 characters of diff text will be displayed
744 | # (+ a number of extra characters like "..." and "[[["/"]]]" which are used to decorate it).
745 | #assertion.equals_section_diff_len=100
746 | # test written out to log to signify start/end of diff delta
747 | #assertion.equals_diff_delta_start=[[[
748 | #assertion.equals_diff_delta_end=]]]
749 |
750 | #---------------------------------------------------------------------------
751 | # Miscellaneous configuration
752 | #---------------------------------------------------------------------------
753 |
754 | # If defined, then start the mirror server on the port
755 | #mirror.server.port=8081
756 |
757 | # ORO PatternCacheLRU size
758 | #oro.patterncache.size=1000
759 |
760 | #TestBeanGui
761 | #
762 | #propertyEditorSearchPath=null
763 |
764 | # Turn expert mode on/off: expert mode will show expert-mode beans and properties
765 | #jmeter.expertMode=true
766 |
767 | # Maximum redirects to follow in a single sequence (default 5)
768 | #httpsampler.max_redirects=5
769 | # Maximum frame/iframe nesting depth (default 5)
770 | #httpsampler.max_frame_depth=5
771 | # Maximum await termination timeout (secs) when concurrent download embedded resources (default 60)
772 | #httpsampler.await_termination_timeout=60
773 | # Revert to BUG 51939 behaviour (no separate container for embedded resources) by setting the following false:
774 | #httpsampler.separate.container=true
775 |
776 | # If embedded resources download fails due to missing resources or other reasons, if this property is true
777 | # Parent sample will not be marked as failed
778 | #httpsampler.ignore_failed_embedded_resources=false
779 |
780 | # The encoding to be used if none is provided (default ISO-8859-1)
781 | #sampleresult.default.encoding=ISO-8859-1
782 |
783 | # Network response size calculation method
784 | # Use real size: number of bytes for response body return by webserver
785 | # (i.e. the network bytes received for response)
786 | # if set to false, the (uncompressed) response data size will used (default before 2.5)
787 | # Include headers: add the headers size in real size
788 | #sampleresult.getbytes.body_real_size=true
789 | #sampleresult.getbytes.headers_size=true
790 |
791 | # CookieManager behaviour - should cookies with null/empty values be deleted?
792 | # Default is true. Use false to revert to original behaviour
793 | #CookieManager.delete_null_cookies=true
794 |
795 | # CookieManager behaviour - should variable cookies be allowed?
796 | # Default is true. Use false to revert to original behaviour
797 | #CookieManager.allow_variable_cookies=true
798 |
799 | # CookieManager behaviour - should Cookies be stored as variables?
800 | # Default is false
801 | #CookieManager.save.cookies=false
802 |
803 | # CookieManager behaviour - prefix to add to cookie name before storing it as a variable
804 | # Default is COOKIE_; to remove the prefix, define it as one or more spaces
805 | #CookieManager.name.prefix=
806 |
807 | # CookieManager behaviour - check received cookies are valid before storing them?
808 | # Default is true. Use false to revert to previous behaviour
809 | #CookieManager.check.cookies=true
810 |
811 | # (2.0.3) JMeterThread behaviour has been changed to set the started flag before
812 | # the controllers are initialised. This is so controllers can access variables earlier.
813 | # In case this causes problems, the previous behaviour can be restored by uncommenting
814 | # the following line.
815 | #jmeterthread.startearlier=false
816 |
817 | # (2.2.1) JMeterThread behaviour has changed so that PostProcessors are run in forward order
818 | # (as they appear in the test plan) rather than reverse order as previously.
819 | # Uncomment the following line to revert to the original behaviour
820 | #jmeterthread.reversePostProcessors=true
821 |
822 | # (2.2) StandardJMeterEngine behaviour has been changed to notify the listeners after
823 | # the running version is enabled. This is so they can access variables.
824 | # In case this causes problems, the previous behaviour can be restored by uncommenting
825 | # the following line.
826 | #jmeterengine.startlistenerslater=false
827 |
828 | # Number of milliseconds to wait for a thread to stop
829 | #jmeterengine.threadstop.wait=5000
830 |
831 | #Whether to invoke System.exit(0) in server exit code after stopping RMI
832 | #jmeterengine.remote.system.exit=false
833 |
834 | # Whether to call System.exit(1) on failure to stop threads in non-GUI mode.
835 | # If this is disabled, it may be necessary to kill the JVM externally
836 | #jmeterengine.stopfail.system.exit=true
837 |
838 | # How long to pause (in ms) in the daemon thread before reporting that the JVM has failed to exit.
839 | # If the value is <= 0, the JMeter does not start the daemon thread
840 | #jmeter.exit.check.pause=2000
841 |
842 | # If running non-GUI, then JMeter listens on the following port for a shutdown message.
843 | # To disable, set the port to 1000 or less.
844 | #jmeterengine.nongui.port=4445
845 | #
846 | # If the initial port is busy, keep trying until this port is reached
847 | # (to disable searching, set the value less than or equal to the .port property)
848 | #jmeterengine.nongui.maxport=4455
849 |
850 | # How often to check for shutdown during ramp-up (milliseconds)
851 | #jmeterthread.rampup.granularity=1000
852 |
853 | #Should JMeter expand the tree when loading a test plan?
854 | # default value is false since JMeter 2.7
855 | #onload.expandtree=false
856 |
857 | # Maximum size of HTML page that can be displayed; default=200 * 1024
858 | # Set to 0 to disable the size check
859 | #view.results.tree.max_size=0
860 |
861 | # Maximum size of Document that can be parsed by Tika engine; defaut=10 * 1024 * 1024 (10MB)
862 | # Set to 0 to disable the size check
863 | #document.max_size=0
864 |
865 | #JMS options
866 | # Enable the following property to stop JMS Point-to-Point Sampler from using
867 | # the properties java.naming.security.[principal|credentials] when creating the queue connection
868 | #JMSSampler.useSecurity.properties=false
869 |
870 | # Set the following value to true in order to skip the delete confirmation dialogue
871 | #confirm.delete.skip=false
872 |
873 | # Used by Webservice Sampler (SOAP)
874 | # Size of Document Cache
875 | #soap.document_cache=50
876 |
877 | # Used by JSR223 elements
878 | # Size of compiled scripts cache
879 | #jsr223.compiled_scripts_cache_size=100
880 |
881 | #---------------------------------------------------------------------------
882 | # Classpath configuration
883 | #---------------------------------------------------------------------------
884 |
885 | # List of paths (separated by ;) to search for additional JMeter extension classes
886 | # - for example new GUI elements and samplers
887 | # These are in addition to lib/ext. Do not use this for utility jars.
888 | #search_paths=/app1/lib;/app2/lib
889 |
890 | # Users can define additional classpath items by setting the property below
891 | # - for example, utility jars or JUnit test cases
892 | #
893 | # Use the default separator for the host version of Java
894 | # Paths with spaces may cause problems for the JVM
895 | #user.classpath=../classes;../jars/jar1.jar
896 |
897 | # Classpath finder
898 | # ================
899 | # The classpath finder currently needs to load every single JMeter class to find
900 | # the classes it needs.
901 | # For non-GUI mode, it's only necessary to scan for Function classes, but all classes
902 | # are still loaded.
903 | # All current Function classes include ".function." in their name,
904 | # and none include ".gui." in the name, so the number of unwanted classes loaded can be
905 | # reduced by checking for these. However, if a valid function class name does not match
906 | # these restrictions, it will not be loaded. If problems are encountered, then comment
907 | # or change the following properties:
908 | classfinder.functions.contain=.functions.
909 | classfinder.functions.notContain=.gui.
910 |
911 | #---------------------------------------------------------------------------
912 | # Additional property files to load
913 | #---------------------------------------------------------------------------
914 |
915 | # Should JMeter automatically load additional JMeter properties?
916 | # File name to look for (comment to disable)
917 | user.properties=user.properties
918 |
919 | # Should JMeter automatically load additional system properties?
920 | # File name to look for (comment to disable)
921 | system.properties=system.properties
--------------------------------------------------------------------------------
/src/test/resources/saveservice.properties:
--------------------------------------------------------------------------------
1 | #---------------------------------------------------------
2 | # SAVESERVICE PROPERTIES
3 | #---------------------------------------------------------
4 |
5 | ## Licensed to the Apache Software Foundation (ASF) under one or more
6 | ## contributor license agreements. See the NOTICE file distributed with
7 | ## this work for additional information regarding copyright ownership.
8 | ## The ASF licenses this file to You under the Apache License, Version 2.0
9 | ## (the "License"); you may not use this file except in compliance with
10 | ## the License. You may obtain a copy of the License at
11 | ##
12 | ## http://www.apache.org/licenses/LICENSE-2.0
13 | ##
14 | ## Unless required by applicable law or agreed to in writing, software
15 | ## distributed under the License is distributed on an "AS IS" BASIS,
16 | ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 | ## See the License for the specific language governing permissions and
18 | ## limitations under the License.
19 |
20 | #---------------------------------------------------------
21 |
22 | # N.B. To ensure backward compatibility, please do NOT change or delete any entries
23 |
24 | # New entries can be added as necessary.
25 | #
26 | # Note that keys starting with an underscore are special,
27 | # and are not used as aliases.
28 | #
29 | # Please keep the entries in alphabetical order within the sections
30 | # to reduce the likelihood of duplicates
31 | #
32 | # version number of this file (automatically generated by SVN)
33 | _file_version=$Revision: 1427507 $
34 | #
35 | # Conversion version (for JMX output files)
36 | # Must be updated if the file has been changed since the previous release
37 | #
38 | # 1.7 = 2.1.1
39 | # 1.8 = 2.1.2
40 | # (Some version updates were missed here...)
41 | # 2.0 = 2.3.1
42 | # 2.1 = 2.3.2
43 | # (Some version updates were missed here...)
44 | # 2.2 = 2.6
45 | # 2.3 = 2.7
46 | # 2.4 = 2.9
47 | #
48 | _version=2.4
49 | #
50 | #
51 | # Character set encoding used to read and write JMeter XML files and CSV results
52 | #
53 | _file_encoding=UTF-8
54 | #
55 | #---------------------------------------------------------
56 | #
57 | # The following properties are used to create aliases
58 | # [Must all start with capital letter]
59 | #
60 | AccessLogSampler=org.apache.jmeter.protocol.http.sampler.AccessLogSampler
61 | AjpSampler=org.apache.jmeter.protocol.http.sampler.AjpSampler
62 | AjpSamplerGui=org.apache.jmeter.protocol.http.control.gui.AjpSamplerGui
63 | AnchorModifier=org.apache.jmeter.protocol.http.modifier.AnchorModifier
64 | AnchorModifierGui=org.apache.jmeter.protocol.http.modifier.gui.AnchorModifierGui
65 | Argument=org.apache.jmeter.config.Argument
66 | Arguments=org.apache.jmeter.config.Arguments
67 | ArgumentsPanel=org.apache.jmeter.config.gui.ArgumentsPanel
68 | AssertionGui=org.apache.jmeter.assertions.gui.AssertionGui
69 | AssertionVisualizer=org.apache.jmeter.visualizers.AssertionVisualizer
70 | AuthManager=org.apache.jmeter.protocol.http.control.AuthManager
71 | Authorization=org.apache.jmeter.protocol.http.control.Authorization
72 | AuthPanel=org.apache.jmeter.protocol.http.gui.AuthPanel
73 | BarChart=org.apache.jmeter.testelement.BarChart
74 | BarChartGui=org.apache.jmeter.report.gui.BarChartGui
75 | BeanShellAssertion=org.apache.jmeter.assertions.BeanShellAssertion
76 | BeanShellAssertionGui=org.apache.jmeter.assertions.gui.BeanShellAssertionGui
77 | BeanShellListener=org.apache.jmeter.visualizers.BeanShellListener
78 | BeanShellPostProcessor=org.apache.jmeter.extractor.BeanShellPostProcessor
79 | BeanShellPreProcessor=org.apache.jmeter.modifiers.BeanShellPreProcessor
80 | BeanShellSampler=org.apache.jmeter.protocol.java.sampler.BeanShellSampler
81 | BeanShellSamplerGui=org.apache.jmeter.protocol.java.control.gui.BeanShellSamplerGui
82 | BeanShellTimer=org.apache.jmeter.timers.BeanShellTimer
83 | BSFAssertion=org.apache.jmeter.assertions.BSFAssertion
84 | BSFListener=org.apache.jmeter.visualizers.BSFListener
85 | BSFPreProcessor=org.apache.jmeter.modifiers.BSFPreProcessor
86 | BSFPostProcessor=org.apache.jmeter.extractor.BSFPostProcessor
87 | BSFSampler=org.apache.jmeter.protocol.java.sampler.BSFSampler
88 | BSFSamplerGui=org.apache.jmeter.protocol.java.control.gui.BSFSamplerGui
89 | BSFTimer=org.apache.jmeter.timers.BSFTimer
90 | CacheManager=org.apache.jmeter.protocol.http.control.CacheManager
91 | CacheManagerGui=org.apache.jmeter.protocol.http.gui.CacheManagerGui
92 | CompareAssertion=org.apache.jmeter.assertions.CompareAssertion
93 | ComparisonVisualizer=org.apache.jmeter.visualizers.ComparisonVisualizer
94 | ConfigTestElement=org.apache.jmeter.config.ConfigTestElement
95 | ConstantThroughputTimer=org.apache.jmeter.timers.ConstantThroughputTimer
96 | ConstantTimer=org.apache.jmeter.timers.ConstantTimer
97 | ConstantTimerGui=org.apache.jmeter.timers.gui.ConstantTimerGui
98 | Cookie=org.apache.jmeter.protocol.http.control.Cookie
99 | CookieManager=org.apache.jmeter.protocol.http.control.CookieManager
100 | CookiePanel=org.apache.jmeter.protocol.http.gui.CookiePanel
101 | CounterConfig=org.apache.jmeter.modifiers.CounterConfig
102 | CounterConfigGui=org.apache.jmeter.modifiers.gui.CounterConfigGui
103 | CSVDataSet=org.apache.jmeter.config.CSVDataSet
104 | DebugPostProcessor=org.apache.jmeter.extractor.DebugPostProcessor
105 | DebugSampler=org.apache.jmeter.sampler.DebugSampler
106 | DistributionGraphVisualizer=org.apache.jmeter.visualizers.DistributionGraphVisualizer
107 | DurationAssertion=org.apache.jmeter.assertions.DurationAssertion
108 | DurationAssertionGui=org.apache.jmeter.assertions.gui.DurationAssertionGui
109 | # Should really have been defined as floatProp to agree with other properties
110 | # No point changing this now
111 | FloatProperty=org.apache.jmeter.testelement.property.FloatProperty
112 | ForeachController=org.apache.jmeter.control.ForeachController
113 | ForeachControlPanel=org.apache.jmeter.control.gui.ForeachControlPanel
114 | FtpConfigGui=org.apache.jmeter.protocol.ftp.config.gui.FtpConfigGui
115 | FTPSampler=org.apache.jmeter.protocol.ftp.sampler.FTPSampler
116 | FtpTestSamplerGui=org.apache.jmeter.protocol.ftp.control.gui.FtpTestSamplerGui
117 | GaussianRandomTimer=org.apache.jmeter.timers.GaussianRandomTimer
118 | GaussianRandomTimerGui=org.apache.jmeter.timers.gui.GaussianRandomTimerGui
119 | GenericController=org.apache.jmeter.control.GenericController
120 | GraphAccumVisualizer=org.apache.jmeter.visualizers.GraphAccumVisualizer
121 | GraphVisualizer=org.apache.jmeter.visualizers.GraphVisualizer
122 | Header=org.apache.jmeter.protocol.http.control.Header
123 | HeaderManager=org.apache.jmeter.protocol.http.control.HeaderManager
124 | HeaderPanel=org.apache.jmeter.protocol.http.gui.HeaderPanel
125 | HTMLAssertion=org.apache.jmeter.assertions.HTMLAssertion
126 | HTMLAssertionGui=org.apache.jmeter.assertions.gui.HTMLAssertionGui
127 | HTMLReportWriter=org.apache.jmeter.report.writers.HTMLReportWriter
128 | HTMLReportWriterGui=org.apache.jmeter.report.writers.gui.HTMLReportWriterGui
129 | HTTPArgument=org.apache.jmeter.protocol.http.util.HTTPArgument
130 | HTTPArgumentsPanel=org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel
131 | HTTPFileArg=org.apache.jmeter.protocol.http.util.HTTPFileArg
132 | HTTPFileArgs=org.apache.jmeter.protocol.http.util.HTTPFileArgs
133 | HttpDefaultsGui=org.apache.jmeter.protocol.http.config.gui.HttpDefaultsGui
134 | HtmlExtractor=org.apache.jmeter.extractor.HtmlExtractor
135 | HtmlExtractorGui=org.apache.jmeter.extractor.gui.HtmlExtractorGui
136 | # removed in r1039684, probably not released. Not present in r322831 or since.
137 | #HttpGenericSampler=org.apache.jmeter.protocol.http.sampler.HttpGenericSampler
138 | # removed in r1039684, probably not released. Not present in r322831 or since.
139 | #HttpGenericSamplerGui=org.apache.jmeter.protocol.http.control.gui.HttpGenericSamplerGui
140 | HttpMirrorControl=org.apache.jmeter.protocol.http.control.HttpMirrorControl
141 | HttpMirrorControlGui=org.apache.jmeter.protocol.http.control.gui.HttpMirrorControlGui
142 | # r397955 - removed test class. Keep as commented entry for info only.
143 | #HTTPNullSampler=org.apache.jmeter.protocol.http.sampler.HTTPNullSampler
144 | # Merge previous 2 HTTP samplers into one
145 | HTTPSampler_=org.apache.jmeter.protocol.http.sampler.HTTPSampler
146 | HTTPSampler2_=org.apache.jmeter.protocol.http.sampler.HTTPSampler2
147 | HTTPSamplerProxy,HTTPSampler,HTTPSampler2=org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy
148 | DummySampler=net.unit8.jmeter.protocol.websocket.DummySampler
149 | # Merge GUIs
150 | HttpTestSampleGui,HttpTestSampleGui2=org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui
151 | #HttpTestSampleGui2=org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui2
152 | IfController=org.apache.jmeter.control.IfController
153 | IfControllerPanel=org.apache.jmeter.control.gui.IfControllerPanel
154 | IncludeController=org.apache.jmeter.control.IncludeController
155 | IncludeControllerGui=org.apache.jmeter.control.gui.IncludeControllerGui
156 | InterleaveControl=org.apache.jmeter.control.InterleaveControl
157 | InterleaveControlGui=org.apache.jmeter.control.gui.InterleaveControlGui
158 | JavaConfig=org.apache.jmeter.protocol.java.config.JavaConfig
159 | JavaConfigGui=org.apache.jmeter.protocol.java.config.gui.JavaConfigGui
160 | JavaSampler=org.apache.jmeter.protocol.java.sampler.JavaSampler
161 | JavaTest=org.apache.jmeter.protocol.java.test.JavaTest
162 | JavaTestSamplerGui=org.apache.jmeter.protocol.java.control.gui.JavaTestSamplerGui
163 | JDBCDataSource=org.apache.jmeter.protocol.jdbc.config.DataSourceElement
164 | JDBCPostProcessor=org.apache.jmeter.protocol.jdbc.processor.JDBCPostProcessor
165 | JDBCPreProcessor=org.apache.jmeter.protocol.jdbc.processor.JDBCPreProcessor
166 | JDBCSampler=org.apache.jmeter.protocol.jdbc.sampler.JDBCSampler
167 | # Renamed to JMSSamplerGui; keep original entry for backwards compatibility
168 | JMSConfigGui=org.apache.jmeter.protocol.jms.control.gui.JMSConfigGui
169 | JMSPublisherGui=org.apache.jmeter.protocol.jms.control.gui.JMSPublisherGui
170 | JMSSampler=org.apache.jmeter.protocol.jms.sampler.JMSSampler
171 | JMSSamplerGui=org.apache.jmeter.protocol.jms.control.gui.JMSSamplerGui
172 | JMSSubscriberGui=org.apache.jmeter.protocol.jms.control.gui.JMSSubscriberGui
173 | # Removed in r545311 as Jndi no longer present; keep for compat.
174 | JndiDefaultsGui=org.apache.jmeter.protocol.jms.control.gui.JndiDefaultsGui
175 | JSR223Assertion=org.apache.jmeter.assertions.JSR223Assertion
176 | JSR223Listener=org.apache.jmeter.visualizers.JSR223Listener
177 | JSR223PostProcessor=org.apache.jmeter.extractor.JSR223PostProcessor
178 | JSR223PreProcessor=org.apache.jmeter.modifiers.JSR223PreProcessor
179 | JSR223Sampler=org.apache.jmeter.protocol.java.sampler.JSR223Sampler
180 | JSR223Timer=org.apache.jmeter.timers.JSR223Timer
181 | JUnitSampler=org.apache.jmeter.protocol.java.sampler.JUnitSampler
182 | JUnitTestSamplerGui=org.apache.jmeter.protocol.java.control.gui.JUnitTestSamplerGui
183 | KeystoreConfig=org.apache.jmeter.config.KeystoreConfig
184 | LDAPArgument=org.apache.jmeter.protocol.ldap.config.gui.LDAPArgument
185 | LDAPArguments=org.apache.jmeter.protocol.ldap.config.gui.LDAPArguments
186 | LDAPArgumentsPanel=org.apache.jmeter.protocol.ldap.config.gui.LDAPArgumentsPanel
187 | LdapConfigGui=org.apache.jmeter.protocol.ldap.config.gui.LdapConfigGui
188 | LdapExtConfigGui=org.apache.jmeter.protocol.ldap.config.gui.LdapExtConfigGui
189 | LDAPExtSampler=org.apache.jmeter.protocol.ldap.sampler.LDAPExtSampler
190 | LdapExtTestSamplerGui=org.apache.jmeter.protocol.ldap.control.gui.LdapExtTestSamplerGui
191 | LDAPSampler=org.apache.jmeter.protocol.ldap.sampler.LDAPSampler
192 | LdapTestSamplerGui=org.apache.jmeter.protocol.ldap.control.gui.LdapTestSamplerGui
193 | LineChart=org.apache.jmeter.testelement.LineChart
194 | LineGraphGui=org.apache.jmeter.report.gui.LineGraphGui
195 | LogicControllerGui=org.apache.jmeter.control.gui.LogicControllerGui
196 | LoginConfig=org.apache.jmeter.config.LoginConfig
197 | LoginConfigGui=org.apache.jmeter.config.gui.LoginConfigGui
198 | LoopController=org.apache.jmeter.control.LoopController
199 | LoopControlPanel=org.apache.jmeter.control.gui.LoopControlPanel
200 | MailerModel=org.apache.jmeter.reporters.MailerModel
201 | MailerResultCollector=org.apache.jmeter.reporters.MailerResultCollector
202 | MailerVisualizer=org.apache.jmeter.visualizers.MailerVisualizer
203 | MailReaderSampler=org.apache.jmeter.protocol.mail.sampler.MailReaderSampler
204 | MailReaderSamplerGui=org.apache.jmeter.protocol.mail.sampler.gui.MailReaderSamplerGui
205 | MD5HexAssertion=org.apache.jmeter.assertions.MD5HexAssertion
206 | MD5HexAssertionGUI=org.apache.jmeter.assertions.gui.MD5HexAssertionGUI
207 | ModuleController=org.apache.jmeter.control.ModuleController
208 | ModuleControllerGui=org.apache.jmeter.control.gui.ModuleControllerGui
209 | MonitorHealthVisualizer=org.apache.jmeter.visualizers.MonitorHealthVisualizer
210 | NamePanel=org.apache.jmeter.gui.NamePanel
211 | ObsoleteGui=org.apache.jmeter.config.gui.ObsoleteGui
212 | OnceOnlyController=org.apache.jmeter.control.OnceOnlyController
213 | OnceOnlyControllerGui=org.apache.jmeter.control.gui.OnceOnlyControllerGui
214 | ParamMask=org.apache.jmeter.protocol.http.modifier.ParamMask
215 | ParamModifier=org.apache.jmeter.protocol.http.modifier.ParamModifier
216 | ParamModifierGui=org.apache.jmeter.protocol.http.modifier.gui.ParamModifierGui
217 | PoissonRandomTimer=org.apache.jmeter.timers.PoissonRandomTimer
218 | PoissonRandomTimerGui=org.apache.jmeter.timers.gui.PoissonRandomTimerGui
219 | PropertyControlGui=org.apache.jmeter.visualizers.PropertyControlGui
220 | ProxyControl=org.apache.jmeter.protocol.http.proxy.ProxyControl
221 | ProxyControlGui=org.apache.jmeter.protocol.http.proxy.gui.ProxyControlGui
222 | PublisherSampler=org.apache.jmeter.protocol.jms.sampler.PublisherSampler
223 | RandomControlGui=org.apache.jmeter.control.gui.RandomControlGui
224 | RandomController=org.apache.jmeter.control.RandomController
225 | RandomOrderController=org.apache.jmeter.control.RandomOrderController
226 | RandomOrderControllerGui=org.apache.jmeter.control.gui.RandomOrderControllerGui
227 | RandomVariableConfig=org.apache.jmeter.config.RandomVariableConfig
228 | RecordController=org.apache.jmeter.protocol.http.control.gui.RecordController
229 | RecordingController=org.apache.jmeter.protocol.http.control.RecordingController
230 | # removed in r1039684, class was deleted in r580452
231 | ReflectionThreadGroup=org.apache.jmeter.threads.ReflectionThreadGroup
232 | RegexExtractor=org.apache.jmeter.extractor.RegexExtractor
233 | RegexExtractorGui=org.apache.jmeter.extractor.gui.RegexExtractorGui
234 | RegExUserParameters=org.apache.jmeter.protocol.http.modifier.RegExUserParameters
235 | RegExUserParametersGui=org.apache.jmeter.protocol.http.modifier.gui.RegExUserParametersGui
236 | RemoteListenerWrapper=org.apache.jmeter.samplers.RemoteListenerWrapper
237 | RemoteSampleListenerWrapper=org.apache.jmeter.samplers.RemoteSampleListenerWrapper
238 | RemoteTestListenerWrapper=org.apache.jmeter.samplers.RemoteTestListenerWrapper
239 | ReportGui=org.apache.jmeter.control.gui.ReportGui
240 | ReportPage=org.apache.jmeter.testelement.ReportPage
241 | ReportPageGui=org.apache.jmeter.report.gui.ReportPageGui
242 | ReportPlan=org.apache.jmeter.testelement.ReportPlan
243 | ResponseAssertion=org.apache.jmeter.assertions.ResponseAssertion
244 | RespTimeGraphVisualizer=org.apache.jmeter.visualizers.RespTimeGraphVisualizer
245 | ResultAction=org.apache.jmeter.reporters.ResultAction
246 | ResultActionGui=org.apache.jmeter.reporters.gui.ResultActionGui
247 | ResultCollector=org.apache.jmeter.reporters.ResultCollector
248 | ResultSaver=org.apache.jmeter.reporters.ResultSaver
249 | ResultSaverGui=org.apache.jmeter.reporters.gui.ResultSaverGui
250 | RunTime=org.apache.jmeter.control.RunTime
251 | RunTimeGui=org.apache.jmeter.control.gui.RunTimeGui
252 | SampleSaveConfiguration=org.apache.jmeter.samplers.SampleSaveConfiguration
253 | SimpleConfigGui=org.apache.jmeter.config.gui.SimpleConfigGui
254 | SimpleDataWriter=org.apache.jmeter.visualizers.SimpleDataWriter
255 | SizeAssertion=org.apache.jmeter.assertions.SizeAssertion
256 | SizeAssertionGui=org.apache.jmeter.assertions.gui.SizeAssertionGui
257 | SMIMEAssertion=org.apache.jmeter.assertions.SMIMEAssertionTestElement
258 | SMIMEAssertionGui=org.apache.jmeter.assertions.gui.SMIMEAssertionGui
259 | SmtpSampler=org.apache.jmeter.protocol.smtp.sampler.SmtpSampler
260 | SmtpSamplerGui=org.apache.jmeter.protocol.smtp.sampler.gui.SmtpSamplerGui
261 | SoapSampler=org.apache.jmeter.protocol.http.sampler.SoapSampler
262 | SoapSamplerGui=org.apache.jmeter.protocol.http.control.gui.SoapSamplerGui
263 | SplineVisualizer=org.apache.jmeter.visualizers.SplineVisualizer
264 | # Originally deleted in r397955 as class is obsolete; needed for compat.
265 | SqlConfigGui=org.apache.jmeter.protocol.jdbc.config.gui.SqlConfigGui
266 | StatGraphVisualizer=org.apache.jmeter.visualizers.StatGraphVisualizer
267 | StatVisualizer=org.apache.jmeter.visualizers.StatVisualizer
268 | SubscriberSampler=org.apache.jmeter.protocol.jms.sampler.SubscriberSampler
269 | SubstitutionElement=org.apache.jmeter.assertions.SubstitutionElement
270 | Summariser=org.apache.jmeter.reporters.Summariser
271 | SummariserGui=org.apache.jmeter.reporters.gui.SummariserGui
272 | SummaryReport=org.apache.jmeter.visualizers.SummaryReport
273 | SwitchController=org.apache.jmeter.control.SwitchController
274 | SwitchControllerGui=org.apache.jmeter.control.gui.SwitchControllerGui
275 | SyncTimer=org.apache.jmeter.timers.SyncTimer
276 | SystemSampler=org.apache.jmeter.protocol.system.SystemSampler
277 | SystemSamplerGui=org.apache.jmeter.protocol.system.gui.SystemSamplerGui
278 | Table=org.apache.jmeter.testelement.Table
279 | TableGui=org.apache.jmeter.report.gui.TableGui
280 | TableVisualizer=org.apache.jmeter.visualizers.TableVisualizer
281 | TCPConfigGui=org.apache.jmeter.protocol.tcp.config.gui.TCPConfigGui
282 | TCPSampler=org.apache.jmeter.protocol.tcp.sampler.TCPSampler
283 | TCPSamplerGui=org.apache.jmeter.protocol.tcp.control.gui.TCPSamplerGui
284 | TestAction=org.apache.jmeter.sampler.TestAction
285 | TestActionGui=org.apache.jmeter.sampler.gui.TestActionGui
286 | TestBeanGUI=org.apache.jmeter.testbeans.gui.TestBeanGUI
287 | TestFragmentController=org.apache.jmeter.control.TestFragmentController
288 | TestFragmentControllerGui=org.apache.jmeter.control.gui.TestFragmentControllerGui
289 | TestPlan=org.apache.jmeter.testelement.TestPlan
290 | TestPlanGui=org.apache.jmeter.control.gui.TestPlanGui
291 | ThreadGroup=org.apache.jmeter.threads.ThreadGroup
292 | ThreadGroupGui=org.apache.jmeter.threads.gui.ThreadGroupGui
293 | PostThreadGroup=org.apache.jmeter.threads.PostThreadGroup
294 | PostThreadGroupGui=org.apache.jmeter.threads.gui.PostThreadGroupGui
295 | SetupThreadGroup=org.apache.jmeter.threads.SetupThreadGroup
296 | SetupThreadGroupGui=org.apache.jmeter.threads.gui.SetupThreadGroupGui
297 | ThroughputController=org.apache.jmeter.control.ThroughputController
298 | ThroughputControllerGui=org.apache.jmeter.control.gui.ThroughputControllerGui
299 | TransactionController=org.apache.jmeter.control.TransactionController
300 | TransactionControllerGui=org.apache.jmeter.control.gui.TransactionControllerGui
301 | TransactionSampler=org.apache.jmeter.control.TransactionSampler
302 | UniformRandomTimer=org.apache.jmeter.timers.UniformRandomTimer
303 | UniformRandomTimerGui=org.apache.jmeter.timers.gui.UniformRandomTimerGui
304 | URLRewritingModifier=org.apache.jmeter.protocol.http.modifier.URLRewritingModifier
305 | URLRewritingModifierGui=org.apache.jmeter.protocol.http.modifier.gui.URLRewritingModifierGui
306 | UserParameterModifier=org.apache.jmeter.protocol.http.modifier.UserParameterModifier
307 | UserParameterModifierGui=org.apache.jmeter.protocol.http.modifier.gui.UserParameterModifierGui
308 | UserParameters=org.apache.jmeter.modifiers.UserParameters
309 | UserParametersGui=org.apache.jmeter.modifiers.gui.UserParametersGui
310 | ViewResultsFullVisualizer=org.apache.jmeter.visualizers.ViewResultsFullVisualizer
311 | WebServiceSampler=org.apache.jmeter.protocol.http.sampler.WebServiceSampler
312 | WebServiceSamplerGui=org.apache.jmeter.protocol.http.control.gui.WebServiceSamplerGui
313 | WhileController=org.apache.jmeter.control.WhileController
314 | WhileControllerGui=org.apache.jmeter.control.gui.WhileControllerGui
315 | WorkBench=org.apache.jmeter.testelement.WorkBench
316 | WorkBenchGui=org.apache.jmeter.control.gui.WorkBenchGui
317 | XMLAssertion=org.apache.jmeter.assertions.XMLAssertion
318 | XMLAssertionGui=org.apache.jmeter.assertions.gui.XMLAssertionGui
319 | XMLSchemaAssertion=org.apache.jmeter.assertions.XMLSchemaAssertion
320 | XMLSchemaAssertionGUI=org.apache.jmeter.assertions.gui.XMLSchemaAssertionGUI
321 | XPathAssertion=org.apache.jmeter.assertions.XPathAssertion
322 | XPathAssertionGui=org.apache.jmeter.assertions.gui.XPathAssertionGui
323 | XPathExtractor=org.apache.jmeter.extractor.XPathExtractor
324 | XPathExtractorGui=org.apache.jmeter.extractor.gui.XPathExtractorGui
325 | #
326 | # Properties - all start with lower case letter and end with Prop
327 | #
328 | boolProp=org.apache.jmeter.testelement.property.BooleanProperty
329 | collectionProp=org.apache.jmeter.testelement.property.CollectionProperty
330 | doubleProp=org.apache.jmeter.testelement.property.DoubleProperty
331 | elementProp=org.apache.jmeter.testelement.property.TestElementProperty
332 | # see above - already defined as FloatProperty
333 | #floatProp=org.apache.jmeter.testelement.property.FloatProperty
334 | intProp=org.apache.jmeter.testelement.property.IntegerProperty
335 | longProp=org.apache.jmeter.testelement.property.LongProperty
336 | mapProp=org.apache.jmeter.testelement.property.MapProperty
337 | objProp=org.apache.jmeter.testelement.property.ObjectProperty
338 | stringProp=org.apache.jmeter.testelement.property.StringProperty
339 | #
340 | # Other - must start with a lower case letter (and not end with Prop)
341 | # (otherwise they could clash with the initial set of aliases)
342 | #
343 | hashTree=org.apache.jorphan.collections.ListedHashTree
344 | jmeterTestPlan=org.apache.jmeter.save.ScriptWrapper
345 | sample=org.apache.jmeter.samplers.SampleResult
346 | httpSample=org.apache.jmeter.protocol.http.sampler.HTTPSampleResult
347 | statSample=org.apache.jmeter.samplers.StatisticalSampleResult
348 | testResults=org.apache.jmeter.save.TestResultWrapper
349 | assertionResult=org.apache.jmeter.assertions.AssertionResult
350 | monitorStats=org.apache.jmeter.visualizers.MonitorStats
351 | sampleEvent=org.apache.jmeter.samplers.SampleEvent
352 | #
353 | # Converters to register. Must start line with '_'
354 | # If the converter is a collection of subitems, set equal to "collection"
355 | # If the converter needs to know the class mappings but is not a collection of
356 | # subitems, set it equal to "mapping"
357 | _org.apache.jmeter.protocol.http.sampler.HTTPSamplerBaseConverter=collection
358 | _org.apache.jmeter.protocol.http.util.HTTPResultConverter=collection
359 | _org.apache.jmeter.save.converters.BooleanPropertyConverter=
360 | _org.apache.jmeter.save.converters.IntegerPropertyConverter=
361 | _org.apache.jmeter.save.converters.LongPropertyConverter=
362 | _org.apache.jmeter.save.converters.MultiPropertyConverter=collection
363 | _org.apache.jmeter.save.converters.SampleEventConverter=
364 | _org.apache.jmeter.save.converters.SampleResultConverter=collection
365 | _org.apache.jmeter.save.converters.SampleSaveConfigurationConverter=collection
366 | _org.apache.jmeter.save.converters.StringPropertyConverter=
367 | _org.apache.jmeter.save.converters.HashTreeConverter=collection
368 | _org.apache.jmeter.save.converters.TestElementConverter=collection
369 | _org.apache.jmeter.save.converters.TestElementPropertyConverter=collection
370 | _org.apache.jmeter.save.converters.TestResultWrapperConverter=collection
371 | _org.apache.jmeter.save.ScriptWrapperConverter=mapping
372 | #
373 | # Remember to update the _version entry
374 | #
375 |
--------------------------------------------------------------------------------
/src/test/resources/users.csv:
--------------------------------------------------------------------------------
1 | USER_NAME
2 | Lyle
3 | Malcolm
4 | Quinlan
5 | Madaline
6 | Brady
7 | Ariel
8 | Sebastian
9 | Fiona
10 | Kathleen
11 | Quynn
12 | Alisa
13 | Lyle
14 | Orla
15 | Carissa
16 | Buffy
17 | Eliana
18 | Gannon
19 | Moana
20 | Quamar
21 | Deacon
22 | Jesse
23 | Bell
24 | Ira
25 | Rooney
26 | Justine
27 | Gloria
28 | Kameko
29 | Maxwell
30 | Zane
31 | Leo
32 | Karina
33 | Linda
34 | Cooper
35 | Echo
36 | Craig
37 | Gage
38 | Geoffrey
39 | Aretha
40 | McKenzie
41 | Steel
42 | Scarlet
43 | Nash
44 | Jin
45 | Laith
46 | Shay
47 | Madeline
48 | Sierra
49 | Chava
50 | Emma
51 | Madaline
52 | Irene
53 | Rana
54 | Norman
55 | Suki
56 | Levi
57 | Courtney
58 | Dana
59 | Blair
60 | Suki
61 | Cruz
62 | Nehru
63 | Hector
64 | Salvador
65 | Tyrone
66 | Miranda
67 | Amy
68 | Debra
69 | Alec
70 | Bradley
71 | Timothy
72 | Tara
73 | Warren
74 | Lillith
75 | Hanae
76 | Kaseem
77 | Jackson
78 | Abdul
79 | Hall
80 | Mariko
81 | Eric
82 | Zia
83 | Autumn
84 | Axel
85 | Nolan
86 | Wilma
87 | Mohammad
88 | Victoria
89 | Cheyenne
90 | Raven
91 | Rosalyn
92 | Idola
93 | Jesse
94 | Clementine
95 | Darryl
96 | Henry
97 | Sydney
98 | Emerald
99 | Maryam
100 | Thor
101 | Holmes
--------------------------------------------------------------------------------
/src/test/scripts/chat.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | process.title = 'chat';
4 |
5 | var webSocketsServerPort = 9090;
6 |
7 | var webSocketServer = require('websocket').server;
8 | var http = require('http');
9 |
10 | var history = [ ];
11 | var clients = [ ];
12 |
13 | var server = http.createServer(function(request, response) {
14 | });
15 |
16 | server.listen(webSocketsServerPort, function() {
17 | console.log((new Date()) + " Server is listening on port " + webSocketsServerPort);
18 | });
19 |
20 | var wsServer = new webSocketServer({
21 | httpServer: server
22 | });
23 |
24 | wsServer.on('request', function(request) {
25 | var query = request.resourceURL.query;
26 | var name = query["name"] || "unknown";
27 |
28 | var connection = request.accept(null, request.origin);
29 | var index = clients.push(connection) - 1;
30 |
31 | if (history.length > 0) {
32 | connection.sendUTF(JSON.stringify(history));
33 | }
34 |
35 | connection.on('message', function(message) {
36 | if (message.type !== 'utf8')
37 | return;
38 |
39 | var message = message.utf8Data;
40 |
41 | var chat = {
42 | name: name,
43 | message: message,
44 | chatedAt: new Date()
45 | };
46 | history.push(chat);
47 | history = history.slice(-100);
48 |
49 | var json = JSON.stringify([chat]);
50 | for (var i=0; i < clients.length; i++) {
51 | clients[i].sendUTF(json);
52 | }
53 | });
54 |
55 | connection.on('close', function(connection) {
56 | console.log((new Date()) + " User "
57 | + name + " disconnected.");
58 | clients.splice(index, 1);
59 | });
60 | });
--------------------------------------------------------------------------------