CE-609 Increase javalin test coverage (manageSessions and hotSwap)

This commit is contained in:
2023-08-09 10:31:59 -05:00
parent dbaad85ec7
commit 366639c882
2 changed files with 137 additions and 3 deletions

View File

@ -160,7 +160,7 @@ public class QJavalinImplementation
private static Supplier<QInstance> qInstanceHotSwapSupplier; private static Supplier<QInstance> qInstanceHotSwapSupplier;
private static long lastQInstanceHotSwapMillis; private static long lastQInstanceHotSwapMillis;
private static final long MILLIS_BETWEEN_HOT_SWAPS = 2500; private static long MILLIS_BETWEEN_HOT_SWAPS = 2500;
public static final long SLOW_LOG_THRESHOLD_MS = 1000; public static final long SLOW_LOG_THRESHOLD_MS = 1000;
private static final Integer DEFAULT_COUNT_TIMEOUT_SECONDS = 60; private static final Integer DEFAULT_COUNT_TIMEOUT_SECONDS = 60;
@ -1857,4 +1857,14 @@ public class QJavalinImplementation
return StringUtils.joinWithCommasAndAnd(errors.stream().map(QStatusMessage::getMessage).toList()); return StringUtils.joinWithCommasAndAnd(errors.stream().map(QStatusMessage::getMessage).toList());
} }
/*******************************************************************************
**
*******************************************************************************/
public static void setMillisBetweenHotSwaps(long millisBetweenHotSwaps)
{
MILLIS_BETWEEN_HOT_SWAPS = millisBetweenHotSwaps;
}
} }

View File

@ -29,9 +29,17 @@ import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormat; import com.kingsrook.qqq.backend.core.model.actions.reporting.ReportFormat;
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType; import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType;
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
import com.kingsrook.qqq.backend.core.utils.JsonUtils; import com.kingsrook.qqq.backend.core.utils.JsonUtils;
import com.kingsrook.qqq.backend.core.utils.SleepUtils;
import kong.unirest.HttpResponse; import kong.unirest.HttpResponse;
import kong.unirest.Unirest; import kong.unirest.Unirest;
import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpStatus;
@ -43,6 +51,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
@ -635,7 +644,8 @@ class QJavalinImplementationTest extends QJavalinTestBase
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody()); JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
assertNotNull(jsonObject); assertNotNull(jsonObject);
assertEquals(1, jsonObject.getInt("deletedRecordCount")); assertEquals(1, jsonObject.getInt("deletedRecordCount"));
TestUtils.runTestSql("SELECT id FROM person", (rs -> { TestUtils.runTestSql("SELECT id FROM person", (rs ->
{
int rowsFound = 0; int rowsFound = 0;
while(rs.next()) while(rs.next())
{ {
@ -832,4 +842,118 @@ class QJavalinImplementationTest extends QJavalinTestBase
assertTrue(jsonObject.has("type")); assertTrue(jsonObject.has("type"));
} }
/*******************************************************************************
**
*******************************************************************************/
@Test
void testManageSession()
{
String body = """
{
"accessToken": "abcd",
"doStoreUserSession": true
}
""";
HttpResponse<String> response = Unirest.post(BASE_URL + "/manageSession")
.header("Content-Type", "application/json")
.body(body)
.asString();
assertEquals(200, response.getStatus());
JSONObject jsonObject = JsonUtils.toJSONObject(response.getBody());
assertNotNull(jsonObject);
assertTrue(jsonObject.has("uuid"));
response.getHeaders().get("Set-Cookie").stream().anyMatch(s -> s.contains("sessionUUID"));
}
/*******************************************************************************
**
*******************************************************************************/
@Test
void testHotSwap()
{
Function<String, QInstance> makeNewInstanceWithBackendName = (backendName) ->
{
QInstance newInstance = new QInstance();
newInstance.addBackend(new QBackendMetaData().withName(backendName).withBackendType("mock"));
if(!"invalid".equals(backendName))
{
newInstance.addTable(new QTableMetaData()
.withName("newTable")
.withBackendName(backendName)
.withField(new QFieldMetaData("newField", QFieldType.INTEGER))
.withPrimaryKeyField("newField")
);
}
return (newInstance);
};
QJavalinImplementation.setQInstanceHotSwapSupplier(() -> makeNewInstanceWithBackendName.apply("newBackend"));
/////////////////////////////////////////////////////////////////////////////////
// make sure before a hot-swap, that the instance doesn't have our new backend //
/////////////////////////////////////////////////////////////////////////////////
assertNull(QJavalinImplementation.qInstance.getBackend("newBackend"));
///////////////////////////////////////////////////////
// do a hot-swap, make sure the new backend is there //
///////////////////////////////////////////////////////
QJavalinImplementation.hotSwapQInstance(null);
assertNotNull(QJavalinImplementation.qInstance.getBackend("newBackend"));
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// now change to make a different backend - try to swap again - but the newer backend shouldn't be there, //
// because the millis-between-hot-swaps won't have passed //
////////////////////////////////////////////////////////////////////////////////////////////////////////////
QJavalinImplementation.setQInstanceHotSwapSupplier(() -> makeNewInstanceWithBackendName.apply("newerBackend"));
QJavalinImplementation.hotSwapQInstance(null);
assertNull(QJavalinImplementation.qInstance.getBackend("newerBackend"));
////////////////////////////////////////////////////////////////////////////////////////////
// set the sleep threshold to 1 milli, sleep for 2, and then assert that we do swap again //
////////////////////////////////////////////////////////////////////////////////////////////
QJavalinImplementation.setMillisBetweenHotSwaps(1);
SleepUtils.sleep(2, TimeUnit.MILLISECONDS);
QJavalinImplementation.setQInstanceHotSwapSupplier(() -> makeNewInstanceWithBackendName.apply("newerBackend"));
QJavalinImplementation.hotSwapQInstance(null);
assertNotNull(QJavalinImplementation.qInstance.getBackend("newerBackend"));
////////////////////////////////////////////////////////////
// assert that an invalid instance doesn't get swapped in //
// e.g., "newerBackend" still exists //
////////////////////////////////////////////////////////////
SleepUtils.sleep(2, TimeUnit.MILLISECONDS);
QJavalinImplementation.setQInstanceHotSwapSupplier(() -> makeNewInstanceWithBackendName.apply("invalid"));
QJavalinImplementation.hotSwapQInstance(null);
assertNotNull(QJavalinImplementation.qInstance.getBackend("newerBackend"));
///////////////////////////////////////////////////////
// assert that if the supplier throws, we don't swap //
// e.g., "newerBackend" still exists //
///////////////////////////////////////////////////////
SleepUtils.sleep(2, TimeUnit.MILLISECONDS);
QJavalinImplementation.setQInstanceHotSwapSupplier(() ->
{
throw new RuntimeException("oops");
});
QJavalinImplementation.hotSwapQInstance(null);
assertNotNull(QJavalinImplementation.qInstance.getBackend("newerBackend"));
/////////////////////////////////////////////////////////////
// assert that if the supplier returns null, we don't swap //
// e.g., "newerBackend" still exists //
/////////////////////////////////////////////////////////////
SleepUtils.sleep(2, TimeUnit.MILLISECONDS);
QJavalinImplementation.setQInstanceHotSwapSupplier(() -> null);
QJavalinImplementation.hotSwapQInstance(null);
assertNotNull(QJavalinImplementation.qInstance.getBackend("newerBackend"));
}
} }