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

50 Adding integration tests #167

Merged
merged 32 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b2d4106
Add HazeIT.java
kappsegla Feb 12, 2023
aeed8ab
Update findFreePort method
kappsegla Feb 13, 2023
7afd6e2
Remove IT testcode not working with current server impl.
kappsegla Feb 18, 2023
e7a32ac
Add Integration test for list
kappsegla Feb 21, 2023
91ae640
Merge branch '156-databases-are-split-so-many-commands-dont-work-with…
kappsegla Feb 21, 2023
70402c3
Change HazeIT to use testcontainers
kappsegla Feb 22, 2023
fd999eb
Create HazeExtension for running integration tests
kappsegla Feb 24, 2023
03f94b0
Add dependency for slf4j-nop
kappsegla Feb 24, 2023
fee0107
Update Dockerfile to download dependencies from internet
kappsegla Feb 25, 2023
fb7a558
Merge remote-tracking branch 'origin/156-databases-are-split-so-many-…
kappsegla Mar 4, 2023
f3117c8
Update tests to work with the latest code
kappsegla Mar 4, 2023
736579f
Disable generation of jar file, not needed.
kappsegla Mar 4, 2023
03ee3e8
Merge remote-tracking branch 'origin/main' into 50-integration-tests
kappsegla Mar 4, 2023
d8e3c24
Update release.yml to run Integration tests
kappsegla Mar 4, 2023
6a0375e
Fix code smells.
kappsegla Mar 4, 2023
8d52331
Add HazeIT.java
kappsegla Feb 12, 2023
565f756
Update findFreePort method
kappsegla Feb 13, 2023
47efeda
Remove IT testcode not working with current server impl.
kappsegla Feb 18, 2023
b4499c9
Add Integration test for list
kappsegla Feb 21, 2023
da4b919
Change HazeIT to use testcontainers
kappsegla Feb 22, 2023
2378d65
Create HazeExtension for running integration tests
kappsegla Feb 24, 2023
77de081
Add dependency for slf4j-nop
kappsegla Feb 24, 2023
becb206
Update Dockerfile to download dependencies from internet
kappsegla Feb 25, 2023
7cbc3c8
Update tests to work with the latest code
kappsegla Mar 4, 2023
f4f96dd
Disable generation of jar file, not needed.
kappsegla Mar 4, 2023
058b925
Update release.yml to run Integration tests
kappsegla Mar 4, 2023
4b412fe
Fix code smells.
kappsegla Mar 4, 2023
84a7908
Merge remote-tracking branch 'origin/50-integration-tests' into 50-in…
kappsegla Feb 2, 2024
98afaba
Update versions for java and plugins
kappsegla Feb 4, 2024
7be0794
Merge branch 'main' into 50-integration-tests
kappsegla Feb 6, 2024
247a5b4
Revert MaintTest.java
kappsegla Feb 6, 2024
73dc9b4
Clean up Dockerfile
kappsegla Feb 6, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
cache: maven

- name: Compile and test with Maven
run: mvn -B test --file pom.xml
run: mvn -B verify --file pom.xml

- name: Set up QEMU
uses: docker/setup-qemu-action@v2
Expand Down
16 changes: 13 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
FROM eclipse-temurin:19-jre-jammy
kappsegla marked this conversation as resolved.
Show resolved Hide resolved
COPY target/dependency /lib
COPY target/classes /app
#COPY target/dependency /lib
WORKDIR /app
ARG USERNAME=hazeuser
ARG USER_UID=1000
ARG USER_GID=$USER_UID
RUN groupadd --gid $USER_GID $USERNAME && \
useradd --uid $USER_UID --gid $USER_GID -m $USERNAME
ADD https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-core/2.20.0/log4j-core-2.20.0.jar ./lib/
ADD https://repo1.maven.org/maven2/org/apache/logging/log4j/log4j-api/2.20.0/log4j-api-2.20.0.jar ./lib/
#RUN chmod --recursive 440 ./lib/
COPY target/classes .
RUN chown --recursive $USERNAME:$USERNAME .
USER $USERNAME
EXPOSE 6379
ENTRYPOINT ["java","-cp" , "/app:/lib/*", "--enable-preview", "org.fungover.haze.Main"]
ENTRYPOINT ["java","-cp","/app:/app/lib/*","--enable-preview","org.fungover.haze.Main"]
51 changes: 34 additions & 17 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,30 @@
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.17.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>1.17.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.36</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down Expand Up @@ -95,6 +119,16 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>default-jar</id>
<phase>none</phase>
<configuration>
<finalName>unwanted</finalName>
<classifier>unwanted</classifier>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
Expand Down Expand Up @@ -163,23 +197,6 @@
<argLine>@{argLine} --enable-preview</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>test</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
20 changes: 6 additions & 14 deletions src/main/java/org/fungover/haze/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand All @@ -35,7 +36,6 @@ public static void main(String[] args) {
serverSocket.bind(new InetSocketAddress(initialize.getPort()));
while (serverOpen) {
var client = serverSocket.accept();
logger.info("Application started: serverSocket.accept()");

Runnable newThread = () -> {
try {
Expand All @@ -45,19 +45,16 @@ public static void main(String[] args) {
List<String> inputList = new ArrayList<>();

String firstReading = input.readLine();
logger.debug(firstReading);
readInputStream(input, inputList, firstReading);

clientAuthenticated = authenticateClient(auth, isPasswordSet, client, inputList, clientAuthenticated);

client.getOutputStream().write(executeCommand(hazeDatabase, inputList, hazeList).getBytes());

inputList.forEach(System.out::println); // For checking incoming message

printThreadDebug();
client.getOutputStream().write(executeCommand(hazeDatabase, inputList, hazeList).getBytes(StandardCharsets.UTF_8));
client.getOutputStream().flush();

inputList.clear();
}

} catch (IOException e) {
logger.error(e);
}
Expand All @@ -75,14 +72,9 @@ private static void shutdown(HazeDatabase hazeDatabase) {
logger.info("Shutting down....");
}

private static void printThreadDebug() {
logger.debug("ThreadID {}", () -> Thread.currentThread().threadId()); // Only for Debug
logger.debug("Is virtual Thread {}", () -> Thread.currentThread().isVirtual()); // Only for Debug
}

public static String executeCommand(HazeDatabase hazeDatabase, List<String> inputList, HazeList hazeList) {
if (inputList.isEmpty() || inputList.get(0).isEmpty()) {
return "-ERR no command provided\r\n";
return "-ERR unknown command\r\n";
}

logger.debug("executeCommand: {} {} ", () -> hazeDatabase, () -> inputList);
Expand Down Expand Up @@ -118,7 +110,7 @@ public static String executeCommand(HazeDatabase hazeDatabase, List<String> inpu

private static void readInputStream(BufferedReader input, List<String> inputList, String firstReading) throws
IOException {
logger.debug("readInputStream: {} {} {}", () -> input, () -> inputList, () -> firstReading);
logger.debug("readInputStream: {} {}", () -> inputList, () -> firstReading);
int size;
if (firstReading.startsWith("*")) {
size = Integer.parseInt(firstReading.substring(1)) * 2;
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/org/fungover/haze/MainTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ void callingExecuteCommandWithValidNonExistingInputReturnsColonOne() {

@Test
void callingExecuteCommandWithInvalidInputStringReturnsErrorMessage() {
assertThat(Main.executeCommand(database, List.of(""), hazeList)).isEqualTo("-ERR no command provided\r\n");
assertThat(Main.executeCommand(database, List.of(""), hazeList)).isEqualTo("-ERR unknown command\r\n");

}

Expand Down
55 changes: 55 additions & 0 deletions src/test/java/org/fungover/haze/integration/HazeExtension.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.fungover.haze.integration;

import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.images.builder.ImageFromDockerfile;
import redis.clients.jedis.JedisPooled;

import java.lang.reflect.Field;
import java.nio.file.Path;
import java.util.List;

public class HazeExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback {

private GenericContainer<?> haze;
private JedisPooled pool;

@Override
public void beforeAll(ExtensionContext extensionContext) throws Exception {
haze = new GenericContainer<>(new ImageFromDockerfile()
.withDockerfile(Path.of("./Dockerfile")))
.withExposedPorts(6379);
haze.start();
pool = new JedisPooled(haze.getHost(), haze.getFirstMappedPort());
}

@Override
public void afterAll(ExtensionContext context) {
// do nothing, Testcontainers handles container shutdown
if (pool != null)
pool.close();
}

@Override
public void beforeEach(ExtensionContext extensionContext) throws Exception {

// Get the list of test instances (instances of test classes)
final List<Object> testInstances =
extensionContext.getRequiredTestInstances().getAllInstances();

testInstances.forEach((ti) -> {
for (Field field : ti.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(Pool.class)) {
try {
field.set(ti, pool);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
});
}
}
90 changes: 90 additions & 0 deletions src/test/java/org/fungover/haze/integration/HazeIT.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package org.fungover.haze.integration;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import redis.clients.jedis.JedisPooled;
import redis.clients.jedis.Protocol;
import redis.clients.jedis.util.SafeEncoder;

import static org.assertj.core.api.Assertions.assertThat;

@ExtendWith(HazeExtension.class)
class HazeIT {

@Pool
JedisPooled pool;

@Test
void pingPong() {
//Simple PING command with no message should return PONG as simple string
var result = pool.sendCommand(Protocol.Command.PING);
assertThat(SafeEncoder.encode((byte[]) result)).isEqualTo("PONG");
//PING with message argument should return bulk string with the argument
result = pool.sendCommand(Protocol.Command.PING, "HELLO");
assertThat(SafeEncoder.encode((byte[]) result)).isEqualTo("HELLO");
//PING with message argument containing space should return bulk string with the argument
// result = pool.sendCommand(Protocol.Command.PING, "HELLO\r\n There");
// assertThat(SafeEncoder.encode((byte[]) result)).isEqualTo("HELLO\r\n There");
}

@Test
void setNx() {
pool.del("test");
pool.del("test1");
assertThat(pool.setnx("test", "test")).isEqualTo(1);
assertThat(pool.setnx("test1", "test")).isEqualTo(1);
//Key test already exists so should not be set
assertThat(pool.setnx("test", "test1")).isZero();
pool.del("test");
pool.del("test1");
}

@Test
void setGet() {
assertThat(pool.set("test", "test")).isEqualTo("OK");
assertThat(pool.get("test")).isEqualTo("test");
pool.del("test");
}

@Test
void exists() {
assertThat(pool.set("test", "test")).isEqualTo("OK");
assertThat(pool.exists("test")).isTrue();
pool.del("notused");
assertThat(pool.exists("notused")).isFalse();
}

@Test
void listLPushLPop() {
assertThat(pool.lpush("left", "first")).isEqualTo(1);
assertThat(pool.llen("left")).isEqualTo(1);
assertThat(pool.lpop("left")).isEqualTo("first");
assertThat(pool.llen("left")).isZero();
pool.del("left");
assertThat(pool.exists("left")).isFalse();
}

@Test
void listRPushRPop() {
assertThat(pool.rpush("right", "first")).isEqualTo(1);
assertThat(pool.llen("right")).isEqualTo(1);
assertThat(pool.rpop("right")).isEqualTo("first");
assertThat(pool.llen("right")).isZero();
pool.del("right");
assertThat(pool.exists("right")).isFalse();
}

@Test
void listKeyWithMultipleValues() {
assertThat(pool.lpush("test", "first")).isEqualTo(1);
assertThat(pool.lpush("test", "second")).isEqualTo(2);
assertThat(pool.llen("test")).isEqualTo(2);
assertThat(pool.lpush("test", "third", "fourth")).isEqualTo(4);
assertThat(pool.llen("test")).isEqualTo(4);
assertThat(pool.rpush("test", "fifth", "sixth")).isEqualTo(6);
assertThat(pool.llen("test")).isEqualTo(6);

pool.del("test");
assertThat(pool.exists("right")).isFalse();
}
}
9 changes: 9 additions & 0 deletions src/test/java/org/fungover/haze/integration/Pool.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.fungover.haze.integration;

import java.lang.annotation.*;

@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Pool {
}
Loading