/* * ------------------------------------------------------------------------------------------------ * Copyright 2014 by Swiss Post, Information Technology Services * ------------------------------------------------------------------------------------------------ * $Id$ * ------------------------------------------------------------------------------------------------ */ package org.swisspush.reststorage.lua; import org.apache.commons.lang3.StringUtils; import org.junit.Test; import io.vertx.core.json.JsonArray; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; public class RedisStorageExpandLuaScriptTests extends AbstractLuaScriptTest { @Test public void testStorageExpand() { // ARRANGE evalScriptPut(":project:server:test:item1", "{\"content\": \"content_1\"}"); evalScriptPut(":project:server:test:item2", "{\"content\": \"content_2\"}"); evalScriptPut(":project:server:test:item3", "{\"content\": \"content_3\"}"); // ACT List<String> subResources = Arrays.asList("item2", "item1", "item3"); List<List<String>> value = evalScriptStorageExpandAndExtract(":project:server:test", subResources); // ASSERT assertThat(value.size(), equalTo(3)); assertThat(value.get(0).get(0), equalTo("item2")); assertThat(value.get(0).get(1), equalTo("{\"content\": \"content_2\"}")); assertThat(value.get(1).get(0), equalTo("item1")); assertThat(value.get(1).get(1), equalTo("{\"content\": \"content_1\"}")); assertThat(value.get(2).get(0), equalTo("item3")); assertThat(value.get(2).get(1), equalTo("{\"content\": \"content_3\"}")); } @Test public void testStorageExpandEmptySubresources() { // ARRANGE evalScriptPut(":project:server:test:item1", "{\"content\": \"content_1\"}"); evalScriptPut(":project:server:test:item2", "{\"content\": \"content_2\"}"); evalScriptPut(":project:server:test:item3", "{\"content\": \"content_3\"}"); // ACT List<List<String>> value = evalScriptStorageExpandAndExtract(":project:server:test", new ArrayList<>()); // ASSERT assertNotNull(value); assertThat(value.size(), equalTo(0)); } /** * StorageExpand does not care about correct (json) content. */ @Test public void testStorageExpandInvalidSubresources() { // ARRANGE evalScriptPut(":project:server:test:item1", "{\"content\": \"content_1\"}"); evalScriptPut(":project:server:test:item2", "{\"content\": \"content_2\"}"); evalScriptPut(":project:server:test:item3", "{\"content\""); // ACT List<String> subResources = Arrays.asList("item1", "item2", "item3"); List<List<String>> value = evalScriptStorageExpandAndExtract(":project:server:test", subResources); // ASSERT assertThat(value.size(), equalTo(3)); assertThat(value.get(2).get(0), equalTo("item3")); assertThat(value.get(2).get(1), equalTo("{\"content\"")); } @Test public void testStorageExpandWithSubCollections() { // ARRANGE evalScriptPut(":project:server:test:item1", "{\"content\": \"content_1\"}"); evalScriptPut(":project:server:test:item2", "{\"content\": \"content_2\"}"); evalScriptPut(":project:server:test:item3", "{\"content\": \"content_3\"}"); evalScriptPut(":project:server:test:sub:sub1", "{\"content\": \"content_sub_1\"}"); evalScriptPut(":project:server:test:sub:sub2", "{\"content\": \"content_sub_2\"}"); // ACT List<String> subResources = Arrays.asList("sub/", "item1", "item2", "item3"); List<List<String>> value = evalScriptStorageExpandAndExtract(":project:server:test", subResources); // ASSERT assertThat(value.size(), equalTo(4)); assertThat(value.get(0).get(0), equalTo("sub")); assertThat(value.get(0).get(1), equalTo("[\"sub1\",\"sub2\"]")); assertThat(value.get(1).get(0), equalTo("item1")); assertThat(value.get(1).get(1), equalTo("{\"content\": \"content_1\"}")); assertThat(value.get(2).get(0), equalTo("item2")); assertThat(value.get(2).get(1), equalTo("{\"content\": \"content_2\"}")); assertThat(value.get(3).get(0), equalTo("item3")); assertThat(value.get(3).get(1), equalTo("{\"content\": \"content_3\"}")); } @Test public void testStorageExpandWithSubSubCollections() { // ARRANGE evalScriptPut(":project:server:test:sub:subsub:item1", "{\"content\": \"content_sub_1\"}"); evalScriptPut(":project:server:test:sub:subsub:item2", "{\"content\": \"content_sub_2\"}"); evalScriptPut(":project:server:test:sub:othersubsub:item3", "{\"content\": \"content_sub_3\"}"); evalScriptPut(":project:server:test:sub:othersubsub:item4", "{\"content\": \"content_sub_4\"}"); // ACT List<String> subResources = Arrays.asList("sub/"); List<List<String>> value = evalScriptStorageExpandAndExtract(":project:server:test", subResources); // ASSERT assertThat(value.size(), equalTo(1)); assertThat(value.get(0).get(0), equalTo("sub")); assertThat(value.get(0).get(1), equalTo("[\"othersubsub\\/\",\"subsub\\/\"]")); // ACT subResources = Arrays.asList("subsub/"); value = evalScriptStorageExpandAndExtract(":project:server:test:sub", subResources); // ASSERT assertThat(value.size(), equalTo(1)); assertThat(value.get(0).get(0), equalTo("subsub")); assertThat(value.get(0).get(1), equalTo("[\"item1\",\"item2\"]")); // ACT subResources = Arrays.asList("item1", "item2"); value = evalScriptStorageExpandAndExtract(":project:server:test:sub:subsub", subResources); // ASSERT assertThat(value.size(), equalTo(2)); assertThat(value.get(0).get(0), equalTo("item1")); assertThat(value.get(0).get(1), equalTo("{\"content\": \"content_sub_1\"}")); assertThat(value.get(1).get(0), equalTo("item2")); assertThat(value.get(1).get(1), equalTo("{\"content\": \"content_sub_2\"}")); } @Test public void testStorageExpandWithCollectionsOnly() { // ARRANGE evalScriptPut(":project:server:test:sub:sub1", "{\"content\": \"content_sub_1\"}"); evalScriptPut(":project:server:test:sub:sub2", "{\"content\": \"content_sub_2\"}"); evalScriptPut(":project:server:test:anothersub:sub3", "{\"content\": \"content_sub_3\"}"); evalScriptPut(":project:server:test:anothersub:sub4", "{\"content\": \"content_sub_4\"}"); // ACT List<String> subResources = Arrays.asList("sub/", "anothersub/"); List<List<String>> value = evalScriptStorageExpandAndExtract(":project:server:test", subResources); // ASSERT assertThat(value.size(), equalTo(2)); assertThat(value.get(0).get(0), equalTo("sub")); assertThat(value.get(0).get(1), equalTo("[\"sub1\",\"sub2\"]")); assertThat(value.get(1).get(0), equalTo("anothersub")); assertThat(value.get(1).get(1), equalTo("[\"sub3\",\"sub4\"]")); } @Test public void testStorageExpandWithNoMatchingResources() { // ARRANGE evalScriptPut(":project:server:test:item1", "{\"content\": \"content_1\"}"); evalScriptPut(":project:server:test:item2", "{\"content\": \"content_2\"}"); evalScriptPut(":project:server:test:item3", "{\"content\": \"content_3\"}"); // ACT List<String> subResources = Arrays.asList("item2x", "item1x", "item3x"); List<List<String>> value = evalScriptStorageExpandAndExtract(":project:server:test", subResources); // ASSERT assertNotNull(value); assertThat(value.size(), equalTo(0)); } @Test public void testStorageExpandWithInvalidSubresources() { // ARRANGE evalScriptPut(":project:server:test:item1", "{\"content\": \"content_1\"}"); evalScriptPut(":project:server:test:item2", "{\"content\": \"content_2\"}"); evalScriptPut(":project:server:test:item3", "{\"content\": \"content_3\"}"); // ACT List<String> subResources = Arrays.asList("item3", "invalidItem", "item1"); List<List<String>> value = evalScriptStorageExpandAndExtract(":project:server:test", subResources); // ASSERT assertThat(value.size(), equalTo(2)); assertThat(value.get(0).get(0), equalTo("item3")); assertThat(value.get(0).get(1), equalTo("{\"content\": \"content_3\"}")); assertThat(value.get(1).get(0), equalTo("item1")); assertThat(value.get(1).get(1), equalTo("{\"content\": \"content_1\"}")); // ACT subResources = Arrays.asList("item3", "invalidSub/"); value = evalScriptStorageExpandAndExtract(":project:server:test", subResources); // ASSERT assertThat(value.size(), equalTo(1)); assertThat(value.get(0).get(0), equalTo("item3")); assertThat(value.get(0).get(1), equalTo("{\"content\": \"content_3\"}")); } @Test public void testStorageExpandExpired() throws InterruptedException { // ARRANGE String now = String.valueOf(System.currentTimeMillis()); evalScriptPut(":project:server:test:item1", "{\"content\": \"content_1\"}", now); String nowPlus100 = String.valueOf(System.currentTimeMillis() + 100); evalScriptPut(":project:server:test:item2", "{\"content\": \"content_2\"}", nowPlus100); Thread.sleep(15); // ACT String timestamp = String.valueOf(System.currentTimeMillis()); List<List<String>> value = evalScriptStorageExpandAndExtract(":project:server:test", Arrays.asList("item1", "item2"), timestamp); // ASSERT assertThat(value.size(), equalTo(1)); assertThat(value.get(0).get(0), equalTo("item2")); assertThat(value.get(0).get(1), equalTo("{\"content\": \"content_2\"}")); Thread.sleep(100); // ACT timestamp = String.valueOf(System.currentTimeMillis()); value = evalScriptStorageExpandAndExtract(":project:server:test", Arrays.asList("item1", "item2"), timestamp); // ASSERT assertNotNull(value); assertThat(value.size(), equalTo(0)); } @Test public void testStorageExpandExpiredWithCollections() throws InterruptedException { // ARRANGE String now = String.valueOf(System.currentTimeMillis()); String nowPlus1000 = String.valueOf(System.currentTimeMillis() + 1000); evalScriptPut(":project:server:test:item1", "{\"content\": \"content_1\"}", now); evalScriptPut(":project:server:test:item2", "{\"content\": \"content_2\"}", now); evalScriptPut(":project:server:test:item3", "{\"content\": \"content_3\"}", nowPlus1000); evalScriptPut(":project:server:test:sub:sub1", "{\"content\": \"content_sub_1\"}", now); evalScriptPut(":project:server:test:sub:sub2", "{\"content\": \"content_sub_2\"}", nowPlus1000); Thread.sleep(15); // ACT String timestamp = String.valueOf(System.currentTimeMillis()); List<List<String>> value = evalScriptStorageExpandAndExtract(":project:server:test", Arrays.asList("sub/", "item1", "item2", "item3"), timestamp); // ASSERT assertThat(value.size(), equalTo(2)); assertThat(value.get(0).get(0), equalTo("sub")); assertThat(value.get(0).get(1), equalTo("[\"sub2\"]")); assertThat(value.get(1).get(0), equalTo("item3")); assertThat(value.get(1).get(1), equalTo("{\"content\": \"content_3\"}")); } @Test public void testStorageExpandCompressedDataInCollection() { // ARRANGE evalScriptPut(":project:server:test:item1", "{\"content\": \"content_1\"}", AbstractLuaScriptTest.MAX_EXPIRE, "etag1", true); // ACT List<String> subResources = Arrays.asList("item1"); String value = (String) evalScriptStorageExpand(":project:server:test", subResources); // ASSERT assertThat(value, equalTo("compressionNotSupported")); } @Test public void testStorageExpandCompressedAndUncompressedDataInCollection() { // ARRANGE evalScriptPut(":project:server:test:item1", "{\"content\": \"content_1\"}", AbstractLuaScriptTest.MAX_EXPIRE, "etag1", false); evalScriptPut(":project:server:test:item2", "{\"content\": \"content_2\"}", AbstractLuaScriptTest.MAX_EXPIRE, "etag2", true); evalScriptPut(":project:server:test:item3", "{\"content\": \"content_3\"}", AbstractLuaScriptTest.MAX_EXPIRE, "etag3", false); // ACT List<String> subResources = Arrays.asList("item2", "item1", "item3"); String value = (String) evalScriptStorageExpand(":project:server:test", subResources); // ASSERT assertThat(value, equalTo("compressionNotSupported")); // ACT List<String> subResources2 = Arrays.asList("item1", "item3"); List<List<String>> value2 = evalScriptStorageExpandAndExtract(":project:server:test", subResources2); // ASSERT assertThat(value2.size(), equalTo(2)); assertThat(value2.get(0).get(0), equalTo("item1")); assertThat(value2.get(0).get(1), equalTo("{\"content\": \"content_1\"}")); assertThat(value2.get(1).get(0), equalTo("item3")); assertThat(value2.get(1).get(1), equalTo("{\"content\": \"content_3\"}")); } @SuppressWarnings({"rawtypes", "unchecked", "serial"}) private Object evalScriptStorageExpand(final String resourceName1, final List<String> subResources) { return evalScriptStorageExpand(resourceName1, subResources, String.valueOf(System.currentTimeMillis())); } @SuppressWarnings({"rawtypes", "unchecked", "serial"}) private Object evalScriptStorageExpand(final String resourceName1, final List<String> subResources, final String timestamp) { String getScript = readScript("storageExpand.lua"); return jedis.eval(getScript, new ArrayList() { { add(resourceName1); } }, new ArrayList() { { add(prefixResources); add(prefixCollections); add(expirableSet); add(timestamp); add("9999999999999"); add(StringUtils.join(subResources, ";")); add(String.valueOf(subResources.size())); } } ); } private List<List<String>> evalScriptStorageExpandAndExtract(String resourceName, List<String> subResources){ return evalScriptStorageExpandAndExtract(resourceName, subResources, null); } private List<List<String>> evalScriptStorageExpandAndExtract(String resourceName, List<String> subResources, String timestamp){ List<List<String>> result = new ArrayList<>(); String valueStr; if(timestamp != null){ valueStr = (String) evalScriptStorageExpand(resourceName, subResources, timestamp); } else { valueStr = (String) evalScriptStorageExpand(resourceName, subResources); } if(valueStr.equals("notFound")){ return result; } JsonArray jsonArray = new JsonArray(valueStr); for (Object arr : jsonArray) { JsonArray subArr = (JsonArray) arr; result.add(Arrays.asList(subArr.getString(0), subArr.getString(1))); } return result; } }