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

Enable BlockHound for integration tests and stability tests #2863

Merged
merged 6 commits into from
Nov 23, 2021
Merged
Show file tree
Hide file tree
Changes from 5 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 @@ -130,6 +130,7 @@
<netty-open-ssl-version>2.0.43.Final</netty-open-ssl-version>
<dynamodb-local.version>1.16.0</dynamodb-local.version>
<sqllite.version>1.0.392</sqllite.version>
<blockhound.version>1.0.6.RELEASE</blockhound.version>

<!-- build plugin dependencies-->
<maven.surefire.version>3.0.0-M5</maven.surefire.version>
Expand Down
12 changes: 12 additions & 0 deletions services/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,18 @@
<version>${awsjavasdk.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.projectreactor.tools</groupId>
<artifactId>blockhound</artifactId>
<version>${blockhound.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor.tools</groupId>
<artifactId>blockhound-junit-platform</artifactId>
<version>${blockhound.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>service-test-utils</artifactId>
<groupId>software.amazon.awssdk</groupId>
Expand Down
14 changes: 14 additions & 0 deletions services/s3/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@
</archive>
</configuration>
</plugin>
<plugin>
Bennett-Lynch marked this conversation as resolved.
Show resolved Hide resolved
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<configuration>
<ignoredUsedUndeclaredDependencies>
<ignoredUnusedDeclaredDependency>org.junit.jupiter:*</ignoredUnusedDeclaredDependency>
</ignoredUsedUndeclaredDependencies>
</configuration>
</plugin>
</plugins>
</build>

Expand Down Expand Up @@ -117,5 +126,10 @@
<version>${awsjavasdk.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.services;


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

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.EventLoop;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import reactor.blockhound.BlockHound;
import reactor.blockhound.BlockingOperationError;
import reactor.blockhound.integration.BlockHoundIntegration;
import reactor.blockhound.junit.platform.BlockHoundTestExecutionListener;
import software.amazon.awssdk.testutils.service.AwsIntegrationTestBase;
import software.amazon.awssdk.testutils.service.AwsTestBase;
import software.amazon.awssdk.utils.Logger;

/**
* This test ensures that BlockHound is correctly installed for integration tests. The test is somewhat arbitrarily placed in the
* {@code s3} module in order to assert against the configuration of all service integration tests.
* <p>
* BlockHound is installed in one of two ways:
* <ol>
* <li>Using BlockHound's provided {@link BlockHoundTestExecutionListener}, which will be automatically detected by the
* JUnit 5 platform upon initialization.</li>
* <li>Manually calling {@link BlockHound#install(BlockHoundIntegration...)}. This is done as part of static initialization in
* {@link AwsIntegrationTestBase}, as an extra precaution, and in {@link AwsTestBase} for our stability tests, which are not
* built upon JUnit.
* </ol>
* <p>
* This test ensures BlockHound is correctly installed by intentionally performing a blocking operation on the Netty
* {@link EventLoop} and asserting that a {@link BlockingOperationError} is thrown to forbid it.
*/
class BlockHoundInstalledTest {
private static final Logger log = Logger.loggerFor(BlockHoundInstalledTest.class);

AtomicReference<Throwable> throwableReference;
CountDownLatch latch;
EventLoopGroup bossGroup;
EventLoopGroup workerGroup;
Socket clientSocket;
Channel serverChannel;

@BeforeEach
public void setup() {
throwableReference = new AtomicReference<>();
latch = new CountDownLatch(1);
bossGroup = new NioEventLoopGroup();
workerGroup = new NioEventLoopGroup();
}

@AfterEach
public void teardown() throws Exception {
if (clientSocket != null) {
clientSocket.close();
}
if (serverChannel != null) {
serverChannel.close();
}
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}

@Test
void testBlockHoundInstalled() throws Exception {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelDuplexHandler() {
@Override
public void channelActive(ChannelHandlerContext ctx) {
log.info(() -> "Preparing to sleep on the EventLoop to test if BlockHound is installed");
try {
Thread.sleep(1000);
log.info(() -> "BlockHound does not appear to be successfully installed");
} catch (Throwable t) {
log.info(() -> "BlockHound is successfully installed", t);
throwableReference.set(t);
}
latch.countDown();
ctx.fireChannelActive();
}
});

int port = getUnusedPort();
serverChannel = bootstrap.bind(port).sync().channel();
clientSocket = new Socket("localhost", port);

latch.await(5, TimeUnit.SECONDS);
Bennett-Lynch marked this conversation as resolved.
Show resolved Hide resolved
assertThat(throwableReference.get())
.withFailMessage("BlockHound does not appear to be successfully installed. Ensure that either BlockHound.install() "
+ "is called prior to all test executions or that BlockHoundTestExecutionListener is available on "
+ "the class path and correctly detected by JUnit: "
+ "https://github.com/reactor/BlockHound/blob/master/docs/supported_testing_frameworks.md")
.isInstanceOf(BlockingOperationError.class);
}

private static int getUnusedPort() throws IOException {
try (ServerSocket socket = new ServerSocket(0)) {
socket.setReuseAddress(true);
return socket.getLocalPort();
}
}
}
13 changes: 13 additions & 0 deletions test/service-test-utils/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,18 @@
<artifactId>junit</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.projectreactor.tools</groupId>
<artifactId>blockhound</artifactId>
<version>${blockhound.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.projectreactor.tools</groupId>
<artifactId>blockhound-junit-platform</artifactId>
<version>${blockhound.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
Expand All @@ -101,6 +113,7 @@
<ignoredUnusedDeclaredDependency>software.amazon.awssdk:test-utils:*</ignoredUnusedDeclaredDependency>
<ignoredUnusedDeclaredDependency>org.junit.jupiter:*</ignoredUnusedDeclaredDependency>
<ignoredUnusedDeclaredDependency>org.junit.vintage:*</ignoredUnusedDeclaredDependency>
<ignoredUnusedDeclaredDependency>io.projectreactor.tools:blockhound-junit-platform:*</ignoredUnusedDeclaredDependency>
</ignoredUnusedDeclaredDependencies>
</configuration>
</plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.io.IOException;
import java.io.InputStream;
import reactor.blockhound.BlockHound;
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain;
Expand All @@ -27,6 +28,10 @@

public abstract class AwsIntegrationTestBase {

static {
BlockHound.install();
}

/** Default Properties Credentials file path. */
private static final String TEST_CREDENTIALS_PROFILE_NAME = "aws-test-account";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,19 @@
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import reactor.blockhound.BlockHound;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.core.exception.SdkServiceException;
import software.amazon.awssdk.utils.IoUtils;

public abstract class AwsTestBase {

static {
BlockHound.install();
}

/** Default Properties Credentials file path. */
private static final String TEST_CREDENTIALS_PROFILE_NAME = "aws-test-account";

Expand Down
12 changes: 12 additions & 0 deletions test/stability-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,18 @@
<version>${junit5.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor.tools</groupId>
<artifactId>blockhound</artifactId>
<version>${blockhound.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor.tools</groupId>
<artifactId>blockhound-junit-platform</artifactId>
<version>${blockhound.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
Expand Down