package org.infinispan.stats.logic; import static java.util.concurrent.TimeUnit.NANOSECONDS; import static org.infinispan.stats.CacheStatisticCollector.convertNanosToMicro; import static org.infinispan.stats.CacheStatisticCollector.convertNanosToSeconds; import static org.infinispan.stats.container.ExtendedStatistic.ABORT_RATE; import static org.infinispan.stats.container.ExtendedStatistic.ALL_GET_EXECUTION; import static org.infinispan.stats.container.ExtendedStatistic.ARRIVAL_RATE; import static org.infinispan.stats.container.ExtendedStatistic.ASYNC_COMPLETE_NOTIFY_TIME; import static org.infinispan.stats.container.ExtendedStatistic.CLUSTERED_GET_COMMAND_SIZE; import static org.infinispan.stats.container.ExtendedStatistic.COMMIT_COMMAND_SIZE; import static org.infinispan.stats.container.ExtendedStatistic.COMMIT_EXECUTION_TIME; import static org.infinispan.stats.container.ExtendedStatistic.LOCAL_COMMIT_EXECUTION_TIME; import static org.infinispan.stats.container.ExtendedStatistic.LOCAL_EXEC_NO_CONT; import static org.infinispan.stats.container.ExtendedStatistic.LOCAL_GET_EXECUTION; import static org.infinispan.stats.container.ExtendedStatistic.LOCAL_PREPARE_EXECUTION_TIME; import static org.infinispan.stats.container.ExtendedStatistic.LOCAL_PUT_EXECUTION; import static org.infinispan.stats.container.ExtendedStatistic.LOCAL_ROLLBACK_EXECUTION_TIME; import static org.infinispan.stats.container.ExtendedStatistic.LOCK_HOLD_TIME; import static org.infinispan.stats.container.ExtendedStatistic.LOCK_HOLD_TIME_LOCAL; import static org.infinispan.stats.container.ExtendedStatistic.LOCK_HOLD_TIME_REMOTE; import static org.infinispan.stats.container.ExtendedStatistic.LOCK_HOLD_TIME_SUCCESS_LOCAL_TX; import static org.infinispan.stats.container.ExtendedStatistic.LOCK_WAITING_TIME; import static org.infinispan.stats.container.ExtendedStatistic.NUM_ABORTED_RO_TX; import static org.infinispan.stats.container.ExtendedStatistic.NUM_ABORTED_WR_TX; import static org.infinispan.stats.container.ExtendedStatistic.NUM_ASYNC_COMPLETE_NOTIFY; import static org.infinispan.stats.container.ExtendedStatistic.NUM_COMMITTED_RO_TX; import static org.infinispan.stats.container.ExtendedStatistic.NUM_COMMITTED_TX; import static org.infinispan.stats.container.ExtendedStatistic.NUM_COMMITTED_WR_TX; import static org.infinispan.stats.container.ExtendedStatistic.NUM_COMMIT_COMMAND; import static org.infinispan.stats.container.ExtendedStatistic.NUM_GET; import static org.infinispan.stats.container.ExtendedStatistic.NUM_GETS_RO_TX; import static org.infinispan.stats.container.ExtendedStatistic.NUM_GETS_WR_TX; import static org.infinispan.stats.container.ExtendedStatistic.NUM_HELD_LOCKS; import static org.infinispan.stats.container.ExtendedStatistic.NUM_HELD_LOCKS_SUCCESS_LOCAL_TX; import static org.infinispan.stats.container.ExtendedStatistic.NUM_LOCAL_COMMITTED_TX; import static org.infinispan.stats.container.ExtendedStatistic.NUM_LOCK_FAILED_DEADLOCK; import static org.infinispan.stats.container.ExtendedStatistic.NUM_LOCK_FAILED_TIMEOUT; import static org.infinispan.stats.container.ExtendedStatistic.NUM_LOCK_PER_LOCAL_TX; import static org.infinispan.stats.container.ExtendedStatistic.NUM_LOCK_PER_REMOTE_TX; import static org.infinispan.stats.container.ExtendedStatistic.NUM_NODES_COMMIT; import static org.infinispan.stats.container.ExtendedStatistic.NUM_NODES_COMPLETE_NOTIFY; import static org.infinispan.stats.container.ExtendedStatistic.NUM_NODES_GET; import static org.infinispan.stats.container.ExtendedStatistic.NUM_NODES_PREPARE; import static org.infinispan.stats.container.ExtendedStatistic.NUM_NODES_ROLLBACK; import static org.infinispan.stats.container.ExtendedStatistic.NUM_PREPARE_COMMAND; import static org.infinispan.stats.container.ExtendedStatistic.NUM_PUT; import static org.infinispan.stats.container.ExtendedStatistic.NUM_PUTS_WR_TX; import static org.infinispan.stats.container.ExtendedStatistic.NUM_REMOTE_GET; import static org.infinispan.stats.container.ExtendedStatistic.NUM_REMOTE_GETS_RO_TX; import static org.infinispan.stats.container.ExtendedStatistic.NUM_REMOTE_GETS_WR_TX; import static org.infinispan.stats.container.ExtendedStatistic.NUM_REMOTE_PUT; import static org.infinispan.stats.container.ExtendedStatistic.NUM_REMOTE_PUTS_WR_TX; import static org.infinispan.stats.container.ExtendedStatistic.NUM_ROLLBACK_COMMAND; import static org.infinispan.stats.container.ExtendedStatistic.NUM_SYNC_COMMIT; import static org.infinispan.stats.container.ExtendedStatistic.NUM_SYNC_GET; import static org.infinispan.stats.container.ExtendedStatistic.NUM_SYNC_PREPARE; import static org.infinispan.stats.container.ExtendedStatistic.NUM_SYNC_ROLLBACK; import static org.infinispan.stats.container.ExtendedStatistic.NUM_WAITED_FOR_LOCKS; import static org.infinispan.stats.container.ExtendedStatistic.NUM_WRITE_SKEW; import static org.infinispan.stats.container.ExtendedStatistic.PREPARE_COMMAND_SIZE; import static org.infinispan.stats.container.ExtendedStatistic.PREPARE_EXECUTION_TIME; import static org.infinispan.stats.container.ExtendedStatistic.REMOTE_COMMIT_EXECUTION_TIME; import static org.infinispan.stats.container.ExtendedStatistic.REMOTE_GET_EXECUTION; import static org.infinispan.stats.container.ExtendedStatistic.REMOTE_PREPARE_EXECUTION_TIME; import static org.infinispan.stats.container.ExtendedStatistic.REMOTE_PUT_EXECUTION; import static org.infinispan.stats.container.ExtendedStatistic.REMOTE_ROLLBACK_EXECUTION_TIME; import static org.infinispan.stats.container.ExtendedStatistic.RESPONSE_TIME; import static org.infinispan.stats.container.ExtendedStatistic.ROLLBACK_EXECUTION_TIME; import static org.infinispan.stats.container.ExtendedStatistic.RO_TX_ABORTED_EXECUTION_TIME; import static org.infinispan.stats.container.ExtendedStatistic.RO_TX_SUCCESSFUL_EXECUTION_TIME; import static org.infinispan.stats.container.ExtendedStatistic.SUCCESSFUL_WRITE_TX_PERCENTAGE; import static org.infinispan.stats.container.ExtendedStatistic.SYNC_COMMIT_TIME; import static org.infinispan.stats.container.ExtendedStatistic.SYNC_GET_TIME; import static org.infinispan.stats.container.ExtendedStatistic.SYNC_PREPARE_TIME; import static org.infinispan.stats.container.ExtendedStatistic.SYNC_ROLLBACK_TIME; import static org.infinispan.stats.container.ExtendedStatistic.THROUGHPUT; import static org.infinispan.stats.container.ExtendedStatistic.WRITE_SKEW_PROBABILITY; import static org.infinispan.stats.container.ExtendedStatistic.WRITE_TX_PERCENTAGE; import static org.infinispan.stats.container.ExtendedStatistic.WR_TX_ABORTED_EXECUTION_TIME; import static org.infinispan.stats.container.ExtendedStatistic.WR_TX_SUCCESSFUL_EXECUTION_TIME; import static org.infinispan.stats.container.ExtendedStatistic.values; import static org.infinispan.test.TestingUtil.extractField; import static org.infinispan.test.TestingUtil.extractLockManager; import static org.infinispan.test.TestingUtil.replaceField; import static org.infinispan.test.TestingUtil.sleepThread; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; import java.util.concurrent.TimeUnit; import org.infinispan.configuration.cache.CacheMode; import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.interceptors.impl.TxInterceptor; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.stats.CacheStatisticCollector; import org.infinispan.stats.CacheStatisticManager; import org.infinispan.stats.container.ConcurrentGlobalContainer; import org.infinispan.stats.container.ExtendedStatistic; import org.infinispan.stats.wrappers.ExtendedStatisticInterceptor; import org.infinispan.stats.wrappers.ExtendedStatisticLockManager; import org.infinispan.test.SingleCacheManagerTest; import org.infinispan.test.fwk.TestCacheManagerFactory; import org.infinispan.util.DefaultTimeService; import org.infinispan.util.TimeService; import org.infinispan.util.concurrent.IsolationLevel; import org.testng.annotations.Test; /** * @author Pedro Ruivo * @since 6.0 */ @Test(groups = "functional", testName = "stats.logic.LocalTxClusterExtendedStatisticLogicTest") public class LocalTxClusterExtendedStatisticLogicTest extends SingleCacheManagerTest { private static final int SLEEP_TIME = 500; private static final TimeService TEST_TIME_SERVICE = new DefaultTimeService() { @Override public long time() { return 0; } @Override public long timeDuration(long startTime, TimeUnit outputTimeUnit) { assertEquals(startTime, 0, "Start timestamp must be zero!"); assertEquals(outputTimeUnit, NANOSECONDS, "TimeUnit is different from expected"); return 1; } @Override public long timeDuration(long startTime, long endTime, TimeUnit outputTimeUnit) { assertEquals(startTime, 0, "Start timestamp must be zero!"); assertEquals(endTime, 0, "End timestamp must be zero!"); assertEquals(outputTimeUnit, NANOSECONDS, "TimeUnit is different from expected"); return 1; } }; private static final double MICROSECONDS = convertNanosToMicro(TEST_TIME_SERVICE.timeDuration(0, NANOSECONDS)); private static final double SECONDS = convertNanosToSeconds(TEST_TIME_SERVICE.timeDuration(0, NANOSECONDS)); //private final TransactionInterceptor[] transactionInterceptors = new TransactionInterceptor[NUM_NODES]; private final List<Object> keys = new ArrayList<>(128); private ExtendedStatisticInterceptor extendedStatisticInterceptor; public final void testPutTxAndReadOnlyTx() throws Exception { testStats(WriteOperation.PUT, 2, 7, 3, 4, 5, false); } public final void testPutTxAndReadOnlyTxRollback() throws Exception { testStats(WriteOperation.PUT, 3, 6, 2, 5, 4, true); } public final void testConditionalPutTxAndReadOnlyTx() throws Exception { testStats(WriteOperation.PUT_IF, 4, 5, 4, 6, 3, false); } public final void testConditionalPutTxAndReadOnlyTxRollback() throws Exception { testStats(WriteOperation.PUT_IF, 5, 4, 5, 7, 2, true); } public final void testReplaceTxAndReadOnlyTx() throws Exception { testStats(WriteOperation.REPLACE, 2, 7, 3, 4, 5, false); } public final void testReplaceTxAndReadOnlyTxRollback() throws Exception { testStats(WriteOperation.REPLACE, 3, 6, 2, 5, 4, true); } public final void testConditionalReplaceTxAndReadOnlyTx() throws Exception { testStats(WriteOperation.REPLACE_IF, 4, 5, 4, 6, 3, false); } public final void testConditionalReplaceTxAndReadOnlyTxRollback() throws Exception { testStats(WriteOperation.REPLACE_IF, 5, 4, 5, 7, 2, true); } public final void testRemoveTxAndReadOnlyTx() throws Exception { testStats(WriteOperation.REMOVE, 2, 7, 3, 4, 5, false); } public final void testRemoveTxAndReadOnlyTxRollback() throws Exception { testStats(WriteOperation.REMOVE, 3, 6, 2, 5, 4, true); } public final void testConditionalRemoveTxAndReadOnlyTx() throws Exception { testStats(WriteOperation.REMOVE_IF, 4, 5, 4, 6, 3, false); } public final void testConditionalRemoveTxAndReadOnlyTxRollback() throws Exception { testStats(WriteOperation.REMOVE_IF, 5, 4, 5, 7, 2, true); } @Override protected void setup() throws Exception { super.setup(); CacheStatisticManager manager = extractField(extendedStatisticInterceptor, "cacheStatisticManager"); CacheStatisticCollector collector = extractField(manager, "cacheStatisticCollector"); ConcurrentGlobalContainer globalContainer = extractField(collector, "globalContainer"); replaceField(TEST_TIME_SERVICE, "timeService", manager, CacheStatisticManager.class); replaceField(TEST_TIME_SERVICE, "timeService", collector, CacheStatisticCollector.class); replaceField(TEST_TIME_SERVICE, "timeService", globalContainer, ConcurrentGlobalContainer.class); replaceField(TEST_TIME_SERVICE, "timeService", extendedStatisticInterceptor, ExtendedStatisticInterceptor.class); replaceField(TEST_TIME_SERVICE, "timeService", extractLockManager(cache()), ExtendedStatisticLockManager.class); } @Override protected EmbeddedCacheManager createCacheManager() throws Exception { ConfigurationBuilder builder = getDefaultClusteredCacheConfig(CacheMode.LOCAL, true); builder.locking().isolationLevel(IsolationLevel.REPEATABLE_READ) .lockAcquisitionTimeout(0); builder.clustering().hash().numOwners(1); builder.transaction().recovery().disable(); extendedStatisticInterceptor = new ExtendedStatisticInterceptor(); builder.customInterceptors().addInterceptor().interceptor(extendedStatisticInterceptor) .after(TxInterceptor.class); return TestCacheManagerFactory.createCacheManager(builder); } private void testStats(WriteOperation operation, int numOfWriteTx, int numOfWrites, int numOfReadsPerWriteTx, int numOfReadOnlyTx, int numOfReadPerReadTx, boolean abort) throws Exception { for (int i = 1; i <= (numOfReadsPerWriteTx + numOfWrites) * numOfWriteTx + numOfReadPerReadTx * numOfReadOnlyTx; ++i) { cache().put(getKey(i), getInitValue(i)); } sleepThread(SLEEP_TIME); resetStats(); int localGetsReadTx = 0; int localGetsWriteTx = 0; int localPuts = 0; int localLocks = 0; int numOfLocalWriteTx = 0; int keyIndex = 0; //write tx for (int tx = 1; tx <= numOfWriteTx; ++tx) { tm().begin(); for (int i = 1; i <= numOfReadsPerWriteTx; ++i) { keyIndex++; Object key = getKey(keyIndex); localGetsWriteTx++; assertEquals(cache().get(key), getInitValue(keyIndex)); } for (int i = 1; i <= numOfWrites; ++i) { keyIndex++; Object key = operation == WriteOperation.PUT_IF ? getKey(-keyIndex) : getKey(keyIndex); switch (operation) { case PUT: cache().put(key, getValue(keyIndex)); break; case PUT_IF: cache().putIfAbsent(key, getValue(keyIndex)); break; case REPLACE: cache().replace(key, getValue(keyIndex)); break; case REPLACE_IF: cache().replace(key, getInitValue(keyIndex), getValue(keyIndex)); break; case REMOVE: cache().remove(key); break; case REMOVE_IF: cache().remove(key, getInitValue(keyIndex)); break; default: //nothing } localPuts++; if (!abort) { localLocks++; } } numOfLocalWriteTx++; if (abort) { tm().rollback(); } else { tm().commit(); } } sleepThread(SLEEP_TIME); //read tx for (int tx = 1; tx <= numOfReadOnlyTx; ++tx) { tm().begin(); for (int i = 1; i <= numOfReadPerReadTx; ++i) { keyIndex++; Object key = getKey(keyIndex); localGetsReadTx++; assertEquals(cache().get(key), getInitValue(keyIndex)); } if (abort) { tm().rollback(); } else { tm().commit(); } } sleepThread(SLEEP_TIME); EnumSet<ExtendedStatistic> statsToValidate = getStatsToValidate(); assertTxValues(statsToValidate, numOfLocalWriteTx, numOfReadOnlyTx, abort); assertLockingValues(statsToValidate, localLocks, numOfLocalWriteTx, abort); assertAccessesValues(statsToValidate, localGetsReadTx, localGetsWriteTx, localPuts, numOfWriteTx, numOfReadOnlyTx, abort); assertAttributeValue(NUM_WRITE_SKEW, statsToValidate, 0); assertAttributeValue(WRITE_SKEW_PROBABILITY, statsToValidate, 0); assertAllStatsValidated(statsToValidate); resetStats(); } private Object getKey(int i) { if (i < 0) { return "KEY_" + i; } for (int j = keys.size(); j <= i; ++j) { keys.add("KEY_" + (j + 1)); } return keys.get(i - 1); } private Object getInitValue(int i) { return "INIT_" + i; } private Object getValue(int i) { return "VALUE_" + i; } private void assertTxValues(EnumSet<ExtendedStatistic> statsToValidate, int numOfWriteTx, int numOfReadTx, boolean abort) { log.infof("Check Tx value: writeTx=%s, readTx=%s, abort?=%s", numOfWriteTx, numOfReadTx, abort); if (abort) { assertAttributeValue(NUM_COMMITTED_RO_TX, statsToValidate, 0); //not exposed via JMX assertAttributeValue(NUM_COMMITTED_WR_TX, statsToValidate, 0); //not exposed via JMX assertAttributeValue(NUM_ABORTED_WR_TX, statsToValidate, numOfWriteTx); //not exposed via JMX assertAttributeValue(NUM_ABORTED_RO_TX, statsToValidate, numOfReadTx); //not exposed via JMX assertAttributeValue(NUM_COMMITTED_TX, statsToValidate, 0); assertAttributeValue(NUM_LOCAL_COMMITTED_TX, statsToValidate, 0); assertAttributeValue(LOCAL_EXEC_NO_CONT, statsToValidate, 0); assertAttributeValue(WRITE_TX_PERCENTAGE, statsToValidate, numOfWriteTx * 1.0 / (numOfWriteTx + numOfReadTx)); assertAttributeValue(SUCCESSFUL_WRITE_TX_PERCENTAGE, statsToValidate, 0); assertAttributeValue(WR_TX_ABORTED_EXECUTION_TIME, statsToValidate, numOfWriteTx != 0 ? MICROSECONDS : 0); assertAttributeValue(RO_TX_ABORTED_EXECUTION_TIME, statsToValidate, numOfReadTx); //not exposed via JMX assertAttributeValue(WR_TX_SUCCESSFUL_EXECUTION_TIME, statsToValidate, 0); assertAttributeValue(RO_TX_SUCCESSFUL_EXECUTION_TIME, statsToValidate, 0); assertAttributeValue(ABORT_RATE, statsToValidate, 1); assertAttributeValue(ARRIVAL_RATE, statsToValidate, (numOfWriteTx + numOfReadTx) / SECONDS); assertAttributeValue(THROUGHPUT, statsToValidate, 0); assertAttributeValue(ROLLBACK_EXECUTION_TIME, statsToValidate, numOfReadTx != 0 || numOfWriteTx != 0 ? MICROSECONDS : 0); assertAttributeValue(NUM_ROLLBACK_COMMAND, statsToValidate, numOfReadTx + numOfWriteTx); assertAttributeValue(LOCAL_ROLLBACK_EXECUTION_TIME, statsToValidate, numOfReadTx != 0 || numOfWriteTx != 0 ? MICROSECONDS : 0); assertAttributeValue(REMOTE_ROLLBACK_EXECUTION_TIME, statsToValidate, 0); assertAttributeValue(COMMIT_EXECUTION_TIME, statsToValidate, 0); assertAttributeValue(NUM_COMMIT_COMMAND, statsToValidate, 0); assertAttributeValue(LOCAL_COMMIT_EXECUTION_TIME, statsToValidate, 0); assertAttributeValue(REMOTE_COMMIT_EXECUTION_TIME, statsToValidate, 0); assertAttributeValue(PREPARE_EXECUTION_TIME, statsToValidate, 0); // //not exposed via JMX assertAttributeValue(NUM_PREPARE_COMMAND, statsToValidate, 0); assertAttributeValue(LOCAL_PREPARE_EXECUTION_TIME, statsToValidate, 0); assertAttributeValue(REMOTE_PREPARE_EXECUTION_TIME, statsToValidate, 0); assertAttributeValue(NUM_SYNC_PREPARE, statsToValidate, 0); assertAttributeValue(SYNC_PREPARE_TIME, statsToValidate, 0); assertAttributeValue(NUM_SYNC_COMMIT, statsToValidate, 0); assertAttributeValue(SYNC_COMMIT_TIME, statsToValidate, 0); assertAttributeValue(NUM_SYNC_ROLLBACK, statsToValidate, 0); assertAttributeValue(SYNC_ROLLBACK_TIME, statsToValidate, 0); assertAttributeValue(ASYNC_COMPLETE_NOTIFY_TIME, statsToValidate, 0); assertAttributeValue(NUM_ASYNC_COMPLETE_NOTIFY, statsToValidate, 0); assertAttributeValue(NUM_NODES_PREPARE, statsToValidate, 0); assertAttributeValue(NUM_NODES_COMMIT, statsToValidate, 0); assertAttributeValue(NUM_NODES_ROLLBACK, statsToValidate, 0); assertAttributeValue(NUM_NODES_COMPLETE_NOTIFY, statsToValidate, 0); assertAttributeValue(RESPONSE_TIME, statsToValidate, 0); } else { assertAttributeValue(NUM_COMMITTED_RO_TX, statsToValidate, numOfReadTx); //not exposed via JMX assertAttributeValue(NUM_COMMITTED_WR_TX, statsToValidate, numOfWriteTx); //not exposed via JMX assertAttributeValue(NUM_ABORTED_WR_TX, statsToValidate, 0); //not exposed via JMX assertAttributeValue(NUM_ABORTED_RO_TX, statsToValidate, 0); //not exposed via JMX assertAttributeValue(NUM_COMMITTED_TX, statsToValidate, numOfWriteTx + numOfReadTx); assertAttributeValue(NUM_LOCAL_COMMITTED_TX, statsToValidate, numOfReadTx + numOfWriteTx); assertAttributeValue(LOCAL_EXEC_NO_CONT, statsToValidate, numOfWriteTx != 0 ? MICROSECONDS : 0); assertAttributeValue(WRITE_TX_PERCENTAGE, statsToValidate, (numOfWriteTx * 1.0) / (numOfReadTx + numOfWriteTx)); assertAttributeValue(SUCCESSFUL_WRITE_TX_PERCENTAGE, statsToValidate, (numOfReadTx + numOfWriteTx) > 0 ? (numOfWriteTx * 1.0) / (numOfReadTx + numOfWriteTx) : 0); assertAttributeValue(WR_TX_ABORTED_EXECUTION_TIME, statsToValidate, 0); assertAttributeValue(RO_TX_ABORTED_EXECUTION_TIME, statsToValidate, 0); //not exposed via JMX assertAttributeValue(WR_TX_SUCCESSFUL_EXECUTION_TIME, statsToValidate, numOfWriteTx != 0 ? MICROSECONDS : 0); assertAttributeValue(RO_TX_SUCCESSFUL_EXECUTION_TIME, statsToValidate, numOfReadTx != 0 ? MICROSECONDS : 0); assertAttributeValue(ABORT_RATE, statsToValidate, 0); assertAttributeValue(ARRIVAL_RATE, statsToValidate, (numOfWriteTx + numOfReadTx) / SECONDS); assertAttributeValue(THROUGHPUT, statsToValidate, (numOfWriteTx + numOfReadTx) / SECONDS); assertAttributeValue(ROLLBACK_EXECUTION_TIME, statsToValidate, 0); assertAttributeValue(NUM_ROLLBACK_COMMAND, statsToValidate, 0); assertAttributeValue(LOCAL_ROLLBACK_EXECUTION_TIME, statsToValidate, 0); assertAttributeValue(REMOTE_ROLLBACK_EXECUTION_TIME, statsToValidate, 0); assertAttributeValue(COMMIT_EXECUTION_TIME, statsToValidate, (numOfReadTx != 0 || numOfWriteTx != 0) ? MICROSECONDS : 0); assertAttributeValue(NUM_COMMIT_COMMAND, statsToValidate, numOfReadTx + numOfWriteTx); assertAttributeValue(LOCAL_COMMIT_EXECUTION_TIME, statsToValidate, (numOfReadTx != 0 || numOfWriteTx != 0) ? MICROSECONDS : 0); assertAttributeValue(REMOTE_COMMIT_EXECUTION_TIME, statsToValidate, 0); assertAttributeValue(PREPARE_EXECUTION_TIME, statsToValidate, numOfReadTx + numOfWriteTx); // //not exposed via JMX assertAttributeValue(NUM_PREPARE_COMMAND, statsToValidate, numOfReadTx + numOfWriteTx); assertAttributeValue(LOCAL_PREPARE_EXECUTION_TIME, statsToValidate, (numOfReadTx != 0 || numOfWriteTx != 0) ? MICROSECONDS : 0); assertAttributeValue(REMOTE_PREPARE_EXECUTION_TIME, statsToValidate, 0); assertAttributeValue(NUM_SYNC_PREPARE, statsToValidate, 0); assertAttributeValue(SYNC_PREPARE_TIME, statsToValidate, 0); assertAttributeValue(NUM_SYNC_COMMIT, statsToValidate, 0); assertAttributeValue(SYNC_COMMIT_TIME, statsToValidate, 0); assertAttributeValue(NUM_SYNC_ROLLBACK, statsToValidate, 0); assertAttributeValue(SYNC_ROLLBACK_TIME, statsToValidate, 0); assertAttributeValue(ASYNC_COMPLETE_NOTIFY_TIME, statsToValidate, 0); assertAttributeValue(NUM_ASYNC_COMPLETE_NOTIFY, statsToValidate, 0); assertAttributeValue(NUM_NODES_PREPARE, statsToValidate, 0); assertAttributeValue(NUM_NODES_COMMIT, statsToValidate, 0); assertAttributeValue(NUM_NODES_ROLLBACK, statsToValidate, 0); assertAttributeValue(NUM_NODES_COMPLETE_NOTIFY, statsToValidate, 0); assertAttributeValue(RESPONSE_TIME, statsToValidate, numOfReadTx != 0 || numOfWriteTx != 0 ? MICROSECONDS : 0); } } private void assertLockingValues(EnumSet<ExtendedStatistic> statsToValidate, int numOfLocks, int numOfWriteTx, boolean abort) { log.infof("Check Locking value. locks=%s, writeTx=%s, abort?=%s", numOfLocks, numOfWriteTx, abort); //remote puts always acquire locks assertAttributeValue(LOCK_HOLD_TIME_LOCAL, statsToValidate, numOfLocks != 0 ? MICROSECONDS : 0); assertAttributeValue(LOCK_HOLD_TIME_REMOTE, statsToValidate, 0); assertAttributeValue(NUM_LOCK_PER_LOCAL_TX, statsToValidate, numOfWriteTx != 0 ? numOfLocks * 1.0 / numOfWriteTx : 0); assertAttributeValue(NUM_LOCK_PER_REMOTE_TX, statsToValidate, 0); assertAttributeValue(LOCK_HOLD_TIME_SUCCESS_LOCAL_TX, statsToValidate, 0); assertAttributeValue(NUM_HELD_LOCKS_SUCCESS_LOCAL_TX, statsToValidate, !abort && numOfWriteTx != 0 ? numOfLocks * 1.0 / numOfWriteTx : 0); assertAttributeValue(LOCK_HOLD_TIME, statsToValidate, numOfLocks != 0 ? MICROSECONDS : 0); assertAttributeValue(NUM_HELD_LOCKS, statsToValidate, numOfLocks); assertAttributeValue(NUM_WAITED_FOR_LOCKS, statsToValidate, 0); assertAttributeValue(LOCK_WAITING_TIME, statsToValidate, 0); assertAttributeValue(NUM_LOCK_FAILED_TIMEOUT, statsToValidate, 0); assertAttributeValue(NUM_LOCK_FAILED_DEADLOCK, statsToValidate, 0); } private void assertAccessesValues(EnumSet<ExtendedStatistic> statsToValidate, int getsReadTx, int getsWriteTx, int puts, int numOfWriteTx, int numOfReadTx, boolean abort) { log.infof("Check accesses values. getsReadTx=%s, getsWriteTx=%s, puts=%s, writeTx=%s, readTx=%s, abort?=%s", getsReadTx, getsWriteTx, puts, numOfWriteTx, numOfReadTx, abort); assertAttributeValue(NUM_REMOTE_PUT, statsToValidate, 0); assertAttributeValue(REMOTE_PUT_EXECUTION, statsToValidate, 0); assertAttributeValue(LOCAL_PUT_EXECUTION, statsToValidate, 0); assertAttributeValue(NUM_PUT, statsToValidate, puts); assertAttributeValue(NUM_PUTS_WR_TX, statsToValidate, !abort && numOfWriteTx != 0 ? puts * 1.0 / numOfWriteTx : 0); assertAttributeValue(NUM_REMOTE_PUTS_WR_TX, statsToValidate, 0); assertAttributeValue(NUM_REMOTE_GET, statsToValidate, 0); assertAttributeValue(NUM_GET, statsToValidate, getsReadTx + getsWriteTx); assertAttributeValue(NUM_GETS_RO_TX, statsToValidate, !abort && numOfReadTx != 0 ? getsReadTx * 1.0 / numOfReadTx : 0); assertAttributeValue(NUM_GETS_WR_TX, statsToValidate, !abort && numOfWriteTx != 0 ? getsWriteTx * 1.0 / numOfWriteTx : 0); assertAttributeValue(NUM_REMOTE_GETS_WR_TX, statsToValidate, 0); assertAttributeValue(NUM_REMOTE_GETS_RO_TX, statsToValidate, 0); assertAttributeValue(ALL_GET_EXECUTION, statsToValidate, getsReadTx + getsWriteTx); //always zero because the all get execution and the rtt is always 1 (all get execution - rtt == 0) assertAttributeValue(LOCAL_GET_EXECUTION, statsToValidate, getsReadTx != 0 || getsWriteTx != 0 ? MICROSECONDS : 0); assertAttributeValue(REMOTE_GET_EXECUTION, statsToValidate, 0); assertAttributeValue(NUM_SYNC_GET, statsToValidate, 0); assertAttributeValue(SYNC_GET_TIME, statsToValidate, 0); assertAttributeValue(NUM_NODES_GET, statsToValidate, 0); } private void resetStats() { extendedStatisticInterceptor.resetStatistics(); for (ExtendedStatistic extendedStatistic : values()) { assertEquals(extendedStatisticInterceptor.getAttribute(extendedStatistic), 0.0, "Attribute " + extendedStatistic + " is not zero after reset"); } } private void assertAttributeValue(ExtendedStatistic attr, EnumSet<ExtendedStatistic> statsToValidate, double txExecutorValue) { assertTrue(statsToValidate.contains(attr), "Attribute " + attr + " already validated"); assertEquals(extendedStatisticInterceptor.getAttribute(attr), txExecutorValue, "Attribute " + attr + " has wrong value for cache."); statsToValidate.remove(attr); } private EnumSet<ExtendedStatistic> getStatsToValidate() { EnumSet<ExtendedStatistic> statsToValidate = EnumSet.allOf(ExtendedStatistic.class); //TODO fix this statsToValidate.removeAll(EnumSet.of(PREPARE_COMMAND_SIZE, COMMIT_COMMAND_SIZE, CLUSTERED_GET_COMMAND_SIZE)); return statsToValidate; } private void assertAllStatsValidated(EnumSet<ExtendedStatistic> statsToValidate) { assertTrue(statsToValidate.isEmpty(), "Stats not validated: " + statsToValidate + "."); } private enum WriteOperation { PUT, PUT_IF, REPLACE, REPLACE_IF, REMOVE, REMOVE_IF } }