This is an automated email from the ASF dual-hosted git repository. gxd pushed a commit to branch test_bingding_java in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git
commit 214e9637e03a01bb5686ea2b86b336f4f74d1031 Author: G-XD <[email protected]> AuthorDate: Wed Nov 1 23:11:44 2023 +0800 test(binding/java): add read_only test --- .../opendal/test/behavior/AsyncReadOnlyTest.java | 154 +++++++++++++++++++++ .../opendal/test/behavior/BehaviorTestBase.java | 21 +++ .../test/behavior/BlockingReadOnlyTest.java | 107 ++++++++++++++ 3 files changed, 282 insertions(+) diff --git a/bindings/java/src/test/java/org/apache/opendal/test/behavior/AsyncReadOnlyTest.java b/bindings/java/src/test/java/org/apache/opendal/test/behavior/AsyncReadOnlyTest.java new file mode 100644 index 000000000..579b4b995 --- /dev/null +++ b/bindings/java/src/test/java/org/apache/opendal/test/behavior/AsyncReadOnlyTest.java @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.opendal.test.behavior; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; +import java.security.NoSuchAlgorithmException; +import java.util.UUID; +import org.apache.opendal.Capability; +import org.apache.opendal.Metadata; +import org.apache.opendal.OpenDALException; +import org.apache.opendal.test.condition.OpenDALExceptionCondition; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class AsyncReadOnlyTest extends BehaviorTestBase { + + private static final String NORMAL_FILE_NAME = "normal_file.txt"; + private static final String NORMAL_DIR_NAME = "normal_dir/"; + private static final String SPECIAL_FILE_NAME = "special_file !@#$%^&()_+-=;',.txt"; + private static final String SPECIAL_DIR_NAME = "special_dir !@#$%^&()_+-=;',./"; + private static final String FILE_SHA256_DIGEST = "943048ba817cdcd786db07d1f42d5500da7d10541c2f9353352cd2d3f66617e5"; + private static final long FILE_LENGTH = 30482L; + + @BeforeAll + public void precondition() { + final Capability capability = op().info.fullCapability; + assumeTrue(capability.read && !capability.write); + } + + /** + * Stat normal file and dir should return metadata + */ + @Test + public void testReadOnlyStatFileAndDir() { + final Metadata fileMeta = op().stat(NORMAL_FILE_NAME).join(); + assertTrue(fileMeta.isFile()); + assertEquals(FILE_LENGTH, fileMeta.getContentLength()); + + final Metadata dirMeta = op().stat(NORMAL_DIR_NAME).join(); + assertTrue(dirMeta.isDir()); + } + + /** + * Stat special file and dir should return metadata + */ + @Test + public void testReadOnlyStatSpecialChars() { + final Metadata fileMeta = op().stat(SPECIAL_FILE_NAME).join(); + assertTrue(fileMeta.isFile()); + assertEquals(FILE_LENGTH, fileMeta.getContentLength()); + + final Metadata dirMeta = op().stat(SPECIAL_DIR_NAME).join(); + assertTrue(dirMeta.isDir()); + } + + /** + * Stat not cleaned path should also succeed. + */ + @Test + public void testReadOnlyStatNotCleanedPath() { + final Metadata fileMeta = op().stat("//" + NORMAL_FILE_NAME).join(); + assertTrue(fileMeta.isFile()); + assertEquals(FILE_LENGTH, fileMeta.getContentLength()); + } + + /** + * Stat not exist file should return NotFound + */ + @Test + public void testReadOnlyStatNotExist() { + final String path = UUID.randomUUID().toString(); + + assertThatThrownBy(() -> op().stat(path).join()) + .is(OpenDALExceptionCondition.ofAsync(OpenDALException.Code.NotFound)); + } + + /** + * Root should be able to stat and returns DIR. + */ + @Test + public void testReadOnlyStatRoot() { + final Metadata meta1 = op().stat("").join(); + assertTrue(meta1.isDir()); + + final Metadata meta2 = op().stat("/").join(); + assertTrue(meta2.isDir()); + } + + /** + * Read full content should match. + */ + @Test + public void testReadOnlyReadFull() throws NoSuchAlgorithmException { + final byte[] content = op().read(NORMAL_FILE_NAME).join(); + assertEquals(FILE_LENGTH, content.length); + + assertEquals(FILE_SHA256_DIGEST, sha256Digest(content)); + } + + /** + * Read full content should match. + */ + @Test + public void testReadOnlyReadFullWithSpecialChars() throws NoSuchAlgorithmException { + final byte[] content = op().read(SPECIAL_FILE_NAME).join(); + assertEquals(FILE_LENGTH, content.length); + + assertEquals(FILE_SHA256_DIGEST, sha256Digest(content)); + } + + /** + * Read not exist file should return NotFound + */ + @Test + public void testReadOnlyReadNotExist() { + final String path = UUID.randomUUID().toString(); + + assertThatThrownBy(() -> op().read(path).join()) + .is(OpenDALExceptionCondition.ofAsync(OpenDALException.Code.NotFound)); + } + + /** + * Read with dir path should return an error. + */ + @Test + public void testReadOnlyReadWithDirPath() { + final String path = UUID.randomUUID().toString() + "/"; + + assertThatThrownBy(() -> op().read(path).join()) + .is(OpenDALExceptionCondition.ofAsync(OpenDALException.Code.IsADirectory)); + } +} diff --git a/bindings/java/src/test/java/org/apache/opendal/test/behavior/BehaviorTestBase.java b/bindings/java/src/test/java/org/apache/opendal/test/behavior/BehaviorTestBase.java index fe2287ec6..57bc718d7 100644 --- a/bindings/java/src/test/java/org/apache/opendal/test/behavior/BehaviorTestBase.java +++ b/bindings/java/src/test/java/org/apache/opendal/test/behavior/BehaviorTestBase.java @@ -20,6 +20,8 @@ package org.apache.opendal.test.behavior; import static org.junit.jupiter.api.Assumptions.assumeTrue; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.Random; import org.apache.opendal.BlockingOperator; import org.apache.opendal.Operator; @@ -54,4 +56,23 @@ public abstract class BehaviorTestBase { random.nextBytes(content); return content; } + + /** + * Calculate SHA256 digest of input bytes + * + * @param input input bytes + * @return SHA256 digest string + * @throws NoSuchAlgorithmException + */ + public static String sha256Digest(final byte[] input) throws NoSuchAlgorithmException { + final MessageDigest digest = MessageDigest.getInstance("SHA-256"); + final byte[] hash = digest.digest(input); + final StringBuilder hexString = new StringBuilder(); + for (int i = 0; i < hash.length; i++) { + final String hex = Integer.toHexString(0xff & hash[i]); + if (hex.length() == 1) hexString.append('0'); + hexString.append(hex); + } + return hexString.toString(); + } } diff --git a/bindings/java/src/test/java/org/apache/opendal/test/behavior/BlockingReadOnlyTest.java b/bindings/java/src/test/java/org/apache/opendal/test/behavior/BlockingReadOnlyTest.java new file mode 100644 index 000000000..149bd3428 --- /dev/null +++ b/bindings/java/src/test/java/org/apache/opendal/test/behavior/BlockingReadOnlyTest.java @@ -0,0 +1,107 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.opendal.test.behavior; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; +import java.security.NoSuchAlgorithmException; +import java.util.UUID; +import org.apache.opendal.Capability; +import org.apache.opendal.Metadata; +import org.apache.opendal.OpenDALException; +import org.apache.opendal.test.condition.OpenDALExceptionCondition; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class BlockingReadOnlyTest extends BehaviorTestBase { + + private static final String NORMAL_FILE_NAME = "normal_file.txt"; + private static final String NORMAL_DIR_NAME = "normal_dir/"; + private static final String SPECIAL_FILE_NAME = "special_file !@#$%^&()_+-=;',.txt"; + private static final String SPECIAL_DIR_NAME = "special_dir !@#$%^&()_+-=;',./"; + private static final String FILE_SHA256_DIGEST = "943048ba817cdcd786db07d1f42d5500da7d10541c2f9353352cd2d3f66617e5"; + private static final long FILE_LENGTH = 30482L; + + @BeforeAll + public void precondition() { + final Capability capability = blockingOp().info.fullCapability; + assumeTrue(capability.read && !capability.write && capability.blocking); + } + + /** + * Stat normal file and dir should return metadata + */ + @Test + public void testBlockingReadOnlyStatFileAndDir() { + final Metadata fileMeta = blockingOp().stat(NORMAL_FILE_NAME); + assertTrue(fileMeta.isFile()); + assertEquals(FILE_LENGTH, fileMeta.getContentLength()); + + final Metadata dirMeta = blockingOp().stat(NORMAL_DIR_NAME); + assertTrue(dirMeta.isDir()); + } + + /** + * Stat special file and dir should return metadata + */ + @Test + public void testBlockingReadOnlyStatSpecialChars() { + final Metadata fileMeta = blockingOp().stat(SPECIAL_FILE_NAME); + assertTrue(fileMeta.isFile()); + assertEquals(FILE_LENGTH, fileMeta.getContentLength()); + + final Metadata dirMeta = blockingOp().stat(SPECIAL_DIR_NAME); + assertTrue(dirMeta.isDir()); + } + + /** + * Stat not exist file should return NotFound + */ + @Test + public void testBlockingReadOnlyStatNotExist() { + final String path = UUID.randomUUID().toString(); + assertThatThrownBy(() -> blockingOp().stat(path)) + .is(OpenDALExceptionCondition.ofSync(OpenDALException.Code.NotFound)); + } + + /** + * Read full content should match. + */ + @Test + public void testBlockingReadonlyReadFull() throws NoSuchAlgorithmException { + final byte[] content = blockingOp().read(NORMAL_FILE_NAME); + assertEquals(FILE_LENGTH, content.length); + assertEquals(FILE_SHA256_DIGEST, sha256Digest(content)); + } + + /** + * Read not exist file should return NotFound + */ + @Test + public void testBlockingReadOnlyReadNotExist() { + final String path = UUID.randomUUID().toString(); + assertThatThrownBy(() -> blockingOp().read(path)) + .is(OpenDALExceptionCondition.ofSync(OpenDALException.Code.NotFound)); + } +}
