From 2285a5b91c3f760afc676a8accce947355f1af52 Mon Sep 17 00:00:00 2001 From: skrzypo987 Date: Wed, 5 Oct 2022 11:48:23 +0200 Subject: [PATCH] Test setting S3 region explicitly Using minio container as a mock of S3. It is, by no means, a proper replacement of the S3 service, but it fails the request if the incorrect region is requested, which proves that the set region is properly sent in the request. --- .../hive/containers/HiveMinioDataLake.java | 11 ++++- .../hive/s3/TestS3WrongRegionPicked.java | 42 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 plugin/trino-hive/src/test/java/io/trino/plugin/hive/s3/TestS3WrongRegionPicked.java diff --git a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/containers/HiveMinioDataLake.java b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/containers/HiveMinioDataLake.java index fbfb5aeb3cc3..6b6e4575b8da 100644 --- a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/containers/HiveMinioDataLake.java +++ b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/containers/HiveMinioDataLake.java @@ -34,6 +34,12 @@ public class HiveMinioDataLake public static final String MINIO_ACCESS_KEY = Minio.MINIO_ACCESS_KEY; @Deprecated public static final String MINIO_SECRET_KEY = Minio.MINIO_SECRET_KEY; + /** + * In S3 this region is implicitly the default one. In Minio, however, + * if we set an empty region, it will accept any. + * So setting it by default to `us-east-1` simulates S3 better + */ + public static final String MINIO_DEFAULT_REGION = "us-east-1"; private final String bucketName; private final Minio minio; @@ -64,6 +70,7 @@ public HiveMinioDataLake(String bucketName, Map hiveHadoopFilesT .withEnvVars(ImmutableMap.builder() .put("MINIO_ACCESS_KEY", MINIO_ACCESS_KEY) .put("MINIO_SECRET_KEY", MINIO_SECRET_KEY) + .put("MINIO_REGION", MINIO_DEFAULT_REGION) .buildOrThrow()) .build()); @@ -74,7 +81,7 @@ public HiveMinioDataLake(String bucketName, Map hiveHadoopFilesT this.hiveHadoop = closer.register(hiveHadoopBuilder.build()); } - public void start() + public HiveMinioDataLake start() { checkState(state == State.INITIAL, "Already started: %s", state); state = State.STARTING; @@ -83,6 +90,8 @@ public void start() minioClient = closer.register(minio.createMinioClient()); minio.createBucket(bucketName); state = State.STARTED; + + return this; } public void stop() diff --git a/plugin/trino-hive/src/test/java/io/trino/plugin/hive/s3/TestS3WrongRegionPicked.java b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/s3/TestS3WrongRegionPicked.java new file mode 100644 index 000000000000..2d8608c6942c --- /dev/null +++ b/plugin/trino-hive/src/test/java/io/trino/plugin/hive/s3/TestS3WrongRegionPicked.java @@ -0,0 +1,42 @@ +/* + * 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.trino.plugin.hive.s3; + +import com.google.common.collect.ImmutableMap; +import io.trino.plugin.hive.containers.HiveMinioDataLake; +import io.trino.testing.QueryRunner; +import org.testng.annotations.Test; + +import static io.trino.testing.sql.TestTable.randomTableSuffix; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class TestS3WrongRegionPicked +{ + @Test + public void testS3WrongRegionSelection() + throws Exception + { + try (HiveMinioDataLake dataLake = new HiveMinioDataLake("test-bucket").start(); + QueryRunner queryRunner = S3HiveQueryRunner.builder(dataLake) + .setHiveProperties(ImmutableMap.of("hive.s3.region", "eu-central-1")) // Different than the default one + .build()) { + String tableName = "s3_region_test_" + randomTableSuffix(); + queryRunner.execute("CREATE TABLE default." + tableName + " (a int) WITH (external_location = 's3://test-bucket/" + tableName + "')"); + assertThatThrownBy(() -> queryRunner.execute("SELECT * FROM default." + tableName)) + .getRootCause() + .hasMessageContaining("Status Code: 400") + .hasMessageContaining("Error Code: AuthorizationHeaderMalformed"); // That is how Minio reacts to bad region + } + } +}