/**
* 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 org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.Assert;
import org.junit.Test;
/***
* Test class to hold all Live Azure storage concurrency tests.
*/
public class TestNativeAzureFileSystemConcurrencyLive
extends AbstractWasbTestBase {
private static final int TEST_COUNT = 102;
@Override
protected AzureBlobStorageTestAccount createTestAccount() throws Exception {
return AzureBlobStorageTestAccount.create();
}
/**
* Test multi-threaded deletes in WASB. Expected behavior is one of the thread
* should be to successfully delete the file and return true and all other
* threads need to return false.
*/
@Test
public void testMultiThreadedDeletes() throws Exception {
Path testFile = new Path("test.dat");
fs.create(testFile).close();
int threadCount = TEST_COUNT;
DeleteHelperThread[] helperThreads = new DeleteHelperThread[threadCount];
for (int i = 0; i < threadCount; i++) {
helperThreads[i] = new DeleteHelperThread(fs, testFile);
}
Thread[] threads = new Thread[threadCount];
for (int i = 0; i < threadCount; i++) {
threads[i] = new Thread(helperThreads[i]);
threads[i].start();
}
for (int i = 0; i < threadCount; i++) {
threads[i].join();
}
boolean deleteSuccess = false;
for (int i = 0; i < threadCount; i++) {
Assert.assertFalse("child thread has exception : " + helperThreads[i].getException(),
helperThreads[i].getExceptionEncounteredFlag());
if (deleteSuccess) {
Assert.assertFalse("More than one thread delete() retuhelperThreads[i].getDeleteSuccess()",
helperThreads[i].getExceptionEncounteredFlag());
} else {
deleteSuccess = helperThreads[i].getDeleteSuccess();
}
}
Assert.assertTrue("No successfull delete found", deleteSuccess);
}
}
class DeleteHelperThread implements Runnable {
private FileSystem fs;
private Path p;
private boolean deleteSuccess;
private boolean exceptionEncountered;
private Exception ex;
public DeleteHelperThread(FileSystem fs, Path p) {
this.fs = fs;
this.p = p;
}
public void run() {
try {
deleteSuccess = fs.delete(p, false);
} catch (Exception ioEx) {
exceptionEncountered = true;
this.ex = ioEx;
}
}
public boolean getDeleteSuccess() {
return deleteSuccess;
}
public boolean getExceptionEncounteredFlag() {
return exceptionEncountered;
}
public Exception getException() {
return ex;
}
}