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

feat(e2e): move e2e tests #328

Merged
merged 3 commits into from
Sep 1, 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
9 changes: 8 additions & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,15 @@ jobs:
java-version: 11
distribution: temurin

- name: Read version from properties file
id: read-version
run: |
version=$(grep -oP 'version=\K[^[:space:]]+' gradle.properties)
echo "Version found: $version"
echo "VERSION=$version" >> $GITHUB_ENV

- name: Build with Gradle
run: ./gradlew build
run: make build/distributions/tiered-storage-for-apache-kafka-${{ env.VERSION }}.tgz

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
38 changes: 36 additions & 2 deletions .github/workflows/main_push_and_pull_request_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,46 @@ jobs:
distribution: temurin

- name: Build with Gradle
run: ./gradlew build distTar -x integrationTest
run: make build

- name: Run integration tests
run: ./gradlew integrationTest
run: make integration_test

- name: Upload Build Artifacts
uses: actions/upload-artifact@v3
with:
name: build-${{ matrix.java-version }}
path: build/distributions/*.tgz
e2e_test:
strategy:
matrix:
java-version: [ 11, 17 ]
runs-on: [ ubuntu-latest ]
name: E2E tests on ${{ matrix.runs-on }} with jdk ${{ matrix.java-version }}
runs-on: ${{ matrix.runs-on }}
needs:
- build
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Download Build Artifacts
uses: actions/download-artifact@v3
with:
name: build-${{ matrix.java-version }}
path: build/distributions

- name: Display structure of downloaded files
run: ls -R
working-directory: build/distributions

- name: Build Docker image
run: make docker_image

- name: Run E2E tests
timeout-minutes: 30
run: make e2e_test

# TODO: publish docker image
19 changes: 15 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,30 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
VERSION=0.0.1-SNAPSHOT
IMAGE_TAG=aivenoy/kafka:3.3-2022-10-06-tiered-storage-1-ts-2
VERSION := $(shell grep -oP 'version=\K[^[:space:]]+' gradle.properties)
IMAGE_NAME := aivenoy/kafka-with-ts-plugin
IMAGE_VERSION := latest
IMAGE_TAG := $(IMAGE_NAME):$(IMAGE_VERSION)

.PHONY: clean checkstyle build integration_test e2e_test docker_image docker_push

.PHONY: clean
clean:
./gradlew clean

checkstyle:
./gradlew checkstyleMain checkstyleTest checkstyleIntegrationTest

build: build/distributions/tiered-storage-for-apache-kafka-$(VERSION).tgz

build/distributions/tiered-storage-for-apache-kafka-$(VERSION).tgz:
./gradlew build distTar -x integrationTest
./gradlew build distTar -x integrationTest -x e2e:test

integration_test: build/distributions/tiered-storage-for-apache-kafka-$(VERSION).tgz
./gradlew integrationTest

e2e_test: build/distributions/tiered-storage-for-apache-kafka-$(VERSION).tgz
./gradlew e2e:test

.PHONY: docker_image
docker_image: build/distributions/tiered-storage-for-apache-kafka-$(VERSION).tgz
docker build . \
Expand Down
13 changes: 12 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,18 @@ subprojects {
slf4jVersion = "1.7.36"

// Don't bump this version without need, as this is the min supported version for the plugin.
kafkaVersion = "3.0.0"
kafkaVersion = "3.3.2"

assertJVersion = "3.24.2"

apacheCommonsIOVersion = "2.13.0"

jacksonVersion = "2.15.2"

awaitilityVersion = "4.2.0"

awsSdkVersion = "1.12.520"

testcontainersVersion = "1.18.3"
}

Expand All @@ -133,6 +137,8 @@ subprojects {
testImplementation "org.mockito:mockito-core:$mockitoVersion"
testImplementation "org.mockito:mockito-junit-jupiter:$mockitoVersion"

testImplementation "org.awaitility:awaitility:$awaitilityVersion"

testRuntimeOnly "org.slf4j:slf4j-log4j12:$slf4jVersion"
}

Expand Down Expand Up @@ -253,3 +259,8 @@ tasks.register('validateDependencies') {
assert !conflictsFound : "Dependency conflicts found!"
}
}

// TODO fix GCP dependency issues
//tasks.named("check") {
// dependsOn(tasks.named("validateDependencies"))
//}
3 changes: 3 additions & 0 deletions checkstyle/suppressions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@
<suppress checks="ClassDataAbstractionCoupling" files="Metrics.java"/>
<suppress checks="ClassDataAbstractionCoupling" files="MetricCollector.java"/>
<suppress checks="CyclomaticComplexity" files="MetricCollector.java"/>
<suppress checks="CyclomaticComplexity" files="SingleBrokerTest.java"/>
<suppress checks="NPathComplexity" files="SingleBrokerTest.java"/>
<suppress checks="JavaNCSSCheck" files="MetricsRegistry.java"/>
<suppress checks="JavaNCSSCheck" files="RemoteStorageManagerMetricsTest.java"/>
<suppress checks="JavaNCSSCheck" files="SingleBrokerTest.java"/>
<suppress checks="NPathComplexity" files="CredentialsBuilder.java"/>
</suppressions>
3 changes: 0 additions & 3 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ ext {
caffeineVersion = "3.1.7"

zstdVersion = "1.5.5-5"

awaitilityVersion = "4.2.0"
}

dependencies {
Expand All @@ -51,6 +49,5 @@ dependencies {
testImplementation(project(":storage:filesystem"))

testImplementation "com.github.luben:zstd-jni:$zstdVersion"
testImplementation "org.awaitility:awaitility:$awaitilityVersion"
integrationTestImplementation sourceSets.test.output
}
2 changes: 1 addition & 1 deletion demo/compose-local-fs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ services:
ZOOKEEPER_CLIENT_PORT: 2181

kafka:
image: "aivenoy/kafka:3.3-2022-10-06-tiered-storage-1-ts-2"
image: "aivenoy/kafka-with-ts-plugin"
container_name: "kafka-ts"
depends_on:
- zookeeper
Expand Down
2 changes: 1 addition & 1 deletion demo/compose-s3-aws.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ services:
ZOOKEEPER_CLIENT_PORT: 2181

kafka:
image: "aivenoy/kafka:3.3-2022-10-06-tiered-storage-1-ts-2"
image: "aivenoy/kafka-with-ts-plugin"
container_name: "kafka-ts"
depends_on:
- zookeeper
Expand Down
2 changes: 1 addition & 1 deletion demo/compose-s3-minio.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ services:
ZOOKEEPER_CLIENT_PORT: 2181

kafka:
image: "aivenoy/kafka:3.3-2022-10-06-tiered-storage-1-ts-2"
image: "aivenoy/kafka-with-ts-plugin"
container_name: "kafka-ts"
depends_on:
- zookeeper
Expand Down
8 changes: 8 additions & 0 deletions e2e/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# End-to-end tests for Kafka tiered storage

## Usage

Docker is needed for running the tests.

1. Build the image with < TBD >.
2. `./gradlew test`
43 changes: 43 additions & 0 deletions e2e/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2023 Aiven Oy
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

dependencies {
testImplementation "org.apache.kafka:kafka-clients:$kafkaVersion"
testImplementation "org.apache.kafka:kafka-storage:$kafkaVersion"
testImplementation "org.apache.kafka:kafka-storage-api:$kafkaVersion"

testImplementation "commons-io:commons-io:$apacheCommonsIOVersion"
testImplementation "com.amazonaws:aws-java-sdk-s3:$awsSdkVersion"

testImplementation "org.testcontainers:junit-jupiter:$testcontainersVersion"
testImplementation "org.testcontainers:kafka:$testcontainersVersion"

testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion"
testRuntimeOnly "org.slf4j:slf4j-log4j12:$slf4jVersion"
}

tasks.named('test') {
// Use junit platform for unit tests.
useJUnitPlatform()
testLogging {
events 'passed', 'skipped', 'failed'
showStandardStreams = true
showExceptions = true
showStackTraces = true
showCauses = true
exceptionFormat "full"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2023 Aiven Oy
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.aiven.kafka.tieredstorage.e2e;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.kafka.common.TopicIdPartition;
import org.apache.kafka.common.Uuid;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;

public class LocalSystemSingleBrokerTest extends SingleBrokerTest {
static final String TS_DATA_SUBDIR_HOST = "ts-data";
static final String TS_DATA_DIR_CONTAINER = "/home/appuser/kafka-tiered-storage";

static Path tieredDataDir;

@BeforeAll
static void init() throws Exception {
setupKafka(kafka -> {
tieredDataDir = baseDir.resolve(TS_DATA_SUBDIR_HOST);
tieredDataDir.toFile().mkdirs();
tieredDataDir.toFile().setWritable(true, false);

kafka
.withEnv("KAFKA_RSM_CONFIG_STORAGE_BACKEND_CLASS",
"io.aiven.kafka.tieredstorage.storage.filesystem.FileSystemStorage")
.withEnv("KAFKA_RSM_CONFIG_STORAGE_ROOT", TS_DATA_DIR_CONTAINER)
.withFileSystemBind(tieredDataDir.toString(), TS_DATA_DIR_CONTAINER);
});
}

@AfterAll
static void cleanup() {
stopKafka();
cleanupStorage();
}

@Override
boolean assertNoTopicDataOnTierStorage(final String topicName, final Uuid topicId) {
final String prefix = String.format("%s-%s", topicName, topicId.toString());
try (final var files = Files.list(tieredDataDir)) {
return files.noneMatch(path -> path.getFileName().startsWith(prefix));
} catch (final IOException e) {
throw new RuntimeException(e);
}
}

@Override
List<String> remotePartitionFiles(final TopicIdPartition topicIdPartition) {
final Path dir = tieredDataDir.resolve(
String.format("%s-%s/%s",
topicIdPartition.topic(),
topicIdPartition.topicId().toString(),
topicIdPartition.partition()));
try (final var paths = Files.list(dir)) {
return paths.map(Path::getFileName)
.map(Path::toString)
.sorted()
.collect(Collectors.toList());
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
}
Loading