blob: 389322e841da006825baddcd6f923079a31b0121 [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;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.cache.CacheWriteSynchronizationMode;
import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
import org.apache.ignite.configuration.CacheConfiguration;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import static org.apache.ignite.testframework.GridTestUtils.waitForCondition;
/**
* Data types coverage for basic cache operations.
*/
@RunWith(Parameterized.class)
@SuppressWarnings("ZeroLengthArrayAllocation")
public class GridCacheDataTypesCoverageTest extends AbstractDataTypesCoverageTest {
/** @inheritDoc */
@Before
@Override public void init() throws Exception {
super.init();
}
/**
* @throws Exception If failed.
*/
@Test
public void testByteDataType() throws Exception {
checkBasicCacheOperations(
Byte.MIN_VALUE,
Byte.MAX_VALUE,
(byte)0,
(byte)1);
}
/**
* @throws Exception If failed.
*/
@Test
public void testShortDataType() throws Exception {
checkBasicCacheOperations(
Short.MIN_VALUE,
Short.MAX_VALUE,
(short)0,
(short)1);
}
/**
* @throws Exception If failed.
*/
@Test
public void testIntegerDataType() throws Exception {
checkBasicCacheOperations(
Integer.MIN_VALUE,
Integer.MAX_VALUE,
0,
1);
}
/**
* @throws Exception If failed.
*/
@Test
public void testLongDataType() throws Exception {
checkBasicCacheOperations(
Long.MIN_VALUE,
Long.MAX_VALUE,
0L,
1L);
}
/**
* @throws Exception If failed.
*/
@Test
public void testFloatDataType() throws Exception {
checkBasicCacheOperations(
Float.MIN_VALUE,
Float.MAX_VALUE,
Float.NaN,
Float.NEGATIVE_INFINITY,
Float.POSITIVE_INFINITY,
0F,
0.0F,
1F,
1.1F);
}
/**
* @throws Exception If failed.
*/
@Test
public void testDoubleDataType() throws Exception {
checkBasicCacheOperations(
Double.MIN_VALUE,
Double.MAX_VALUE,
Double.NaN,
Double.NEGATIVE_INFINITY,
Double.POSITIVE_INFINITY,
0D,
0.0D,
1D,
1.1D);
}
/**
* @throws Exception If failed.
*/
@Test
public void testBooleanDataType() throws Exception {
checkBasicCacheOperations(
Boolean.TRUE,
Boolean.FALSE);
}
/**
* @throws Exception If failed.
*/
@Test
public void testCharacterDataType() throws Exception {
checkBasicCacheOperations(
'a',
'A');
}
/**
* @throws Exception If failed.
*/
@Test
public void testStringDataType() throws Exception {
checkBasicCacheOperations(
"aAbB",
"");
}
/**
* @throws Exception If failed.
*/
@Ignore("https://issues.apache.org/jira/browse/IGNITE-12314")
@Test
public void testByteArrayDataType() throws Exception {
checkBasicCacheOperations(
new Byte[] {},
new Byte[] {1, 2, 3},
new byte[] {3, 2, 1});
}
/**
* @throws Exception If failed.
*/
@Test
public void testObjectArrayDataType() throws Exception {
checkBasicCacheOperations(
new Object[] {},
new Object[] {"String", Boolean.TRUE, 'A', 1},
new Object[] {
"String",
new ObjectBasedOnPrimitives(123, 123.123, true)});
}
/**
* @throws Exception If failed.
*/
@Test
public void testListDataType() throws Exception {
checkBasicCacheOperations(
new ArrayList<>(),
(Serializable)Collections.singletonList("Aaa"),
(Serializable)Arrays.asList("String", Boolean.TRUE, 'A', 1));
}
/**
* @throws Exception If failed.
*/
@Test
public void testSetDataType() throws Exception {
checkBasicCacheOperations(
new HashSet<>(),
(Serializable)Collections.singleton("Aaa"),
new HashSet<>(Arrays.asList("String", Boolean.TRUE, 'A', 1)));
}
/**
* @throws Exception If failed.
*/
@Ignore("https://issues.apache.org/jira/browse/IGNITE-12315")
@Test
public void testQueueDataType() throws Exception {
ArrayBlockingQueue<Integer> queueToCheck = new ArrayBlockingQueue<>(5);
queueToCheck.addAll(Arrays.asList(1, 2, 3));
checkBasicCacheOperations(
new LinkedList<>(),
new LinkedList<>(Arrays.asList("Aaa", "Bbb")),
queueToCheck);
}
/**
* @throws Exception If failed.
*/
@Test
public void testObjectBasedOnPrimitivesDataType() throws Exception {
checkBasicCacheOperations(
new ObjectBasedOnPrimitives(0, 0.0, false),
new ObjectBasedOnPrimitives(123, 123.123, true));
}
/**
* @throws Exception If failed.
*/
@Test
public void testObjectBasedOnPrimitivesAndCollectionsDataType() throws Exception {
checkBasicCacheOperations(
new ObjectBasedOnPrimitivesAndCollections(0,
Collections.emptyList(),
new boolean[] {}),
new ObjectBasedOnPrimitivesAndCollections(123,
Arrays.asList(1.0, 0.0),
new boolean[] {true, false}));
}
/**
* @throws Exception If failed.
*/
@Test
public void testObjectBasedOnPrimitivesAndCollectionsAndNestedObjectsDataType() throws Exception {
checkBasicCacheOperations(
new ObjectBasedOnPrimitivesCollectionsAndNestedObject(0,
Collections.emptyList(),
new ObjectBasedOnPrimitivesAndCollections(
0,
Collections.emptyList(),
new boolean[] {})),
new ObjectBasedOnPrimitivesCollectionsAndNestedObject(-1,
Collections.singletonList(0.0),
new ObjectBasedOnPrimitivesAndCollections(
Integer.MAX_VALUE,
new ArrayList<>(Collections.singleton(22.2)),
new boolean[] {true, false, true})));
}
/**
* @throws Exception If failed.
*/
@Test
public void testDateDataType() throws Exception {
checkBasicCacheOperations(
new Date(),
new Date(Long.MIN_VALUE),
new Date(Long.MAX_VALUE));
}
/**
* @throws Exception If failed.
*/
@Test
public void testSqlDateDataType() throws Exception {
checkBasicCacheOperations(
new java.sql.Date(Long.MIN_VALUE),
new java.sql.Date(Long.MAX_VALUE));
}
/**
* @throws Exception If failed.
*/
@Test
public void testCalendarDataType() throws Exception {
checkBasicCacheOperations(new GregorianCalendar());
}
/**
* @throws Exception If failed.
*/
@Test
public void testInstantDataType() throws Exception {
checkBasicCacheOperations(
Instant.now(),
Instant.ofEpochMilli(Long.MIN_VALUE),
Instant.ofEpochMilli(Long.MAX_VALUE));
}
/**
* @throws Exception If failed.
*/
@Test
public void testLocalDateDataType() throws Exception {
checkBasicCacheOperations(
LocalDate.of(2015, 2, 20),
LocalDate.now().plusDays(1));
}
/**
* @throws Exception If failed.
*/
@Test
public void testLocalDateTimeDataType() throws Exception {
checkBasicCacheOperations(
LocalDateTime.of(2015, 2, 20, 9, 4, 30),
LocalDateTime.now().plusDays(1));
}
/**
* @throws Exception If failed.
*/
@Test
public void testLocalTimeDataType() throws Exception {
checkBasicCacheOperations(
LocalTime.of(9, 4, 40),
LocalTime.now());
}
/**
* @throws Exception If failed.
*/
@Test
public void testBigIntegerDataType() throws Exception {
checkBasicCacheOperations(
new BigInteger("1"),
BigInteger.ONE,
BigInteger.ZERO,
new BigInteger("123456789"));
}
/**
* @throws Exception If failed.
*/
@Test
public void testBigDecimalDataType() throws Exception {
checkBasicCacheOperations(
new BigDecimal(123.123),
BigDecimal.ONE,
BigDecimal.ZERO,
BigDecimal.valueOf(123456789, 0),
BigDecimal.valueOf(123456789, 1),
BigDecimal.valueOf(123456789, 2),
BigDecimal.valueOf(123456789, 3));
}
/**
* Verification that following cache methods works correctly:
*
* <ul>
* <li>put</li>
* <li>putAll</li>
* <li>remove</li>
* <li>removeAll</li>
* <li>get</li>
* <li>getAll</li>
* </ul>
*
* @param valsToCheck Array of values to check.
*/
@SuppressWarnings("unchecked")
protected void checkBasicCacheOperations(Serializable... valsToCheck) throws Exception {
assert valsToCheck.length > 0;
// In case of BigDecimal, cache internally changes bitLength of BigDecimal's intValue,
// so that EqualsBuilder.reflectionEquals returns false.
// As a result in case of BigDecimal data type Objects.equals is used.
// Same is about BigInteger.
BiFunction<Object, Object, Boolean> equalsProcessor =
valsToCheck[0] instanceof BigDecimal || valsToCheck[0] instanceof BigInteger ?
Objects::equals :
(lhs, rhs) -> EqualsBuilder.reflectionEquals(
lhs, rhs, false, lhs.getClass(), true);
String cacheName = "cache" + UUID.randomUUID();
IgniteCache<Object, Object> cache = grid(new Random().nextInt(NODES_CNT)).createCache(
new CacheConfiguration<>()
.setName(cacheName)
.setAtomicityMode(atomicityMode)
.setCacheMode(cacheMode)
.setExpiryPolicyFactory(ttlFactory)
.setBackups(backups)
.setEvictionPolicyFactory(evictionFactory)
.setOnheapCacheEnabled(evictionFactory != null || onheapCacheEnabled)
.setWriteSynchronizationMode(writeSyncMode)
.setAffinity(new RendezvousAffinityFunction(false, PARTITIONS_CNT)));
Map<Serializable, Serializable> keyValMap = new HashMap<>();
for (int i = 0; i < valsToCheck.length; i++)
keyValMap.put(valsToCheck[i], valsToCheck[valsToCheck.length - i - 1]);
for (Map.Entry<Serializable, Serializable> keyValEntry : keyValMap.entrySet()) {
// Put.
cache.put(keyValEntry.getKey(), keyValEntry.getValue());
Serializable clonedKey = SerializationUtils.clone(keyValEntry.getKey());
if (writeSyncMode == CacheWriteSynchronizationMode.FULL_ASYNC &&
!waitForCondition(() -> cache.get(clonedKey) != null, TIMEOUT_FOR_KEY_RETRIEVAL_IN_FULL_ASYNC_MODE))
fail("Unable to retrieve value for key = [" + clonedKey + "].");
// Check Put/Get.
assertTrue(equalsProcessor.apply(keyValEntry.getValue(), cache.get(clonedKey)));
// Remove.
cache.remove(clonedKey);
if (writeSyncMode == CacheWriteSynchronizationMode.FULL_ASYNC &&
!waitForCondition(() -> cache.get(clonedKey) == null, TIMEOUT_FOR_KEY_RETRIEVAL_IN_FULL_ASYNC_MODE))
fail("Unable to retrieve null value for key = [" + clonedKey + "] after entry removal.");
// Check remove.
assertNull(cache.get(clonedKey));
}
// PutAll
cache.putAll(keyValMap);
// Check putAll.
for (Map.Entry<Serializable, Serializable> keyValEntry : keyValMap.entrySet()) {
Serializable clonedKey = SerializationUtils.clone(keyValEntry.getKey());
if (writeSyncMode == CacheWriteSynchronizationMode.FULL_ASYNC &&
!waitForCondition(() -> cache.get(clonedKey) != null, TIMEOUT_FOR_KEY_RETRIEVAL_IN_FULL_ASYNC_MODE))
fail("Unable to retrieve value for key = [" + clonedKey + "].");
assertTrue(equalsProcessor.apply(keyValEntry.getValue(), cache.get(clonedKey)));
}
Set<Serializable> clonedKeySet =
keyValMap.keySet().stream().map(SerializationUtils::clone).collect(Collectors.toSet());
if (writeSyncMode == CacheWriteSynchronizationMode.FULL_ASYNC &&
!waitForCondition(() -> cache.getAll(clonedKeySet) != null, TIMEOUT_FOR_KEY_RETRIEVAL_IN_FULL_ASYNC_MODE))
fail("Unable to retrieve values value for keySet = [" + clonedKeySet + "].");
// Check get all.
Map<Object, Object> mapToCheck = cache.getAll(clonedKeySet);
assertEquals(keyValMap.size(), mapToCheck.size());
for (Map.Entry<Serializable, Serializable> keyValEntry : keyValMap.entrySet()) {
boolean keyFound = false;
for (Map.Entry<Object, Object> keyValEntryToCheck : mapToCheck.entrySet()) {
if (equalsProcessor.apply(keyValEntry.getKey(), keyValEntryToCheck.getKey())) {
keyFound = true;
assertTrue(equalsProcessor.apply(keyValEntry.getValue(), keyValEntryToCheck.getValue()));
break;
}
}
assertTrue(keyFound);
}
// Remove all.
cache.removeAll(clonedKeySet);
// Check remove all.
for (Serializable clonedKey : clonedKeySet) {
if (writeSyncMode == CacheWriteSynchronizationMode.FULL_ASYNC &&
!waitForCondition(() -> cache.get(clonedKey) == null, TIMEOUT_FOR_KEY_RETRIEVAL_IN_FULL_ASYNC_MODE))
fail("Unable to retrieve null value for key = [" + clonedKey + "] after entry removal.");
assertNull(cache.get(clonedKey));
}
}
}