Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce runtime of long-running S2S unit tests (and fix OF-2942 as a byproduct) #2644

Merged
merged 7 commits into from
Jan 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading