package cc.blynk.integration.tcp;
import cc.blynk.integration.IntegrationBase;
import cc.blynk.integration.model.tcp.ClientPair;
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.device.Device;
import cc.blynk.server.core.protocol.model.messages.ResponseMessage;
import cc.blynk.server.core.protocol.model.messages.appllication.CreateDevice;
import cc.blynk.server.hardware.HardwareServer;
import cc.blynk.utils.JsonParser;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import static cc.blynk.server.core.model.widgets.FrequencyWidget.READING_MSG_ID;
import static cc.blynk.server.core.protocol.enums.Command.HARDWARE;
import static cc.blynk.server.core.protocol.enums.Response.ILLEGAL_COMMAND_BODY;
import static cc.blynk.server.core.protocol.enums.Response.OK;
import static cc.blynk.server.core.protocol.model.messages.MessageFactory.produce;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.*;
/**
* The Blynk Project.
* Created by Dmitriy Dumanskiy.
* Created on 2/2/2015.
*
*/
@RunWith(MockitoJUnitRunner.class)
public class ReadingWorkflowTest extends IntegrationBase {
private BaseServer appServer;
private BaseServer hardwareServer;
private ClientPair clientPair;
@Before
public void init() throws Exception {
this.hardwareServer = new HardwareServer(holder).start();
this.appServer = new AppServer(holder).start();
this.clientPair = initAppAndHardPair();
}
@After
public void shutdown() {
this.appServer.close();
this.hardwareServer.close();
this.clientPair.stop();
}
@Test
public void testNoReadingWidgetOnPin() throws Exception {
clientPair.appClient.send("hardware 1 ar 111");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(new ResponseMessage(1, ILLEGAL_COMMAND_BODY)));
}
@Test
public void testReadingCommandNotAcceptedAnymoreFromApp() throws Exception {
clientPair.appClient.send("hardware 1 ar 7");
verify(clientPair.hardwareClient.responseMock, after(500).never()).channelRead(any(), any());
}
@Test
public void testServerSendReadingCommandWithReadingWorkerEnabled() throws Exception {
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(holder.readingWidgetsWorker, 0, 1000, TimeUnit.MILLISECONDS);
verify(clientPair.hardwareClient.responseMock, timeout(1000)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("ar 7"))));
verify(clientPair.hardwareClient.responseMock, timeout(1000)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("ar 30"))));
}
@Test
public void testServerSendReadingCommandCorrectly() throws Exception {
clientPair.appClient.send("createWidget 1\0{\"id\":155, \"frequency\":400, \"width\":1, \"height\":1, \"x\":0, \"y\":0, \"label\":\"Some Text\", \"type\":\"GAUGE\", \"pinType\":\"VIRTUAL\", \"pin\":100}");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(1)));
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(holder.readingWidgetsWorker, 0, 500, TimeUnit.MILLISECONDS);
verify(clientPair.hardwareClient.responseMock, after(600).times(2)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 100"))));
}
@Test
public void testServerDontSendReadingCommandsForNonActiveDash() throws Exception {
clientPair.appClient.send("createWidget 1\0{\"id\":155, \"frequency\":400, \"width\":1, \"height\":1, \"x\":0, \"y\":0, \"label\":\"Some Text\", \"type\":\"GAUGE\", \"pinType\":\"VIRTUAL\", \"pin\":100}");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(1)));
clientPair.appClient.send("deactivate 1");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(2)));
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(holder.readingWidgetsWorker, 0, 500, TimeUnit.MILLISECONDS);
verify(clientPair.hardwareClient.responseMock, after(1000).never()).channelRead(any(), any());
}
@Test
public void testSendReadCommandsForLCD() throws Exception {
clientPair.appClient.send("createWidget 1\0{\"type\":\"LCD\",\"id\":1923810267,\"x\":0,\"y\":6,\"color\":600084223,\"width\":8,\"height\":2,\"tabId\":0,\"" +
"pins\":[" +
"{\"pin\":100,\"pinType\":\"VIRTUAL\",\"pwmMode\":false,\"rangeMappingOn\":false,\"min\":0,\"max\":1023}," +
"{\"pin\":101,\"pinType\":\"VIRTUAL\",\"pwmMode\":false,\"rangeMappingOn\":false,\"min\":0,\"max\":1023}]," +
"\"advancedMode\":false,\"textLight\":false,\"textLightOn\":false,\"frequency\":900}");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(1)));
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(holder.readingWidgetsWorker, 0, 1000, TimeUnit.MILLISECONDS);
verify(clientPair.hardwareClient.responseMock, timeout(500)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 100"))));
verify(clientPair.hardwareClient.responseMock, timeout(500)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 101"))));
clientPair.hardwareClient.reset();
verify(clientPair.hardwareClient.responseMock, timeout(1500)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 100"))));
verify(clientPair.hardwareClient.responseMock, timeout(1500)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 101"))));
}
@Test
public void testSendReadForMultipleDevices() throws Exception {
Device device2 = new Device(2, "My Device", "ESP8266");
clientPair.appClient.send("createDevice 1\0" + device2.toString());
String createdDevice = clientPair.appClient.getBody();
device2 = JsonParser.parseDevice(createdDevice);
assertNotNull(device2);
assertNotNull(device2.token);
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(new CreateDevice(1, device2.toString())));
TestHardClient hardClient2 = new TestHardClient("localhost", tcpHardPort);
hardClient2.start();
hardClient2.send("login " + device2.token);
verify(hardClient2.responseMock, timeout(500)).channelRead(any(), eq(new ResponseMessage(1, OK)));
clientPair.appClient.reset();
clientPair.appClient.send("createWidget 1\0{\"id\":155, \"deviceId\":0, \"frequency\":400, \"width\":1, \"height\":1, \"x\":0, \"y\":0, \"label\":\"Some Text\", \"type\":\"GAUGE\", \"pinType\":\"VIRTUAL\", \"pin\":100}");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(1)));
clientPair.appClient.send("createWidget 1\0{\"id\":156, \"deviceId\":2, \"frequency\":400, \"width\":1, \"height\":1, \"x\":0, \"y\":0, \"label\":\"Some Text\", \"type\":\"GAUGE\", \"pinType\":\"VIRTUAL\", \"pin\":101}");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(2)));
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(holder.readingWidgetsWorker, 0, 500, TimeUnit.MILLISECONDS);
verify(clientPair.hardwareClient.responseMock, timeout(750)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 100"))));
verify(hardClient2.responseMock, timeout(750)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 101"))));
}
@Test
public void testSendReadForDeviceSelector() throws Exception {
Device device2 = new Device(2, "My Device", "ESP8266");
clientPair.appClient.send("createDevice 1\0" + device2.toString());
String createdDevice = clientPair.appClient.getBody();
device2 = JsonParser.parseDevice(createdDevice);
assertNotNull(device2);
assertNotNull(device2.token);
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(new CreateDevice(1, device2.toString())));
TestHardClient hardClient2 = new TestHardClient("localhost", tcpHardPort);
hardClient2.start();
hardClient2.send("login " + device2.token);
verify(hardClient2.responseMock, timeout(500)).channelRead(any(), eq(new ResponseMessage(1, OK)));
clientPair.appClient.reset();
clientPair.appClient.send("createWidget 1\0{\"id\":200000, \"width\":1, \"value\":2, \"height\":1, \"x\":0, \"y\":0, \"label\":\"Some Text\", \"type\":\"DEVICE_SELECTOR\"}");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(1)));
clientPair.appClient.send("createWidget 1\0{\"id\":155, \"deviceId\":200000, \"frequency\":400, \"width\":1, \"height\":1, \"x\":0, \"y\":0, \"label\":\"Some Text\", \"type\":\"GAUGE\", \"pinType\":\"VIRTUAL\", \"pin\":100}");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(2)));
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(holder.readingWidgetsWorker, 0, 500, TimeUnit.MILLISECONDS);
verify(hardClient2.responseMock, timeout(500)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 100"))));
verify(clientPair.hardwareClient.responseMock, after(100).never()).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 100"))));
clientPair.hardwareClient.reset();
hardClient2.reset();
clientPair.appClient.send("hardware 1 vu 200000 0");
verify(clientPair.hardwareClient.responseMock, timeout(500)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 100"))));
verify(hardClient2.responseMock, after(100).never()).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 100"))));
}
@Test
public void testSendReadForMultipleDevices2() throws Exception {
Device device2 = new Device(2, "My Device", "ESP8266");
clientPair.appClient.send("createDevice 1\0" + device2.toString());
String createdDevice = clientPair.appClient.getBody();
device2 = JsonParser.parseDevice(createdDevice);
assertNotNull(device2);
assertNotNull(device2.token);
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(new CreateDevice(1, device2.toString())));
TestHardClient hardClient2 = new TestHardClient("localhost", tcpHardPort);
hardClient2.start();
hardClient2.send("login " + device2.token);
verify(hardClient2.responseMock, timeout(500)).channelRead(any(), eq(new ResponseMessage(1, OK)));
clientPair.appClient.reset();
clientPair.appClient.send("createWidget 1\0{\"id\":155, \"deviceId\":0, \"frequency\":400, \"width\":1, \"height\":1, \"x\":0, \"y\":0, \"label\":\"Some Text\", \"type\":\"GAUGE\", \"pinType\":\"VIRTUAL\", \"pin\":100}");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(1)));
clientPair.appClient.send("createWidget 1\0{\"id\":156, \"deviceId\":0, \"frequency\":400, \"width\":1, \"height\":1, \"x\":0, \"y\":0, \"label\":\"Some Text\", \"type\":\"GAUGE\", \"pinType\":\"VIRTUAL\", \"pin\":101}");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(2)));
clientPair.appClient.send("createWidget 1\0{\"id\":157, \"deviceId\":2, \"frequency\":400, \"width\":1, \"height\":1, \"x\":0, \"y\":0, \"label\":\"Some Text\", \"type\":\"GAUGE\", \"pinType\":\"VIRTUAL\", \"pin\":102}");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(3)));
clientPair.appClient.send("createWidget 1\0{\"id\":158, \"deviceId\":2, \"frequency\":400, \"width\":1, \"height\":1, \"x\":0, \"y\":0, \"label\":\"Some Text\", \"type\":\"GAUGE\", \"pinType\":\"VIRTUAL\", \"pin\":103}");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(4)));
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(holder.readingWidgetsWorker, 0, 500, TimeUnit.MILLISECONDS);
verify(clientPair.hardwareClient.responseMock, timeout(500)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 100"))));
verify(clientPair.hardwareClient.responseMock, timeout(500)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 101"))));
verify(hardClient2.responseMock, timeout(500)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 102"))));
verify(hardClient2.responseMock, timeout(500)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 103"))));
hardClient2.reset();
clientPair.hardwareClient.reset();
verify(clientPair.hardwareClient.responseMock, timeout(500)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 100"))));
verify(clientPair.hardwareClient.responseMock, timeout(500)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 101"))));
verify(hardClient2.responseMock, timeout(500)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 102"))));
verify(hardClient2.responseMock, timeout(500)).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 103"))));
clientPair.appClient.send("deactivate 1");
hardClient2.reset();
clientPair.hardwareClient.reset();
verify(clientPair.hardwareClient.responseMock, after(500).never()).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 100"))));
verify(clientPair.hardwareClient.responseMock, after(500).never()).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 101"))));
verify(hardClient2.responseMock, after(500).never()).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 102"))));
verify(hardClient2.responseMock, after(500).never()).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 103"))));
}
@Test
public void testSendReadOnlyForOnlineApp() throws Exception {
Device device2 = new Device(2, "My Device", "ESP8266");
clientPair.appClient.send("createDevice 1\0" + device2.toString());
String createdDevice = clientPair.appClient.getBody();
device2 = JsonParser.parseDevice(createdDevice);
assertNotNull(device2);
assertNotNull(device2.token);
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(new CreateDevice(1, device2.toString())));
TestHardClient hardClient2 = new TestHardClient("localhost", tcpHardPort);
hardClient2.start();
hardClient2.send("login " + device2.token);
verify(hardClient2.responseMock, timeout(500)).channelRead(any(), eq(new ResponseMessage(1, OK)));
clientPair.appClient.reset();
clientPair.appClient.send("createWidget 1\0{\"id\":155, \"deviceId\":0, \"frequency\":400, \"width\":1, \"height\":1, \"x\":0, \"y\":0, \"label\":\"Some Text\", \"type\":\"GAUGE\", \"pinType\":\"VIRTUAL\", \"pin\":100}");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(1)));
clientPair.appClient.send("createWidget 1\0{\"id\":156, \"deviceId\":2, \"frequency\":400, \"width\":1, \"height\":1, \"x\":0, \"y\":0, \"label\":\"Some Text\", \"type\":\"GAUGE\", \"pinType\":\"VIRTUAL\", \"pin\":101}");
verify(clientPair.appClient.responseMock, timeout(500)).channelRead(any(), eq(ok(2)));
clientPair.appClient.stop().await();
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(holder.readingWidgetsWorker, 0, 500, TimeUnit.MILLISECONDS);
verify(clientPair.hardwareClient.responseMock, after(500).never()).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 100"))));
verify(hardClient2.responseMock, after(500).never()).channelRead(any(), eq(produce(READING_MSG_ID, HARDWARE, b("vr 101"))));
}
}