http://git-wip-us.apache.org/repos/asf/ignite/blob/878dcd92/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderAdditionalSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderAdditionalSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderAdditionalSelfTest.java new file mode 100644 index 0000000..1a41a4d --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderAdditionalSelfTest.java @@ -0,0 +1,1001 @@ +/* + * 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.portable; + +import org.apache.ignite.*; +import org.apache.ignite.configuration.*; +import org.apache.ignite.internal.portable.mutabletest.*; +import org.apache.ignite.internal.processors.cache.portable.*; +import org.apache.ignite.internal.util.lang.*; +import org.apache.ignite.marshaller.portable.*; +import org.apache.ignite.portable.*; +import org.apache.ignite.testframework.*; +import org.apache.ignite.testframework.junits.common.*; + +import com.google.common.collect.*; +import org.junit.*; + +import java.lang.reflect.*; +import java.sql.*; +import java.util.*; +import java.util.Date; + +import static org.apache.ignite.cache.CacheMode.*; +import static org.apache.ignite.internal.portable.mutabletest.GridPortableTestClasses.*; + +/** + * + */ +public class GridPortableBuilderAdditionalSelfTest extends GridCommonAbstractTest { + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(gridName); + + CacheConfiguration cacheCfg = new CacheConfiguration(); + + cacheCfg.setCacheMode(REPLICATED); + + cfg.setCacheConfiguration(cacheCfg); + + PortableMarshaller marsh = new PortableMarshaller(); + + marsh.setClassNames(Arrays.asList("org.apache.ignite.internal.portable.mutabletest.*")); + + marsh.setConvertStringToBytes(useUtf8()); + + cfg.setMarshaller(marsh); + + return cfg; + } + + /** {@inheritDoc} */ + @Override protected void beforeTestsStarted() throws Exception { + startGrids(1); + } + + /** {@inheritDoc} */ + @Override protected void afterTestsStopped() throws Exception { + stopAllGrids(); + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + jcache(0).clear(); + } + + /** + * @return Whether to use UTF8 strings. + */ + protected boolean useUtf8() { + return true; + } + + /** + * @return Portables API. + */ + protected IgnitePortables portables() { + return grid(0).portables(); + } + + /** + * @throws Exception If failed. + */ + public void testSimpleTypeFieldRead() throws Exception { + TestObjectAllTypes exp = new TestObjectAllTypes(); + + exp.setDefaultData(); + + PortableBuilder mutPo = wrap(exp); + + for (Field field : TestObjectAllTypes.class.getDeclaredFields()) { + Object expVal = field.get(exp); + Object actVal = mutPo.getField(field.getName()); + + switch (field.getName()) { + case "anEnum": + assertEquals(((PortableBuilderEnum)actVal).getOrdinal(), ((Enum)expVal).ordinal()); + break; + + case "enumArr": { + PortableBuilderEnum[] actArr = (PortableBuilderEnum[])actVal; + Enum[] expArr = (Enum[])expVal; + + assertEquals(expArr.length, actArr.length); + + for (int i = 0; i < actArr.length; i++) + assertEquals(expArr[i].ordinal(), actArr[i].getOrdinal()); + + break; + } + + case "entry": + assertEquals(((Map.Entry)expVal).getKey(), ((Map.Entry)actVal).getKey()); + assertEquals(((Map.Entry)expVal).getValue(), ((Map.Entry)actVal).getValue()); + break; + + default: + assertTrue(field.getName(), Objects.deepEquals(expVal, actVal)); + break; + } + } + } + + /** + * + */ + public void testSimpleTypeFieldSerialize() { + TestObjectAllTypes exp = new TestObjectAllTypes(); + + exp.setDefaultData(); + + PortableBuilderImpl mutPo = wrap(exp); + + TestObjectAllTypes res = mutPo.build().deserialize(); + + GridTestUtils.deepEquals(exp, res); + } + + /** + * @throws Exception If any error occurs. + */ + public void testSimpleTypeFieldOverride() throws Exception { + TestObjectAllTypes exp = new TestObjectAllTypes(); + + exp.setDefaultData(); + + PortableBuilderImpl mutPo = wrap(new TestObjectAllTypes()); + + for (Field field : TestObjectAllTypes.class.getDeclaredFields()) + mutPo.setField(field.getName(), field.get(exp)); + + TestObjectAllTypes res = mutPo.build().deserialize(); + + GridTestUtils.deepEquals(exp, res); + } + + /** + * @throws Exception If any error occurs. + */ + public void testSimpleTypeFieldSetNull() throws Exception { + TestObjectAllTypes exp = new TestObjectAllTypes(); + + exp.setDefaultData(); + + PortableBuilderImpl mutPo = wrap(exp); + + for (Field field : TestObjectAllTypes.class.getDeclaredFields()) { + if (!field.getType().isPrimitive()) + mutPo.setField(field.getName(), null); + } + + TestObjectAllTypes res = mutPo.build().deserialize(); + + for (Field field : TestObjectAllTypes.class.getDeclaredFields()) { + if (!field.getType().isPrimitive()) + assertNull(field.getName(), field.get(res)); + } + } + + /** + * @throws IgniteCheckedException If any error occurs. + */ + public void testMakeCyclicDependency() throws IgniteCheckedException { + TestObjectOuter outer = new TestObjectOuter(); + outer.inner = new TestObjectInner(); + + PortableBuilderImpl mutOuter = wrap(outer); + + PortableBuilderImpl mutInner = mutOuter.getField("inner"); + + mutInner.setField("outer", mutOuter); + mutInner.setField("foo", mutInner); + + TestObjectOuter res = mutOuter.build().deserialize(); + + assertEquals(res, res.inner.outer); + assertEquals(res.inner, res.inner.foo); + } + + /** + * + */ + public void testSimpleArrayModification() { + TestObjectAllTypes obj = new TestObjectAllTypes(); + + obj.strArr = new String[]{"a", "a", "a"}; + + PortableBuilderImpl mutObj = wrap(obj); + + String[] arr = mutObj.getField("strArr"); + arr[0] = "b"; + + TestObjectAllTypes res = mutObj.build().deserialize(); + + Assert.assertArrayEquals(obj.strArr, res.strArr); + } + + /** + * + */ + public void testModifyObjectArray() { + fail("https://issues.apache.org/jira/browse/IGNITE-1273"); + + TestObjectContainer obj = new TestObjectContainer(); + obj.foo = new Object[]{"a"}; + + PortableBuilderImpl mutObj = wrap(obj); + + Object[] arr = mutObj.getField("foo"); + + Assert.assertArrayEquals(new Object[]{"a"}, arr); + + arr[0] = "b"; + + TestObjectContainer res = mutObj.build().deserialize(); + + Assert.assertArrayEquals(new Object[] {"a"}, (Object[])res.foo); + } + + /** + * + */ + public void testOverrideObjectArrayField() { + PortableBuilderImpl mutObj = wrap(new TestObjectContainer()); + + Object[] createdArr = {mutObj, "a", 1, new String[] {"s", "s"}, new byte[]{1, 2}, new UUID(3, 0)}; + + mutObj.setField("foo", createdArr.clone()); + + TestObjectContainer res = mutObj.build().deserialize(); + + createdArr[0] = res; + + assertTrue(Objects.deepEquals(createdArr, res.foo)); + } + + /** + * + */ + public void testDeepArray() { + TestObjectContainer obj = new TestObjectContainer(); + obj.foo = new Object[]{new Object[]{"a", obj}}; + + PortableBuilderImpl mutObj = wrap(obj); + + Object[] arr = (Object[])mutObj.<Object[]>getField("foo")[0]; + + assertEquals("a", arr[0]); + assertSame(mutObj, arr[1]); + + arr[0] = mutObj; + + TestObjectContainer res = mutObj.build().deserialize(); + + arr = (Object[])((Object[])res.foo)[0]; + + assertSame(arr[0], res); + assertSame(arr[0], arr[1]); + } + + /** + * + */ + public void testArrayListRead() { + TestObjectContainer obj = new TestObjectContainer(); + obj.foo = Lists.newArrayList(obj, "a"); + + PortableBuilderImpl mutObj = wrap(obj); + + List<Object> list = mutObj.getField("foo"); + + assert list.equals(Lists.newArrayList(mutObj, "a")); + } + + /** + * + */ + public void testArrayListOverride() { + TestObjectContainer obj = new TestObjectContainer(); + + PortableBuilderImpl mutObj = wrap(obj); + + ArrayList<Object> list = Lists.newArrayList(mutObj, "a", Lists.newArrayList(1, 2)); + + mutObj.setField("foo", list); + + TestObjectContainer res = mutObj.build().deserialize(); + + list.set(0, res); + + assertNotSame(list, res.foo); + assertEquals(list, res.foo); + } + + /** + * + */ + public void testArrayListModification() { + TestObjectContainer obj = new TestObjectContainer(); + obj.foo = Lists.newArrayList("a", "b", "c"); + + PortableBuilderImpl mutObj = wrap(obj); + + List<String> list = mutObj.getField("foo"); + + list.add("!"); // "a", "b", "c", "!" + list.add(0, "_"); // "_", "a", "b", "c", "!" + + String s = list.remove(1); // "_", "b", "c", "!" + assertEquals("a", s); + + assertEquals(Arrays.asList("c", "!"), list.subList(2, 4)); + assertEquals(1, list.indexOf("b")); + assertEquals(1, list.lastIndexOf("b")); + + TestObjectContainer res = mutObj.build().deserialize(); + + assertTrue(res.foo instanceof ArrayList); + assertEquals(Arrays.asList("_", "b", "c", "!"), res.foo); + } + + /** + * + */ + public void testArrayListClear() { + TestObjectContainer obj = new TestObjectContainer(); + obj.foo = Lists.newArrayList("a", "b", "c"); + + PortableBuilderImpl mutObj = wrap(obj); + + List<String> list = mutObj.getField("foo"); + + list.clear(); + + assertEquals(Collections.emptyList(), mutObj.build().<TestObjectContainer>deserialize().foo); + } + + /** + * + */ + public void testArrayListWriteUnmodifiable() { + TestObjectContainer obj = new TestObjectContainer(); + + ArrayList<Object> src = Lists.newArrayList(obj, "a", "b", "c"); + + obj.foo = src; + + PortableBuilderImpl mutObj = wrap(obj); + + TestObjectContainer deserialized = mutObj.build().deserialize(); + + List<Object> res = (List<Object>)deserialized.foo; + + src.set(0, deserialized); + + assertEquals(src, res); + } + + /** + * + */ + public void testLinkedListRead() { + TestObjectContainer obj = new TestObjectContainer(); + obj.foo = Lists.newLinkedList(Arrays.asList(obj, "a")); + + PortableBuilderImpl mutObj = wrap(obj); + + List<Object> list = mutObj.getField("foo"); + + assert list.equals(Lists.newLinkedList(Arrays.asList(mutObj, "a"))); + } + + /** + * + */ + public void testLinkedListOverride() { + TestObjectContainer obj = new TestObjectContainer(); + + PortableBuilderImpl mutObj = wrap(obj); + + List<Object> list = Lists.newLinkedList(Arrays.asList(mutObj, "a", Lists.newLinkedList(Arrays.asList(1, 2)))); + + mutObj.setField("foo", list); + + TestObjectContainer res = mutObj.build().deserialize(); + + list.set(0, res); + + assertNotSame(list, res.foo); + assertEquals(list, res.foo); + } + + /** + * + */ + public void testLinkedListModification() { + TestObjectContainer obj = new TestObjectContainer(); + + obj.foo = Lists.newLinkedList(Arrays.asList("a", "b", "c")); + + PortableBuilderImpl mutObj = wrap(obj); + + List<String> list = mutObj.getField("foo"); + + list.add("!"); // "a", "b", "c", "!" + list.add(0, "_"); // "_", "a", "b", "c", "!" + + String s = list.remove(1); // "_", "b", "c", "!" + assertEquals("a", s); + + assertEquals(Arrays.asList("c", "!"), list.subList(2, 4)); + assertEquals(1, list.indexOf("b")); + assertEquals(1, list.lastIndexOf("b")); + + TestObjectContainer res = mutObj.build().deserialize(); + + assertTrue(res.foo instanceof LinkedList); + assertEquals(Arrays.asList("_", "b", "c", "!"), res.foo); + } + + /** + * + */ + public void testLinkedListWriteUnmodifiable() { + TestObjectContainer obj = new TestObjectContainer(); + + LinkedList<Object> src = Lists.newLinkedList(Arrays.asList(obj, "a", "b", "c")); + + obj.foo = src; + + PortableBuilderImpl mutObj = wrap(obj); + + TestObjectContainer deserialized = mutObj.build().deserialize(); + + List<Object> res = (List<Object>)deserialized.foo; + + src.set(0, deserialized); + + assertEquals(src, res); + } + + /** + * + */ + public void testHashSetRead() { + TestObjectContainer obj = new TestObjectContainer(); + obj.foo = Sets.newHashSet(obj, "a"); + + PortableBuilderImpl mutObj = wrap(obj); + + Set<Object> set = mutObj.getField("foo"); + + assert set.equals(Sets.newHashSet(mutObj, "a")); + } + + /** + * + */ + public void testHashSetOverride() { + TestObjectContainer obj = new TestObjectContainer(); + + PortableBuilderImpl mutObj = wrap(obj); + + Set<Object> c = Sets.newHashSet(mutObj, "a", Sets.newHashSet(1, 2)); + + mutObj.setField("foo", c); + + TestObjectContainer res = mutObj.build().deserialize(); + + c.remove(mutObj); + c.add(res); + + assertNotSame(c, res.foo); + assertEquals(c, res.foo); + } + + /** + * + */ + public void testHashSetModification() { + TestObjectContainer obj = new TestObjectContainer(); + obj.foo = Sets.newHashSet("a", "b", "c"); + + PortableBuilderImpl mutObj = wrap(obj); + + Set<String> set = mutObj.getField("foo"); + + set.remove("b"); + set.add("!"); + + assertEquals(Sets.newHashSet("a", "!", "c"), set); + assertTrue(set.contains("a")); + assertTrue(set.contains("!")); + + TestObjectContainer res = mutObj.build().deserialize(); + + assertTrue(res.foo instanceof HashSet); + assertEquals(Sets.newHashSet("a", "!", "c"), res.foo); + } + + /** + * + */ + public void testHashSetWriteUnmodifiable() { + TestObjectContainer obj = new TestObjectContainer(); + + Set<Object> src = Sets.newHashSet(obj, "a", "b", "c"); + + obj.foo = src; + + TestObjectContainer deserialized = wrap(obj).build().deserialize(); + + Set<Object> res = (Set<Object>)deserialized.foo; + + src.remove(obj); + src.add(deserialized); + + assertEquals(src, res); + } + + /** + * + */ + public void testMapRead() { + TestObjectContainer obj = new TestObjectContainer(); + obj.foo = Maps.newHashMap(ImmutableMap.of(obj, "a", "b", obj)); + + PortableBuilderImpl mutObj = wrap(obj); + + Map<Object, Object> map = mutObj.getField("foo"); + + assert map.equals(ImmutableMap.of(mutObj, "a", "b", mutObj)); + } + + /** + * + */ + public void testMapOverride() { + TestObjectContainer obj = new TestObjectContainer(); + + PortableBuilderImpl mutObj = wrap(obj); + + Map<Object, Object> map = Maps.newHashMap(ImmutableMap.of(mutObj, "a", "b", mutObj)); + + mutObj.setField("foo", map); + + TestObjectContainer res = mutObj.build().deserialize(); + + assertEquals(ImmutableMap.of(res, "a", "b", res), res.foo); + } + + /** + * + */ + public void testMapModification() { + TestObjectContainer obj = new TestObjectContainer(); + obj.foo = Maps.newHashMap(ImmutableMap.of(1, "a", 2, "b")); + + PortableBuilderImpl mutObj = wrap(obj); + + Map<Object, Object> map = mutObj.getField("foo"); + + map.put(3, mutObj); + Object rmv = map.remove(1); + + assertEquals("a", rmv); + + TestObjectContainer res = mutObj.build().deserialize(); + + assertEquals(ImmutableMap.of(2, "b", 3, res), res.foo); + } + + /** + * + */ + public void testEnumArrayModification() { + TestObjectAllTypes obj = new TestObjectAllTypes(); + + obj.enumArr = new TestObjectEnum[]{TestObjectEnum.A, TestObjectEnum.B}; + + PortableBuilderImpl mutObj = wrap(obj); + + PortableBuilderEnum[] arr = mutObj.getField("enumArr"); + arr[0] = new PortableBuilderEnum(mutObj.typeId(), TestObjectEnum.B); + + TestObjectAllTypes res = mutObj.build().deserialize(); + + Assert.assertArrayEquals(new TestObjectEnum[] {TestObjectEnum.A, TestObjectEnum.B}, res.enumArr); + } + + /** + * + */ + public void testEditObjectWithRawData() { + GridPortableMarshalerAwareTestClass obj = new GridPortableMarshalerAwareTestClass(); + + obj.s = "a"; + obj.sRaw = "aa"; + + PortableBuilderImpl mutableObj = wrap(obj); + + mutableObj.setField("s", "z"); + + GridPortableMarshalerAwareTestClass res = mutableObj.build().deserialize(); + assertEquals("z", res.s); + assertEquals("aa", res.sRaw); + } + + /** + * + */ + public void testHashCode() { + TestObjectContainer obj = new TestObjectContainer(); + + PortableBuilderImpl mutableObj = wrap(obj); + + assertEquals(obj.hashCode(), mutableObj.build().hashCode()); + + mutableObj.hashCode(25); + + assertEquals(25, mutableObj.build().hashCode()); + } + + /** + * + */ + public void testCollectionsInCollection() { + TestObjectContainer obj = new TestObjectContainer(); + obj.foo = Lists.newArrayList( + Lists.newArrayList(1, 2), + Lists.newLinkedList(Arrays.asList(1, 2)), + Sets.newHashSet("a", "b"), + Sets.newLinkedHashSet(Arrays.asList("a", "b")), + Maps.newHashMap(ImmutableMap.of(1, "a", 2, "b"))); + + TestObjectContainer deserialized = wrap(obj).build().deserialize(); + + assertEquals(obj.foo, deserialized.foo); + } + + /** + * + */ + public void testMapEntryModification() { + TestObjectContainer obj = new TestObjectContainer(); + obj.foo = ImmutableMap.of(1, "a").entrySet().iterator().next(); + + PortableBuilderImpl mutableObj = wrap(obj); + + Map.Entry<Object, Object> entry = mutableObj.getField("foo"); + + assertEquals(1, entry.getKey()); + assertEquals("a", entry.getValue()); + + entry.setValue("b"); + + TestObjectContainer res = mutableObj.build().deserialize(); + + assertEquals(new GridMapEntry<>(1, "b"), res.foo); + } + + /** + * + */ + public void testMapEntryOverride() { + TestObjectContainer obj = new TestObjectContainer(); + + PortableBuilderImpl mutableObj = wrap(obj); + + mutableObj.setField("foo", new GridMapEntry<>(1, "a")); + + TestObjectContainer res = mutableObj.build().deserialize(); + + assertEquals(new GridMapEntry<>(1, "a"), res.foo); + } + + /** + * + */ + public void testMetadataChangingDoublePut() { + PortableBuilderImpl mutableObj = wrap(new TestObjectContainer()); + + mutableObj.setField("xx567", "a"); + mutableObj.setField("xx567", "b"); + + mutableObj.build(); + + PortableMetadata metadata = portables().metadata(TestObjectContainer.class); + + assertEquals("String", metadata.fieldTypeName("xx567")); + } + + /** + * + */ + public void testMetadataChangingDoublePut2() { + PortableBuilderImpl mutableObj = wrap(new TestObjectContainer()); + + mutableObj.setField("xx567", "a"); + mutableObj.setField("xx567", "b"); + + mutableObj.build(); + + PortableMetadata metadata = portables().metadata(TestObjectContainer.class); + + assertEquals("String", metadata.fieldTypeName("xx567")); + } + + /** + * + */ + public void testMetadataChanging() { + TestObjectContainer c = new TestObjectContainer(); + + PortableBuilderImpl mutableObj = wrap(c); + + mutableObj.setField("intField", 1); + mutableObj.setField("intArrField", new int[] {1}); + mutableObj.setField("arrField", new String[] {"1"}); + mutableObj.setField("strField", "1"); + mutableObj.setField("colField", Lists.newArrayList("1")); + mutableObj.setField("mapField", Maps.newHashMap(ImmutableMap.of(1, "1"))); + mutableObj.setField("enumField", TestObjectEnum.A); + mutableObj.setField("enumArrField", new Enum[] {TestObjectEnum.A}); + + mutableObj.build(); + + PortableMetadata metadata = portables().metadata(c.getClass()); + + assertTrue(metadata.fields().containsAll(Arrays.asList("intField", "intArrField", "arrField", "strField", + "colField", "mapField", "enumField", "enumArrField"))); + + assertEquals("int", metadata.fieldTypeName("intField")); + assertEquals("int[]", metadata.fieldTypeName("intArrField")); + assertEquals("String[]", metadata.fieldTypeName("arrField")); + assertEquals("String", metadata.fieldTypeName("strField")); + assertEquals("Collection", metadata.fieldTypeName("colField")); + assertEquals("Map", metadata.fieldTypeName("mapField")); + assertEquals("Enum", metadata.fieldTypeName("enumField")); + assertEquals("Enum[]", metadata.fieldTypeName("enumArrField")); + } + + /** + * + */ + public void testDateInObjectField() { + TestObjectContainer obj = new TestObjectContainer(); + + obj.foo = new Date(); + + PortableBuilderImpl mutableObj = wrap(obj); + + assertEquals(Timestamp.class, mutableObj.getField("foo").getClass()); + } + + /** + * + */ + public void testDateInCollection() { + TestObjectContainer obj = new TestObjectContainer(); + + obj.foo = Lists.newArrayList(new Date()); + + PortableBuilderImpl mutableObj = wrap(obj); + + assertEquals(Timestamp.class, ((List<?>)mutableObj.getField("foo")).get(0).getClass()); + } + + /** + * + */ + @SuppressWarnings("AssertEqualsBetweenInconvertibleTypes") + public void testDateArrayOverride() { + TestObjectContainer obj = new TestObjectContainer(); + + PortableBuilderImpl mutableObj = wrap(obj); + + Date[] arr = {new Date()}; + + mutableObj.setField("foo", arr); + + TestObjectContainer res = mutableObj.build().deserialize(); + + assertEquals(Date[].class, res.foo.getClass()); + assertTrue(Objects.deepEquals(arr, res.foo)); + } + + /** + * + */ + public void testChangeMap() { + AddressBook addrBook = new AddressBook(); + + addrBook.addCompany(new Company(1, "Google inc", 100, new Address("Saint-Petersburg", "Torzhkovskya", 1, 53), "occupation")); + addrBook.addCompany(new Company(2, "Apple inc", 100, new Address("Saint-Petersburg", "Torzhkovskya", 1, 54), "occupation")); + addrBook.addCompany(new Company(3, "Microsoft", 100, new Address("Saint-Petersburg", "Torzhkovskya", 1, 55), "occupation")); + addrBook.addCompany(new Company(4, "Oracle", 100, new Address("Saint-Petersburg", "Nevskiy", 1, 1), "occupation")); + + PortableBuilderImpl mutableObj = wrap(addrBook); + + Map<String, List<PortableBuilderImpl>> map = mutableObj.getField("companyByStreet"); + + List<PortableBuilderImpl> list = map.get("Torzhkovskya"); + + PortableBuilderImpl company = list.get(0); + + assert "Google inc".equals(company.<String>getField("name")); + + list.remove(0); + + AddressBook res = mutableObj.build().deserialize(); + + assertEquals(Arrays.asList("Nevskiy", "Torzhkovskya"), new ArrayList<>(res.getCompanyByStreet().keySet())); + + List<Company> torzhkovskyaCompanies = res.getCompanyByStreet().get("Torzhkovskya"); + + assertEquals(2, torzhkovskyaCompanies.size()); + assertEquals("Apple inc", torzhkovskyaCompanies.get(0).name); + } + + /** + * + */ + public void testSavingObjectWithNotZeroStart() { + TestObjectOuter out = new TestObjectOuter(); + TestObjectInner inner = new TestObjectInner(); + + out.inner = inner; + inner.outer = out; + + PortableBuilderImpl builder = wrap(out); + + PortableBuilderImpl innerBuilder = builder.getField("inner"); + + TestObjectInner res = innerBuilder.build().deserialize(); + + assertSame(res, res.outer.inner); + } + + /** + * + */ + public void testPortableObjectField() { + TestObjectContainer container = new TestObjectContainer(toPortable(new TestObjectArrayList())); + + PortableBuilderImpl wrapper = wrap(container); + + assertTrue(wrapper.getField("foo") instanceof PortableObject); + + TestObjectContainer deserialized = wrapper.build().deserialize(); + assertTrue(deserialized.foo instanceof PortableObject); + } + + /** + * + */ + public void testAssignPortableObject() { + TestObjectContainer container = new TestObjectContainer(); + + PortableBuilderImpl wrapper = wrap(container); + + wrapper.setField("foo", toPortable(new TestObjectArrayList())); + + TestObjectContainer deserialized = wrapper.build().deserialize(); + assertTrue(deserialized.foo instanceof TestObjectArrayList); + } + + /** + * + */ + public void testRemoveFromNewObject() { + PortableBuilderImpl wrapper = newWrapper(TestObjectAllTypes.class); + + wrapper.setField("str", "a"); + + wrapper.removeField("str"); + + assertNull(wrapper.build().<TestObjectAllTypes>deserialize().str); + } + + /** + * + */ + public void testRemoveFromExistingObject() { + TestObjectAllTypes obj = new TestObjectAllTypes(); + obj.setDefaultData(); + + PortableBuilderImpl wrapper = wrap(toPortable(obj)); + + wrapper.removeField("str"); + + assertNull(wrapper.build().<TestObjectAllTypes>deserialize().str); + } + + /** + * + */ + public void testCyclicArrays() { + fail("https://issues.apache.org/jira/browse/IGNITE-1273"); + + TestObjectContainer obj = new TestObjectContainer(); + + Object[] arr1 = new Object[1]; + Object[] arr2 = new Object[]{arr1}; + + arr1[0] = arr2; + + obj.foo = arr1; + + TestObjectContainer res = toPortable(obj).deserialize(); + + Object[] resArr = (Object[])res.foo; + + assertSame(((Object[])resArr[0])[0], resArr); + } + + /** + * + */ + @SuppressWarnings("TypeMayBeWeakened") + public void testCyclicArrayList() { + fail("https://issues.apache.org/jira/browse/IGNITE-1273"); + TestObjectContainer obj = new TestObjectContainer(); + + List<Object> arr1 = new ArrayList<>(); + List<Object> arr2 = new ArrayList<>(); + + arr1.add(arr2); + arr2.add(arr1); + + obj.foo = arr1; + + TestObjectContainer res = toPortable(obj).deserialize(); + + List<?> resArr = (List<?>)res.foo; + + assertSame(((List<Object>)resArr.get(0)).get(0), resArr); + } + + /** + * @param obj Object. + * @return Object in portable format. + */ + private PortableObject toPortable(Object obj) { + return portables().toPortable(obj); + } + + /** + * @param obj Object. + * @return GridMutablePortableObject. + */ + private PortableBuilderImpl wrap(Object obj) { + return PortableBuilderImpl.wrap(toPortable(obj)); + } + + /** + * @param aCls Class. + * @return Wrapper. + */ + private PortableBuilderImpl newWrapper(Class<?> aCls) { + CacheObjectPortableProcessorImpl processor = (CacheObjectPortableProcessorImpl)( + (IgnitePortablesImpl)portables()).processor(); + + return new PortableBuilderImpl(processor.portableContext(), processor.typeId(aCls.getName()), + aCls.getSimpleName()); + } +}
http://git-wip-us.apache.org/repos/asf/ignite/blob/878dcd92/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderSelfTest.java new file mode 100644 index 0000000..6ffa3dd --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderSelfTest.java @@ -0,0 +1,1007 @@ +/* + * 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.portable; + +import org.apache.ignite.*; +import org.apache.ignite.configuration.*; +import org.apache.ignite.internal.processors.cache.portable.*; +import org.apache.ignite.internal.util.*; +import org.apache.ignite.internal.util.typedef.*; +import org.apache.ignite.marshaller.portable.*; +import org.apache.ignite.portable.*; +import org.apache.ignite.testframework.*; +import org.apache.ignite.testframework.junits.common.*; + +import org.apache.ignite.internal.portable.mutabletest.GridPortableTestClasses.*; +import sun.misc.*; + +import java.math.*; +import java.util.*; + +/** + * Portable builder test. + */ +public class GridPortableBuilderSelfTest extends GridCommonAbstractTest { + /** */ + private static final Unsafe UNSAFE = GridUnsafe.unsafe(); + + /** */ + protected static final long BYTE_ARR_OFF = UNSAFE.arrayBaseOffset(byte[].class); + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(gridName); + + PortableMarshaller marsh = new PortableMarshaller(); + + marsh.setClassNames(Arrays.asList(Key.class.getName(), Value.class.getName(), + "org.gridgain.grid.internal.util.portable.mutabletest.*")); + + PortableTypeConfiguration customIdMapper = new PortableTypeConfiguration(); + + customIdMapper.setClassName(CustomIdMapper.class.getName()); + customIdMapper.setIdMapper(new PortableIdMapper() { + @Override public int typeId(String clsName) { + return ~PortableContext.DFLT_ID_MAPPER.typeId(clsName); + } + + @Override public int fieldId(int typeId, String fieldName) { + return typeId + ~PortableContext.DFLT_ID_MAPPER.fieldId(typeId, fieldName); + } + }); + + marsh.setTypeConfigurations(Collections.singleton(customIdMapper)); + + marsh.setConvertStringToBytes(useUtf8()); + + cfg.setMarshaller(marsh); + + return cfg; + } + + /** {@inheritDoc} */ + @Override protected void beforeTestsStarted() throws Exception { + startGrids(1); + } + + /** {@inheritDoc} */ + @Override protected void afterTestsStopped() throws Exception { + stopAllGrids(); + } + + /** + * @return Whether to use UTF8 strings. + */ + protected boolean useUtf8() { + return true; + } + + /** + * + */ + public void testAllFieldsSerialization() { + TestObjectAllTypes obj = new TestObjectAllTypes(); + obj.setDefaultData(); + obj.enumArr = null; + + TestObjectAllTypes deserialized = builder(toPortable(obj)).build().deserialize(); + + GridTestUtils.deepEquals(obj, deserialized); + } + + /** + * @throws Exception If failed. + */ + public void testByteField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("byteField", (byte)1); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertEquals((byte)1, po.<Byte>field("byteField").byteValue()); + } + + /** + * @throws Exception If failed. + */ + public void testShortField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("shortField", (short)1); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertEquals((short)1, po.<Short>field("shortField").shortValue()); + } + + /** + * @throws Exception If failed. + */ + public void testIntField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("intField", 1); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertEquals(1, po.<Integer>field("intField").intValue()); + } + + /** + * @throws Exception If failed. + */ + public void testLongField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("longField", 1L); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertEquals(1L, po.<Long>field("longField").longValue()); + } + + /** + * @throws Exception If failed. + */ + public void testFloatField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("floatField", 1.0f); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertEquals(1.0f, po.<Float>field("floatField").floatValue(), 0); + } + + /** + * @throws Exception If failed. + */ + public void testDoubleField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("doubleField", 1.0d); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertEquals(1.0d, po.<Double>field("doubleField").doubleValue(), 0); + } + + /** + * @throws Exception If failed. + */ + public void testCharField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("charField", (char)1); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertEquals((char)1, po.<Character>field("charField").charValue()); + } + + /** + * @throws Exception If failed. + */ + public void testBooleanField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("booleanField", true); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertTrue(po.<Boolean>field("booleanField")); + } + + /** + * @throws Exception If failed. + */ + public void testDecimalField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("decimalField", BigDecimal.TEN); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertEquals(BigDecimal.TEN, po.<String>field("decimalField")); + } + + /** + * @throws Exception If failed. + */ + public void testStringField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("stringField", "str"); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertEquals("str", po.<String>field("stringField")); + } + + /** + * @throws Exception If failed. + */ + public void testUuidField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + UUID uuid = UUID.randomUUID(); + + builder.setField("uuidField", uuid); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertEquals(uuid, po.<UUID>field("uuidField")); + } + + /** + * @throws Exception If failed. + */ + public void testByteArrayField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("byteArrayField", new byte[] {1, 2, 3}); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertTrue(Arrays.equals(new byte[] {1, 2, 3}, po.<byte[]>field("byteArrayField"))); + } + + /** + * @throws Exception If failed. + */ + public void testShortArrayField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("shortArrayField", new short[] {1, 2, 3}); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertTrue(Arrays.equals(new short[] {1, 2, 3}, po.<short[]>field("shortArrayField"))); + } + + /** + * @throws Exception If failed. + */ + public void testIntArrayField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("intArrayField", new int[] {1, 2, 3}); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertTrue(Arrays.equals(new int[] {1, 2, 3}, po.<int[]>field("intArrayField"))); + } + + /** + * @throws Exception If failed. + */ + public void testLongArrayField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("longArrayField", new long[] {1, 2, 3}); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertTrue(Arrays.equals(new long[] {1, 2, 3}, po.<long[]>field("longArrayField"))); + } + + /** + * @throws Exception If failed. + */ + public void testFloatArrayField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("floatArrayField", new float[] {1, 2, 3}); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertTrue(Arrays.equals(new float[] {1, 2, 3}, po.<float[]>field("floatArrayField"))); + } + + /** + * @throws Exception If failed. + */ + public void testDoubleArrayField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("doubleArrayField", new double[] {1, 2, 3}); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertTrue(Arrays.equals(new double[] {1, 2, 3}, po.<double[]>field("doubleArrayField"))); + } + + /** + * @throws Exception If failed. + */ + public void testCharArrayField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("charArrayField", new char[] {1, 2, 3}); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertTrue(Arrays.equals(new char[] {1, 2, 3}, po.<char[]>field("charArrayField"))); + } + + /** + * @throws Exception If failed. + */ + public void testBooleanArrayField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("booleanArrayField", new boolean[] {true, false}); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + boolean[] arr = po.field("booleanArrayField"); + + assertEquals(2, arr.length); + + assertTrue(arr[0]); + assertFalse(arr[1]); + } + + /** + * @throws Exception If failed. + */ + public void testDecimalArrayField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("decimalArrayField", new BigDecimal[] {BigDecimal.ONE, BigDecimal.TEN}); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertTrue(Arrays.equals(new BigDecimal[] {BigDecimal.ONE, BigDecimal.TEN}, po.<String[]>field("decimalArrayField"))); + } + + /** + * @throws Exception If failed. + */ + public void testStringArrayField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("stringArrayField", new String[] {"str1", "str2", "str3"}); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertTrue(Arrays.equals(new String[] {"str1", "str2", "str3"}, po.<String[]>field("stringArrayField"))); + } + + /** + * @throws Exception If failed. + */ + public void testUuidArrayField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + UUID[] arr = new UUID[] {UUID.randomUUID(), UUID.randomUUID()}; + + builder.setField("uuidArrayField", arr); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertTrue(Arrays.equals(arr, po.<UUID[]>field("uuidArrayField"))); + } + + /** + * @throws Exception If failed. + */ + public void testObjectField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("objectField", new Value(1)); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertEquals(1, po.<PortableObject>field("objectField").<Value>deserialize().i); + } + + /** + * @throws Exception If failed. + */ + public void testObjectArrayField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("objectArrayField", new Value[] {new Value(1), new Value(2)}); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + Object[] arr = po.field("objectArrayField"); + + assertEquals(2, arr.length); + + assertEquals(1, ((PortableObject)arr[0]).<Value>deserialize().i); + assertEquals(2, ((PortableObject)arr[1]).<Value>deserialize().i); + } + + /** + * @throws Exception If failed. + */ + public void testCollectionField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("collectionField", Arrays.asList(new Value(1), new Value(2))); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + List<PortableObject> list = po.field("collectionField"); + + assertEquals(2, list.size()); + + assertEquals(1, list.get(0).<Value>deserialize().i); + assertEquals(2, list.get(1).<Value>deserialize().i); + } + + /** + * @throws Exception If failed. + */ + public void testMapField() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("mapField", F.asMap(new Key(1), new Value(1), new Key(2), new Value(2))); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + Map<PortableObject, PortableObject> map = po.field("mapField"); + + assertEquals(2, map.size()); + + for (Map.Entry<PortableObject, PortableObject> e : map.entrySet()) + assertEquals(e.getKey().<Key>deserialize().i, e.getValue().<Value>deserialize().i); + } + + /** + * @throws Exception If failed. + */ + public void testSeveralFields() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("i", 111); + builder.setField("f", 111.111f); + builder.setField("iArr", new int[] {1, 2, 3}); + builder.setField("obj", new Key(1)); + builder.setField("col", Arrays.asList(new Value(1), new Value(2))); + + PortableObject po = builder.build(); + + assertEquals("class".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertEquals(111, po.<Integer>field("i").intValue()); + assertEquals(111.111f, po.<Float>field("f").floatValue(), 0); + assertTrue(Arrays.equals(new int[] {1, 2, 3}, po.<int[]>field("iArr"))); + assertEquals(1, po.<PortableObject>field("obj").<Key>deserialize().i); + + List<PortableObject> list = po.field("col"); + + assertEquals(2, list.size()); + + assertEquals(1, list.get(0).<Value>deserialize().i); + assertEquals(2, list.get(1).<Value>deserialize().i); + } + + /** + * @throws Exception If failed. + */ + public void testOffheapPortable() throws Exception { + PortableBuilder builder = builder("Class"); + + builder.hashCode(100); + + builder.setField("i", 111); + builder.setField("f", 111.111f); + builder.setField("iArr", new int[] {1, 2, 3}); + builder.setField("obj", new Key(1)); + builder.setField("col", Arrays.asList(new Value(1), new Value(2))); + + PortableObject po = builder.build(); + + byte[] arr = ((CacheObjectPortableProcessorImpl)(grid(0)).context().cacheObjects()).marshal(po); + + long ptr = UNSAFE.allocateMemory(arr.length + 5); + + try { + long ptr0 = ptr; + + UNSAFE.putBoolean(null, ptr0++, false); + + UNSAFE.putInt(ptr0, arr.length); + + UNSAFE.copyMemory(arr, BYTE_ARR_OFF, null, ptr0 + 4, arr.length); + + PortableObject offheapObj = (PortableObject) + ((CacheObjectPortableProcessorImpl)(grid(0)).context().cacheObjects()).unmarshal(ptr, false); + + assertEquals(PortableObjectOffheapImpl.class, offheapObj.getClass()); + + assertEquals("class".hashCode(), offheapObj.typeId()); + assertEquals(100, offheapObj.hashCode()); + + assertEquals(111, offheapObj.<Integer>field("i").intValue()); + assertEquals(111.111f, offheapObj.<Float>field("f").floatValue(), 0); + assertTrue(Arrays.equals(new int[] {1, 2, 3}, offheapObj.<int[]>field("iArr"))); + assertEquals(1, offheapObj.<PortableObject>field("obj").<Key>deserialize().i); + + List<PortableObject> list = offheapObj.field("col"); + + assertEquals(2, list.size()); + + assertEquals(1, list.get(0).<Value>deserialize().i); + assertEquals(2, list.get(1).<Value>deserialize().i); + + assertEquals(po, offheapObj); + assertEquals(offheapObj, po); + } + finally { + UNSAFE.freeMemory(ptr); + } + } + + /** + * @throws Exception If failed. + */ + public void testBuildAndDeserialize() throws Exception { + PortableBuilder builder = builder(Value.class.getName()); + + builder.hashCode(100); + + builder.setField("i", 1); + + PortableObject po = builder.build(); + + assertEquals("value".hashCode(), po.typeId()); + assertEquals(100, po.hashCode()); + + assertEquals(1, po.<Value>deserialize().i); + } + + /** + * @throws Exception If failed. + */ + public void testMetaData2() throws Exception { + PortableBuilder builder = builder("org.test.MetaTest2"); + + builder.setField("objectField", "a", Object.class); + + PortableObject po = builder.build(); + + PortableMetadata meta = po.metaData(); + + assertEquals("MetaTest2", meta.typeName()); + assertEquals("Object", meta.fieldTypeName("objectField")); + } + + /** + * @throws Exception If failed. + */ + public void testMetaData() throws Exception { + PortableBuilder builder = builder("org.test.MetaTest"); + + builder.hashCode(100); + + builder.setField("intField", 1); + builder.setField("byteArrayField", new byte[] {1, 2, 3}); + + PortableObject po = builder.build(); + + PortableMetadata meta = po.metaData(); + + assertEquals("MetaTest", meta.typeName()); + + Collection<String> fields = meta.fields(); + + assertEquals(2, fields.size()); + + assertTrue(fields.contains("intField")); + assertTrue(fields.contains("byteArrayField")); + + assertEquals("int", meta.fieldTypeName("intField")); + assertEquals("byte[]", meta.fieldTypeName("byteArrayField")); + + builder = builder("org.test.MetaTest"); + + builder.hashCode(100); + + builder.setField("intField", 2); + builder.setField("uuidField", UUID.randomUUID()); + + po = builder.build(); + + meta = po.metaData(); + + assertEquals("MetaTest", meta.typeName()); + + fields = meta.fields(); + + assertEquals(3, fields.size()); + + assertTrue(fields.contains("intField")); + assertTrue(fields.contains("byteArrayField")); + assertTrue(fields.contains("uuidField")); + + assertEquals("int", meta.fieldTypeName("intField")); + assertEquals("byte[]", meta.fieldTypeName("byteArrayField")); + assertEquals("UUID", meta.fieldTypeName("uuidField")); + } + + /** + * + */ + public void testGetFromCopiedObj() { + PortableObject objStr = builder(TestObjectAllTypes.class.getName()).setField("str", "aaa").build(); + + PortableBuilderImpl builder = builder(objStr); + assertEquals("aaa", builder.getField("str")); + + builder.setField("str", "bbb"); + assertEquals("bbb", builder.getField("str")); + + assertNull(builder.getField("i_")); + assertEquals("bbb", builder.build().<TestObjectAllTypes>deserialize().str); + } + + /** + * + */ + public void testCopyFromInnerObjects() { + ArrayList<Object> list = new ArrayList<>(); + list.add(new TestObjectAllTypes()); + list.add(list.get(0)); + + TestObjectContainer c = new TestObjectContainer(list); + + PortableBuilderImpl builder = builder(toPortable(c)); + builder.<List>getField("foo").add("!!!"); + + PortableObject res = builder.build(); + + TestObjectContainer deserialized = res.deserialize(); + + List deserializedList = (List)deserialized.foo; + + assertSame(deserializedList.get(0), deserializedList.get(1)); + assertEquals("!!!", deserializedList.get(2)); + assertTrue(deserializedList.get(0) instanceof TestObjectAllTypes); + } + + /** + * + */ + public void testSetPortableObject() { + PortableObject portableObj = builder(TestObjectContainer.class.getName()) + .setField("foo", toPortable(new TestObjectAllTypes())) + .build(); + + assertTrue(portableObj.<TestObjectContainer>deserialize().foo instanceof TestObjectAllTypes); + } + + /** + * + */ + public void testPlainPortableObjectCopyFrom() { + TestObjectPlainPortable obj = new TestObjectPlainPortable(toPortable(new TestObjectAllTypes())); + + PortableBuilderImpl builder = builder(toPortable(obj)); + assertTrue(builder.getField("plainPortable") instanceof PortableObject); + + TestObjectPlainPortable deserialized = builder.build().deserialize(); + assertTrue(deserialized.plainPortable instanceof PortableObject); + } + + /** + * + */ + public void testRemoveFromNewObject() { + PortableBuilder builder = builder(TestObjectAllTypes.class.getName()); + + builder.setField("str", "a"); + + builder.removeField("str"); + + assertNull(builder.build().<TestObjectAllTypes>deserialize().str); + } + + /** + * + */ + public void testRemoveFromExistingObject() { + TestObjectAllTypes obj = new TestObjectAllTypes(); + obj.setDefaultData(); + obj.enumArr = null; + + PortableBuilder builder = builder(toPortable(obj)); + + builder.removeField("str"); + + assertNull(builder.build().<TestObjectAllTypes>deserialize().str); + } + + /** + * + */ + public void testRemoveFromExistingObjectAfterGet() { + TestObjectAllTypes obj = new TestObjectAllTypes(); + obj.setDefaultData(); + obj.enumArr = null; + + PortableBuilderImpl builder = builder(toPortable(obj)); + + builder.getField("i_"); + + builder.removeField("str"); + + assertNull(builder.build().<TestObjectAllTypes>deserialize().str); + } + + /** + * @throws IgniteCheckedException If any error occurs. + */ + public void testDontBrokeCyclicDependency() throws IgniteCheckedException { + TestObjectOuter outer = new TestObjectOuter(); + outer.inner = new TestObjectInner(); + outer.inner.outer = outer; + outer.foo = "a"; + + PortableBuilder builder = builder(toPortable(outer)); + + builder.setField("foo", "b"); + + TestObjectOuter res = builder.build().deserialize(); + + assertEquals("b", res.foo); + assertSame(res, res.inner.outer); + } + + /** + * @return Portables. + */ + private IgnitePortables portables() { + return grid(0).portables(); + } + + /** + * @param obj Object. + * @return Portable object. + */ + private PortableObject toPortable(Object obj) { + return portables().toPortable(obj); + } + + /** + * @return Builder. + */ + private <T> PortableBuilder builder(int typeId) { + return portables().builder(typeId); + } + + /** + * @return Builder. + */ + private <T> PortableBuilder builder(String clsName) { + return portables().builder(clsName); + } + + /** + * @return Builder. + */ + private <T> PortableBuilderImpl builder(PortableObject obj) { + return (PortableBuilderImpl)portables().builder(obj); + } + + /** + * + */ + private static class CustomIdMapper { + /** */ + private String str = "a"; + + /** */ + private int i = 10; + } + + /** + */ + private static class Key { + /** */ + private int i; + + /** + */ + private Key() { + // No-op. + } + + /** + * @param i Index. + */ + private Key(int i) { + this.i = i; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || getClass() != o.getClass()) + return false; + + Key key = (Key)o; + + return i == key.i; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return i; + } + } + + /** + */ + private static class Value { + /** */ + private int i; + + /** + */ + private Value() { + // No-op. + } + + /** + * @param i Index. + */ + private Value(int i) { + this.i = i; + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/878dcd92/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderStringAsCharsAdditionalSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderStringAsCharsAdditionalSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderStringAsCharsAdditionalSelfTest.java new file mode 100644 index 0000000..71f670d --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderStringAsCharsAdditionalSelfTest.java @@ -0,0 +1,28 @@ +/* + * 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.portable; + +/** + * + */ +public class GridPortableBuilderStringAsCharsAdditionalSelfTest extends GridPortableBuilderAdditionalSelfTest { + /** {@inheritDoc} */ + @Override protected boolean useUtf8() { + return false; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/878dcd92/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderStringAsCharsSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderStringAsCharsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderStringAsCharsSelfTest.java new file mode 100644 index 0000000..4ba9dfa --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableBuilderStringAsCharsSelfTest.java @@ -0,0 +1,28 @@ +/* + * 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.portable; + +/** + * Portable builder test. + */ +public class GridPortableBuilderStringAsCharsSelfTest extends GridPortableBuilderSelfTest { + /** {@inheritDoc} */ + @Override protected boolean useUtf8() { + return false; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/878dcd92/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerCtxDisabledSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerCtxDisabledSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerCtxDisabledSelfTest.java new file mode 100644 index 0000000..0cb6197 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerCtxDisabledSelfTest.java @@ -0,0 +1,128 @@ +/* + * 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.portable; + +import org.apache.ignite.*; +import org.apache.ignite.internal.*; +import org.apache.ignite.internal.util.*; +import org.apache.ignite.marshaller.portable.*; +import org.apache.ignite.portable.*; +import org.apache.ignite.testframework.junits.common.*; + +/** + * + */ +public class GridPortableMarshallerCtxDisabledSelfTest extends GridCommonAbstractTest { + /** */ + protected static final PortableMetaDataHandler META_HND = new PortableMetaDataHandler() { + @Override public void addMeta(int typeId, PortableMetadata meta) { + // No-op. + } + + @Override public PortableMetadata metadata(int typeId) { + return null; + } + }; + + /** + * @throws Exception If failed. + */ + public void testObjectExchange() throws Exception { + PortableMarshaller marsh = new PortableMarshaller(); + marsh.setContext(new MarshallerContextWithNoStorage()); + + PortableContext context = new PortableContext(META_HND, null); + + IgniteUtils.invoke(PortableMarshaller.class, marsh, "setPortableContext", context); + + SimpleObject obj0 = new SimpleObject(); + + obj0.b = 2; + obj0.bArr = new byte[] {2, 3, 4, 5, 5}; + obj0.c = 'A'; + obj0.enumVal = TestEnum.D; + obj0.objArr = new Object[] {"hello", "world", "from", "me"}; + obj0.enumArr = new TestEnum[] {TestEnum.C, TestEnum.B}; + + byte[] arr = marsh.marshal(obj0); + + SimpleObject obj2 = marsh.unmarshal(arr, null); + + assertEquals(obj0.b, obj2.b); + assertEquals(obj0.c, obj2.c); + assertEquals(obj0.enumVal, obj2.enumVal); + + for (int i = 0; i < obj0.bArr.length; i++) + assertEquals(obj0.bArr[i], obj2.bArr[i]); + + for (int i = 0; i < obj0.objArr.length; i++) + assertEquals(obj0.objArr[i], obj2.objArr[i]); + + for (int i = 0; i < obj0.enumArr.length; i++) + assertEquals(obj0.enumArr[i], obj2.enumArr[i]); + } + + /** + * Marshaller context with no storage. Platform has to work in such environment as well by marshalling class name + * of a portable object. + */ + private static class MarshallerContextWithNoStorage extends MarshallerContextAdapter { + /** */ + public MarshallerContextWithNoStorage() { + super(null); + } + + /** {@inheritDoc} */ + @Override protected boolean registerClassName(int id, String clsName) throws IgniteCheckedException { + return false; + } + + /** {@inheritDoc} */ + @Override protected String className(int id) throws IgniteCheckedException { + return null; + } + } + + /** + */ + private enum TestEnum { + A, B, C, D, E + } + + /** + */ + private static class SimpleObject { + /** */ + private byte b; + + /** */ + private char c; + + /** */ + private byte[] bArr; + + /** */ + private Object[] objArr; + + /** */ + private TestEnum enumVal; + + /** */ + private TestEnum[] enumArr; + } +}