/*
* 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.event;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.EntryEventType;
import com.hazelcast.internal.serialization.impl.HeapData;
import com.hazelcast.map.impl.EventListenerFilter;
import com.hazelcast.map.impl.ListenerAdapter;
import com.hazelcast.map.impl.MapServiceContext;
import com.hazelcast.map.listener.EntryAddedListener;
import com.hazelcast.nio.Address;
import com.hazelcast.spi.NodeEngine;
import com.hazelcast.spi.impl.eventservice.impl.TrueEventFilter;
import com.hazelcast.test.HazelcastParametersRunnerFactory;
import com.hazelcast.test.annotation.ParallelTest;
import com.hazelcast.test.annotation.QuickTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Collection;
import static com.hazelcast.core.EntryEventType.INVALIDATION;
import static com.hazelcast.map.impl.ListenerAdapters.createListenerAdapter;
import static com.hazelcast.map.impl.MapListenerFlagOperator.setAndGetListenerFlags;
import static com.hazelcast.map.impl.event.FilteringStrategy.FILTER_DOES_NOT_MATCH;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Test EntryEventDataCache implementations
*/
@RunWith(Parameterized.class)
@Parameterized.UseParametersRunnerFactory(HazelcastParametersRunnerFactory.class)
@Category({QuickTest.class, ParallelTest.class})
public class EntryEventDataCacheTest {
private EntryEventDataCache instance;
private static final Address ADDRESS;
static {
Address address = null;
try {
address = new Address("127.0.0.1", 5701);
} catch (UnknownHostException e) {
}
ADDRESS = address;
}
@Parameterized.Parameter
public FilteringStrategy filteringStrategy;
@Parameterized.Parameters(name = "{0}")
public static Collection<Object[]> parameters() {
// setup mock MapServiceContext & NodeEngine, required by FilteringStrategy's
MapServiceContext mapServiceContext = mock(MapServiceContext.class);
NodeEngine mockNodeEngine = mock(NodeEngine.class);
when(mockNodeEngine.getThisAddress()).thenReturn(ADDRESS);
when(mapServiceContext.toData(anyObject())).thenReturn(new HeapData());
when(mapServiceContext.getNodeEngine()).thenReturn(mockNodeEngine);
return Arrays.asList(new Object[][]{
{new DefaultEntryEventFilteringStrategy(null, mapServiceContext)},
{new QueryCacheNaturalFilteringStrategy(null, mapServiceContext)},
});
}
@Before
public void setup() {
instance = filteringStrategy.getEntryEventDataCache();
}
@Test
public void getOrCreateEventDataIncludingValues_whenAlreadyCached() throws Exception {
// when: creating EntryEventData including values with same arguments
EntryEventData eed = instance.getOrCreateEventData("test", ADDRESS, new HeapData(), new Object(),
new Object(), new Object(), EntryEventType.ADDED.getType(), true);
EntryEventData shouldBeCached = instance.getOrCreateEventData("test", ADDRESS, new HeapData(), new Object(),
new Object(), new Object(), EntryEventType.ADDED.getType(), true);
// then: returned instances are the same
assertSame(eed, shouldBeCached);
}
@Test
public void getOrCreateEventDataExcludingValues_whenAlreadyCached() throws Exception {
// when: creating EntryEventData including values with same arguments
EntryEventData eed = instance.getOrCreateEventData("test", ADDRESS, new HeapData(), new Object(),
new Object(), new Object(), EntryEventType.ADDED.getType(), false);
EntryEventData shouldBeCached = instance.getOrCreateEventData("test", ADDRESS, new HeapData(), new Object(),
new Object(), new Object(), EntryEventType.ADDED.getType(), false);
// then: returned instances are the same
assertSame(eed, shouldBeCached);
}
@Test
public void isEmpty_whenNoEntryEventDataHaveBeenCreated() throws Exception {
// when: no EntryEventData have been getOrCreate'd
// then: the cache is empty
assertTrue(instance.isEmpty());
}
@Test
public void isEmpty_whenEntryEventDataHaveBeenCreated() throws Exception {
// when: EntryEventData have been getOrCreate'd
instance.getOrCreateEventData("test", ADDRESS, new HeapData(), new Object(),
new Object(), new Object(), EntryEventType.ADDED.getType(), false);
// then: the cache is not empty
assertFalse(instance.isEmpty());
}
@Test
public void eventDataIncludingValues_whenValueIsCached() throws Exception {
// when: EntryEventData including values have been created
EntryEventData eed = instance.getOrCreateEventData("test", ADDRESS, new HeapData(), new Object(),
new Object(), new Object(), EntryEventType.ADDED.getType(), true);
// then: the cache is not empty & eventDataIncludingValues returns the cached entry
assertFalse(instance.isEmpty());
assertSame(eed, instance.eventDataIncludingValues().iterator().next());
}
@Test
public void eventDataIncludingValues_whenNoValuesCached() throws Exception {
// when: EntryEventData including values have been created
// then: the cache is empty & eventDataIncludingValues returns null or empty collection
assertTrue(instance.isEmpty());
assertTrue(instance.eventDataIncludingValues() == null || instance.eventDataIncludingValues().isEmpty());
}
@Test
public void eventDataIncludingValues_whenDataExcludingValuesAreCached() throws Exception {
// when: EntryEventData excluding values have been created
EntryEventData eed = instance.getOrCreateEventData("test", ADDRESS, new HeapData(), new Object(),
new Object(), new Object(), EntryEventType.ADDED.getType(), false);
// then: eventDataIncludingValues returns null or empty collection
assertTrue(instance.eventDataIncludingValues() == null || instance.eventDataIncludingValues().isEmpty());
}
@Test
public void eventDataExcludingValues_whenValueIsCached() throws Exception {
// when: EntryEventData excluding values have been created
EntryEventData eed = instance.getOrCreateEventData("test", ADDRESS, new HeapData(), new Object(),
new Object(), new Object(), EntryEventType.ADDED.getType(), false);
// then: the cache is not empty & eventDataExcludingValues returns the cached entry
assertFalse(instance.isEmpty());
assertSame(eed, instance.eventDataExcludingValues().iterator().next());
}
@Test
public void eventDataExcludingValues_whenNoValuesCached() throws Exception {
// when: no EntryEventData values have been created
// then: the cache is empty & eventDataIncludingValues returns null or empty collection
assertTrue(instance.isEmpty());
assertTrue(instance.eventDataIncludingValues() == null || instance.eventDataIncludingValues().isEmpty());
}
@Test
public void eventDataExcludingValues_whenDataIncludingValuesAreCached() throws Exception {
// when: no EntryEventData values have been created
EntryEventData eed = instance.getOrCreateEventData("test", ADDRESS, new HeapData(), new Object(),
new Object(), new Object(), EntryEventType.ADDED.getType(), true);
// then: the cache is empty & eventDataIncludingValues returns null or empty collection
assertTrue(instance.eventDataExcludingValues() == null || instance.eventDataExcludingValues().isEmpty());
}
@Test
public void filteringStrategy_rejects_invalidation_events() throws Exception {
EventListenerFilter filter = createInvalidationEventRejectingFilter();
int matched = filteringStrategy.doFilter(filter, null, null, null, INVALIDATION, "mapName");
assertEquals(FILTER_DOES_NOT_MATCH, matched);
}
private static EventListenerFilter createInvalidationEventRejectingFilter() {
ListenerAdapter listenerAdapter = createListenerAdapter(new EntryAddedListener() {
@Override
public void entryAdded(EntryEvent event) {
}
});
int flags = setAndGetListenerFlags(listenerAdapter);
return new EventListenerFilter(flags, TrueEventFilter.INSTANCE);
}
}