/*
* Copyright (c) 2008-2017, Hazelcast, Inc. All Rights Reserved.
*
* Licensed 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 com.hazelcast.map.impl.tx;
import com.hazelcast.config.Config;
import com.hazelcast.core.EntryAdapter;
import com.hazelcast.core.EntryListener;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import com.hazelcast.core.TransactionalMap;
import com.hazelcast.query.EntryObject;
import com.hazelcast.query.Predicate;
import com.hazelcast.query.PredicateBuilder;
import com.hazelcast.query.SampleObjects;
import com.hazelcast.query.SqlPredicate;
import com.hazelcast.test.HazelcastParallelClassRunner;
import com.hazelcast.test.HazelcastTestSupport;
import com.hazelcast.test.TestHazelcastInstanceFactory;
import com.hazelcast.test.annotation.NightlyTest;
import com.hazelcast.transaction.TransactionContext;
import com.hazelcast.transaction.TransactionException;
import com.hazelcast.transaction.TransactionOptions;
import com.hazelcast.transaction.TransactionalTask;
import com.hazelcast.transaction.TransactionalTaskContext;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
@RunWith(HazelcastParallelClassRunner.class)
@Category(NightlyTest.class)
public class MapTransactionRegressionTest extends HazelcastTestSupport {
private final TransactionOptions options = new TransactionOptions()
.setTransactionType(TransactionOptions.TransactionType.TWO_PHASE);
@Test
public void test_Issue615_keySet() throws TransactionException {
Config config = getConfig();
final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2);
final HazelcastInstance h1 = factory.newHazelcastInstance(config);
final HazelcastInstance h2 = factory.newHazelcastInstance(config);
final IMap map = h2.getMap("default");
map.put("1", "1");
map.put("2", "2");
boolean b = h1.executeTransaction(options, new TransactionalTask<Boolean>() {
public Boolean execute(TransactionalTaskContext context) throws TransactionException {
final TransactionalMap<Object, Object> txMap = context.getMap("default");
txMap.put("3", "3");
assertEquals(3, txMap.keySet().size());
map.put("4", "4");
assertEquals(4, txMap.keySet().size());
txMap.remove("1");
assertEquals(3, txMap.keySet().size());
map.remove("2");
assertEquals(2, txMap.keySet().size());
assertEquals(2, txMap.size());
return true;
}
});
assertEquals(2, map.keySet().size());
// raise an exception and rollback changes.
try {
boolean b2 = h1.executeTransaction(options, new TransactionalTask<Boolean>() {
public Boolean execute(TransactionalTaskContext context) throws TransactionException {
final TransactionalMap<Object, Object> txMap = context.getMap("default");
txMap.put("5", "5");
assertEquals(3, txMap.keySet().size());
assertEquals(2, map.keySet().size());
throw new DummyUncheckedHazelcastTestException();
}
});
} catch (Exception e) {
if (!(e instanceof DummyUncheckedHazelcastTestException)) {
throw new RuntimeException(e);
}
}
assertEquals(2, map.keySet().size());
h1.shutdown();
h2.shutdown();
}
@Test
public void test_Issue615_KeysetWithPredicate() throws TransactionException {
Config config = getConfig();
final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2);
final HazelcastInstance h1 = factory.newHazelcastInstance(config);
final HazelcastInstance h2 = factory.newHazelcastInstance(config);
final IMap map = h2.getMap("default");
final SampleObjects.Employee employee1 = new SampleObjects.Employee("abc-123-xvz", 34, true, 10D);
final SampleObjects.Employee employee2 = new SampleObjects.Employee("abc-1xvz", 4, true, 7D);
final SampleObjects.Employee employee3 = new SampleObjects.Employee("abc-1xasda...vz", 7, true, 1D);
final SampleObjects.Employee employee4 = new SampleObjects.Employee("abc-1asdsaxvz", 2, true, 2D);
map.put(1, employee1);
try {
h1.executeTransaction(options, new TransactionalTask<Boolean>() {
public Boolean execute(TransactionalTaskContext context) throws TransactionException {
final TransactionalMap<Object, Object> txMap = context.getMap("default");
assertEquals(0, txMap.keySet(new SqlPredicate("age <= 10")).size());
//put
txMap.put(2, employee2);
Set keys = txMap.keySet(new SqlPredicate("age <= 10"));
Iterator iterator = keys.iterator();
assertEquals(1, keys.size());
while (iterator.hasNext()) {
assertEquals(2, ((Integer) iterator.next()).intValue());
}
txMap.put(3, employee3);
txMap.put(4, employee4);
keys = txMap.keySet(new SqlPredicate("age <= 10"));
assertEquals(3, keys.size());
// force rollback.
throw new DummyUncheckedHazelcastTestException();
}
});
} catch (Exception e) {
if (!(e instanceof DummyUncheckedHazelcastTestException)) {
throw new RuntimeException(e);
}
}
assertEquals(1, map.size());
assertEquals(1, map.keySet().size());
assertEquals(0, map.keySet(new SqlPredicate("age <= 10")).size());
h1.shutdown();
h2.shutdown();
}
@Test
public void test_Issue615_KeysetPredicates() throws TransactionException {
final String MAP_NAME = "defaultMap";
final Config config = getConfig();
final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2);
final HazelcastInstance h1 = factory.newHazelcastInstance(config);
final HazelcastInstance h2 = factory.newHazelcastInstance(config);
final IMap map = h2.getMap(MAP_NAME);
final SampleObjects.Employee employee1 = new SampleObjects.Employee("abc-123-xvz", 34, true, 10D);
final SampleObjects.Employee employee2 = new SampleObjects.Employee("abc-1xvz", 4, true, 7D);
final SampleObjects.Employee employee3 = new SampleObjects.Employee("abc-1xasda...vz", 7, true, 1D);
final SampleObjects.Employee employee4 = new SampleObjects.Employee("abc-1asdsaxvz", 2, true, 2D);
map.put(employee1, employee1);
final TransactionContext context = h1.newTransactionContext();
context.beginTransaction();
final TransactionalMap<Object, Object> txMap = context.getMap(MAP_NAME);
assertNull(txMap.put(employee2, employee2));
assertEquals(2, txMap.size());
assertEquals(2, txMap.keySet().size());
assertEquals(1, txMap.keySet(new SqlPredicate("age = 34")).size());
context.commitTransaction();
assertEquals(2, map.size());
h1.shutdown();
h2.shutdown();
}
@Test
public void test_Issue615_values() throws TransactionException {
Config config = getConfig();
final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2);
final HazelcastInstance h1 = factory.newHazelcastInstance(config);
final HazelcastInstance h2 = factory.newHazelcastInstance(config);
final IMap map2 = h2.getMap("default");
map2.put("1", "1");
map2.put("2", "2");
boolean b = h1.executeTransaction(options, new TransactionalTask<Boolean>() {
public Boolean execute(TransactionalTaskContext context) throws TransactionException {
final TransactionalMap<Object, Object> txMap = context.getMap("default");
txMap.put("3", "3");
assertEquals(3, txMap.values().size());
map2.put("4", "4");
assertEquals(4, txMap.values().size());
txMap.remove("1");
assertEquals(3, txMap.values().size());
map2.remove("2");
assertEquals(2, txMap.values().size());
assertEquals(2, txMap.size());
txMap.put("12", "32");
assertEquals(2, map2.values().size());
return true;
}
});
assertEquals(3, map2.values().size());
h1.shutdown();
h2.shutdown();
}
@Test
public void test_Issue615_ValuesWithPredicate() throws TransactionException {
Config config = getConfig();
final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2);
final HazelcastInstance h1 = factory.newHazelcastInstance(config);
final HazelcastInstance h2 = factory.newHazelcastInstance(config);
final IMap map2 = h2.getMap("default");
final SampleObjects.Employee emp1 = new SampleObjects.Employee("abc-123-xvz", 34, true, 10D);
map2.put(1, emp1);
final SampleObjects.Employee emp2 = new SampleObjects.Employee("xvz", 4, true, 10D);
boolean b = h1.executeTransaction(options, new TransactionalTask<Boolean>() {
public Boolean execute(TransactionalTaskContext context) throws TransactionException {
final TransactionalMap<Object, Object> txMap = context.getMap("default");
assertEquals(0, txMap.values(new SqlPredicate("age <= 10")).size());
txMap.put(2, emp2);
Collection coll = txMap.values(new SqlPredicate("age <= 10"));
Iterator<Object> iterator = coll.iterator();
while (iterator.hasNext()) {
final SampleObjects.Employee e = (SampleObjects.Employee) iterator.next();
assertEquals(emp2, e);
}
coll = txMap.values(new SqlPredicate("age > 30 "));
iterator = coll.iterator();
while (iterator.hasNext()) {
final SampleObjects.Employee e = (SampleObjects.Employee) iterator.next();
assertEquals(emp1, e);
}
txMap.remove(2);
coll = txMap.values(new SqlPredicate("age <= 10 "));
assertEquals(0, coll.size());
return true;
}
});
assertEquals(0, map2.values(new SqlPredicate("age <= 10")).size());
assertEquals(1, map2.values(new SqlPredicate("age = 34")).size());
h1.shutdown();
h2.shutdown();
}
//unfortunately the bug can't be detected by a unit test since the exception is thrown in a background thread (and logged)
@Test
public void test_Issue1056s() throws InterruptedException {
Config config = getConfig();
final TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(2);
HazelcastInstance instance = factory.newHazelcastInstance(config);
final HazelcastInstance instance2 = factory.newHazelcastInstance(config);
final CountDownLatch latch = new CountDownLatch(1);
final Thread t = new Thread() {
@Override
public void run() {
TransactionContext ctx = instance2.newTransactionContext();
ctx.beginTransaction();
TransactionalMap<Integer, Integer> txnMap = ctx.getMap("test");
latch.countDown();
txnMap.delete(1);
ctx.commitTransaction();
}
};
t.start();
TransactionContext ctx = instance2.newTransactionContext();
ctx.beginTransaction();
TransactionalMap<Integer, Integer> txnMap = ctx.getMap("test");
txnMap.delete(1);
latch.await();
ctx.commitTransaction();
t.join();
}
@Test
public void test_Issue1076() {
Config config = getConfig();
final HazelcastInstance inst = createHazelcastInstance(config);
IMap map = inst.getMap("default");
EntryListener<String, Integer> l = new EntryAdapter<String, Integer>() {
};
EntryObject e = new PredicateBuilder().getEntryObject();
Predicate<String, Integer> p = e.equal(1);
map.addEntryListener(l, p, null, false);
for (Integer i = 0; i < 100; i++) {
TransactionContext context = inst.newTransactionContext();
context.beginTransaction();
TransactionalMap<String, Integer> txnMap = context.getMap("default");
txnMap.remove(i.toString());
context.commitTransaction();
}
assertEquals(0, map.size());
inst.shutdown();
}
}