package cc.blynk.integration.tcp; import cc.blynk.integration.IntegrationBase; import cc.blynk.integration.model.tcp.TestAppClient; import cc.blynk.integration.model.tcp.TestHardClient; import cc.blynk.server.application.AppServer; import cc.blynk.server.core.BaseServer; import cc.blynk.server.core.model.DashBoard; import cc.blynk.server.core.protocol.model.messages.ResponseMessage; import cc.blynk.server.core.protocol.model.messages.appllication.GetServerMessage; import cc.blynk.server.core.protocol.model.messages.hardware.ConnectRedirectMessage; import cc.blynk.server.hardware.HardwareServer; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; import redis.clients.jedis.Jedis; import static cc.blynk.server.core.protocol.enums.Response.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; /** * The Blynk Project. * Created by Dmitriy Dumanskiy. * Created on 5/09/2016. * */ @RunWith(MockitoJUnitRunner.class) public class LoadBalancingTest extends IntegrationBase { private BaseServer appServer; private BaseServer hardwareServer; @Before public void init() throws Exception { hardwareServer = new HardwareServer(holder).start(); appServer = new AppServer(holder).start(); try (Jedis jedis = holder.redisClient.getTokenPool().getResource()) { jedis.flushDB(); } try (Jedis jedis = holder.redisClient.getUserPool().getResource()) { jedis.flushDB(); } } @After public void shutdown() { appServer.close(); hardwareServer.close(); } @Test public void testCreateFewAccountWithDifferentApp() throws Exception { TestAppClient appClient1 = new TestAppClient("localhost", tcpAppPort, properties); appClient1.start(); String email = "test@gmmail.com"; String pass = "a"; String appName = "Blynk"; appClient1.send("getServer"); verify(appClient1.responseMock, timeout(1000)).channelRead(any(), eq(new ResponseMessage(1, ILLEGAL_COMMAND))); appClient1.send("getServer " + email + "\0" + appName); verify(appClient1.responseMock, timeout(1000)).channelRead(any(), eq(new GetServerMessage(2, "127.0.0.1"))); appClient1.send("register " + email + " " + pass + " " + appName); verify(appClient1.responseMock, timeout(1000)).channelRead(any(), eq(new ResponseMessage(3, OK))); appClient1.send("login " + email + " " + pass + " Android 1.10.4 " + appName); //we should wait until login finished. Only after that we can send commands verify(appClient1.responseMock, timeout(1000)).channelRead(any(), eq(new ResponseMessage(4, OK))); appClient1.send("getServer " + email + "\0" + appName); verify(appClient1.responseMock, timeout(1000).times(0)).channelRead(any(), eq(new GetServerMessage(5, "127.0.0.1"))); } @Test @Ignore public void testConnectRedirect() throws Exception { TestHardClient hardClient = new TestHardClient("localhost", tcpHardPort); hardClient.start(); hardClient.send("login 123"); verify(hardClient.responseMock, timeout(1000)).channelRead(any(), eq(new ResponseMessage(1, INVALID_TOKEN))); holder.redisClient.assignServerToToken("123", "123.123.123.123"); hardClient.send("login 123"); verify(hardClient.responseMock, timeout(1000)).channelRead(any(), eq(new ConnectRedirectMessage(2, b("123.123.123.123 9442")))); } @Test public void testNoRedirectAsTokenIsWrong() throws Exception { TestHardClient hardClient = new TestHardClient("localhost", tcpHardPort); hardClient.start(); hardClient.send("login 123"); verify(hardClient.responseMock, timeout(1000)).channelRead(any(), eq(new ResponseMessage(1, INVALID_TOKEN))); holder.redisClient.assignServerToToken("123", "127.0.0.1"); hardClient.send("login 123"); verify(hardClient.responseMock, timeout(1000)).channelRead(any(), eq(new ResponseMessage(2, INVALID_TOKEN))); } @Test public void testNewUserStoredInRedis() throws Exception { TestAppClient appClient1 = new TestAppClient("localhost", tcpAppPort, properties); appClient1.start(); String email = "test_new@gmail.com"; String pass = "a"; String appName = "Blynk"; appClient1.send("getServer " + email + "\0" + appName); verify(appClient1.responseMock, timeout(1000)).channelRead(any(), eq(new GetServerMessage(1, "127.0.0.1"))); appClient1.reset(); String token = workflowForUser(appClient1, email, pass, appName); assertEquals( "127.0.0.1", holder.redisClient.getServerByToken(token)); assertEquals( "127.0.0.1", holder.redisClient.getServerByUser(email)); } @Test public void testUserIsOnOtherServer() throws Exception { TestAppClient appClient1 = new TestAppClient("localhost", tcpAppPort, properties); appClient1.start(); String email = "test_new@gmail.com"; String appName = "Blynk"; holder.redisClient.assignServerToUser(email, "100.100.100.100"); appClient1.send("getServer " + email + "\0" + appName); verify(appClient1.responseMock, timeout(1000)).channelRead(any(), eq(new GetServerMessage(1, "100.100.100.100"))); } @Test public void testDeleteTokenFromRedis() throws Exception { TestAppClient appClient1 = new TestAppClient("localhost", tcpAppPort, properties); appClient1.start(); String email = "test_new@gmail.com"; String pass = "a"; String appName = "Blynk"; appClient1.send("getServer " + email + "\0" + appName); verify(appClient1.responseMock, timeout(1000)).channelRead(any(), eq(new GetServerMessage(1, "127.0.0.1"))); appClient1.reset(); String token = workflowForUser(appClient1, email, pass, appName); assertEquals( "127.0.0.1", holder.redisClient.getServerByToken(token)); assertEquals( "127.0.0.1", holder.redisClient.getServerByUser(email)); appClient1.reset(); appClient1.send("deleteDash 1"); verify(appClient1.responseMock, timeout(1000)).channelRead(any(), eq(ok(1))); assertNull(holder.redisClient.getServerByToken(token)); assertEquals( "127.0.0.1", holder.redisClient.getServerByUser(email)); } private String workflowForUser(TestAppClient appClient, String email, String pass, String appName) throws Exception{ appClient.send("register " + email + " " + pass + " " + appName); verify(appClient.responseMock, timeout(1000)).channelRead(any(), eq(new ResponseMessage(1, OK))); appClient.send("login " + email + " " + pass + " Android 1.10.4 " + appName); //we should wait until login finished. Only after that we can send commands verify(appClient.responseMock, timeout(1000)).channelRead(any(), eq(new ResponseMessage(2, OK))); DashBoard dash = new DashBoard(); dash.id = 1; dash.name = "test"; appClient.send("createDash " + dash.toString()); verify(appClient.responseMock, timeout(1000)).channelRead(any(), eq(new ResponseMessage(3, OK))); appClient.send("activate 1"); verify(appClient.responseMock, timeout(1000)).channelRead(any(), eq(new ResponseMessage(4, DEVICE_NOT_IN_NETWORK))); appClient.reset(); appClient.send("getToken 1"); String token = appClient.getBody(); assertNotNull(token); return token; } }