Skip to content

Commit

Permalink
Added functional testing framework using TestContainers
Browse files Browse the repository at this point in the history
  • Loading branch information
abevk2023 committed Jun 27, 2024
1 parent dcb4ed5 commit 26e9add
Show file tree
Hide file tree
Showing 17 changed files with 335 additions and 0 deletions.
5 changes: 5 additions & 0 deletions presto-native-execution/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ using [Velox](https://github.com/facebookincubator/velox).
* [Development](#development)
* [Create Pull Request](#create-pull-request)
* [Advance Velox Version](#advance-velox-version)
* [Functional test using containers](#functional-test-using-containers)
* [Troubleshooting](#troubleshooting)

## Build from Source
Expand Down Expand Up @@ -233,5 +234,9 @@ For Prestissimo to use a newer Velox version from the Presto repository root:
* Build and run tests (including E2E) to ensure everything works.
* Submit a PR, get it approved and merged.

## Functional test using containers
To build container images and do functional tests, see [Prestissimo: Functional Testing Using Containers](testcontainers/README.md).

## Troubleshooting
For known build issues check the wiki page [Troubleshooting known build issues](https://github.com/prestodb/presto/wiki/Troubleshooting-known-build-issues).

92 changes: 92 additions & 0 deletions presto-native-execution/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,17 @@
<groupId>com.facebook.airlift</groupId>
<artifactId>testing</artifactId>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -299,5 +310,86 @@
</plugins>
</build>
</profile>
<profile>
<id>docker-build</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<id>copy-presto-cli-executable</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.parent.basedir}/docker/</outputDirectory>
<resources>
<resource>
<directory>${project.parent.basedir}/presto-cli/target</directory>
<includes>
<include>presto-cli-*-executable.jar</include>
</includes>
</resource>
<resource>
<directory>${project.parent.basedir}/presto-server/target</directory>
<includes>
<include>presto-server-*.tar.gz</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.13</version>
<executions>
<execution>
<id>coordinator</id>
<phase>install</phase>
<goals>
<goal>build</goal>
</goals>
<configuration>
<repository>presto-coordinator</repository>
<tag>latest</tag>
<contextDirectory>${project.parent.basedir}/docker/</contextDirectory>
<dockerfile>${project.parent.basedir}/docker/Dockerfile</dockerfile>
<buildArgs>
<PRESTO_VERSION>0.289-SNAPSHOT</PRESTO_VERSION>
</buildArgs>
<writeTestMetadata>false</writeTestMetadata>
</configuration>
</execution>
<execution>
<id>worker</id>
<phase>install</phase>
<goals>
<goal>build</goal>
</goals>
<configuration>
<repository>presto-worker</repository>
<tag>latest</tag>
<contextDirectory>${project.basedir}</contextDirectory>
<dockerfile>${project.basedir}/scripts/dockerfiles/prestissimo-runtime.dockerfile</dockerfile>
<buildArgs>
<BUILD_TYPE>Release</BUILD_TYPE>
<DEPENDENCY_IMAGE>public.ecr.aws/oss-presto/presto-native-dependency:latest</DEPENDENCY_IMAGE>
<EXTRA_CMAKE_FLAGS>-DPRESTO_ENABLE_PARQUET=ON -DPRESTO_ENABLE_S3=ON</EXTRA_CMAKE_FLAGS>
</buildArgs>
<writeTestMetadata>false</writeTestMetadata>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* 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 com.facebook.presto.nativeworker;

import org.testcontainers.containers.BindMode;
import org.testcontainers.containers.Container;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.Network;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.io.IOException;
import java.time.Duration;

import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;

public class TestPrestoNativeWithContainers
{
private static final String PRESTO_COORDINATOR_IMAGE = System.getProperty("coordinatorImage", "presto-coordinator:latest");
private static final String PRESTO_WORKER_IMAGE = System.getProperty("workerImage", "presto-worker:latest");
private static final String BASE_DIR = System.getProperty("user.dir");
private static final Network network = Network.newNetwork();
private GenericContainer<?> coordinator;
private GenericContainer<?> worker;

@BeforeClass
public void setUp()
throws InterruptedException
{
coordinator = new GenericContainer<>(PRESTO_COORDINATOR_IMAGE)
.withExposedPorts(8081)
.withNetwork(network).withNetworkAliases("presto-coordinator")
.withFileSystemBind(BASE_DIR + "/testcontainers/coordinator/etc", "/opt/presto-server/etc", BindMode.READ_WRITE)
.withFileSystemBind(BASE_DIR + "/testcontainers/coordinator/entrypoint.sh", "/opt/entrypoint.sh", BindMode.READ_ONLY)
.waitingFor(Wait.forLogMessage(".*======== SERVER STARTED ========.*", 1))
.withStartupTimeout(Duration.ofSeconds(120));

worker = new GenericContainer<>(PRESTO_WORKER_IMAGE)
.withExposedPorts(7777)
.withNetwork(network).withNetworkAliases("presto-worker")
.withFileSystemBind(BASE_DIR + "/testcontainers/nativeworker/velox-etc", "/opt/presto-server/etc", BindMode.READ_ONLY)
.withFileSystemBind(BASE_DIR + "/testcontainers/nativeworker/entrypoint.sh", "/opt/entrypoint.sh", BindMode.READ_ONLY)
.waitingFor(Wait.forLogMessage(".*Announcement succeeded: HTTP 202.*", 1));

coordinator.start();
worker.start();
}

@AfterClass
public void tearDown()
{
coordinator.stop();
worker.stop();
}

private Container.ExecResult executeQuery(String sql)
throws IOException, InterruptedException
{
// Command to run inside the coordinator container using the presto-cli.
String[] command = {
"/opt/presto-cli",
"--server",
"presto-coordinator:8081",
"--execute",
sql
};

Container.ExecResult execResult = coordinator.execInContainer(command);
if (execResult.getExitCode() != 0) {
String errorDetails = "Stdout: " + execResult.getStdout() + "\nStderr: " + execResult.getStderr();
fail("Presto CLI exited with error code: " + execResult.getExitCode() + "\n" + errorDetails);
}
return execResult;
}

@Test
public void testBasics()
throws IOException, InterruptedException
{
String selectRuntimeNodes = "select * from system.runtime.nodes";
executeQuery(selectRuntimeNodes);
String showCatalogs = "show catalogs";
executeQuery(showCatalogs);
String showSession = "show session";
executeQuery(showSession);
}

@Test
public void testFunctions()
throws IOException, InterruptedException
{
String countValues = "SELECT COUNT(*) FROM (VALUES 1, 0, 0, 2, 3, 3) as t(x)";
Container.ExecResult countResult = executeQuery(countValues);
assertTrue(countResult.getStdout().contains("6"), "Count is incorrect.");

String sqlArrayIntegers = "SELECT array_sort(ARRAY [5, 20, null, 5, 3, 50])";
Container.ExecResult execResultIntegers = executeQuery(sqlArrayIntegers);
assertTrue(execResultIntegers.getStdout().contains("[3, 5, 5, 20, 50, null]"), "Integer array not sorted correctly.");
}
}
50 changes: 50 additions & 0 deletions presto-native-execution/testcontainers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Prestissimo: Functional Testing Using Containers

This Java test framework allows you to run test cases by deploying Presto coordinator and worker nodes in containers.
#### To set up Docker services and basic build tools on Ubuntu 22.04 x86_64 machine, run the following command:
```
apt install podman-docker
apt install make
apt install cmake
```
Note: Run the following commands to fix an open bug related to CNI network in podman.
Reference: https://bugs.launchpad.net/ubuntu/+source/libpod/+bug/2024394
```
curl -O http://archive.ubuntu.com/ubuntu/pool/universe/g/golang-github-containernetworking-plugins/containernetworking-plugins_1.1.1+ds1-3build1_amd64.deb
dpkg -i containernetworking-plugins_1.1.1+ds1-3build1_amd64.deb
```

## Quick Start

### 1. Build Presto using Maven
The container images required for functional tests are integrated into the presto-native-execution and are built under a Maven profile named _docker-build_.

```bash
./mvnw clean install -DskipTests -Pdocker-build
```

### 2. Run functional tests
#### Using Command Line
Export the following environment variables:
```bash
export TESTCONTAINERS_RYUK_DISABLED=true
export DOCKER_HOST=unix:///run/podman/podman.sock
```
Then, run the functional test using a command similar to this example for `TestPrestoNativeWithContainers`:
```bash
./mvnw test -pl presto-native-execution -Dtest=com.facebook.presto.nativeworker.TestPrestoNativeWithContainers
```

#### Using IntelliJ
Go to the tests with containers at `TestPrestoNativeWithContainers`.
Edit the run/debug configuration of the test or test case, and add the following as environment variables:
```
TESTCONTAINERS_RYUK_DISABLED=true
DOCKER_HOST=unix:///run/podman/podman.sock
```
Then, run or debug the test.

#### Note: Existing java and native docker files are reused for functional testing. The coordinator and worker configurations are available in `presto-native-execution/testcontainers`.



16 changes: 16 additions & 0 deletions presto-native-execution/testcontainers/coordinator/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/sh
# 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.

set -e

$PRESTO_HOME/bin/launcher run
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
connector.name=hive-hadoop2
hive.metastore=file
hive.metastore.catalog.dir=file:/var/lib/presto/dwrf_data/
hive.storage-format=DWRF
hive.pushdown-filter-enabled=true
hive.compression-codec=SNAPPY
hive.orc-compression-codec=ZSTD
hive.allow-drop-table=true
hive.metastore.authentication.type=NONE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
connector.name=tpcds
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
connector.name=tpch
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
coordinator=true
presto.version=testversion
node-scheduler.include-coordinator=false
http-server.http.port=8081
discovery-server.enabled=true
discovery.uri=http://presto-coordinator:8081
native-execution-enabled=true
list-built-in-functions-only=false
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-server
-Xmx1G
-XX:+UseG1GC
-XX:G1HeapRegionSize=32M
-XX:+UseGCOverheadLimit
-XX:+ExplicitGCInvokesConcurrent
-XX:+HeapDumpOnOutOfMemoryError
-XX:+ExitOnOutOfMemoryError
-Djdk.attach.allowAttachSelf=true
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
com.facebook.presto=DEBUG
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node.environment=testing
node.location=testing-location
node.data-dir=/var/lib/presto/data
16 changes: 16 additions & 0 deletions presto-native-execution/testcontainers/nativeworker/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/sh
# 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.

GLOG_logtostderr=1 presto_server \
--etc-dir=/opt/presto-server/etc

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
connector.name=hive
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
presto.version=testversion
http-server.http.port=7777
discovery.uri=http://presto-coordinator:8081
system-memory-gb=2
native.sidecar=false
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node.environment=testing
node.id=e4901aae-a1c9-4ff7-97a9-5687835ad54c
node.location=testing-location
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mutable-config=true

0 comments on commit 26e9add

Please sign in to comment.