blob: 25b659875a39054cee85e4daf622cce221ef36ee [file] [log] [blame]
/**
* 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.oozie.util;
import org.apache.oozie.test.XTestCase;
public class TestMemoryLocks extends XTestCase {
private XLog log = XLog.getLog(getClass());
private MemoryLocks locks;
protected void setUp() throws Exception {
super.setUp();
locks = new MemoryLocks();
}
protected void tearDown() throws Exception {
locks = null;
super.tearDown();
}
public abstract class Locker implements Runnable {
protected String name;
private String nameIndex;
private StringBuffer sb;
protected long timeout;
public Locker(String name, int nameIndex, long timeout, StringBuffer buffer) {
this.name = name;
this.nameIndex = name + ":" + nameIndex;
this.sb = buffer;
this.timeout = timeout;
}
public void run() {
try {
log.info("Getting lock [{0}]", nameIndex);
MemoryLocks.LockToken token = getLock();
if (token != null) {
log.info("Got lock [{0}]", nameIndex);
sb.append(nameIndex + "-L ");
synchronized (this) {
wait();
}
sb.append(nameIndex + "-U ");
token.release();
log.info("Release lock [{0}]", nameIndex);
}
else {
sb.append(nameIndex + "-N ");
log.info("Did not get lock [{0}]", nameIndex);
}
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public void finish() {
synchronized (this) {
notify();
}
}
protected abstract MemoryLocks.LockToken getLock() throws InterruptedException;
}
public class ReadLocker extends Locker {
public ReadLocker(String name, int nameIndex, long timeout, StringBuffer buffer) {
super(name, nameIndex, timeout, buffer);
}
protected MemoryLocks.LockToken getLock() throws InterruptedException {
return locks.getReadLock(name, timeout);
}
}
public class WriteLocker extends Locker {
public WriteLocker(String name, int nameIndex, long timeout, StringBuffer buffer) {
super(name, nameIndex, timeout, buffer);
}
protected MemoryLocks.LockToken getLock() throws InterruptedException {
return locks.getWriteLock(name, timeout);
}
}
public void testWaitWriteLock() throws Exception {
StringBuffer sb = new StringBuffer("");
Locker l1 = new WriteLocker("a", 1, -1, sb);
Locker l2 = new WriteLocker("a", 2, -1, sb);
new Thread(l1).start();
Thread.sleep(500);
new Thread(l2).start();
Thread.sleep(500);
l1.finish();
Thread.sleep(500);
l2.finish();
Thread.sleep(500);
assertEquals("a:1-L a:1-U a:2-L a:2-U", sb.toString().trim());
}
public void testNoWaitWriteLock() throws Exception {
StringBuffer sb = new StringBuffer("");
Locker l1 = new WriteLocker("a", 1, 0, sb);
Locker l2 = new WriteLocker("a", 2, 0, sb);
new Thread(l1).start();
Thread.sleep(500);
new Thread(l2).start();
Thread.sleep(500);
l1.finish();
Thread.sleep(500);
l2.finish();
Thread.sleep(500);
assertEquals("a:1-L a:2-N a:1-U", sb.toString().trim());
}
public void testTimeoutWaitingWriteLock() throws Exception {
StringBuffer sb = new StringBuffer("");
Locker l1 = new WriteLocker("a", 1, 0, sb);
Locker l2 = new WriteLocker("a", 2, 1000, sb);
new Thread(l1).start();
Thread.sleep(500);
new Thread(l2).start();
Thread.sleep(500);
l1.finish();
Thread.sleep(500);
l2.finish();
Thread.sleep(500);
assertEquals("a:1-L a:1-U a:2-L a:2-U", sb.toString().trim());
}
public void testTimeoutTimingOutWriteLock() throws Exception {
StringBuffer sb = new StringBuffer("");
Locker l1 = new WriteLocker("a", 1, 0, sb);
Locker l2 = new WriteLocker("a", 2, 50, sb);
new Thread(l1).start();
Thread.sleep(500);
new Thread(l2).start();
Thread.sleep(500);
l1.finish();
Thread.sleep(500);
l2.finish();
Thread.sleep(500);
assertEquals("a:1-L a:2-N a:1-U", sb.toString().trim());
}
public void testReadLock() throws Exception {
StringBuffer sb = new StringBuffer("");
Locker l1 = new ReadLocker("a", 1, -1, sb);
Locker l2 = new ReadLocker("a", 2, -1, sb);
new Thread(l1).start();
Thread.sleep(500);
new Thread(l2).start();
Thread.sleep(500);
l1.finish();
Thread.sleep(500);
l2.finish();
Thread.sleep(500);
assertEquals("a:1-L a:2-L a:1-U a:2-U", sb.toString().trim());
}
public void testReadWriteLock() throws Exception {
StringBuffer sb = new StringBuffer("");
Locker l1 = new ReadLocker("a", 1, -1, sb);
Locker l2 = new WriteLocker("a", 2, -1, sb);
new Thread(l1).start();
Thread.sleep(500);
new Thread(l2).start();
Thread.sleep(500);
l1.finish();
Thread.sleep(500);
l2.finish();
Thread.sleep(500);
assertEquals("a:1-L a:1-U a:2-L a:2-U", sb.toString().trim());
}
public void testWriteReadLock() throws Exception {
StringBuffer sb = new StringBuffer("");
Locker l1 = new WriteLocker("a", 1, -1, sb);
Locker l2 = new ReadLocker("a", 2, -1, sb);
new Thread(l1).start();
Thread.sleep(500);
new Thread(l2).start();
Thread.sleep(500);
l1.finish();
Thread.sleep(500);
l2.finish();
Thread.sleep(500);
assertEquals("a:1-L a:1-U a:2-L a:2-U", sb.toString().trim());
}
}