rusefi/java_console/ui/src/test/java/com/rusefi/FullServerTest.java

169 lines
7.7 KiB
Java

package com.rusefi;
import com.devexperts.logging.Logging;
import com.opensr5.ConfigurationImage;
import com.opensr5.ini.field.ScalarIniField;
import com.rusefi.binaryprotocol.BinaryProtocol;
import com.rusefi.config.generated.Fields;
import com.rusefi.core.rusEFIVersion;
import com.rusefi.io.ConnectionStateListener;
import com.rusefi.io.LinkManager;
import com.rusefi.io.tcp.BinaryProtocolServer;
import com.rusefi.io.tcp.TcpConnector;
import com.rusefi.io.tcp.TcpIoStream;
import com.rusefi.proxy.NetworkConnector;
import com.rusefi.proxy.NetworkConnectorContext;
import com.rusefi.proxy.client.LocalApplicationProxy;
import com.rusefi.proxy.client.LocalApplicationProxyContext;
import com.rusefi.proxy.client.UpdateType;
import com.rusefi.server.*;
import com.rusefi.tools.online.HttpUtil;
import org.apache.http.HttpResponse;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import static com.devexperts.logging.Logging.getLogging;
import static com.rusefi.TestHelper.*;
import static com.rusefi.Timeouts.SECOND;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class FullServerTest {
private static final Logging log = getLogging(FullServerTest.class);
@Before
public void setup() throws MalformedURLException {
BackendTestHelper.commonServerTest();
}
@Test
public void testRelayWorkflow() throws InterruptedException, IOException {
ScalarIniField iniField = TestHelper.createIniField(Fields.CYLINDERSCOUNT);
int value = 241;
int userId = 7;
LocalApplicationProxyContext localApplicationProxyContext = new LocalApplicationProxyContext() {
@Override
public String executeGet(String url) throws IOException {
return HttpUtil.executeGet(url);
}
@Override
public int serverPortForRemoteApplications() {
return 7003;
}
@Override
public int authenticatorPort() {
return 7004;
}
};
CountDownLatch controllerRegistered = new CountDownLatch(1);
CountDownLatch applicationClosed = new CountDownLatch(1);
UserDetailsResolver userDetailsResolver = authToken -> new UserDetails(authToken.substring(0, 5), userId);
int httpPort = 8103;
int applicationTimeout = 7 * SECOND;
try (Backend backend = new Backend(userDetailsResolver, httpPort, applicationTimeout) {
@Override
public void register(ControllerConnectionState controllerConnectionState) {
super.register(controllerConnectionState);
controllerRegistered.countDown();
}
@Override
protected void close(ApplicationConnectionState applicationConnectionState) {
super.close(applicationConnectionState);
applicationClosed.countDown();
}
}; LinkManager clientManager = new LinkManager().setNeedPullData(false);
NetworkConnector networkConnector = new NetworkConnector()) {
int serverPortForControllers = 7001;
// first start backend server
BackendTestHelper.runControllerConnectorBlocking(backend, serverPortForControllers);
BackendTestHelper.runApplicationConnectorBlocking(backend, localApplicationProxyContext.serverPortForRemoteApplications());
// create virtual controller to which "rusEFI network connector" connects to
int controllerPort = 7002;
ConfigurationImage controllerImage = prepareImage(value, createIniField(Fields.CYLINDERSCOUNT));
TestHelper.createVirtualController(controllerPort, controllerImage, new BinaryProtocolServer.Context());
CountDownLatch softwareUpdateRequest = new CountDownLatch(1);
NetworkConnectorContext networkConnectorContext = new NetworkConnectorContext() {
@Override
public int serverPortForControllers() {
return serverPortForControllers;
}
@Override
public void onConnectorSoftwareUpdateToLatestRequest() {
softwareUpdateRequest.countDown();
}
};
// start "rusEFI network connector" to connect controller with backend since in real life controller has only local serial port it does not have network
NetworkConnector.NetworkConnectorResult networkConnectorResult = networkConnector.start(NetworkConnector.Implementation.Unknown,
TestHelper.TEST_TOKEN_1, TcpConnector.LOCALHOST + ":" + controllerPort, networkConnectorContext, NetworkConnector.ReconnectListener.VOID);
ControllerInfo controllerInfo = networkConnectorResult.getControllerInfo();
TestHelper.assertLatch("controllerRegistered. todo: this test should not depend on internet connection and having real .ini on rusEFI online", controllerRegistered);
SessionDetails authenticatorSessionDetails = new SessionDetails(NetworkConnector.Implementation.Unknown, controllerInfo, TEST_TOKEN_3, networkConnectorResult.getOneTimeToken(), rusEFIVersion.CONSOLE_VERSION);
ApplicationRequest applicationRequest = new ApplicationRequest(authenticatorSessionDetails, userDetailsResolver.apply(TestHelper.TEST_TOKEN_1));
HttpResponse response = LocalApplicationProxy.requestSoftwareUpdate(httpPort, applicationRequest, UpdateType.CONTROLLER);
log.info("requestSoftwareUpdate response: " + response.toString());
assertLatch("update requested", softwareUpdateRequest);
// start authenticator
LocalApplicationProxy.startAndRun(localApplicationProxyContext, applicationRequest, httpPort,
TcpIoStream.DisconnectListener.VOID,
LocalApplicationProxy.ConnectionListener.VOID);
CountDownLatch connectionEstablishedCountDownLatch = new CountDownLatch(1);
// connect to proxy and read virtual controller through it
clientManager.startAndConnect(TcpConnector.LOCALHOST + ":" + localApplicationProxyContext.authenticatorPort(), new ConnectionStateListener() {
@Override
public void onConnectionEstablished() {
connectionEstablishedCountDownLatch.countDown();
}
@Override
public void onConnectionFailed(String s) {
System.out.println("Failed");
}
});
assertLatch("Proxied ECU Connection established", connectionEstablishedCountDownLatch);
BinaryProtocol clientStreamState = clientManager.getCurrentStreamState();
Objects.requireNonNull(clientStreamState, "clientStreamState");
ConfigurationImage clientImage = clientStreamState.getControllerConfiguration();
String clientValue = iniField.getValue(clientImage);
assertEquals(Double.toString(value), clientValue);
assertEquals(1, backend.getApplications().size());
assertEquals(1, applicationClosed.getCount());
// now let's test that application connector would be terminated by server due to inactivity
log.info("**************************************");
log.info("Sleeping twice the application timeout");
log.info("**************************************");
assertLatch("applicationClosed", applicationClosed, 3 * applicationTimeout);
assertEquals("applications size", 0, backend.getApplications().size());
}
}
}