blob: 77f13e4597dd87b9849a3850e40c4d6ad753f711 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.ignite.internal.processors.cache.datastructures;
import java.util.Random;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteAtomicLong;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteException;
import org.apache.ignite.configuration.AtomicConfiguration;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.transactions.Transaction;
import org.junit.Test;
import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
/**
* Cache atomic long api test.
*/
public abstract class IgniteAtomicLongApiAbstractSelfTest extends IgniteAtomicsAbstractTest {
/** Random number generator. */
private static final Random RND = new Random();
/** */
private static final String TRANSACTIONAL_CACHE_NAME = "tx_cache";
/** {@inheritDoc} */
@Override protected int gridCount() {
return 1;
}
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
CacheConfiguration ccfg = new CacheConfiguration(DEFAULT_CACHE_NAME);
ccfg.setName(TRANSACTIONAL_CACHE_NAME);
ccfg.setAtomicityMode(TRANSACTIONAL);
cfg.setCacheConfiguration(ccfg);
return cfg;
}
/**
* @throws Exception If failed.
*/
@Test
public void testCreateRemove() throws Exception {
info("Running test [name=" + getName() + ", cacheMode=" + atomicsCacheMode() + ']');
Ignite ignite = grid(0);
String atomicName1 = "FIRST";
String atomicName2 = "SECOND";
IgniteAtomicLong atomic1 = ignite.atomicLong(atomicName1, 0, true);
IgniteAtomicLong atomic2 = ignite.atomicLong(atomicName2, 0, true);
IgniteAtomicLong atomic3 = ignite.atomicLong(atomicName1, 0, true);
assertNotNull(atomic1);
assertNotNull(atomic2);
assertNotNull(atomic3);
assert atomic1.equals(atomic3);
assert atomic3.equals(atomic1);
assert !atomic3.equals(atomic2);
atomic1.close();
atomic2.close();
atomic3.close();
assertNull(ignite.atomicLong(atomicName1, 0, false));
assertNull(ignite.atomicLong(atomicName2, 0, false));
try {
atomic1.get();
fail();
}
catch (IllegalStateException | IgniteException e) {
info("Caught expected exception: " + e.getMessage());
}
}
/**
* @throws Exception If failed.
*/
@Test
public void testIncrementAndGet() throws Exception {
info("Running test [name=" + getName() + ", cacheMode=" + atomicsCacheMode() + ']');
Ignite ignite = grid(0);
IgniteAtomicLong atomic = ignite.atomicLong("atomic", 0, true);
long curAtomicVal = atomic.get();
assert curAtomicVal + 1 == atomic.incrementAndGet();
assert curAtomicVal + 1 == atomic.get();
}
/**
* @throws Exception If failed.
*/
@Test
public void testGetAndIncrement() throws Exception {
info("Running test [name=" + getName() + ", cacheMode=" + atomicsCacheMode() + ']');
Ignite ignite = grid(0);
IgniteAtomicLong atomic = ignite.atomicLong("atomic", 0, true);
long curAtomicVal = atomic.get();
assert curAtomicVal == atomic.getAndIncrement();
assert curAtomicVal + 1 == atomic.get();
}
/**
* @throws Exception If failed.
*/
@Test
public void testDecrementAndGet() throws Exception {
info("Running test [name=" + getName() + ", cacheMode=" + atomicsCacheMode() + ']');
Ignite ignite = grid(0);
IgniteAtomicLong atomic = ignite.atomicLong("atomic", 0, true);
long curAtomicVal = atomic.get();
assert curAtomicVal - 1 == atomic.decrementAndGet();
assert curAtomicVal - 1 == atomic.get();
}
/**
* @throws Exception If failed.
*/
@Test
public void testGetAndDecrement() throws Exception {
info("Running test [name=" + getName() + ", cacheMode=" + atomicsCacheMode() + ']');
Ignite ignite = grid(0);
IgniteAtomicLong atomic = ignite.atomicLong("atomic", 0, true);
long curAtomicVal = atomic.get();
assert curAtomicVal == atomic.getAndDecrement();
assert curAtomicVal - 1 == atomic.get();
}
/**
* @throws Exception If failed.
*/
@Test
public void testGetAndAdd() throws Exception {
info("Running test [name=" + getName() + ", cacheMode=" + atomicsCacheMode() + ']');
Ignite ignite = grid(0);
IgniteAtomicLong atomic = ignite.atomicLong("atomic", 0, true);
long delta = RND.nextLong();
long curAtomicVal = atomic.get();
assert curAtomicVal == atomic.getAndAdd(delta);
assert curAtomicVal + delta == atomic.get();
}
/**
* @throws Exception If failed.
*/
@Test
public void testAddAndGet() throws Exception {
info("Running test [name=" + getName() + ", cacheMode=" + atomicsCacheMode() + ']');
Ignite ignite = grid(0);
IgniteAtomicLong atomic = ignite.atomicLong("atomic", 0, true);
long delta = RND.nextLong();
long curAtomicVal = atomic.get();
assert curAtomicVal + delta == atomic.addAndGet(delta);
assert curAtomicVal + delta == atomic.get();
}
/**
* @throws Exception If failed.
*/
@Test
public void testGetAndSet() throws Exception {
info("Running test [name=" + getName() + ", cacheMode=" + atomicsCacheMode() + ']');
Ignite ignite = grid(0);
IgniteAtomicLong atomic = ignite.atomicLong("atomic", 0, true);
long newVal = RND.nextLong();
long curAtomicVal = atomic.get();
assert curAtomicVal == atomic.getAndSet(newVal);
assert newVal == atomic.get();
}
/**
* @throws Exception If failed.
*/
@Test
public void testCompareAndSet() throws Exception {
info("Running test [name=" + getName() + ", cacheMode=" + atomicsCacheMode() + ']');
Ignite ignite = grid(0);
IgniteAtomicLong atomic = ignite.atomicLong("atomic", 0, true);
long newVal = RND.nextLong();
final long oldVal = atomic.get();
// Don't set new value.
assert !atomic.compareAndSet(oldVal - 1, newVal);
assert oldVal == atomic.get();
// Set new value.
assert atomic.compareAndSet(oldVal, newVal);
assert newVal == atomic.get();
}
/**
* @throws Exception If failed.
*/
@Test
public void testGetAndSetInTx() throws Exception {
info("Running test [name=" + getName() + ", cacheMode=" + atomicsCacheMode() + ']');
Ignite ignite = grid(0);
IgniteAtomicLong atomic = ignite.atomicLong("atomic", 0, true);
IgniteCache<Object, Object> cache = ignite.cache(TRANSACTIONAL_CACHE_NAME);
try (Transaction tx = ignite.transactions().txStart()) {
cache.put(1, 1);
long newVal = RND.nextLong();
long curAtomicVal = atomic.get();
assert curAtomicVal == atomic.getAndSet(newVal);
assert newVal == atomic.get();
}
}
/**
* Implementation of ignite data structures internally uses special system caches, need make sure that
* transaction on these system caches do not intersect with transactions started by user.
*
* @throws Exception If failed.
*/
@Test
public void testIsolation() throws Exception {
Ignite ignite = grid(0);
IgniteCache<Object, Object> cache = ignite.cache(TRANSACTIONAL_CACHE_NAME);
IgniteAtomicLong atomic = ignite.atomicLong("atomic", 0, true);
long curAtomicVal = atomic.get();
try (Transaction tx = ignite.transactions().txStart()) {
atomic.getAndIncrement();
cache.put(1, 1);
tx.rollback();
}
assertEquals(0, cache.size());
assertEquals(curAtomicVal + 1, atomic.get());
}
/**
* Tests that basic API works correctly when there are multiple structures in multiple groups.
*
* @throws Exception If failed.
*/
@Test
public void testMultipleStructuresInDifferentGroups() throws Exception {
Ignite ignite = grid(0);
AtomicConfiguration cfg = new AtomicConfiguration().setGroupName("grp1");
IgniteAtomicLong atomic1 = ignite.atomicLong("atomic1", 1, true);
IgniteAtomicLong atomic2 = ignite.atomicLong("atomic2", 2, true);
IgniteAtomicLong atomic3 = ignite.atomicLong("atomic3", cfg, 3, true);
IgniteAtomicLong atomic4 = ignite.atomicLong("atomic4", cfg, 4, true);
assertNull(ignite.atomicLong("atomic1", cfg, 1, false));
assertNull(ignite.atomicLong("atomic2", cfg, 2, false));
assertNull(ignite.atomicLong("atomic3", 3, false));
assertNull(ignite.atomicLong("atomic4", 4, false));
assertTrue(atomic1.compareAndSet(1, 11));
assertTrue(atomic2.compareAndSet(2, 12));
assertTrue(atomic3.compareAndSet(3, 13));
assertTrue(atomic4.compareAndSet(4, 14));
assertFalse(atomic1.compareAndSet(1, 0));
assertFalse(atomic2.compareAndSet(2, 0));
assertFalse(atomic3.compareAndSet(3, 0));
assertFalse(atomic4.compareAndSet(4, 0));
atomic2.close();
atomic4.close();
assertTrue(atomic2.removed());
assertTrue(atomic4.removed());
assertNull(ignite.atomicLong("atomic2", 2, false));
assertNull(ignite.atomicLong("atomic4", cfg, 4, false));
assertFalse(atomic1.removed());
assertFalse(atomic3.removed());
assertNotNull(ignite.atomicLong("atomic1", 1, false));
assertNotNull(ignite.atomicLong("atomic3", cfg, 3, false));
}
}