<commit_before>package org.rapidoid.http;

/*
 * #%L
 * rapidoid-http
 * %%
 * Copyright (C) 2014 - 2015 <NAME>
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import org.rapidoid.annotation.Authors;
import org.rapidoid.annotation.Since;
import org.rapidoid.bytes.BytesUtil;
import org.rapidoid.config.Conf;
import org.rapidoid.data.Range;
import org.rapidoid.data.Ranges;
import org.rapidoid.net.Protocol;
import org.rapidoid.net.TCP;
import org.rapidoid.net.abstracts.Channel;
import org.rapidoid.net.impl.ConnState;
import org.rapidoid.util.D;
import org.rapidoid.util.UTILS;
import org.rapidoid.wrap.BoolWrap;
import org.rapidoid.wrap.IntWrap;
import org.testng.annotations.Test;

@Authors("<NAME>")
@Since("2.0.0")
public class HttpPipeliningTest extends HttpTestCommons {

	protected static final byte[] REQ = "GET /hello H\r\nasf:asf\r\n\r\n".getBytes();

	protected static final byte[] RESP = "Hello".getBytes();

	@Test
	public void testHttpServerPipelining() {
		Conf.args("workers=1");

		defaultServerSetup();

		final int connections = 1000;
		final int pipelining = 10;

		final IntWrap counter = new IntWrap();
		final BoolWrap err = new BoolWrap();

		TCP.client().host("localhost").port(8080).connections(connections).protocol(new Protocol() {
			@Override
			public void process(final Channel ctx) {
				ConnState state = ctx.state();

				final Ranges lines = ctx.helper().ranges1;
				final Range resp = ctx.helper().ranges2.ranges[0];

				if (state.n == 0) {
					for (int i = 0; i < pipelining; i++) {
						ctx.write(REQ);
					}
					state.n = 1;
				} else if (state.n == 1) {
					for (int i = 0; i < pipelining; i++) {
						ctx.input().scanLnLn(lines.reset());
						ctx.input().scanN(5, resp); // response body: "Hello"

						if (!BytesUtil.matches(ctx.input().bytes(), resp, RESP, true)) {
							err.value = true;
						}

						counter.value++;
					}

					for (int i = 0; i < pipelining; i++) {
						ctx.write(REQ);
					}
				}
			}
		}).build().start();

		int sec = 5;
		UTILS.sleep(sec * 1000);
		shutdown();

		isFalse(err.value);
		D.print(counter.value, counter.value / sec);
	}

}<commit_msg>Refactored HTTP pipelining test using finite state protocol base.<commit_after>package org.rapidoid.http;

/*
 * #%L
 * rapidoid-http
 * %%
 * Copyright (C) 2014 - 2015 <NAME>
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import org.rapidoid.annotation.Authors;
import org.rapidoid.annotation.Since;
import org.rapidoid.bytes.BytesUtil;
import org.rapidoid.config.Conf;
import org.rapidoid.data.Range;
import org.rapidoid.data.Ranges;
import org.rapidoid.net.TCP;
import org.rapidoid.net.abstracts.Channel;
import org.rapidoid.net.impl.FiniteStateProtocol;
import org.rapidoid.util.D;
import org.rapidoid.util.UTILS;
import org.rapidoid.wrap.BoolWrap;
import org.rapidoid.wrap.IntWrap;
import org.testng.annotations.Test;

@Authors("<NAME>")
@Since("2.0.0")
public class HttpPipeliningTest extends HttpTestCommons {

	protected static final byte[] REQ = "GET /hello H\r\nasf:asf\r\n\r\n".getBytes();

	protected static final byte[] RESP = "Hello".getBytes();

	@Test
	public void testHttpServerPipelining() {
		Conf.args("workers=1");

		defaultServerSetup();

		final int connections = 1000;
		final int pipelining = 10;

		final IntWrap counter = new IntWrap();
		final BoolWrap err = new BoolWrap();

		TCP.client().host("localhost").port(8080).connections(connections).protocol(new FiniteStateProtocol(2) {

			@Override
			protected int state0(Channel ctx) {
				for (int i = 0; i < pipelining; i++) {
					ctx.write(REQ);
				}
				return 1;
			}

			@Override
			protected int state1(Channel ctx) {
				final Ranges lines = ctx.helper().ranges1;
				final Range resp = ctx.helper().ranges2.ranges[0];

				for (int i = 0; i < pipelining; i++) {
					ctx.input().scanLnLn(lines.reset());
					ctx.input().scanN(5, resp); // response body: "Hello"

					if (!BytesUtil.matches(ctx.input().bytes(), resp, RESP, true)) {
						err.value = true;
					}

					counter.value++;
				}

				for (int i = 0; i < pipelining; i++) {
					ctx.write(REQ);
				}

				return 1;
			}

		}).build().start();

		int sec = 5;
		UTILS.sleep(sec * 1000);
		shutdown();

		isFalse(err.value);
		D.print(counter.value, counter.value / sec);
	}

}
{'fraction_non_alphanumeric': 0.13671361502347418, 'fraction_numerical': 0.015774647887323943, 'mean_word_length': 3.483164983164983, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4671005', 'n_tokens_mistral': 2035, 'n_tokens_neox': 1731, 'n_words': 480}