Skip to content

Commit

Permalink
Merge pull request #2644 from guusdk/tests-improve-speed
Browse files Browse the repository at this point in the history
Reduce runtime of long-running S2S unit tests (and fix OF-2942 as a byproduct)
  • Loading branch information
akrherz authored Jan 4, 2025
2 parents cdece9b + a340aa9 commit 92cd5c5
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 112 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023-2024 Ignite Realtime Foundation. All rights reserved.
* Copyright (C) 2023-2025 Ignite Realtime Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -72,6 +72,10 @@ private static boolean remoteFeaturesContainsStartTLS(Element doc) {
return doc.element("starttls") != null;
}

private static boolean remoteFeaturesRequiresStartTLS(Element doc) {
return remoteFeaturesContainsStartTLS(doc) && doc.element("starttls").element("required") != null;
}

private static boolean isSaslExternalOfferred(Element doc) {
boolean saslEXTERNALoffered = false;
if (doc.element("mechanisms") != null) {
Expand Down Expand Up @@ -194,6 +198,10 @@ boolean processUnknowPacket(Element doc) {
LOG.debug("I MUST use TLS but I have no StartTLS in features.");
abandonSessionInitiation();
return false;
} else if (cannotUseTls() && remoteFeaturesRequiresStartTLS(doc)) {
LOG.debug("I CANNOT use TLS but remote server requires the STARTTLS feature.");
abandonSessionInitiation();
return false;
}

// Authentication ------
Expand Down Expand Up @@ -227,6 +235,7 @@ boolean processUnknowPacket(Element doc) {
return true;
} else {
LOG.debug("No authentication mechanism available.");
abandonSessionInitiation();
return false;
}
}
Expand Down Expand Up @@ -332,6 +341,10 @@ private boolean mustUseTls() {
return connection.getConfiguration().getTlsPolicy() == Connection.TLSPolicy.required;
}

private boolean cannotUseTls() {
return connection.getConfiguration().getTlsPolicy() == Connection.TLSPolicy.disabled;
}

@Override
void startTLS() throws Exception {
connection.startTLS(true, false);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Ignite Realtime Foundation. All rights reserved.
* Copyright (C) 2023-2025 Ignite Realtime Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -38,6 +38,12 @@

public class AbstractRemoteServerDummy
{
/**
* When switched to 'true', most XMPP interaction will be printed to standard-out.
*/
public static final boolean doLog = false;
public static long lastLog = System.currentTimeMillis();

public static final String XMPP_DOMAIN = "remote-dummy.example.org";

private final static KeystoreTestUtils.ResultHolder SELF_SIGNED_CERTIFICATE;
Expand All @@ -64,6 +70,19 @@ public class AbstractRemoteServerDummy
}
}

/**
* Logs a message, but only if logging is enabled (which is controlled by the {@link #doLog} field).
*
* @param message The message to be logged.
*/
public static void log(final String message) {
if (doLog) {
long delta = System.currentTimeMillis() - lastLog;
System.out.println(delta + "ms: " + message);
lastLog = System.currentTimeMillis();
}
}

/**
* Updates the TLS encryption policy that's observed by this server.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Ignite Realtime Foundation. All rights reserved.
* Copyright (C) 2023-2025 Ignite Realtime Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -193,19 +193,20 @@ public void incomingTest(final ServerSettings localServerSettings, final ServerS
throws Exception
{
final ExpectedOutcome expected = ExpectedOutcome.generateExpectedOutcome(remoteServerSettings, localServerSettings);
if (RemoteInitiatingServerDummy.doLog) System.out.println("Executing test:\n - Local Server, Recipient, System Under Test Settings: " + localServerSettings + "\n - Remote Server, Initiator, dummy/mock server Settings: " + remoteServerSettings + "\nExpected outcome: " + expected.getConnectionState());
AbstractRemoteServerDummy.log("Executing test:\n - Local Server (Recipient, System Under Test) Settings: " + localServerSettings + "\n - Remote Server (Initiator, dummy/mock server) Settings: " + remoteServerSettings + "\nExpected outcome: " + expected.getConnectionState());

ConnectionListener connectionListener = null;
try {
// Setup test fixture.
AbstractRemoteServerDummy.log("Setup fixture: (start setting up fixture)");

// Remote server TLS policy.
// Setup test fixture.
AbstractRemoteServerDummy.log("Setup fixture: remote server TLS policy.");
remoteInitiatingServerDummy.setEncryptionPolicy(remoteServerSettings.encryptionPolicy);

// Remote server dialback
AbstractRemoteServerDummy.log("Setup fixture: remote server dialback.");
remoteInitiatingServerDummy.setDisableDialback(!remoteServerSettings.dialbackSupported);

// Remote server certificate state
AbstractRemoteServerDummy.log("Setup fixture: remote server certificate state.");
switch (remoteServerSettings.certificateState) {
case INVALID:
remoteInitiatingServerDummy.setUseExpiredEndEntityCertificate(true);
Expand All @@ -224,13 +225,13 @@ public void incomingTest(final ServerSettings localServerSettings, final ServerS
throw new IllegalStateException("Unsupported remote certificate state");
}

// Local server TLS policy.
AbstractRemoteServerDummy.log("Setup fixture: local server TLS policy.");
JiveGlobals.setProperty(ConnectionSettings.Server.TLS_POLICY, localServerSettings.encryptionPolicy.toString());

// Local server dialback.
AbstractRemoteServerDummy.log("Setup fixture: local server dialback.");
JiveGlobals.setProperty(ConnectionSettings.Server.DIALBACK_ENABLED, localServerSettings.dialbackSupported ? "true" : "false");

// Local server certificate state
AbstractRemoteServerDummy.log("Setup fixture: local server certificate state.");
switch (localServerSettings.certificateState) {
case MISSING:
// Do not install domain certificate.
Expand All @@ -245,12 +246,15 @@ public void incomingTest(final ServerSettings localServerSettings, final ServerS
break;
}

AbstractRemoteServerDummy.log("Setup fixture: remote server init");
remoteInitiatingServerDummy.init();
if (remoteInitiatingServerDummy.getDialbackAuthoritativeServerPort() > 0) {
DNSUtil.setDnsOverride(Map.of(RemoteInitiatingServerDummy.XMPP_DOMAIN, new SrvRecord("localhost", remoteInitiatingServerDummy.getDialbackAuthoritativeServerPort(), false)));
}
AbstractRemoteServerDummy.log("Setup fixture: (done with setting up fixture)");

// execute system under test.
AbstractRemoteServerDummy.log("Execute system under test: (start with execution)");
JiveGlobals.setProperty(ConnectionSettings.Server.OLD_SSLPORT, String.valueOf(findFreeLocalPort()));
connectionListener = new ConnectionListener(ConnectionType.SOCKET_S2S,
ConnectionSettings.Server.OLD_SSLPORT,
Expand All @@ -264,18 +268,22 @@ public void incomingTest(final ServerSettings localServerSettings, final ServerS
identityStore.getConfiguration(),
trustStore.getConfiguration(),
ConnectionSettings.Server.COMPRESSION_SETTINGS);
AbstractRemoteServerDummy.log("Execute system under test: starting connection listener");
connectionListener.start();

AbstractRemoteServerDummy.log("Execute system under test: mocking connection manager");
final ConnectionManager connectionManager = Fixtures.mockConnectionManager();
doReturn(Set.of(connectionListener)).when(connectionManager).getListeners(any(ConnectionType.class));
doReturn(connectionListener).when(connectionManager).getListener(any(ConnectionType.class), anyBoolean());
doReturn(connectionManager).when(XMPPServer.getInstance()).getConnectionManager();

// now, make the remote server connect.
AbstractRemoteServerDummy.log("Execute system under test: make the remote server connect.");
remoteInitiatingServerDummy.connect(connectionListener.getPort());
AbstractRemoteServerDummy.log("Execute system under test: start connecting, block until done.");
remoteInitiatingServerDummy.blockUntilDone(1, TimeUnit.MINUTES);
AbstractRemoteServerDummy.log("Execute system under test: done connecting.");

// get the incoming server session object.
AbstractRemoteServerDummy.log("Execute system under test: get the incoming server session object.");
final LocalIncomingServerSession result;
if (remoteInitiatingServerDummy.getReceivedStreamIDs().isEmpty()) {
result = null;
Expand All @@ -284,9 +292,11 @@ public void incomingTest(final ServerSettings localServerSettings, final ServerS
final StreamID lastReceivedID = remoteInitiatingServerDummy.getReceivedStreamIDs().get(remoteInitiatingServerDummy.getReceivedStreamIDs().size()-1);
result = XMPPServer.getInstance().getSessionManager().getIncomingServerSession( lastReceivedID );
}
AbstractRemoteServerDummy.log("Execute system under test: (done with execution)");

// Verify results
if (RemoteInitiatingServerDummy.doLog) System.out.println("Expect: " + expected.getConnectionState() + ", Result: " + result);
AbstractRemoteServerDummy.log("Verify results (start)");
AbstractRemoteServerDummy.log("Expect: " + expected.getConnectionState() + ", Result: " + result);
switch (expected.getConnectionState())
{
case NO_CONNECTION:
Expand Down Expand Up @@ -332,13 +342,16 @@ public void incomingTest(final ServerSettings localServerSettings, final ServerS
assertEquals(2, remoteInitiatingServerDummy.getReceivedStreamFromValues().size());
break;
}
if (RemoteInitiatingServerDummy.doLog) System.out.println("Expectation met.");
AbstractRemoteServerDummy.log("Expectation met.");
AbstractRemoteServerDummy.log("Verify results (done)");
} finally {
// Teardown test fixture.
AbstractRemoteServerDummy.log("Teardown test fixture (start)");
trustStore.delete("unit-test");
if (connectionListener != null) {
connectionListener.stop();
}
AbstractRemoteServerDummy.log("Teardown test fixture (done)");
}
}

Expand Down Expand Up @@ -376,7 +389,7 @@ private static Iterable<Arguments> arguments() {
// failed test case.
int i = 1;
for (Arguments arguments : result) {
System.out.println("Test [" + i++ + "]: " + arguments.get()[0] + ", " + arguments.get()[1]);
AbstractRemoteServerDummy.log("Test [" + i++ + "]: " + arguments.get()[0] + ", " + arguments.get()[1]);
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Ignite Realtime Foundation. All rights reserved.
* Copyright (C) 2023-2025 Ignite Realtime Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -232,12 +232,13 @@ public void outgoingTest(final ServerSettings localServerSettings, final ServerS
throws Exception
{
final ExpectedOutcome expected = ExpectedOutcome.generateExpectedOutcome(localServerSettings, remoteServerSettings);
if (RemoteReceivingServerDummy.doLog) System.out.println("Executing test:\n - Local Server (Openfire, System under test) Settings: " + localServerSettings + "\n - Remote Server (dummy/mock server) Settings: " + remoteServerSettings + "\nExpected outcome: " + expected.getConnectionState());
AbstractRemoteServerDummy.log("Executing test:\n - Local Server (Initiator, Openfire, System under test) Settings: " + localServerSettings + "\n - Remote Server (Recipient, dummy/mock server) Settings: " + remoteServerSettings + "\nExpected outcome: " + expected.getConnectionState());

JiveGlobals.setProperty("xmpp.domain", Fixtures.XMPP_DOMAIN);
JiveGlobals.setProperty("xmpp.server.session.initialise-timeout", Long.toString(1));

try {
AbstractRemoteServerDummy.log("Setup fixture: (start setting up fixture)");
// Setup test fixture.

// Remote server TLS policy.
Expand Down Expand Up @@ -288,12 +289,16 @@ public void outgoingTest(final ServerSettings localServerSettings, final ServerS

final DomainPair domainPair = new DomainPair(Fixtures.XMPP_DOMAIN, RemoteReceivingServerDummy.XMPP_DOMAIN);
final int port = remoteReceivingServerDummy.getPort();
AbstractRemoteServerDummy.log("Setup fixture: (done with setting up fixture)");

// Execute system under test.
AbstractRemoteServerDummy.log("Execute system under test: (start with execution)");
final LocalOutgoingServerSession result = LocalOutgoingServerSession.createOutgoingSession(domainPair, port);
AbstractRemoteServerDummy.log("Execute system under test: (done with execution)");

// Verify results
if (RemoteReceivingServerDummy.doLog) System.out.println("Expect: " + expected.getConnectionState() + ", Result: " + result);
AbstractRemoteServerDummy.log("Verify results (start)");
AbstractRemoteServerDummy.log("Expect: " + expected.getConnectionState() + ", Result: " + result);
switch (expected.getConnectionState())
{
case NO_CONNECTION:
Expand Down Expand Up @@ -323,9 +328,12 @@ public void outgoingTest(final ServerSettings localServerSettings, final ServerS
assertEquals( "TLSv1.3", result.getConnection().getTLSProtocolName().get());
break;
}
AbstractRemoteServerDummy.log("Verify results (done)");
} finally {
// Teardown test fixture.
AbstractRemoteServerDummy.log("Teardown test fixture (start)");
trustStore.delete("unit-test");
AbstractRemoteServerDummy.log("Teardown test fixture (start)");
}
}

Expand Down Expand Up @@ -363,7 +371,7 @@ private static Iterable<Arguments> arguments() {
// failed test case.
int i = 1;
for (Arguments arguments : result) {
System.out.println("Test [" + i++ + "]: " + arguments.get()[0] + ", " + arguments.get()[1]);
AbstractRemoteServerDummy.log("Test [" + i++ + "]: " + arguments.get()[0] + ", " + arguments.get()[1]);
}
return result;
}
Expand Down
Loading

0 comments on commit 92cd5c5

Please sign in to comment.