blob: f62a763c6151a138c66ec5109667ed297545f7f2 [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;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.cache.expiry.AccessedExpiryPolicy;
import javax.cache.expiry.Duration;
import javax.cache.expiry.EternalExpiryPolicy;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.DataRegionConfiguration;
import org.apache.ignite.configuration.DataStorageConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.testframework.ListeningTestLogger;
import org.apache.ignite.testframework.LogListener;
import org.apache.ignite.testframework.junits.GridAbstractTest;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.junit.After;
import org.junit.Test;
import static org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.PARTITION_STATE_FAILED_MSG;
/**
* Checks diagnostic messages at PME.
*/
public class DiagnosticLogForPartitionStatesTest extends GridCommonAbstractTest {
/** Cache 1. */
private static final String CACHE_1 = "cache-1";
/** Any message. */
private static final String ANY_MSG = "";
/** Test logger. */
private final ListeningTestLogger log = new ListeningTestLogger(GridAbstractTest.log);
/** {@inheritDoc} */
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
return super.getConfiguration(igniteInstanceName)
.setGridLogger(log)
.setConsistentId(igniteInstanceName)
.setDataStorageConfiguration(new DataStorageConfiguration()
.setDefaultDataRegionConfiguration(new DataRegionConfiguration()
.setPersistenceEnabled(true)
.setMaxSize(200L * 1024 * 1024)));
}
/**
* @throws Exception if stopAllGrid fails.
*/
@After
public void tearDown() throws Exception {
stopAllGrids();
cleanPersistenceDir();
}
/**
* Tests that partitions validation is triggered and the corresponding message is logged.
*
* @throws Exception If failed.
*/
@Test
public void shouldPrintMessageIfPartitionHasOtherCounter() throws Exception {
doTest(new CacheConfiguration<Integer, Integer>(CACHE_1).setBackups(1), true);
}
/**
* Tests that partitions validation is not triggered when custom expiry policy is explicitly used.
*
* @throws Exception If failed.
*/
@Test
public void shouldNotPrintMessageIfPartitionHasOtherCounterButHasCustomExpiryPolicy() throws Exception {
doTest(
new CacheConfiguration<Integer, Integer>(CACHE_1)
.setBackups(1)
.setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(new Duration(TimeUnit.SECONDS, 1))),
false
);
}
/**
* Tests that partitions validation is triggered and the corresponding message is logged
* when eternal policy is explicitly used.
*
* @throws Exception If failed.
*/
@Test
public void testShouldPrintMessageWhenEternalExpiryPolicyIsExplicitlyUsed() throws Exception {
doTest(
new CacheConfiguration<Integer, Integer>(CACHE_1)
.setBackups(1)
.setExpiryPolicyFactory(EternalExpiryPolicy.factoryOf()),
true
);
}
/**
* Tests that partitions validation is not triggered when a cache in the cache group (at least one of them)
* uses custom expiry policy.
*/
@Test
public void testShouldNotPrintMessageIfPartitionHasOtherCounterButHasCustomExpiryPolicyCacheGroup() throws Exception {
String grpName = "test-group";
CacheConfiguration<Integer, Integer> cfg1 = new CacheConfiguration<Integer, Integer>("cache-1")
.setBackups(1)
.setGroupName(grpName);
CacheConfiguration<Integer, Integer> cfg2 = new CacheConfiguration<Integer, Integer>("cache-2")
.setBackups(1)
.setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(new Duration(TimeUnit.SECONDS, 1)))
.setGroupName(grpName);
doTest(Arrays.asList(cfg1, cfg2), false);
}
/**
* @param cacheCfg Cache configuration.
* @param msgExp {@code true} if warning message is expected.
* @throws Exception If failed.
*/
private void doTest(CacheConfiguration<Integer, Integer> cacheCfg, boolean msgExp) throws Exception {
doTest(Collections.singletonList(cacheCfg), msgExp);
}
/**
* @param cfgs Cache configurations.
* @param msgExp {@code true} if warning message is expected.
* @throws Exception If failed.
*/
private void doTest(List<CacheConfiguration<Integer, Integer>> cfgs, boolean msgExp) throws Exception {
String name = (cfgs.size() == 1) ? cfgs.get(0).getName() : cfgs.get(0).getGroupName();
LogListener lsnr = LogListener
.matches(s -> s.startsWith(String.format(PARTITION_STATE_FAILED_MSG, name, ANY_MSG)))
.times(msgExp ? 1 : 0)
.build();
log.registerListener(lsnr);
IgniteEx node1 = startGrid(0);
IgniteEx node2 = startGrid(1);
node1.cluster().active(true);
List<IgniteCache<Integer, Integer>> caches = cfgs.stream()
.map(cfg -> node1.getOrCreateCache(cfg)).collect(Collectors.toList());
Map<String, Set<Integer>> clearKeys = new HashMap<>();
for (IgniteCache<Integer, Integer> cache : caches) {
String cacheName = cache.getName();
Set<Integer> clr = new HashSet<>();
for (int i = 0; i < 100; i++) {
cache.put(i, i);
if (node2.affinity(cacheName).isPrimary(node2.localNode(), i))
clr.add(i);
}
clearKeys.put(cacheName, clr);
}
for (IgniteCache<Integer, Integer> c : caches) {
node2.context().cache().cache(c.getName())
.clearLocallyAll(clearKeys.get(c.getName()), true, true, true);
}
// Trigger partition map exchange and therefore trigger partitions validation.
startGrid(2);
awaitPartitionMapExchange();
assertTrue(lsnr.check());
}
}