package org.swisspush.reststorage.lua;
import io.vertx.core.json.JsonObject;
import org.junit.Test;
import org.swisspush.reststorage.util.LockMode;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import static com.jayway.awaitility.Awaitility.await;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;
public class RedisPutLuaScriptTests extends AbstractLuaScriptTest {
private final static String COMPRESSED = "compressed";
private final static String RESOURCE = "resource";
private final static String ETAG = "etag";
private final static String OWNER = "owner";
private final static String MODE = "mode";
@Test
public void putResourcePathDepthIs3() {
// ACT
evalScriptPut(":project:server:test:test1:test2", "{\"content\": \"test/test1/test2\"}");
// ASSERT
assertThat("server", equalTo(jedis.zrangeByScore("rest-storage:collections:project", 0d, 9999999999999d).iterator().next()));
assertThat("test", equalTo(jedis.zrangeByScore("rest-storage:collections:project:server", 0d, 9999999999999d).iterator().next()));
assertThat("test1", equalTo(jedis.zrangeByScore("rest-storage:collections:project:server:test", 0d, 9999999999999d).iterator().next()));
assertThat("test2", equalTo(jedis.zrangeByScore("rest-storage:collections:project:server:test:test1", 0d, 9999999999999d).iterator().next()));
assertThat("{\"content\": \"test/test1/test2\"}", equalTo(jedis.hget("rest-storage:resources:project:server:test:test1:test2", RESOURCE)));
}
@Test
public void putResourcePathDepthIs3WithSiblings() {
// ACT
evalScriptPut(":project:server:test:test1:test2", "{\"content\": \"test/test1/test2\"}");
evalScriptPut(":project:server:test:test11", "{\"content\": \"test/test11\"}");
// ASSERT
assertThat(jedis.zrangeByScore("rest-storage:collections:project", 0d, 9999999999999d).iterator().next(), equalTo("server"));
assertThat(jedis.zrangeByScore("rest-storage:collections:project:server", 0d, 9999999999999d).iterator().next(), equalTo("test"));
assertThat(jedis.zrangeByScore("rest-storage:collections:project:server:test", 0d, 9999999999999d).iterator().next(), equalTo("test1"));
assertThat(jedis.zrangeByScore("rest-storage:collections:project:server:test:test1", 0d, 9999999999999d).iterator().next(), equalTo("test2"));
assertThat(jedis.hget("rest-storage:resources:project:server:test:test1:test2", RESOURCE), equalTo("{\"content\": \"test/test1/test2\"}"));
}
@Test
public void putResourcePathDepthIs3WithSiblingsFolderAndDocument() {
// ACT
evalScriptPut(":project:server:test:test1:test2", "{\"content\": \"test/test1/test2\"}");
// ASSERT
assertThat(jedis.zrangeByScore("rest-storage:collections:project", 0d, 9999999999999d).iterator().next(), equalTo("server"));
assertThat(jedis.zrangeByScore("rest-storage:collections:project:server", 0d, 9999999999999d).iterator().next(), equalTo("test"));
assertThat(jedis.zrangeByScore("rest-storage:collections:project:server:test", 0d, 9999999999999d).iterator().next(), equalTo("test1"));
assertThat(jedis.zrangeByScore("rest-storage:collections:project:server:test:test1", 0d, 9999999999999d).iterator().next(), equalTo("test2"));
assertThat(jedis.hget("rest-storage:resources:project:server:test:test1:test2", RESOURCE), equalTo("{\"content\": \"test/test1/test2\"}"));
}
@Test
public void putResourceMergeOnEmpty() {
// ACT
evalScriptPutMerge(":project:server:test:test1:test2", "{\"content\": \"test_test1_test3\"}");
// ASSERT
String result = jedis.hget("rest-storage:resources:project:server:test:test1:test2", RESOURCE);
JsonObject obj = new JsonObject(result);
assertThat(obj.getString("content"), equalTo("test_test1_test3"));
}
@Test
public void putResourceMergeOnExisting() {
// ACT
evalScriptPut(":project:server:test:test1:test2", "{\"content\": \"test_test1_test2\"}");
evalScriptPutMerge(":project:server:test:test1:test2", "{\"content\": \"test_test1_test3\"}");
// ASSERT
String result = jedis.hget("rest-storage:resources:project:server:test:test1:test2", RESOURCE);
JsonObject obj = new JsonObject(result);
assertThat(obj.getString("content"), equalTo("test_test1_test3"));
}
@Test
public void testStoreCompressedAndUnCompressedWithSameEtagValue() {
String originalContent = "{\"content\": \"originalContent\"}";
String modifiedContent = "{\"content\": \"modifiedContent\"}";
String etagValue = "etag1";
// Scenario 1: PUT 1 = {uncompressed, etag1}, PUT 2 = {compressed, etag1}
String putResult1 = evalScriptPut(":project:server:test:test1:test2", originalContent, AbstractLuaScriptTest.MAX_EXPIRE, etagValue, false);
assertThat(jedis.hexists("rest-storage:resources:project:server:test:test1:test2", COMPRESSED), is(false));
String putResult2 = evalScriptPut(":project:server:test:test1:test2", modifiedContent, AbstractLuaScriptTest.MAX_EXPIRE, etagValue, true);
assertThat(jedis.hexists("rest-storage:resources:project:server:test:test1:test2", COMPRESSED), is(true));
assertThat(putResult1, is(not(equalTo("notModified"))));
assertThat(putResult2, is(not(equalTo("notModified"))));
assertThat(jedis.hget("rest-storage:resources:project:server:test:test1:test2", ETAG), equalTo(etagValue));
assertThat(jedis.hget("rest-storage:resources:project:server:test:test1:test2", RESOURCE), equalTo(modifiedContent));
// Scenario 2: PUT 1 = {compressed, etag1}, PUT 2 = {uncompressed, etag1}
jedis.flushAll();
putResult1 = evalScriptPut(":project:server:test:test1:test2", originalContent, AbstractLuaScriptTest.MAX_EXPIRE, etagValue, true);
assertThat(jedis.hexists("rest-storage:resources:project:server:test:test1:test2", COMPRESSED), is(true));
putResult2 = evalScriptPut(":project:server:test:test1:test2", modifiedContent, AbstractLuaScriptTest.MAX_EXPIRE, etagValue, false);
assertThat(jedis.hexists("rest-storage:resources:project:server:test:test1:test2", COMPRESSED), is(false));
assertThat(putResult1, is(not(equalTo("notModified"))));
assertThat(putResult2, is(not(equalTo("notModified"))));
assertThat(jedis.hget("rest-storage:resources:project:server:test:test1:test2", ETAG), equalTo(etagValue));
assertThat(jedis.hget("rest-storage:resources:project:server:test:test1:test2", RESOURCE), equalTo(modifiedContent));
// Scenario 3: PUT 1 = {compressed, etag1}, PUT 2 = {compressed, etag1}
jedis.flushAll();
putResult1 = evalScriptPut(":project:server:test:test1:test2", originalContent, AbstractLuaScriptTest.MAX_EXPIRE, etagValue, true);
assertThat(jedis.hexists("rest-storage:resources:project:server:test:test1:test2", COMPRESSED), is(true));
putResult2 = evalScriptPut(":project:server:test:test1:test2", modifiedContent, AbstractLuaScriptTest.MAX_EXPIRE, etagValue, true);
assertThat(jedis.hexists("rest-storage:resources:project:server:test:test1:test2", COMPRESSED), is(true));
assertThat(putResult1, is(not(equalTo("notModified"))));
assertThat(putResult2, is(equalTo("notModified")));
assertThat(jedis.hget("rest-storage:resources:project:server:test:test1:test2", ETAG), equalTo(etagValue));
assertThat(jedis.hget("rest-storage:resources:project:server:test:test1:test2", RESOURCE), equalTo(originalContent));
// Scenario 4: PUT 1 = {uncompressed, etag1}, PUT 2 = {uncompressed, etag1}
jedis.flushAll();
putResult1 = evalScriptPut(":project:server:test:test1:test2", originalContent, AbstractLuaScriptTest.MAX_EXPIRE, etagValue, false);
assertThat(jedis.hexists("rest-storage:resources:project:server:test:test1:test2", COMPRESSED), is(false));
putResult2 = evalScriptPut(":project:server:test:test1:test2", modifiedContent, AbstractLuaScriptTest.MAX_EXPIRE, etagValue, false);
assertThat(jedis.hexists("rest-storage:resources:project:server:test:test1:test2", COMPRESSED), is(false));
assertThat(putResult1, is(not(equalTo("notModified"))));
assertThat(putResult2, is(equalTo("notModified")));
assertThat(jedis.hget("rest-storage:resources:project:server:test:test1:test2", ETAG), equalTo(etagValue));
assertThat(jedis.hget("rest-storage:resources:project:server:test:test1:test2", RESOURCE), equalTo(originalContent));
}
@Test
public void putResourceWithProvidedEtagValue() {
// ACT
String originalContent = "{\"content\": \"originalContent\"}";
String value = evalScriptPut(":project:server:test:test1:test2", originalContent, AbstractLuaScriptTest.MAX_EXPIRE, "myFancyEtagValue");
String modifiedContent = "{\"content\": \"modifiedContent\"}";
String value2 = evalScriptPut(":project:server:test:test1:test2", modifiedContent, AbstractLuaScriptTest.MAX_EXPIRE, "myFancyEtagValue");
// ASSERT
assertThat(value, is(not(equalTo("notModified"))));
assertThat(value2, is(equalTo("notModified")));
assertThat(jedis.hget("rest-storage:resources:project:server:test:test1:test2", ETAG), equalTo("myFancyEtagValue"));
assertThat(jedis.hget("rest-storage:resources:project:server:test:test1:test2", RESOURCE), equalTo(originalContent));
}
@Test
public void putResourceWithNotProvidedEtagValue() {
// ACT
String originalContent = "{\"content\": \"originalContent\"}";
String value = evalScriptPut(":project:server:test:test1:test2", originalContent);
// ASSERT
assertThat(value, is(not(equalTo("notModified"))));
String etagValue = jedis.hget("rest-storage:resources:project:server:test:test1:test2", ETAG);
assertThat(jedis.hget("rest-storage:resources:project:server:test:test1:test2", RESOURCE), equalTo(originalContent));
// ACT
String modifiedContent = "{\"content\": \"modifiedContent\"}";
String value2 = evalScriptPut(":project:server:test:test1:test2", modifiedContent);
// ASSERT
assertThat(value2, is(not(equalTo("notModified"))));
assertThat(jedis.hget("rest-storage:resources:project:server:test:test1:test2", RESOURCE), equalTo(modifiedContent));
assertThat(jedis.hget("rest-storage:resources:project:server:test:test1:test2", ETAG), is(not(equalTo(etagValue))));
}
@Test
public void tryToPutResourceOnCollectionPathOneLevelBelow() {
// ARRANGE
String resultPutTest2 = evalScriptPut(":project:server:test:test1:test2", "{\"content\": \"test/test1/test2\"}");
String resultPutTest1 = evalScriptPut(":project:server:test:test1", "{\"content\": \"test/test1\"}");
// ACT
List<String> valueTest1 = (List<String>) evalScriptGet(":project:server:test:test1");
List<String> valueTest2 = (List<String>) evalScriptGet(":project:server:test:test1:test2");
// ASSERT
assertThat(resultPutTest2, equalTo("OK"));
assertThat(resultPutTest1, equalTo("existingCollection"));
assertThat(valueTest1, hasItem("test2"));
assertThat(valueTest2.get(1), equalTo("{\"content\": \"test/test1/test2\"}"));
}
@Test
public void tryToPutResourceOnCollectionPathTwoLevelsBelow() {
// ARRANGE
String resultPutTest2 = evalScriptPut(":project:server:test:test1:test2", "{\"content\": \"test/test1/test2\"}");
String resultPutTest1 = evalScriptPut(":project:server:test", "{\"content\": \"test\"}");
// ACT
List<String> valueTest1 = (List<String>) evalScriptGet(":project:server:test");
List<String> valueTest2 = (List<String>) evalScriptGet(":project:server:test:test1:test2");
// ASSERT
assertThat(resultPutTest2, equalTo("OK"));
assertThat(resultPutTest1, equalTo("existingCollection"));
assertThat(valueTest1, hasItem("test1:"));
assertThat(valueTest2.get(1), equalTo("{\"content\": \"test/test1/test2\"}"));
}
@Test
public void tryToPutResourceOnCollectionPathThreeLevelsBelow() {
// ARRANGE
String resultPutTest2 = evalScriptPut(":project:server:test:test1:test2", "{\"content\": \"test/test1/test2\"}");
String resultPutTest1 = evalScriptPut(":project:server", "{\"content\": \"test\"}");
// ACT
List<String> valueTest1 = (List<String>) evalScriptGet(":project:server");
List<String> valueTest2 = (List<String>) evalScriptGet(":project:server:test:test1:test2");
// ASSERT
assertThat(resultPutTest2, equalTo("OK"));
assertThat(resultPutTest1, equalTo("existingCollection"));
assertThat(valueTest1, hasItem("test:"));
assertThat(valueTest2.get(1), equalTo("{\"content\": \"test/test1/test2\"}"));
}
@Test
public void tryToPutResourceOnCollectionFirstLevel() {
// ARRANGE
String resultPutTest2 = evalScriptPut(":project:server:test:test1:test2", "{\"content\": \"test/test1/test2\"}");
String resultPutTest1 = evalScriptPut(":project", "{\"content\": \"test\"}");
// ACT
List<String> valueTest1 = (List<String>) evalScriptGet(":project");
List<String> valueTest2 = (List<String>) evalScriptGet(":project:server:test:test1:test2");
// ASSERT
assertThat(resultPutTest2, equalTo("OK"));
assertThat(resultPutTest1, equalTo("existingCollection"));
assertThat(valueTest1, hasItem("server:"));
assertThat(valueTest2.get(1), equalTo("{\"content\": \"test/test1/test2\"}"));
}
@Test
public void tryToPutCollectionOnResourceOneLevelAbovePath() {
// ARRANGE
String resultPutTest1 = evalScriptPut(":project:server:test:test1", "{\"content\": \"test/test1\"}");
String resultPutTest2 = evalScriptPut(":project:server:test:test1:test2", "{\"content\": \"test/test1/test2\"}");
// ACT
List<String> valueTest1 = (List<String>) evalScriptGet(":project:server:test:test1");
String valueTest2 = (String) evalScriptGet(":project:server:test:test1:test2");
// ASSERT
assertThat(resultPutTest1, equalTo("OK"));
assertThat(resultPutTest2, equalTo("existingResource rest-storage:resources:project:server:test:test1"));
assertThat(valueTest1.get(1), equalTo("{\"content\": \"test/test1\"}"));
assertThat(valueTest2, equalTo("notFound"));
}
@Test
public void tryToPutCollectionOnResourceTwoLevelsAbovePath() {
// ARRANGE
String resultPutTest1 = evalScriptPut(":project:server:test:test1", "{\"content\": \"test/test1\"}");
String resultPutTest3 = evalScriptPut(":project:server:test:test1:test2:test3", "{\"content\": \"test/test1/test2/test3\"}");
// ACT
List<String> valueTest1 = (List<String>) evalScriptGet(":project:server:test:test1");
String valueTest3 = (String) evalScriptGet(":project:server:test:test1:test2:test3");
// ASSERT
assertThat(resultPutTest1, equalTo("OK"));
assertThat(resultPutTest3, equalTo("existingResource rest-storage:resources:project:server:test:test1"));
assertThat(valueTest1.get(1), equalTo("{\"content\": \"test/test1\"}"));
assertThat(valueTest3, equalTo("notFound"));
}
@Test
public void tryToPutCollectionOnResourceOneLevelOneLevelAbovePath() {
// ARRANGE
String resultPutNemo = evalScriptPut(":project", "{\"content\": \"nemo\"}");
String resultPutNemoServer = evalScriptPut(":project:server", "{\"content\": \"nemo/server\"}");
// ACT
List<String> valueNemo = (List<String>) evalScriptGet(":project");
String valueServer = (String) evalScriptGet(":project:server");
// ASSERT
assertThat(resultPutNemo, equalTo("OK"));
assertThat(resultPutNemoServer, equalTo("existingResource rest-storage:resources:project"));
assertThat(valueNemo.get(1), equalTo("{\"content\": \"nemo\"}"));
assertThat(valueServer, equalTo("notFound"));
}
@Test
public void tryToPutCollectionOnResourceFourLevelOneLevelAbovePath() {
// ARRANGE
String resultPutNemo = evalScriptPut(":nemo:server:tests:crush:test1", "{\"content\": \"nemo\"}");
String resultPutNemoServer = evalScriptPut(":nemo:server:tests:crush:test1:test2:test3", "{\"content\": \"nemo/server\"}");
// ACT
List<String> valueNemo = (List<String>) evalScriptGet(":nemo:server:tests:crush:test1");
String valueServer = (String) evalScriptGet(":nemo:server:tests:crush:test1:test2:test3");
// ASSERT
assertThat(resultPutNemo, equalTo("OK"));
assertThat(resultPutNemoServer, equalTo("existingResource rest-storage:resources:nemo:server:tests:crush:test1"));
assertThat(valueNemo.get(1), equalTo("{\"content\": \"nemo\"}"));
assertThat(valueServer, equalTo("notFound"));
}
@SuppressWarnings({ "rawtypes", "unchecked", "serial" })
private Object evalScriptPutMerge(final String resourceName1, final String resourceValue1) {
String putScript = readScript("put.lua");
return jedis.eval(putScript, new ArrayList() {
{
add(resourceName1);
}
}, new ArrayList() {
{
add(prefixResources);
add(prefixCollections);
add(expirableSet);
add("true");
add("9999999999999");
add("9999999999999");
add(resourceValue1);
add(UUID.randomUUID().toString());
add(prefixLock);
}
}
);
}
@Test
public void putResourceWithSilentLockDifferentEtag() {
// ARRANGE
String basePath = ":project:server:silent:";
String lockedPath = basePath + "myResource";
String anotherPath = basePath + "anotherPath";
String lockedResource = "{\"content\" : \"locked\" }";
String normalResource = "{\"content\" : \"normal\" }";
String tryToLockResourceOwner2 = "{\"content\" : \"owner2\" }";
String anotherResource = "{\"content\" : \"anotherResource\" }";
// ACT
String lockedValue = evalScriptPut(lockedPath, lockedResource, AbstractLuaScriptTest.MAX_EXPIRE, "etag1", "owner1", LockMode.SILENT, 300);
String normalValue = evalScriptPut(lockedPath, normalResource, AbstractLuaScriptTest.MAX_EXPIRE, "etag2");
String tryToLockValue = evalScriptPut(lockedPath, tryToLockResourceOwner2, AbstractLuaScriptTest.MAX_EXPIRE, "etag3", "owner2", LockMode.SILENT, 300);
String anotherValue = evalScriptPut(anotherPath, anotherResource, AbstractLuaScriptTest.MAX_EXPIRE);
// ASSERT
assertThat(lockedValue, is(equalTo("OK")));
assertThat(normalValue, is(equalTo(LockMode.SILENT.text())));
assertThat(tryToLockValue, is(equalTo(LockMode.SILENT.text())));
assertThat(anotherValue, is(equalTo("OK")));
assertThat(jedis.hget("rest-storage:resources" + lockedPath, RESOURCE), equalTo(lockedResource));
assertThat(jedis.hget("rest-storage:resources" + anotherPath, RESOURCE), equalTo(anotherResource));
assertThat(jedis.hget(prefixLock + lockedPath, OWNER), equalTo("owner1"));
assertThat(jedis.hget(prefixLock + lockedPath, MODE), equalTo(LockMode.SILENT.text()));
}
@Test
public void putResourceWithSilentLockSameEtag() {
// ARRANGE
String basePath = ":project:server:silent:";
String lockedPath = basePath + "myResource";
String anotherPath = basePath + "anotherPath";
String lockedResource = "{\"content\" : \"locked\" }";
String normalResource = "{\"content\" : \"normal\" }";
String tryToLockResourceOwner2 = "{\"content\" : \"owner2\" }";
String anotherResource = "{\"content\" : \"anotherResource\" }";
// ACT
String lockedValue = evalScriptPut(lockedPath, lockedResource, AbstractLuaScriptTest.MAX_EXPIRE, "etag", "owner1", LockMode.SILENT, 300);
String normalValue = evalScriptPut(lockedPath, normalResource, AbstractLuaScriptTest.MAX_EXPIRE, "etag");
String tryToLockValue = evalScriptPut(lockedPath, tryToLockResourceOwner2, AbstractLuaScriptTest.MAX_EXPIRE, "etag", "owner2", LockMode.SILENT, 300);
String anotherValue = evalScriptPut(anotherPath, anotherResource, AbstractLuaScriptTest.MAX_EXPIRE, "etag");
// ASSERT
assertThat(lockedValue, is(equalTo("OK")));
assertThat(normalValue, is(equalTo(LockMode.SILENT.text())));
assertThat(tryToLockValue, is(equalTo(LockMode.SILENT.text())));
assertThat(anotherValue, is(equalTo("OK")));
assertThat(jedis.hget("rest-storage:resources" + lockedPath, RESOURCE), equalTo(lockedResource));
assertThat(jedis.hget("rest-storage:resources" + anotherPath, RESOURCE), equalTo(anotherResource));
assertThat(jedis.hget(prefixLock + lockedPath, OWNER), equalTo("owner1"));
assertThat(jedis.hget(prefixLock + lockedPath, MODE), equalTo(LockMode.SILENT.text()));
}
@Test
public void putResourceWithRejectLockDifferentEtag() {
// ARRANGE
String basePath = ":project:server:reject:";
String lockedPath = basePath + "myResource";
String anotherPath = basePath + "anotherPath";
String lockedResource = "{\"content\" : \"locked\" }";
String normalResource = "{\"content\" : \"normal\" }";
String tryToLockResourceOwner2 = "{\"content\" : \"owner2\" }";
String anotherResource = "{\"content\" : \"anotherResource\" }";
// ACT
String lockedValue = evalScriptPut(lockedPath, lockedResource, AbstractLuaScriptTest.MAX_EXPIRE, "etag1", "owner1", LockMode.REJECT, 300);
String normalValue = evalScriptPut(lockedPath, normalResource, AbstractLuaScriptTest.MAX_EXPIRE, "etag2");
String tryToLockValue = evalScriptPut(lockedPath, tryToLockResourceOwner2, AbstractLuaScriptTest.MAX_EXPIRE, "etag3", "owner2", LockMode.REJECT, 300);
String anotherValue = evalScriptPut(anotherPath, anotherResource, AbstractLuaScriptTest.MAX_EXPIRE);
// ASSERT
assertThat(lockedValue, is(equalTo("OK")));
assertThat(normalValue, is(equalTo(LockMode.REJECT.text())));
assertThat(tryToLockValue, is(equalTo(LockMode.REJECT.text())));
assertThat(anotherValue, is(equalTo("OK")));
assertThat(jedis.hget("rest-storage:resources" + lockedPath, RESOURCE), equalTo(lockedResource));
assertThat(jedis.hget("rest-storage:resources" + anotherPath, RESOURCE), equalTo(anotherResource));
assertThat(jedis.hget(prefixLock + lockedPath, OWNER), equalTo("owner1"));
assertThat(jedis.hget(prefixLock + lockedPath, MODE), equalTo(LockMode.REJECT.text()));
}
@Test
public void putResourceWithRejectLockSameEtag() {
// ARRANGE
String basePath = ":project:server:reject:";
String lockedPath = basePath + "myResource";
String anotherPath = basePath + "anotherPath";
String lockedResource = "{\"content\" : \"locked\" }";
String normalResource = "{\"content\" : \"normal\" }";
String tryToLockResourceOwner2 = "{\"content\" : \"owner2\" }";
String anotherResource = "{\"content\" : \"anotherResource\" }";
// ACT
String lockedValue = evalScriptPut(lockedPath, lockedResource, AbstractLuaScriptTest.MAX_EXPIRE, "etag", "owner1", LockMode.REJECT, 300);
String normalValue = evalScriptPut(lockedPath, normalResource, AbstractLuaScriptTest.MAX_EXPIRE, "etag");
String tryToLockValue = evalScriptPut(lockedPath, tryToLockResourceOwner2, AbstractLuaScriptTest.MAX_EXPIRE, "etag", "owner2", LockMode.REJECT, 300);
String anotherValue = evalScriptPut(anotherPath, anotherResource, AbstractLuaScriptTest.MAX_EXPIRE);
// ASSERT
assertThat(lockedValue, is(equalTo("OK")));
assertThat(normalValue, is(equalTo(LockMode.REJECT.text())));
assertThat(tryToLockValue, is(equalTo(LockMode.REJECT.text())));
assertThat(anotherValue, is(equalTo("OK")));
assertThat(jedis.hget("rest-storage:resources" + lockedPath, RESOURCE), equalTo(lockedResource));
assertThat(jedis.hget("rest-storage:resources" + anotherPath, RESOURCE), equalTo(anotherResource));
assertThat(jedis.hget(prefixLock + lockedPath, OWNER), equalTo("owner1"));
assertThat(jedis.hget(prefixLock + lockedPath, MODE), equalTo(LockMode.REJECT.text()));
}
@Test
public void tryToPutLockedResourceSameOwner() {
// ARRANGE
String basePath = ":project:server:silent:";
String lockedPath = basePath + "myResource";
String lockedResource = "{\"content\" : \"locked\" }";
String overwrittenResource = "{\"content\" : \"overwritten by owner of lock\" }";
String normalResource = "{\"content\" : \"normal\" }";
// ACT 1
String lockedValue = evalScriptPut(lockedPath, lockedResource, AbstractLuaScriptTest.MAX_EXPIRE, "etag", "owner1", LockMode.SILENT, 300);
// ASSERT 1
assertThat(lockedValue, is(equalTo("OK")));
assertThat(jedis.hget("rest-storage:resources" + lockedPath, RESOURCE), equalTo(lockedResource));
// ACT 2
String overwrittenValue = evalScriptPut(lockedPath, overwrittenResource, AbstractLuaScriptTest.MAX_EXPIRE, "etag1", "owner1", LockMode.SILENT, 300);
// ASSERT 2
assertThat(overwrittenValue, is(equalTo("OK")));
assertThat(jedis.hget("rest-storage:resources" + lockedPath, RESOURCE), equalTo(overwrittenResource));
// ACT 3
String normalValue = evalScriptPut(lockedPath, normalResource, AbstractLuaScriptTest.MAX_EXPIRE);
// ASSERT 3
assertThat(normalValue, is(equalTo(LockMode.SILENT.text())));
assertThat(jedis.hget("rest-storage:resources" + lockedPath, RESOURCE), equalTo(overwrittenResource));
}
@Test
public void tryToPutWhileAndAfterResourceLock() {
// ARRANGE
long lockExpire = 5;
String basePath = ":project:server:silent:expire:";
String lockedPath = basePath + "myResource";
String lockedResource = "{\"content\" : \"locked\" }";
String newResource = "{\"content\" : \"new\" }";
// ACT 1
jedis.expire(prefixLock + lockedPath, 0);
String lockedValue = evalScriptPut(lockedPath, lockedResource, AbstractLuaScriptTest.MAX_EXPIRE, "etag", "owner1", LockMode.SILENT, lockExpire);
String newValue = evalScriptPut(lockedPath, newResource, AbstractLuaScriptTest.MAX_EXPIRE);
// ASSERT 1
assertThat(lockedValue, is(equalTo("OK")));
assertThat(newValue, is(equalTo(LockMode.SILENT.text())));
assertThat(jedis.hget("rest-storage:resources" + lockedPath, RESOURCE), equalTo(lockedResource));
// ACT 2 - wait
await().atMost(lockExpire * 2, SECONDS).until(() ->
evalScriptPut(lockedPath, newResource, AbstractLuaScriptTest.MAX_EXPIRE),
equalTo("OK")
);
// ASSERT 2
assertThat(jedis.hget("rest-storage:resources" + lockedPath, RESOURCE), equalTo(newResource));
assertThat(jedis.exists(prefixLock + lockedPath), equalTo(false));
}
}