/*
* The Alluxio Open Foundation licenses this work under the Apache License, version 2.0
* (the "License"). You may not use this work except in compliance with the License, which is
* available at www.apache.org/licenses/LICENSE-2.0
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied, as more fully set forth in the License.
*
* See the NOTICE file distributed with this work for information regarding copyright ownership.
*/
package alluxio.underfs.sleepfs;
import alluxio.AlluxioURI;
import alluxio.underfs.UfsDirectoryStatus;
import alluxio.underfs.UfsFileStatus;
import alluxio.underfs.UfsStatus;
import alluxio.underfs.local.LocalUnderFileSystem;
import alluxio.underfs.options.CreateOptions;
import alluxio.underfs.options.DeleteOptions;
import alluxio.underfs.options.FileLocationOptions;
import alluxio.underfs.options.MkdirsOptions;
import alluxio.underfs.options.OpenOptions;
import alluxio.util.CommonUtils;
import alluxio.util.io.PathUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
/**
* An under file system for testing that sleeps a predefined amount of time before executing an
* operation. The operation behavior will be equivalent to that of {@link LocalUnderFileSystem}.
*/
public class SleepingUnderFileSystem extends LocalUnderFileSystem {
private static final String SLEEP_SCHEME = "sleep";
private final SleepingUnderFileSystemOptions mOptions;
/**
* Creates a new {@link SleepingUnderFileSystem} for the given uri.
*
* @param uri path belonging to this under file system
*/
public SleepingUnderFileSystem(AlluxioURI uri, SleepingUnderFileSystemOptions options) {
super(uri);
mOptions = options;
}
@Override
public void close() throws IOException {
sleepIfNecessary(mOptions.getCloseMs());
super.close();
}
@Override
public void connectFromMaster(String hostname) throws IOException {
sleepIfNecessary(mOptions.getConnectFromMasterMs());
super.connectFromMaster(hostname);
}
@Override
public void connectFromWorker(String hostname) throws IOException {
sleepIfNecessary(mOptions.getConnectFromWorkerMs());
super.connectFromWorker(hostname);
}
@Override
public OutputStream create(String path, CreateOptions options) throws IOException {
sleepIfNecessary(mOptions.getCreateMs());
return super.create(cleanPath(path), options);
}
@Override
public OutputStream createDirect(String path, CreateOptions options) throws IOException {
sleepIfNecessary(mOptions.getCreateMs());
return super.createDirect(cleanPath(path), options);
}
@Override
public boolean deleteDirectory(String path, DeleteOptions options) throws IOException {
sleepIfNecessary(mOptions.getDeleteDirectoryMs());
return super.deleteDirectory(cleanPath(path), options);
}
@Override
public boolean deleteFile(String path) throws IOException {
sleepIfNecessary(mOptions.getDeleteFileMs());
return super.deleteFile(cleanPath(path));
}
@Override
public long getBlockSizeByte(String path) throws IOException {
sleepIfNecessary(mOptions.getGetBlockSizeByteMs());
return super.getBlockSizeByte(cleanPath(path));
}
@Override
public UfsDirectoryStatus getDirectoryStatus(String path) throws IOException {
sleepIfNecessary(mOptions.getGetFileStatusMs());
return super.getDirectoryStatus(cleanPath(path));
}
@Override
public List<String> getFileLocations(String path) throws IOException {
sleepIfNecessary(mOptions.getGetFileLocationsMs());
return super.getFileLocations(cleanPath(path));
}
@Override
public List<String> getFileLocations(String path, FileLocationOptions options)
throws IOException {
sleepIfNecessary(mOptions.getGetFileLocationsMs());
return super.getFileLocations(cleanPath(path), options);
}
@Override
public UfsFileStatus getFileStatus(String path) throws IOException {
sleepIfNecessary(mOptions.getGetFileStatusMs());
return super.getFileStatus(cleanPath(path));
}
@Override
public long getSpace(String path, SpaceType type) throws IOException {
sleepIfNecessary(mOptions.getGetSpaceMs());
return super.getSpace(cleanPath(path), type);
}
@Override
public String getUnderFSType() {
sleepIfNecessary(mOptions.getGetUnderFSTypeMs());
return super.getUnderFSType();
}
@Override
public boolean isDirectory(String path) throws IOException {
sleepIfNecessary(mOptions.getIsDirectoryMs());
return super.isDirectory(cleanPath(path));
}
@Override
public boolean isFile(String path) throws IOException {
sleepIfNecessary(mOptions.getIsFileMs());
return super.isFile(cleanPath(path));
}
@Override
public UfsStatus[] listStatus(String path) throws IOException {
sleepIfNecessary(mOptions.getListStatusMs());
return super.listStatus(cleanPath(path));
}
@Override
public boolean mkdirs(String path, MkdirsOptions options) throws IOException {
sleepIfNecessary(mOptions.getMkdirsMs());
return super.mkdirs(cleanPath(path), options);
}
@Override
public InputStream open(String path, OpenOptions options) throws IOException {
sleepIfNecessary(mOptions.getOpenMs());
return super.open(cleanPath(path), options);
}
@Override
public boolean renameDirectory(String src, String dst) throws IOException {
sleepIfNecessary(mOptions.getRenameDirectoryMs());
return super.renameDirectory(cleanPath(src), cleanPath(dst));
}
@Override
public boolean renameFile(String src, String dst) throws IOException {
if (!PathUtils.isTemporaryFileName(src)) {
sleepIfNecessary(mOptions.getRenameFileMs());
} else {
sleepIfNecessary(mOptions.getRenameTemporaryFileMs());
}
return super.renameFile(cleanPath(src), cleanPath(dst));
}
@Override
public void setOwner(String path, String owner, String group) throws IOException {
sleepIfNecessary(mOptions.getSetOwnerMs());
super.setOwner(cleanPath(path), owner, group);
}
@Override
public void setMode(String path, short mode) throws IOException {
sleepIfNecessary(mOptions.getSetModeMs());
super.setMode(cleanPath(path), mode);
}
@Override
public boolean supportsFlush() {
sleepIfNecessary(mOptions.getSupportsFlushMs());
return super.supportsFlush();
}
/**
* Removes the sleep scheme from the path if it exists.
*
* @param path the path to clean
* @return a path without the sleep scheme
*/
private String cleanPath(String path) {
AlluxioURI uri = new AlluxioURI(path);
if (SLEEP_SCHEME.equals(uri.getScheme())) {
return uri.getPath();
}
return path;
}
/**
* Waits for the specified duration if the duration is non-negative. A duration of 0 is
* equivalent to calling Thread.sleep(0).
*
* @param duration time to sleep, negative if the thread should not sleep
*/
private void sleepIfNecessary(long duration) {
if (duration >= 0) {
CommonUtils.sleepMs(duration);
}
}
}