package org.infinispan.query.remote.impl;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
import static org.testng.AssertJUnit.fail;
import java.util.HashMap;
import java.util.Map;
import org.infinispan.Cache;
import org.infinispan.commons.CacheException;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.interceptors.locking.PessimisticLockingInterceptor;
import org.infinispan.query.remote.client.ProtobufMetadataManagerConstants;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.TestingUtil;
import org.infinispan.transaction.LockingMode;
import org.infinispan.transaction.TransactionMode;
import org.infinispan.util.concurrent.IsolationLevel;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
@Test(groups = "functional", testName = "query.remote.impl.ProtobufMetadataManagerInterceptorTest")
public class ProtobufMetadataManagerInterceptorTest extends MultipleCacheManagersTest {
@Override
protected void createCacheManagers() throws Throwable {
//todo [anistor] test with ST, with store , test with manual TX, with batching, with HotRod
addClusterEnabledCacheManager(makeCfg());
addClusterEnabledCacheManager(makeCfg());
waitForClusterToForm();
}
private ConfigurationBuilder makeCfg() {
ConfigurationBuilder cfg = new ConfigurationBuilder();
cfg.transaction()
.transactionMode(TransactionMode.TRANSACTIONAL).invocationBatching().enable()
.clustering().cacheMode(CacheMode.REPL_SYNC)
.clustering().sync()
.stateTransfer().fetchInMemoryState(true)
.transaction().lockingMode(LockingMode.PESSIMISTIC)
.locking().isolationLevel(IsolationLevel.READ_COMMITTED).useLockStriping(false)
.customInterceptors().addInterceptor()
.interceptor(new ProtobufMetadataManagerInterceptor()).after(PessimisticLockingInterceptor.class);
return cfg;
}
@AfterMethod
@Override
protected void clearContent() throws Throwable {
// the base method cleans only the data container without invoking the interceptor stack...
cache(0).clear();
}
public void testValidatePut() {
Cache<String, String> cache0 = cache(0);
Cache<String, String> cache1 = cache(1);
assertTrue(cache0.isEmpty());
assertTrue(cache1.isEmpty());
try {
cache(0).put(42, "import \"test.proto\";");
fail();
} catch (CacheException e) {
assertEquals("The key must be a string", e.getMessage());
}
try {
cache(0).put("some.proto", 42);
fail();
} catch (CacheException e) {
assertEquals("The value must be a string", e.getMessage());
}
try {
cache0.put("some.xml", "import \"test.proto\";");
fail();
} catch (CacheException e) {
assertEquals("The key must be a string ending with \".proto\" : some.xml", e.getMessage());
}
cache0.put("test.proto", "package x");
assertEquals("test.proto", cache0.get(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertEquals("test.proto", cache1.get(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
cache0.remove("test.proto");
assertTrue(cache0.isEmpty());
assertTrue(cache1.isEmpty());
Map<String, String> map = new HashMap<>();
map.put("a.proto", "package a");
map.put("b.proto", "package b;");
cache0.putAll(map);
assertEquals("a.proto", cache0.get(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertEquals("a.proto", cache1.get(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertEquals(4, cache0.size());
assertEquals(4, cache1.size());
assertNoTransactionsAndLocks();
}
public void testValidateReplace() {
Cache<String, String> cache0 = cache(0);
Cache<String, String> cache1 = cache(1);
assertTrue(cache0.isEmpty());
assertTrue(cache1.isEmpty());
String value = "package X;";
cache0.put("test.proto", value);
assertEquals(1, cache0.size());
assertEquals(1, cache1.size());
assertEquals(value, cache0.get("test.proto"));
assertEquals(value, cache1.get("test.proto"));
String newValue = "package XYX";
cache0.replace("test.proto", newValue);
assertEquals("test.proto", cache0.get(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertEquals("test.proto", cache1.get(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertEquals(3, cache0.size());
assertEquals(3, cache1.size());
assertEquals(newValue, cache0.get("test.proto"));
assertEquals(newValue, cache1.get("test.proto"));
assertNoTransactionsAndLocks();
}
public void testStatusAfterPut() {
Cache<String, String> cache0 = cache(0);
Cache<String, String> cache1 = cache(1);
assertTrue(cache0.isEmpty());
assertTrue(cache1.isEmpty());
String value = "import \"missing.proto\";";
cache0.put("test.proto", value);
assertEquals(value, cache0.get("test.proto"));
assertEquals(value, cache1.get("test.proto"));
assertEquals("Import 'missing.proto' not found", cache0.get("test.proto.errors"));
assertEquals("test.proto", cache0.get(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertEquals("Import 'missing.proto' not found", cache1.get("test.proto.errors"));
assertEquals("test.proto", cache1.get(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
value = "package foobar;";
cache0.put("test.proto", value);
assertEquals(value, cache0.get("test.proto"));
assertEquals(value, cache1.get("test.proto"));
assertFalse(cache0.containsKey("test.proto.errors"));
assertFalse(cache1.containsKey("test.proto.errors"));
assertFalse(cache0.containsKey(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertFalse(cache1.containsKey(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertNoTransactionsAndLocks();
}
public void testStatusAfterPutIfAbsent() {
Cache<String, String> cache0 = cache(0);
Cache<String, String> cache1 = cache(1);
assertTrue(cache0.isEmpty());
assertTrue(cache1.isEmpty());
String value = "import \"missing.proto\";";
cache0.putIfAbsent("test.proto", value);
assertEquals(value, cache0.get("test.proto"));
assertEquals(value, cache1.get("test.proto"));
assertEquals("Import 'missing.proto' not found", cache0.get("test.proto.errors"));
assertEquals("test.proto", cache0.get(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertEquals("Import 'missing.proto' not found", cache1.get("test.proto.errors"));
assertEquals("test.proto", cache1.get(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
cache0.putIfAbsent("test.proto", "package foobar;");
assertEquals(value, cache0.get("test.proto"));
assertEquals(value, cache1.get("test.proto"));
assertEquals("Import 'missing.proto' not found", cache0.get("test.proto.errors"));
assertEquals("test.proto", cache0.get(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertEquals("Import 'missing.proto' not found", cache1.get("test.proto.errors"));
assertEquals("test.proto", cache1.get(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
value = "package foobar;";
cache0.put("test.proto", value);
assertEquals(value, cache0.get("test.proto"));
assertEquals(value, cache1.get("test.proto"));
assertFalse(cache0.containsKey("test.proto.errors"));
assertFalse(cache1.containsKey("test.proto.errors"));
assertFalse(cache0.containsKey(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertFalse(cache1.containsKey(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertNoTransactionsAndLocks();
}
public void testStatusAfterPutAll() {
Cache<String, String> cache0 = cache(0);
Cache<String, String> cache1 = cache(1);
assertTrue(cache0.isEmpty());
assertTrue(cache1.isEmpty());
String file1 = "import \"missing.proto\";";
String file2 = "package b;";
Map<String, String> map = new HashMap<>();
map.put("a.proto", file1);
map.put("b.proto", file2);
cache0.putAll(map);
assertEquals(file1, cache0.get("a.proto"));
assertEquals(file2, cache0.get("b.proto"));
assertEquals(file1, cache1.get("a.proto"));
assertEquals(file2, cache1.get("b.proto"));
assertEquals("Import 'missing.proto' not found", cache0.get("a.proto.errors"));
assertEquals("Import 'missing.proto' not found", cache1.get("a.proto.errors"));
assertFalse(cache0.containsKey("b.proto.errors"));
assertFalse(cache1.containsKey("b.proto.errors"));
assertTrue(cache0.containsKey(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertTrue(cache1.containsKey(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertEquals("a.proto", cache0.get(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertEquals("a.proto", cache1.get(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
file1 = "package a;";
map.put("a.proto", file1);
cache0.putAll(map);
assertEquals(file1, cache0.get("a.proto"));
assertEquals(file1, cache1.get("a.proto"));
assertEquals(file2, cache0.get("b.proto"));
assertEquals(file2, cache1.get("b.proto"));
assertFalse(cache0.containsKey("a.proto.errors"));
assertFalse(cache1.containsKey("a.proto.errors"));
assertFalse(cache0.containsKey("b.proto.errors"));
assertFalse(cache1.containsKey("b.proto.errors"));
assertFalse(cache0.containsKey(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertFalse(cache1.containsKey(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertNoTransactionsAndLocks();
}
public void testStatusAfterRemove() {
Cache<String, String> cache0 = cache(0);
Cache<String, String> cache1 = cache(1);
assertTrue(cache0.isEmpty());
assertTrue(cache1.isEmpty());
String value = "import \"missing.proto\";";
cache0.put("test.proto", value);
assertEquals(value, cache0.get("test.proto"));
assertEquals(value, cache1.get("test.proto"));
assertEquals("Import 'missing.proto' not found", cache0.get("test.proto.errors"));
assertEquals("Import 'missing.proto' not found", cache1.get("test.proto.errors"));
cache0.remove("test.proto");
assertFalse(cache0.containsKey("test.proto"));
assertFalse(cache1.containsKey("test.proto"));
assertFalse(cache0.containsKey("test.proto.errors"));
assertFalse(cache1.containsKey("test.proto.errors"));
assertFalse(cache0.containsKey(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertFalse(cache1.containsKey(ProtobufMetadataManagerConstants.ERRORS_KEY_SUFFIX));
assertNoTransactionsAndLocks();
}
private void assertNoTransactionsAndLocks() {
assertNoTransactions();
TestingUtil.assertNoLocks(cache(0));
TestingUtil.assertNoLocks(cache(1));
}
}