/**
* 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.hadoop.fs.azure;
import java.io.FileNotFoundException;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsAction;
import org.apache.hadoop.fs.permission.FsPermission;
import org.junit.After;
import org.junit.Test;
public class TestFileSystemOperationsExceptionHandlingMultiThreaded
extends AbstractWasbTestBase {
FSDataInputStream inputStream = null;
private static Path testPath = new Path("testfile.dat");
private static Path testFolderPath = new Path("testfolder");
/*
* Helper method to creates an input stream to test various scenarios.
*/
private void getInputStreamToTest(FileSystem fs, Path testPath) throws Throwable {
FSDataOutputStream outputStream = fs.create(testPath);
String testString = "This is a test string";
outputStream.write(testString.getBytes());
outputStream.close();
inputStream = fs.open(testPath);
}
/*
* Test to validate correct exception is thrown for Multithreaded read
* scenario for block blobs
*/
@Test(expected=FileNotFoundException.class)
public void testMultiThreadedBlockBlobReadScenario() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
fs = testAccount.getFileSystem();
Path testFilePath1 = new Path("test1.dat");
getInputStreamToTest(fs, testFilePath1);
Thread renameThread = new Thread(new RenameThread(fs, testFilePath1));
renameThread.start();
renameThread.join();
byte[] readBuffer = new byte[512];
inputStream.read(readBuffer);
}
/*
* Test to validate correct exception is thrown for Multithreaded seek
* scenario for block blobs
*/
@Test(expected=FileNotFoundException.class)
public void testMultiThreadBlockBlobSeekScenario() throws Throwable {
AzureBlobStorageTestAccount testAccount = createTestAccount();
fs = testAccount.getFileSystem();
Path testFilePath1 = new Path("test1.dat");
getInputStreamToTest(fs, testFilePath1);
Thread renameThread = new Thread(new RenameThread(fs, testFilePath1));
renameThread.start();
renameThread.join();
inputStream.seek(5);
}
@Test(expected=FileNotFoundException.class)
/*
* Tests basic multi threaded setPermission scenario
*/
public void testMultiThreadedPageBlobSetPermissionScenario() throws Throwable {
ExceptionHandlingTestHelper.createEmptyFile(ExceptionHandlingTestHelper.getPageBlobTestStorageAccount(),
testPath);
Thread t = new Thread(new DeleteThread(fs, testPath));
t.start();
while (t.isAlive()) {
fs.setPermission(testPath, new FsPermission(FsAction.EXECUTE, FsAction.READ, FsAction.READ));
}
fs.setPermission(testPath, new FsPermission(FsAction.EXECUTE, FsAction.READ, FsAction.READ));
}
@Test(expected=FileNotFoundException.class)
/*
* Tests basic multi threaded setPermission scenario
*/
public void testMultiThreadedBlockBlobSetPermissionScenario() throws Throwable {
ExceptionHandlingTestHelper.createEmptyFile(createTestAccount(),
testPath);
Thread t = new Thread(new DeleteThread(fs, testPath));
t.start();
while (t.isAlive()) {
fs.setPermission(testPath, new FsPermission(FsAction.EXECUTE, FsAction.READ, FsAction.READ));
}
fs.setPermission(testPath, new FsPermission(FsAction.EXECUTE, FsAction.READ, FsAction.READ));
}
@Test(expected=FileNotFoundException.class)
/*
* Tests basic multi threaded setPermission scenario
*/
public void testMultiThreadedPageBlobOpenScenario() throws Throwable {
ExceptionHandlingTestHelper.createEmptyFile(createTestAccount(),
testPath);
Thread t = new Thread(new DeleteThread(fs, testPath));
t.start();
while (t.isAlive()) {
inputStream = fs.open(testPath);
inputStream.close();
}
inputStream = fs.open(testPath);
inputStream.close();
}
@Test(expected=FileNotFoundException.class)
/*
* Tests basic multi threaded setPermission scenario
*/
public void testMultiThreadedBlockBlobOpenScenario() throws Throwable {
ExceptionHandlingTestHelper.createEmptyFile(ExceptionHandlingTestHelper.getPageBlobTestStorageAccount(),
testPath);
Thread t = new Thread(new DeleteThread(fs, testPath));
t.start();
while (t.isAlive()) {
inputStream = fs.open(testPath);
inputStream.close();
}
inputStream = fs.open(testPath);
inputStream.close();
}
@Test(expected=FileNotFoundException.class)
/*
* Tests basic multi threaded setOwner scenario
*/
public void testMultiThreadedBlockBlobSetOwnerScenario() throws Throwable {
ExceptionHandlingTestHelper.createEmptyFile(createTestAccount(), testPath);
Thread t = new Thread(new DeleteThread(fs, testPath));
t.start();
while (t.isAlive()) {
fs.setOwner(testPath, "testowner", "testgroup");
}
fs.setOwner(testPath, "testowner", "testgroup");
}
@Test(expected=FileNotFoundException.class)
/*
* Tests basic multi threaded setOwner scenario
*/
public void testMultiThreadedPageBlobSetOwnerScenario() throws Throwable {
ExceptionHandlingTestHelper.createEmptyFile(ExceptionHandlingTestHelper.getPageBlobTestStorageAccount(),
testPath);
Thread t = new Thread(new DeleteThread(fs, testPath));
t.start();
while (t.isAlive()) {
fs.setOwner(testPath, "testowner", "testgroup");
}
fs.setOwner(testPath, "testowner", "testgroup");
}
@Test(expected=FileNotFoundException.class)
/*
* Tests basic multi threaded listStatus scenario
*/
public void testMultiThreadedBlockBlobListStatusScenario() throws Throwable {
ExceptionHandlingTestHelper.createTestFolder(createTestAccount(), testFolderPath);
Thread t = new Thread(new DeleteThread(fs, testFolderPath));
t.start();
while (t.isAlive()) {
fs.listStatus(testFolderPath);
}
fs.listStatus(testFolderPath);
}
@Test(expected=FileNotFoundException.class)
/*
* Tests basic multi threaded listStatus scenario
*/
public void testMultiThreadedPageBlobListStatusScenario() throws Throwable {
ExceptionHandlingTestHelper.createTestFolder(ExceptionHandlingTestHelper.getPageBlobTestStorageAccount(),
testFolderPath);
Thread t = new Thread(new DeleteThread(fs, testFolderPath));
t.start();
while (t.isAlive()) {
fs.listStatus(testFolderPath);
}
fs.listStatus(testFolderPath);
}
/*
* Test to validate correct exception is thrown for Multithreaded read
* scenario for page blobs
*/
@Test(expected=FileNotFoundException.class)
public void testMultiThreadedPageBlobReadScenario() throws Throwable {
AzureBlobStorageTestAccount testAccount = ExceptionHandlingTestHelper.getPageBlobTestStorageAccount();
fs = testAccount.getFileSystem();
Path testFilePath1 = new Path("test1.dat");
getInputStreamToTest(fs, testFilePath1);
Thread renameThread = new Thread(new RenameThread(fs, testFilePath1));
renameThread.start();
renameThread.join();
byte[] readBuffer = new byte[512];
inputStream.read(readBuffer);
}
/*
* Test to validate correct exception is thrown for Multithreaded seek
* scenario for page blobs
*/
@Test(expected=FileNotFoundException.class)
public void testMultiThreadedPageBlobSeekScenario() throws Throwable {
AzureBlobStorageTestAccount testAccount = ExceptionHandlingTestHelper.getPageBlobTestStorageAccount();
fs = testAccount.getFileSystem();
Path testFilePath1 = new Path("test1.dat");
getInputStreamToTest(fs, testFilePath1);
Thread renameThread = new Thread(new RenameThread(fs, testFilePath1));
renameThread.start();
renameThread.join();
inputStream.seek(5);
}
@Override
protected AzureBlobStorageTestAccount createTestAccount() throws Exception {
return AzureBlobStorageTestAccount.create();
}
@After
public void tearDown() throws Exception {
if (inputStream != null) {
inputStream.close();
}
if (fs != null && fs.exists(testPath)) {
fs.delete(testPath, true);
}
}
}
/*
* Helper thread that just renames the test file.
*/
class RenameThread implements Runnable {
private FileSystem fs;
private Path testPath;
private Path renamePath = new Path("test2.dat");
public RenameThread(FileSystem fs, Path testPath) {
this.fs = fs;
this.testPath = testPath;
}
@Override
public void run(){
try {
fs.rename(testPath, renamePath);
}catch (Exception e) {
// Swallowing the exception as the
// correctness of the test is controlled
// by the other thread
}
}
}
class DeleteThread implements Runnable {
private FileSystem fs;
private Path testPath;
public DeleteThread(FileSystem fs, Path testPath) {
this.fs = fs;
this.testPath = testPath;
}
@Override
public void run() {
try {
fs.delete(testPath, true);
} catch (Exception e) {
// Swallowing the exception as the
// correctness of the test is controlled
// by the other thread
}
}
}