Skip to content

chore(unit-test): Add missing unit tests in modules with low coverage #1264

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

Merged
merged 15 commits into from
Jul 10, 2023
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
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@
<version>3.1.2</version>
<configuration>
<argLine>
@{argLine}
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.base/java.lang=ALL-UNNAMED
</argLine>
Expand Down
5 changes: 5 additions & 0 deletions powertools-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,9 @@ public class LambdaConstants {
public static final String AWS_REGION_ENV = "AWS_REGION";
public static final String AWS_LAMBDA_INITIALIZATION_TYPE = "AWS_LAMBDA_INITIALIZATION_TYPE";
public static final String ON_DEMAND = "on-demand";
public static final String X_AMZN_TRACE_ID = "_X_AMZN_TRACE_ID";
public static final String AWS_SAM_LOCAL = "AWS_SAM_LOCAL";
public static final String ROOT_EQUALS = "Root=";
public static final String POWERTOOLS_SERVICE_NAME = "POWERTOOLS_SERVICE_NAME";
public static final String SERVICE_UNDEFINED = "service_undefined";
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,21 @@
import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getenv;

public final class LambdaHandlerProcessor {

// SERVICE_NAME cannot be final for testing purposes
private static String SERVICE_NAME = null != System.getenv("POWERTOOLS_SERVICE_NAME")
? System.getenv("POWERTOOLS_SERVICE_NAME") : "service_undefined";
private static String SERVICE_NAME = calculateServiceName();

private static Boolean IS_COLD_START = null;

private LambdaHandlerProcessor() {
// Hide default constructor
}

private static String calculateServiceName() {
return null != getenv(LambdaConstants.POWERTOOLS_SERVICE_NAME)
? getenv(LambdaConstants.POWERTOOLS_SERVICE_NAME) : LambdaConstants.SERVICE_UNDEFINED;
}

public static boolean isHandlerMethod(final ProceedingJoinPoint pjp) {
return placedOnRequestHandler(pjp) || placedOnStreamHandler(pjp);
}
Expand All @@ -56,23 +62,24 @@ public static boolean placedOnStreamHandler(final ProceedingJoinPoint pjp) {

public static Context extractContext(final ProceedingJoinPoint pjp) {

if (isHandlerMethod(pjp)) {
if (placedOnRequestHandler(pjp)) {
return (Context) pjp.getArgs()[1];
}

if (placedOnStreamHandler(pjp)) {
return (Context) pjp.getArgs()[2];
}
if (placedOnRequestHandler(pjp)) {
return (Context) pjp.getArgs()[1];
} else if (placedOnStreamHandler(pjp)) {
return (Context) pjp.getArgs()[2];
} else {
return null;
}

return null;
}

public static String serviceName() {
return SERVICE_NAME;
}

// Method used for testing purposes
protected static void resetServiceName() {
SERVICE_NAME = calculateServiceName();
}

public static boolean isColdStart() {
return IS_COLD_START == null;
}
Expand All @@ -82,13 +89,13 @@ public static void coldStartDone() {
}

public static boolean isSamLocal() {
return "true".equals(System.getenv("AWS_SAM_LOCAL"));
return "true".equals(getenv(LambdaConstants.AWS_SAM_LOCAL));
}

public static Optional<String> getXrayTraceId() {
final String X_AMZN_TRACE_ID = getenv("_X_AMZN_TRACE_ID");
if(X_AMZN_TRACE_ID != null) {
return of(X_AMZN_TRACE_ID.split(";")[0].replace("Root=", ""));
final String X_AMZN_TRACE_ID = getenv(LambdaConstants.X_AMZN_TRACE_ID);
if (X_AMZN_TRACE_ID != null) {
return of(X_AMZN_TRACE_ID.split(";")[0].replace(LambdaConstants.ROOT_EQUALS, ""));
}
return empty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,60 +6,231 @@
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;
import static software.amazon.lambda.powertools.core.internal.SystemWrapper.getenv;

class LambdaHandlerProcessorTest {

private Signature signature = mock(Signature.class);
private ProceedingJoinPoint pjpMock = mock(ProceedingJoinPoint.class);

@Test
void isHandlerMethod_shouldRecognizeRequestHandler() {
ProceedingJoinPoint pjpMock = mockRequestHandlerPjp();
Object[] args = {new Object(), mock(Context.class)};
ProceedingJoinPoint pjpMock = mockRequestHandlerPjp(RequestHandler.class, args);

assertThat(LambdaHandlerProcessor.isHandlerMethod(pjpMock)).isTrue();
}

@Test
void isHandlerMethod_shouldRecognizeRequestStreamHandler() {
ProceedingJoinPoint pjpMock = mockRequestStreamHandlerPjp();
Object[] args = {mock(InputStream.class), mock(OutputStream.class), mock(Context.class)};
ProceedingJoinPoint pjpMock = mockRequestHandlerPjp(RequestStreamHandler.class, args);

assertThat(LambdaHandlerProcessor.isHandlerMethod(pjpMock)).isTrue();
}

@Test
void isHandlerMethod_shouldReturnFalse() {
ProceedingJoinPoint pjpMock = mockRequestHandlerPjp(Object.class, new Object[]{});

boolean isHandlerMethod = LambdaHandlerProcessor.isHandlerMethod(pjpMock);

assertThat(isHandlerMethod).isFalse();
}

@Test
void placedOnRequestHandler_shouldRecognizeRequestHandler() {
ProceedingJoinPoint pjpMock = mockRequestHandlerPjp();
Object[] args = {new Object(), mock(Context.class)};
ProceedingJoinPoint pjpMock = mockRequestHandlerPjp(RequestHandler.class, args);

assertThat(LambdaHandlerProcessor.placedOnRequestHandler(pjpMock)).isTrue();
}

@Test
void placedOnStreamHandler_shouldRecognizeRequestStreamHandler() {
ProceedingJoinPoint pjpMock = mockRequestStreamHandlerPjp();
Object[] args = {mock(InputStream.class), mock(OutputStream.class), mock(Context.class)};
ProceedingJoinPoint pjpMock = mockRequestHandlerPjp(RequestStreamHandler.class, args);

assertThat(LambdaHandlerProcessor.placedOnStreamHandler(pjpMock)).isTrue();
}

private static ProceedingJoinPoint mockRequestHandlerPjp() {
Signature signature = mock(Signature.class);
when(signature.getDeclaringType()).thenReturn(RequestHandler.class);
ProceedingJoinPoint pjpMock = mock(ProceedingJoinPoint.class);
@Test
void placedOnRequestHandler_shouldInvalidateOnWrongNoOfArgs() {
Object[] args = {new Object()};
ProceedingJoinPoint pjpMock = mockRequestHandlerPjp(RequestHandler.class, args);

boolean isPlacedOnRequestHandler = LambdaHandlerProcessor.placedOnRequestHandler(pjpMock);

assertThat(isPlacedOnRequestHandler).isFalse();
}

@Test
void placedOnRequestHandler_shouldInvalidateOnWrongTypeOfArgs() {
Object[] args = {new Object(), new Object()};
ProceedingJoinPoint pjpMock = mockRequestHandlerPjp(RequestHandler.class, args);

boolean isPlacedOnRequestHandler = LambdaHandlerProcessor.placedOnRequestHandler(pjpMock);

assertThat(isPlacedOnRequestHandler).isFalse();
}

@Test
void placedOnStreamHandler_shouldInvalidateOnWrongNoOfArgs() {
Object[] args = {new Object()};
ProceedingJoinPoint pjpMock = mockRequestHandlerPjp(RequestStreamHandler.class, args);

boolean isPlacedOnStreamHandler = LambdaHandlerProcessor.placedOnStreamHandler(pjpMock);

assertThat(isPlacedOnStreamHandler).isFalse();
}

@Test
void placedOnStreamHandler_shouldInvalidateOnWrongTypeOfArgs() {
Object[] args = {new Object(), new Object(), new Object()};
ProceedingJoinPoint pjpMock = mockRequestHandlerPjp(RequestStreamHandler.class, args);

boolean isPlacedOnStreamHandler = LambdaHandlerProcessor.placedOnStreamHandler(pjpMock);

assertThat(isPlacedOnStreamHandler).isFalse();
}

@Test
void placedOnStreamHandler_shouldInvalidateOnTypeOfArgs_invalidOutputStreamArg() {
Object[] args = {mock(InputStream.class), new Object(), mock(Context.class)};
ProceedingJoinPoint pjpMock = mockRequestHandlerPjp(RequestStreamHandler.class, args);

boolean isPlacedOnStreamHandler = LambdaHandlerProcessor.placedOnStreamHandler(pjpMock);

assertThat(isPlacedOnStreamHandler).isFalse();
}

@Test
void placedOnStreamHandler_shouldInvalidateOnTypeOfArgs_invalidContextArg() {
Object[] args = {mock(InputStream.class), mock(OutputStream.class), new Object()};
ProceedingJoinPoint pjpMock = mockRequestHandlerPjp(RequestStreamHandler.class, args);

boolean isPlacedOnStreamHandler = LambdaHandlerProcessor.placedOnStreamHandler(pjpMock);

assertThat(isPlacedOnStreamHandler).isFalse();
}

@Test
void getXrayTraceId_present() {
String traceID = "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\"";
try (MockedStatic<SystemWrapper> mockedSystemWrapper = mockStatic(SystemWrapper.class)) {
mockedSystemWrapper.when(() -> getenv(LambdaConstants.X_AMZN_TRACE_ID)).thenReturn(traceID);

Optional xRayTraceId = LambdaHandlerProcessor.getXrayTraceId();

assertThat(xRayTraceId.isPresent()).isTrue();
assertThat(traceID.split(";")[0].replace(LambdaConstants.ROOT_EQUALS, "")).isEqualTo(xRayTraceId.get());
}
}

@Test
void getXrayTraceId_notPresent() {
try (MockedStatic<SystemWrapper> mockedSystemWrapper = mockStatic(SystemWrapper.class)) {
mockedSystemWrapper.when(() -> getenv(LambdaConstants.X_AMZN_TRACE_ID)).thenReturn(null);

boolean isXRayTraceIdPresent = LambdaHandlerProcessor.getXrayTraceId().isPresent();

assertThat(isXRayTraceIdPresent).isFalse();
}
}

@Test
void extractContext_fromRequestHandler() {
Object[] args = {new Object(), mock(Context.class)};
when(pjpMock.getArgs()).thenReturn(args);
when(pjpMock.getSignature()).thenReturn(signature);
return pjpMock;
ProceedingJoinPoint pjpMock = mockRequestHandlerPjp(RequestHandler.class, args);

Context context = LambdaHandlerProcessor.extractContext(pjpMock);

assertThat(context).isNotNull();
}

private static ProceedingJoinPoint mockRequestStreamHandlerPjp() {
Signature signature = mock(Signature.class);
when(signature.getDeclaringType()).thenReturn(RequestStreamHandler.class);
ProceedingJoinPoint pjpMock = mock(ProceedingJoinPoint.class);
@Test
void extractContext_fromStreamRequestHandler() {
Object[] args = {mock(InputStream.class), mock(OutputStream.class), mock(Context.class)};
when(pjpMock.getArgs()).thenReturn(args);
ProceedingJoinPoint pjpMock = mockRequestHandlerPjp(RequestStreamHandler.class, args);

Context context = LambdaHandlerProcessor.extractContext(pjpMock);

assertNotNull(context);
}

@Test
void extractContext_notKnownHandler() {
Object[] args = {new Object()};
ProceedingJoinPoint pjpMock = mockRequestHandlerPjp(Object.class, args);

Context context = LambdaHandlerProcessor.extractContext(pjpMock);

assertThat(context).isNull();
}

@Test
void isColdStart() {
boolean isColdStart = LambdaHandlerProcessor.isColdStart();

assertThat(isColdStart).isTrue();
}

@Test
void isColdStart_coldStartDone() {
LambdaHandlerProcessor.coldStartDone();

boolean isColdStart = LambdaHandlerProcessor.isColdStart();

assertThat(isColdStart).isFalse();
}

@Test
void isSamLocal() {
try (MockedStatic<SystemWrapper> mockedSystemWrapper = mockStatic(SystemWrapper.class)) {
mockedSystemWrapper.when(() -> getenv(LambdaConstants.AWS_SAM_LOCAL)).thenReturn("true");

boolean isSamLocal = LambdaHandlerProcessor.isSamLocal();

assertThat(isSamLocal).isTrue();
}
}

@Test
void serviceName() {
try (MockedStatic<SystemWrapper> mockedSystemWrapper = mockStatic(SystemWrapper.class)) {
String expectedServiceName = "MyService";
mockedSystemWrapper.when(() -> getenv(LambdaConstants.POWERTOOLS_SERVICE_NAME)).thenReturn(expectedServiceName);

String actualServiceName = LambdaHandlerProcessor.serviceName();

assertThat(actualServiceName).isEqualTo(expectedServiceName);
}
}

@Test
void serviceName_Undefined() {
LambdaHandlerProcessor.resetServiceName();
try (MockedStatic<SystemWrapper> mockedSystemWrapper = mockStatic(SystemWrapper.class)) {
mockedSystemWrapper.when(() -> getenv(LambdaConstants.POWERTOOLS_SERVICE_NAME)).thenReturn(null);

assertThat(LambdaHandlerProcessor.serviceName()).isEqualTo(LambdaConstants.SERVICE_UNDEFINED);
}
}

private ProceedingJoinPoint mockRequestHandlerPjp(Class handlerClass, Object[] handlerArgs) {
when(signature.getDeclaringType()).thenReturn(handlerClass);
when(pjpMock.getArgs()).thenReturn(handlerArgs);
when(pjpMock.getSignature()).thenReturn(signature);
return pjpMock;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
*/
package software.amazon.lambda.powertools.logging;

import java.util.Map;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.logging.log4j.ThreadContext;

import java.util.Map;

import static java.util.Arrays.asList;

/**
Expand Down
Loading