|
@@ -19,6 +19,7 @@ package org.elasticsearch.core.internal.io;
|
|
|
|
|
|
import org.apache.lucene.mockfile.FilterFileSystemProvider;
|
|
|
import org.apache.lucene.mockfile.FilterPath;
|
|
|
+import org.apache.lucene.util.Constants;
|
|
|
import org.elasticsearch.common.CheckedConsumer;
|
|
|
import org.elasticsearch.common.io.PathUtils;
|
|
|
import org.elasticsearch.test.ESTestCase;
|
|
@@ -27,14 +28,20 @@ import java.io.Closeable;
|
|
|
import java.io.IOException;
|
|
|
import java.io.OutputStream;
|
|
|
import java.net.URI;
|
|
|
+import java.nio.channels.FileChannel;
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
import java.nio.file.AccessDeniedException;
|
|
|
import java.nio.file.FileSystem;
|
|
|
import java.nio.file.Files;
|
|
|
+import java.nio.file.NoSuchFileException;
|
|
|
+import java.nio.file.OpenOption;
|
|
|
import java.nio.file.Path;
|
|
|
+import java.nio.file.attribute.FileAttribute;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.List;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.Set;
|
|
|
import java.util.function.Function;
|
|
|
|
|
|
import static org.hamcrest.Matchers.arrayWithSize;
|
|
@@ -214,6 +221,43 @@ public class IOUtilsTests extends ESTestCase {
|
|
|
// no exception
|
|
|
}
|
|
|
|
|
|
+ private static final class AccessDeniedWhileOpeningDirectoryFileSystem extends FilterFileSystemProvider {
|
|
|
+
|
|
|
+ AccessDeniedWhileOpeningDirectoryFileSystem(final FileSystem delegate) {
|
|
|
+ super("access_denied://", Objects.requireNonNull(delegate));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public FileChannel newFileChannel(
|
|
|
+ final Path path,
|
|
|
+ final Set<? extends OpenOption> options,
|
|
|
+ final FileAttribute<?>... attrs) throws IOException {
|
|
|
+ if (Files.isDirectory(path)) {
|
|
|
+ throw new AccessDeniedException(path.toString());
|
|
|
+ }
|
|
|
+ return delegate.newFileChannel(path, options, attrs);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testFsyncAccessDeniedOpeningDirectory() throws Exception {
|
|
|
+ final Path path = createTempDir().toRealPath();
|
|
|
+ final FileSystem fs = new AccessDeniedWhileOpeningDirectoryFileSystem(path.getFileSystem()).getFileSystem(URI.create("file:///"));
|
|
|
+ final Path wrapped = new FilterPath(path, fs);
|
|
|
+ if (Constants.WINDOWS) {
|
|
|
+ // no exception, we early return and do not even try to open the directory
|
|
|
+ IOUtils.fsync(wrapped, true);
|
|
|
+ } else {
|
|
|
+ expectThrows(AccessDeniedException.class, () -> IOUtils.fsync(wrapped, true));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testFsyncNonExistentDirectory() throws Exception {
|
|
|
+ final Path dir = FilterPath.unwrap(createTempDir()).toRealPath();
|
|
|
+ final Path nonExistentDir = dir.resolve("non-existent");
|
|
|
+ expectThrows(NoSuchFileException.class, () -> IOUtils.fsync(nonExistentDir, true));
|
|
|
+ }
|
|
|
+
|
|
|
public void testFsyncFile() throws IOException {
|
|
|
final Path path = createTempDir().toRealPath();
|
|
|
final Path subPath = path.resolve(randomAlphaOfLength(8));
|