much juicier tests pass and cause the broker to solidify significantly
yeah, I know, those tests are nasty... but so is what we're trying to do here git-svn-id: http://google-refine.googlecode.com/svn/trunk@1072 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
parent
b0b5e5b781
commit
8997264df0
@ -54,7 +54,7 @@ public abstract class GridworksBroker extends ButterflyModuleImpl {
|
||||
static final public String OPEN = "open";
|
||||
|
||||
static final public int ALL = 0;
|
||||
static final public int COLUMN = 1;
|
||||
static final public int COL = 1;
|
||||
static final public int CELL = 2;
|
||||
|
||||
static final protected Logger logger = LoggerFactory.getLogger("gridworks.broker");
|
||||
|
@ -161,6 +161,7 @@ public class GridworksBrokerImpl extends GridworksBroker {
|
||||
protected void obtainLock(HttpServletResponse response, String pid, String uid, int locktype, String lockvalue) throws Exception {
|
||||
logger.trace("> obtain lock");
|
||||
Lock lock = null;
|
||||
Lock blocker = null;
|
||||
|
||||
Transaction txn = env.beginTransaction(null, null);
|
||||
|
||||
@ -168,27 +169,68 @@ public class GridworksBrokerImpl extends GridworksBroker {
|
||||
|
||||
EntityCursor<Lock> cursor = locksByProject.subIndex(pid).entities();
|
||||
|
||||
/*
|
||||
* ALL
|
||||
* blocked -> somebody else's lock
|
||||
* reuse -> you already have an ALL lock
|
||||
* new -> else
|
||||
*
|
||||
* COL
|
||||
* blocked -> somebody else's all lock || a lock on the same col
|
||||
* reuse -> you have an ALL lock || a lock on the same col
|
||||
* new -> else
|
||||
*
|
||||
* CELL
|
||||
* blocked -> somebody else's all lock || a lock on the same col || a lock on the same cell
|
||||
* reuse -> you have a lock on the same cell
|
||||
* yes -> (you have a lock on the same cell) && (nobody else has a lock on the same cell || the same col || all)
|
||||
* new -> else
|
||||
*
|
||||
*/
|
||||
|
||||
try {
|
||||
for (Lock l : cursor) {
|
||||
logger.info("found lock: {}", l.id);
|
||||
|
||||
if (locktype == ALL) {
|
||||
if (l.type == ALL) {
|
||||
lock = l;
|
||||
if (locktype == ALL) {
|
||||
for (Lock l : cursor) {
|
||||
if (!l.uid.equals(uid)) {
|
||||
blocker = l;
|
||||
break;
|
||||
} else {
|
||||
if (l.type == ALL) {
|
||||
lock = l;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (locktype == COLUMN) {
|
||||
if (l.type == ALL ||
|
||||
(l.type == COLUMN && l.value.equals(lockvalue))) {
|
||||
lock = l;
|
||||
break;
|
||||
}
|
||||
} else if (locktype == COL) {
|
||||
for (Lock l : cursor) {
|
||||
if (!l.uid.equals(uid)) {
|
||||
if (l.type == ALL ||
|
||||
(l.type == COL && l.value.equals(lockvalue))) {
|
||||
blocker = l;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (l.type == ALL ||
|
||||
(l.type == COL && l.value.equals(lockvalue))) {
|
||||
lock = l;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (locktype == CELL) {
|
||||
if (l.type == ALL ||
|
||||
(l.type == COLUMN && l.value.equals(lockvalue.split(",")[0])) ||
|
||||
(l.type == CELL && l.value.equals(lockvalue))) {
|
||||
lock = l;
|
||||
break;
|
||||
}
|
||||
} else if (locktype == CELL) {
|
||||
for (Lock l : cursor) {
|
||||
if (!l.uid.equals(uid)) {
|
||||
if (l.type == ALL ||
|
||||
(l.type == COL && l.value.equals(lockvalue.split(",")[0])) ||
|
||||
(l.type == CELL && l.value.equals(lockvalue))) {
|
||||
blocker = l;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (l.type == CELL && l.value.equals(lockvalue)) {
|
||||
lock = l;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -196,8 +238,13 @@ public class GridworksBrokerImpl extends GridworksBroker {
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
if (blocker != null) {
|
||||
logger.info("found a blocking lock {}", lockToString(blocker));
|
||||
throw new RuntimeException("Can't obtain lock, it is blocked by a type '" + blocker.type + "' lock owned by '" + blocker.uid + "'");
|
||||
}
|
||||
|
||||
if (lock == null) {
|
||||
logger.info("no lock found, creating new");
|
||||
logger.info("no comparable lock already exists, creating a new one");
|
||||
lock = new Lock(Long.toHexString(txn.getId()), pid, uid, locktype, lockvalue);
|
||||
lockById.put(txn, lock);
|
||||
txn.commit();
|
||||
@ -287,6 +334,8 @@ public class GridworksBrokerImpl extends GridworksBroker {
|
||||
|
||||
Lock lock = getLock(lid, pid, uid);
|
||||
|
||||
logger.info("obtained lock: {}", lockToString(lock));
|
||||
|
||||
if (lock.type == ALL) {
|
||||
project.transformations.addAll(transformations);
|
||||
} else {
|
||||
@ -295,8 +344,8 @@ public class GridworksBrokerImpl extends GridworksBroker {
|
||||
|
||||
int type = o.getInt("op_type");
|
||||
String value = o.getString("op_value");
|
||||
if (lock.type == COLUMN) {
|
||||
if (type == COLUMN) {
|
||||
if (lock.type == COL) {
|
||||
if (type == COL) {
|
||||
if (value != null && value.equals(lock.value)) {
|
||||
project.transformations.add(s);
|
||||
} else {
|
||||
@ -311,7 +360,7 @@ public class GridworksBrokerImpl extends GridworksBroker {
|
||||
}
|
||||
}
|
||||
} else if (lock.type == CELL) {
|
||||
if (type == COLUMN) {
|
||||
if (type == COL) {
|
||||
throw new RuntimeException("Can't apply '" + s + "': you offered a lock for a single cell and you're attempting an operation for the entire column.");
|
||||
} else if (type == CELL) {
|
||||
if (value != null && value.equals(lock.value)) {
|
||||
@ -324,6 +373,8 @@ public class GridworksBrokerImpl extends GridworksBroker {
|
||||
}
|
||||
}
|
||||
|
||||
projectById.put(txn, project);
|
||||
|
||||
txn.commit();
|
||||
} finally {
|
||||
if (txn != null) {
|
||||
@ -374,7 +425,7 @@ public class GridworksBrokerImpl extends GridworksBroker {
|
||||
writer.array();
|
||||
int size = project.transformations.size();
|
||||
for (int i = rev; i < size; i++) {
|
||||
writer.value(project.transformations.get(i));
|
||||
writer.value(new JSONObject(project.transformations.get(i)));
|
||||
}
|
||||
writer.endArray();
|
||||
|
||||
@ -489,6 +540,10 @@ public class GridworksBrokerImpl extends GridworksBroker {
|
||||
return o;
|
||||
}
|
||||
|
||||
String lockToString(Lock lock) {
|
||||
return lock.id + "," + lock.pid + "," + lock.uid + "," + lock.type + "," + lock.value;
|
||||
}
|
||||
|
||||
@Entity
|
||||
static class Lock {
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.metaweb.gridworks.broker.tests;
|
||||
|
||||
import static com.metaweb.gridworks.broker.GridworksBroker.ALL;
|
||||
import static com.metaweb.gridworks.broker.GridworksBroker.*;
|
||||
import static com.metaweb.gridworks.broker.GridworksBroker.EXPIRE;
|
||||
import static com.metaweb.gridworks.broker.GridworksBroker.GET_STATE;
|
||||
import static com.metaweb.gridworks.broker.GridworksBroker.OBTAIN_LOCK;
|
||||
@ -109,8 +109,7 @@ public class GridworksBrokerTests {
|
||||
@Test
|
||||
public void testService() {
|
||||
try {
|
||||
JSONObject result = call(broker, request, response, EXPIRE);
|
||||
assertJSON(result, "status", "ok");
|
||||
success(broker, request, response, EXPIRE);
|
||||
} catch (Exception e) {
|
||||
Assert.fail();
|
||||
}
|
||||
@ -119,8 +118,7 @@ public class GridworksBrokerTests {
|
||||
@Test
|
||||
public void testObtainLockFailure() {
|
||||
try {
|
||||
JSONObject result = call(broker, request, response, OBTAIN_LOCK);
|
||||
assertJSON(result, "status", "error");
|
||||
failure(broker, request, response, OBTAIN_LOCK);
|
||||
} catch (Exception e) {
|
||||
Assert.fail();
|
||||
}
|
||||
@ -129,8 +127,7 @@ public class GridworksBrokerTests {
|
||||
@Test
|
||||
public void testReleaseLockFailure() {
|
||||
try {
|
||||
JSONObject result = call(broker, request, response, RELEASE_LOCK);
|
||||
assertJSON(result, "status", "error");
|
||||
failure(broker, request, response, RELEASE_LOCK);
|
||||
} catch (Exception e) {
|
||||
Assert.fail();
|
||||
}
|
||||
@ -139,37 +136,120 @@ public class GridworksBrokerTests {
|
||||
@Test
|
||||
public void testStartProject() {
|
||||
try {
|
||||
String project = "1";
|
||||
String project = "proj1";
|
||||
String user = "testuser";
|
||||
String user2 = "testuser2";
|
||||
String data = "blah";
|
||||
String metadata = "{}";
|
||||
String rev = "0";
|
||||
|
||||
JSONObject result = call(broker, request, response, OBTAIN_LOCK, "pid", project, "uid", user, "locktype", Integer.toString(ALL), "lockvalue", "");
|
||||
logger.info("--- obtain ALL lock on project ---");
|
||||
JSONObject result = success(broker, request, response, OBTAIN_LOCK, "pid", project, "uid", user, "locktype", Integer.toString(ALL), "lockvalue", "");
|
||||
assertJSON(result, "uid", "testuser");
|
||||
String lock = result.getString("lock");
|
||||
|
||||
result = call(broker, request, response, START, "pid", project, "uid", user, "lock", lock, "data", data, "metadata", metadata, "rev", rev);
|
||||
assertJSON(result, "status", "ok");
|
||||
logger.info("--- start project ---");
|
||||
success(broker, request, response, START, "pid", project, "uid", user, "lock", lock, "data", data, "metadata", metadata, "rev", rev);
|
||||
|
||||
result = call(broker, request, response, GET_STATE, "pid", project, "uid", user, "rev", rev);
|
||||
logger.info("--- verify project state contains lock ---");
|
||||
result = success(broker, request, response, GET_STATE, "pid", project, "uid", user, "rev", rev);
|
||||
JSONArray locks = result.getJSONArray("locks");
|
||||
Assert.assertEquals(locks.length(), 1);
|
||||
JSONObject l = locks.getJSONObject(0);
|
||||
assertJSON(l, "uid", "testuser");
|
||||
Assert.assertEquals(l.getInt("type"), ALL);
|
||||
|
||||
result = call(broker, request, response, RELEASE_LOCK, "pid", project, "uid", user, "lock", lock);
|
||||
assertJSON(result, "status", "ok");
|
||||
logger.info("--- release ALL lock on project ---");
|
||||
success(broker, request, response, RELEASE_LOCK, "pid", project, "uid", user, "lock", lock);
|
||||
|
||||
result = call(broker, request, response, GET_STATE, "pid", project, "uid", user, "rev", rev);
|
||||
logger.info("--- verify no locks are present ---");
|
||||
result = success(broker, request, response, GET_STATE, "pid", project, "uid", user, "rev", rev);
|
||||
locks = result.getJSONArray("locks");
|
||||
Assert.assertEquals(locks.length(), 0);
|
||||
|
||||
result = call(broker, request, response, OPEN, "pid", project, "uid", user, "rev", rev);
|
||||
assertJSON(result, "status", "ok");
|
||||
logger.info("--- open project and verify data was loaded correctly ---");
|
||||
result = success(broker, request, response, OPEN, "pid", project, "uid", user, "rev", rev);
|
||||
JSONArray result_data = result.getJSONArray("data");
|
||||
Assert.assertEquals(result_data.length(),data.getBytes("UTF-8").length);
|
||||
|
||||
JSONArray tt;
|
||||
JSONObject t;
|
||||
|
||||
logger.info("--- obtain column lock ---");
|
||||
String column = "1";
|
||||
result = success(broker, request, response, OBTAIN_LOCK, "pid", project, "uid", user, "locktype", Integer.toString(COL), "lockvalue", column);
|
||||
String col_lock = result.getString("lock");
|
||||
|
||||
logger.info("--- perform column transformation ---");
|
||||
t = new JSONObject();
|
||||
t.put("op_type", COL);
|
||||
t.put("op_value", column); // operate on col 1
|
||||
t.put("value", new JSONObject());
|
||||
tt = new JSONArray();
|
||||
tt.put(t);
|
||||
result = success(broker, request, response, TRANSFORM, "pid", project, "uid", user, "lock", col_lock, "transformations", tt.toString());
|
||||
|
||||
logger.info("--- make sure transformation was recorded properly ---");
|
||||
result = success(broker, request, response, GET_STATE, "pid", project, "uid", user, "rev", "0");
|
||||
tt = result.getJSONArray("transformations");
|
||||
Assert.assertEquals(tt.length(), 1);
|
||||
t = tt.getJSONObject(0);
|
||||
assertJSON(t, "op_value", column);
|
||||
|
||||
logger.info("--- make sure revision numbers in state management work as expected ---");
|
||||
result = success(broker, request, response, GET_STATE, "pid", project, "uid", user, "rev", "1");
|
||||
tt = result.getJSONArray("transformations");
|
||||
Assert.assertEquals(tt.length(), 0);
|
||||
|
||||
logger.info("--- perform cell transformation ---");
|
||||
String cell = "1";
|
||||
t = new JSONObject();
|
||||
t.put("op_type", CELL);
|
||||
t.put("op_value", column + "," + cell); // operate on cell at row 1 column 1
|
||||
t.put("value", new JSONObject());
|
||||
tt = new JSONArray();
|
||||
tt.put(t);
|
||||
result = success(broker, request, response, TRANSFORM, "pid", project, "uid", user, "lock", col_lock, "transformations", tt.toString());
|
||||
|
||||
logger.info("--- make sure transformation was recorded properly ---");
|
||||
result = success(broker, request, response, GET_STATE, "pid", project, "uid", user, "rev", "0");
|
||||
tt = result.getJSONArray("transformations");
|
||||
Assert.assertEquals(tt.length(), 2);
|
||||
|
||||
result = success(broker, request, response, GET_STATE, "pid", project, "uid", user, "rev", "1");
|
||||
tt = result.getJSONArray("transformations");
|
||||
Assert.assertEquals(tt.length(), 1);
|
||||
t = tt.getJSONObject(0);
|
||||
assertJSON(t, "op_value", column + "," + cell);
|
||||
|
||||
logger.info("--- make sure another user fails to acquire ALL lock ---");
|
||||
failure(broker, request, response, OBTAIN_LOCK, "pid", project, "uid", user2, "locktype", Integer.toString(ALL), "lockvalue", column);
|
||||
|
||||
logger.info("--- make sure another user fails to acquire COL lock on the same column ---");
|
||||
failure(broker, request, response, OBTAIN_LOCK, "pid", project, "uid", user2, "locktype", Integer.toString(COL), "lockvalue", column);
|
||||
|
||||
logger.info("--- make sure another user manages to acquire COL lock on another column ---");
|
||||
String column2 = "2";
|
||||
result = success(broker, request, response, OBTAIN_LOCK, "pid", project, "uid", user2, "locktype", Integer.toString(COL), "lockvalue", column2);
|
||||
String col_lock2 = result.getString("lock");
|
||||
|
||||
logger.info("--- make sure that both locks are present ---");
|
||||
result = success(broker, request, response, GET_STATE, "pid", project, "uid", user, "rev", "2");
|
||||
locks = result.getJSONArray("locks");
|
||||
Assert.assertEquals(locks.length(), 2);
|
||||
|
||||
logger.info("--- make sure we can't escalate our current COL lock to an ALL lock ---");
|
||||
failure(broker, request, response, OBTAIN_LOCK, "pid", project, "uid", user, "locktype", Integer.toString(ALL), "lockvalue", "");
|
||||
|
||||
logger.info("--- release column locks ---");
|
||||
success(broker, request, response, RELEASE_LOCK, "pid", project, "uid", user, "lock", col_lock);
|
||||
success(broker, request, response, RELEASE_LOCK, "pid", project, "uid", user2, "lock", col_lock2);
|
||||
|
||||
logger.info("--- make sure the project has no locks ---");
|
||||
result = success(broker, request, response, GET_STATE, "pid", project, "uid", user, "rev", "2");
|
||||
locks = result.getJSONArray("locks");
|
||||
Assert.assertEquals(locks.length(), 0);
|
||||
|
||||
} catch (Exception e) {
|
||||
Assert.fail();
|
||||
}
|
||||
@ -181,7 +261,15 @@ public class GridworksBrokerTests {
|
||||
Assert.assertEquals(o.get(name), value);
|
||||
}
|
||||
|
||||
private JSONObject call(GridworksBroker broker, HttpServletRequest request, HttpServletResponse response, String service, String... params) throws Exception {
|
||||
private JSONObject success(GridworksBroker broker, HttpServletRequest request, HttpServletResponse response, String service, String... params) throws Exception {
|
||||
return call(true, broker, request, response, service, params);
|
||||
}
|
||||
|
||||
private JSONObject failure(GridworksBroker broker, HttpServletRequest request, HttpServletResponse response, String service, String... params) throws Exception {
|
||||
return call(false, broker, request, response, service, params);
|
||||
}
|
||||
|
||||
private JSONObject call(boolean successful, GridworksBroker broker, HttpServletRequest request, HttpServletResponse response, String service, String... params) throws Exception {
|
||||
if (params != null) {
|
||||
for (int i = 0; i < params.length; ) {
|
||||
String name = params[i++];
|
||||
@ -206,8 +294,14 @@ public class GridworksBrokerTests {
|
||||
|
||||
JSONObject result = new JSONObject(writer.toString());
|
||||
|
||||
logger.info(result.toString());
|
||||
if (successful) {
|
||||
assertJSON(result, "status", "ok");
|
||||
} else {
|
||||
assertJSON(result, "status", "error");
|
||||
}
|
||||
|
||||
logger.info(result.toString());
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user