/* * 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.query.impl; import com.hazelcast.internal.serialization.InternalSerializationService; import com.hazelcast.internal.serialization.impl.DefaultSerializationServiceBuilder; import com.hazelcast.nio.ObjectDataInput; import com.hazelcast.nio.ObjectDataOutput; import com.hazelcast.nio.serialization.Data; import com.hazelcast.nio.serialization.DataSerializable; import com.hazelcast.nio.serialization.Portable; import com.hazelcast.query.QueryConstants; import com.hazelcast.query.SampleObjects; import com.hazelcast.query.impl.getters.Extractors; import com.hazelcast.test.HazelcastParallelClassRunner; import com.hazelcast.test.HazelcastTestSupport; import com.hazelcast.test.annotation.ParallelTest; import com.hazelcast.test.annotation.QuickTest; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import java.io.IOException; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsNot.not; import static org.hamcrest.core.IsSame.sameInstance; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; @RunWith(HazelcastParallelClassRunner.class) @Category({QuickTest.class, ParallelTest.class}) public class QueryEntryTest extends HazelcastTestSupport { protected InternalSerializationService serializationService; @Before public void before() { serializationService = new DefaultSerializationServiceBuilder().build(); } @After public void after() { serializationService.dispose(); } // ========================== getAttribute =========================================== @Test public void getAttribute_whenValueIsPortableObject_thenConvertedToData() { Data key = serializationService.toData("indexedKey"); Portable value = new SampleObjects.PortableEmployee(30, "peter"); QueryableEntry queryEntry = entry(key, value, Extractors.empty()); // in the portable-data, the attribute 'name' is called 'n'. So if we can retrieve on n // correctly it shows that we have used the Portable data, not the actual Portable object Object result = queryEntry.getAttributeValue("n"); assertEquals("peter", result); } @Test public void getAttribute_whenKeyIsPortableObject_thenConvertedToData() { Data key = serializationService.toData(new SampleObjects.PortableEmployee(30, "peter")); SerializableObject value = new SerializableObject(); QueryableEntry queryEntry = entry(key, value, Extractors.empty()); // in the portable-data, the attribute 'name' is called 'n'. So if we can retrieve on n // correctly it shows that we have used the Portable data, not the actual Portable object Object result = queryEntry.getAttributeValue(QueryConstants.KEY_ATTRIBUTE_NAME.value() + ".n"); assertEquals("peter", result); } @Test public void getAttribute_whenKeyPortableObjectThenConvertedToData() { Data key = serializationService.toData(new SampleObjects.PortableEmployee(30, "peter")); SerializableObject value = new SerializableObject(); QueryableEntry queryEntry = entry(key, value, Extractors.empty()); Object result = queryEntry.getAttributeValue(QueryConstants.KEY_ATTRIBUTE_NAME.value() + ".n"); assertEquals("peter", result); } @Test public void getAttribute_whenValueInObjectFormatThenNoSerialization() { Data key = serializationService.toData(new SerializableObject()); SerializableObject value = new SerializableObject(); value.name = "somename"; QueryableEntry queryEntry = entry(key, value, Extractors.empty()); Object result = queryEntry.getAttributeValue("name"); assertEquals("somename", result); assertEquals(0, value.deserializationCount); assertEquals(0, value.serializationCount); } @Test(expected = IllegalArgumentException.class) public void testInit_whenKeyIsNull_thenThrowIllegalArgumentException() { Data key = null; entry(key, new SerializableObject(), Extractors.empty()); } @Test public void test_init() throws Exception { Data dataKey = serializationService.toData("dataKey"); Data dataValue = serializationService.toData("dataValue"); QueryableEntry queryEntry = entry(dataKey, dataValue, Extractors.empty()); Object objectValue = queryEntry.getValue(); Object objectKey = queryEntry.getKey(); init(queryEntry, serializationService, serializationService.toData(objectKey), objectValue, Extractors.empty()); // compare references of objects since they should be cloned after QueryEntry#init call. assertTrue("Old dataKey should not be here", dataKey != queryEntry.getKeyData()); assertTrue("Old dataValue should not be here", dataValue != queryEntry.getValueData()); } @Test(expected = IllegalArgumentException.class) public void test_init_nullKey() throws Exception { entry(null, "value", Extractors.empty()); } @Test(expected = UnsupportedOperationException.class) public void test_setValue() throws Exception { QueryableEntry queryEntry = entry(mock(Data.class), "value", Extractors.empty()); queryEntry.setValue("anyValue"); } @Test(expected = NullPointerException.class) public void test_equality_empty() throws Exception { QueryableEntry entryKeyLeft = entry(); QueryableEntry entryKeyRight = entry(); entryKeyLeft.equals(entryKeyRight); } @Test public void test_equality_same() throws Exception { QueryableEntry entry = entry(); assertTrue(entry.equals(entry)); } @Test public void test_equality_differentType() throws Exception { QueryableEntry entry = entry(); assertFalse(entry.equals("string")); } @Test public void test_equality_null() throws Exception { QueryableEntry entry = entry(); assertFalse(entry.equals(null)); } @Test public void test_equality_differentKey() throws Exception { QueryableEntry queryEntry = entry("dataKey", "dataValue"); QueryableEntry queryEntryOther = entry("dataKeyOther", "dataValue"); assertFalse(queryEntry.equals(queryEntryOther)); } @Test public void test_equality_sameKey() throws Exception { QueryableEntry queryEntry = entry("dataKey", "dataValue"); QueryableEntry queryEntryOther = entry("dataKey", "dataValueOther"); assertTrue(queryEntry.equals(queryEntryOther)); } @Test public void getKey_caching() { QueryableEntry entry = entry("key", "value"); assertThat(entry.getKey(), not(sameInstance(entry.getKey()))); } @Test public void getValue_caching() { QueryableEntry entry = entry("key", "value"); assertThat(entry.getValue(), not(sameInstance(entry.getValue()))); } @Test public void getKeyData_caching() { QueryableEntry entry = entry("key", "value"); assertThat(entry.getKeyData(), sameInstance(entry.getKeyData())); } @Test public void getValueData_caching() { QueryableEntry entry = entry("key", "value"); assertThat(entry.getValueData(), sameInstance(entry.getValueData())); } @SuppressWarnings("unused") private static class SerializableObject implements DataSerializable { private int serializationCount; private int deserializationCount; private String name; @Override public void writeData(ObjectDataOutput out) throws IOException { serializationCount++; } @Override public void readData(ObjectDataInput in) throws IOException { deserializationCount++; } } protected QueryableEntry entry(String key, String value) { return entry(serializationService.toData(key), serializationService.toData(value), Extractors.empty()); } protected QueryableEntry entry(Data key, Object value, Extractors extractors) { return new QueryEntry(serializationService, key, value, extractors); } protected QueryableEntry entry() { return new QueryEntry(); } protected void init(Object entry, InternalSerializationService serializationService, Data key, Object value, Extractors extractors) { ((QueryEntry) entry).init(serializationService, key, value, extractors); } }