/* * Copyright 2015 the original author or authors. * * 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. */ package org.springframework.cloud.stream.module.tcp.source; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.springframework.cloud.stream.test.matcher.MessageQueueMatcher.receivesPayloadThat; import java.net.Socket; import javax.net.SocketFactory; import org.hamcrest.Matchers; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.IntegrationTest; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.boot.test.WebIntegrationTest; import org.springframework.cloud.stream.messaging.Source; import org.springframework.cloud.stream.test.binder.MessageCollector; import org.springframework.integration.ip.tcp.connection.AbstractServerConnectionFactory; import org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory; import org.springframework.integration.ip.tcp.connection.TcpNioServerConnectionFactory; import org.springframework.integration.test.util.TestUtils; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * Tests for TcpSource. * * @author Gary Russell */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = TcpSourceApplication.class) @DirtiesContext @WebIntegrationTest(randomPort = true, value = "port = 0") public abstract class TcpSourceTests { @Autowired protected Source channels; @Autowired protected MessageCollector messageCollector; @Autowired protected AbstractServerConnectionFactory connectionFactory; @Autowired protected TcpSourceProperties properties; @IntegrationTest({ "nio = true", "reverseLookup = true", "useDirectBuffers = true", "socketTimeout = 123", "bufferSize = 5" }) public static class PropertiesPopulatedTests extends TcpSourceTests { @Test public void test() throws Exception { assertThat(this.connectionFactory, Matchers.instanceOf(TcpNioServerConnectionFactory.class)); assertTrue(TestUtils.getPropertyValue(this.connectionFactory, "lookupHost", Boolean.class)); assertTrue(TestUtils.getPropertyValue(this.connectionFactory, "usingDirectBuffers", Boolean.class)); assertEquals(123, TestUtils.getPropertyValue(this.connectionFactory, "soTimeout")); assertEquals(5, TestUtils.getPropertyValue(this.connectionFactory, "deserializer.maxMessageSize")); } } public static class NotNioTests extends TcpSourceTests { @Test public void test() throws Exception { assertThat(this.connectionFactory, Matchers.instanceOf(TcpNetServerConnectionFactory.class)); assertFalse(TestUtils.getPropertyValue(this.connectionFactory, "lookupHost", Boolean.class)); assertEquals(120000, TestUtils.getPropertyValue(this.connectionFactory, "soTimeout")); assertEquals(2048, TestUtils.getPropertyValue(this.connectionFactory, "deserializer.maxMessageSize")); } } public static class CRLFTests extends TcpSourceTests { @Test public void test() throws Exception { doTest("", "foo", "\r\n"); } } @IntegrationTest({ "decoder = LF" }) public static class LFTests extends TcpSourceTests { @Test public void test() throws Exception { doTest("", "foo", "\n"); } } @IntegrationTest({ "decoder = NULL" }) public static class NULLTests extends TcpSourceTests { @Test public void test() throws Exception { doTest("", "foo", "\u0000"); } } @IntegrationTest({ "decoder = STXETX" }) public static class STXETXTests extends TcpSourceTests { @Test public void test() throws Exception { doTest("\u0002", "foo", "\u0003"); } } @IntegrationTest({ "decoder = L1" }) public static class L1Tests extends TcpSourceTests { @Test public void test() throws Exception { doTest("\u0003", "foo", ""); } } @IntegrationTest({ "decoder = L2" }) public static class L2Tests extends TcpSourceTests { @Test public void test() throws Exception { doTest("\u0000\u0003", "foo", ""); } } @IntegrationTest({ "decoder = L4" }) public static class L4Tests extends TcpSourceTests { @Test public void test() throws Exception { doTest("\u0000\u0000\u0000\u0003", "foo", ""); } } @IntegrationTest({ "decoder = RAW" }) public static class RAWTests extends TcpSourceTests { @Test public void test() throws Exception { doTest("", "foo", ""); } } /* * Sends two messages with <prefix><payload><suffix> and asserts the * payload is received on the other side. */ protected void doTest(String prefix, String payload, String suffix) throws Exception { int port = getPort(); Socket socket = SocketFactory.getDefault().createSocket("localhost", port); socket.getOutputStream().write((prefix + payload + suffix).getBytes()); if (prefix.length() == 0 && suffix.length() == 0) { socket.close(); // RAW - for the others, close AFTER the messages are decoded. socket = SocketFactory.getDefault().createSocket("localhost", port); } assertThat(this.messageCollector.forChannel(channels.output()), receivesPayloadThat(is(payload.getBytes()))); socket.getOutputStream().write((prefix + payload + suffix).getBytes()); if (prefix.length() == 0 && suffix.length() == 0) { socket.close(); // RAW - for the others, close AFTER the messages are decoded. } assertThat(this.messageCollector.forChannel(channels.output()), receivesPayloadThat(is(payload.getBytes()))); socket.close(); } private int getPort() throws Exception { int n = 0; while (n++ < 100 && !this.connectionFactory.isListening()) { Thread.sleep(100); } assertTrue("server failed to start listening", this.connectionFactory.isListening()); int port = this.connectionFactory.getPort(); assertTrue("server stopped listening", port > 0); return port; } }