http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerEnumSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerEnumSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerEnumSelfTest.java new file mode 100644 index 0000000..c7a58f7 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerEnumSelfTest.java @@ -0,0 +1,87 @@ +/* + * 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.marshaller.optimized; + +import junit.framework.TestCase; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteLogger; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.marshaller.MarshallerContextTestImpl; +import org.apache.ignite.testframework.junits.GridTestKernalContext; +import org.apache.ignite.testframework.junits.logger.GridTestLog4jLogger; + +/** + * + */ +public class OptimizedMarshallerEnumSelfTest extends TestCase { + + private String igniteHome = System.getProperty("user.dir"); + + private final IgniteLogger rootLog = new GridTestLog4jLogger(false); + /** + * @throws Exception If failed. + */ + public void testEnumSerialisation() throws Exception { + OptimizedMarshaller marsh = new OptimizedMarshaller(); + + MarshallerContextTestImpl context = new MarshallerContextTestImpl(); + + context.onMarshallerProcessorStarted(newContext(), null); + + marsh.setContext(context); + + byte[] bytes = marsh.marshal(TestEnum.Bond); + + TestEnum unmarshalled = marsh.unmarshal(bytes, Thread.currentThread().getContextClassLoader()); + + assertEquals(TestEnum.Bond, unmarshalled); + assertEquals(TestEnum.Bond.desc, unmarshalled.desc); + } + + private GridKernalContext newContext() throws IgniteCheckedException { + IgniteConfiguration cfg = new IgniteConfiguration(); + + cfg.setIgniteHome(igniteHome); + cfg.setClientMode(false); + + return new GridTestKernalContext(rootLog.getLogger(OptimizedMarshallerEnumSelfTest.class), cfg); + } + + private enum TestEnum { + Equity("Equity") { + @Override public String getTestString() { + return "eee"; + } + }, + + Bond("Bond") { + @Override public String getTestString() { + return "qqq"; + } + }; + + public final String desc; + + TestEnum(String desc) { + this.desc = desc; + } + + public abstract String getTestString(); + } +} \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerNodeFailoverTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerNodeFailoverTest.java b/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerNodeFailoverTest.java new file mode 100644 index 0000000..f842b5f --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerNodeFailoverTest.java @@ -0,0 +1,358 @@ +/* + * 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.marshaller.optimized; + +import java.io.File; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Callable; +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.IgniteInternalFuture; +import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; +import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; +import org.apache.ignite.testframework.GridTestUtils; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +import static org.apache.ignite.cache.CacheMode.PARTITIONED; +import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; + +/** + * + */ +public class OptimizedMarshallerNodeFailoverTest extends GridCommonAbstractTest { + /** */ + private static TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true); + + /** */ + private boolean cache; + + /** */ + private String workDir; + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); + + TcpDiscoverySpi disco = new TcpDiscoverySpi(); + + disco.setIpFinder(ipFinder); + + cfg.setDiscoverySpi(disco); + + cfg.setMarshaller(new OptimizedMarshaller()); + + cfg.setWorkDirectory(workDir); + + if (cache) { + CacheConfiguration ccfg = new CacheConfiguration(); + + ccfg.setCacheMode(PARTITIONED); + ccfg.setBackups(1); + ccfg.setWriteSynchronizationMode(FULL_SYNC); + + cfg.setCacheConfiguration(ccfg); + } + else + cfg.setClientMode(true); + + return cfg; + } + + /** + * @throws Exception If failed. + */ + public void testClassCacheUpdateFailover1() throws Exception { + classCacheUpdateFailover(false); + } + + /** + * @throws Exception If failed. + */ + public void testClassCacheUpdateFailover2() throws Exception { + classCacheUpdateFailover(true); + } + + /** + * @param stopSrv If {@code true} restarts server node, otherwise client node. + * @throws Exception If failed. + */ + private void classCacheUpdateFailover(boolean stopSrv) throws Exception { + cache = true; + + startGridsMultiThreaded(2); + + cache = stopSrv; + + IgniteCache<Integer, Object> cache0 = ignite(0).cache(null); + + for (int i = 0; i < 20; i++) { + log.info("Iteration: " + i); + + Map<Integer, Object> map = new HashMap<>(); + + for (int j = 0; j < 10_000; j++) + map.put(j, create(i + 1)); + + final Ignite ignite = startGrid(2); + + IgniteInternalFuture fut = GridTestUtils.runAsync(new Callable() { + @Override public Object call() throws Exception { + ignite.close(); + + return null; + } + }); + + cache0.putAll(map); + + fut.get(); + } + + cache = true; + + Ignite ignite = startGrid(2); // Check can start one more cache node. + + assertNotNull(ignite.cache(null)); + } + + /** + * @throws Exception If failed. + */ + public void testRestartAllNodes() throws Exception { + cache = true; + + String home = U.getIgniteHome(); + + String[] workDirs = new String[3]; + + for (int i = 0; i < 3; i++) { + workDirs[i] = home + "/work/marshallerTestNode_" + i; + + File file = new File(workDirs[i]); + + if (file.exists()) + assert U.delete(file); + } + + try { + for (int i = 0; i < workDirs.length; i++) { + workDir = workDirs[i]; + + startGrid(i); + } + + Marshaller marsh = ignite(0).configuration().getMarshaller(); + + TestClass1 obj = new TestClass1(); + + obj.val = 111; + + byte[] bytes = marsh.marshal(obj); + + stopAllGrids(); + + for (int i = 0; i < workDirs.length; i++) { + workDir = workDirs[i]; + + startGrid(i); + } + + for (int i = 0; i < 3; i++) { + marsh = ignite(i).configuration().getMarshaller(); + + TestClass1 obj0 = marsh.unmarshal(bytes, null); + + assertEquals(111, obj0.val); + } + } + finally { + for (String dir : workDirs) + assert U.delete(new File(dir)); + } + } + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + super.afterTest(); + + stopAllGrids(); + } + + /** + * @param id Class ID. + * @return Test class instance. + */ + private static Object create(int id) { + switch (id) { + case 1: return new TestClass1(); + + case 2: return new TestClass2(); + + case 3: return new TestClass3(); + + case 4: return new TestClass4(); + + case 5: return new TestClass5(); + + case 6: return new TestClass6(); + + case 7: return new TestClass7(); + + case 8: return new TestClass8(); + + case 9: return new TestClass9(); + + case 10: return new TestClass10(); + + case 11: return new TestClass11(); + + case 12: return new TestClass12(); + + case 13: return new TestClass13(); + + case 14: return new TestClass14(); + + case 15: return new TestClass15(); + + case 16: return new TestClass16(); + + case 17: return new TestClass17(); + + case 18: return new TestClass18(); + + case 19: return new TestClass19(); + + case 20: return new TestClass20(); + } + + fail(); + + return null; + } + + /** + * + */ + static class TestClass1 implements Serializable { + /** */ + int val; + } + + /** + * + */ + static class TestClass2 implements Serializable {} + + /** + * + */ + static class TestClass3 implements Serializable {} + + /** + * + */ + static class TestClass4 implements Serializable {} + + /** + * + */ + static class TestClass5 implements Serializable {} + + /** + * + */ + static class TestClass6 implements Serializable {} + + /** + * + */ + static class TestClass7 implements Serializable {} + + /** + * + */ + static class TestClass8 implements Serializable {} + + /** + * + */ + static class TestClass9 implements Serializable {} + + /** + * + */ + static class TestClass10 implements Serializable {} + + /** + * + */ + static class TestClass11 implements Serializable {} + + /** + * + */ + static class TestClass12 implements Serializable {} + + /** + * + */ + static class TestClass13 implements Serializable {} + + /** + * + */ + static class TestClass14 implements Serializable {} + + /** + * + */ + static class TestClass15 implements Serializable {} + + /** + * + */ + static class TestClass16 implements Serializable {} + + /** + * + */ + static class TestClass17 implements Serializable {} + + /** + * + */ + static class TestClass18 implements Serializable {} + + /** + * + */ + static class TestClass19 implements Serializable {} + + /** + * + */ + static class TestClass20 implements Serializable {} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerPooledSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerPooledSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerPooledSelfTest.java new file mode 100644 index 0000000..02954f9 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerPooledSelfTest.java @@ -0,0 +1,46 @@ +/* + * 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.marshaller.optimized; + +import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller; +import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerSelfTest; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.testframework.junits.common.GridCommonTest; + +/** + * Optimized marshaller self test. + */ +@GridCommonTest(group = "Marshaller") +public class OptimizedMarshallerPooledSelfTest extends OptimizedMarshallerSelfTest { + /** {@inheritDoc} */ + @Override protected Marshaller marshaller() { + OptimizedMarshaller m = new OptimizedMarshaller(false); + + m.setPoolSize(8); + + return m; + } + + /** {@inheritDoc} */ + @Override protected void afterTestsStopped() throws Exception { + super.afterTestsStopped(); + + // Reset static registry. + new OptimizedMarshaller().setPoolSize(0); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerSelfTest.java new file mode 100644 index 0000000..fa95abc --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerSelfTest.java @@ -0,0 +1,284 @@ +/* + * 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.marshaller.optimized; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.concurrent.Callable; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller; +import org.apache.ignite.lang.IgniteRunnable; +import org.apache.ignite.marshaller.GridMarshallerAbstractTest; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.testframework.GridTestUtils; +import org.apache.ignite.testframework.junits.common.GridCommonTest; + +/** + * Optimized marshaller self test. + */ +@GridCommonTest(group = "Marshaller") +public class OptimizedMarshallerSelfTest extends GridMarshallerAbstractTest { + /** {@inheritDoc} */ + @Override protected Marshaller marshaller() { + return new OptimizedMarshaller(false); + } + + /** + * @throws Exception If failed. + */ + public void testTestMarshalling() throws Exception { + final String msg = "PASSED"; + + byte[] buf = marshal(new IgniteRunnable() { + @Override public void run() { + c1.apply(msg); + c2.apply(msg); + + c3.apply(); + c4.reduce(); + + System.out.println("Test message: " + msg); + } + }); + + Runnable r = unmarshal(buf); + + assertNotNull(r); + + r.run(); + } + + /** + * Tests marshal self-linked object. + * + * @throws IgniteCheckedException If marshalling failed. + */ + public void testMarshallingSelfLink() throws IgniteCheckedException { + SelfLink sl = new SelfLink("a string 1"); + + sl.link(sl); + + SelfLink sl1 = unmarshal(marshal(sl)); + + assert sl1.link() == sl1; + } + + /** + * @throws Exception If failed. + */ + public void testInvalid() throws Exception { + GridTestUtils.assertThrows( + log, + new Callable<Object>() { + @Override public Object call() throws Exception { + byte[] arr = new byte[10]; + + arr[0] = (byte)200; + + unmarshal(arr); + + return null; + } + }, + IgniteCheckedException.class, + null + ); + } + + /** + * @throws Exception If failed. + */ + public void testNested() throws Exception { + NestedTestObject obj = new NestedTestObject("String", 100); + + NestedTestObject newObj = unmarshal(marshal(obj)); + + assertEquals("String", newObj.str); + assertEquals(100, newObj.val); + } + + /** + * Class for nested execution test. + */ + private static class NestedTestObject implements Serializable { + /** */ + private String str; + + /** */ + private int val; + + /** + * @param str String. + * @param val Value. + */ + private NestedTestObject(String str, int val) { + this.str = str; + this.val = val; + } + + /** {@inheritDoc} */ + private void writeObject(ObjectOutputStream out) throws IOException { + try { + byte[] arr = marshal(str); + + out.writeInt(arr.length); + out.write(arr); + + out.writeInt(val); + } + catch (IgniteCheckedException e) { + throw new IOException(e); + } + } + + /** {@inheritDoc} */ + @SuppressWarnings("UnusedParameters") + private void readObject(ObjectInputStream in) throws IOException { + try { + byte[] arr = new byte[in.readInt()]; + + in.read(arr); + + str = unmarshal(arr); + + val = in.readInt(); + } + catch (IgniteCheckedException e) { + throw new IOException(e); + } + } + } + + /** */ + private static class TestObject2 { + /** */ + private final int i; + + /** + * Constructor for TestObject2 instances. + * + * @param i Integer value to hold. + */ + private TestObject2(int i) { + this.i = i; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + return i == ((TestObject2)o).i; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return i; + } + } + + /** + * Static nested class. + */ + private static class TestObject { + /** */ + private final TestObject2 o2; + + /** The only meaningful field in the class, used for {@link #equals(Object o)} and {@link #hashCode()}. */ + private final String str; + + /** + * @param str String to hold. + * @param i Integer. + */ + TestObject(String str, int i) { + this.str = str; + + o2 = new TestObject2(i); + } + + /** + * Method for accessing value of the hold string after the object is created. + * + * @return Wrapped string. + */ + public String string() { + return str; + } + + /** + * @return Object held in this wrapped. + */ + public TestObject2 obj() { + return o2; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return 31 * o2.hashCode() + str.hashCode(); + } + + /** {@inheritDoc} */ + @SuppressWarnings("RedundantIfStatement") + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || getClass() != o.getClass()) + return false; + + TestObject obj = (TestObject)o; + + if (o2 != null ? !o2.equals(obj.o2) : obj.o2 != null) + return false; + + if (str != null ? !str.equals(obj.str) : obj.str != null) + return false; + + return true; + } + } + + /** + * Static nested class. + */ + private static class SelfLink extends TestObject { + /** */ + private SelfLink link; + + /** + * @param str String to hold. + */ + SelfLink(String str) { + super(str, 1); + } + + /** + * @return The object this link points to,. + */ + public SelfLink link() { + return link; + } + + /** + * @param link The object this link should points to, + */ + public void link(SelfLink link) { + this.link = link; + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerSerialPersistentFieldsSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerSerialPersistentFieldsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerSerialPersistentFieldsSelfTest.java new file mode 100644 index 0000000..5a9d10c --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerSerialPersistentFieldsSelfTest.java @@ -0,0 +1,116 @@ +/* + * 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.marshaller.optimized; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamField; +import java.io.Serializable; + +import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller; +import org.apache.ignite.marshaller.GridMarshallerAbstractTest; +import org.apache.ignite.marshaller.Marshaller; + +/** + * Test that Optimized Marshaller works with classes with serialPersistentFields. + */ +public class OptimizedMarshallerSerialPersistentFieldsSelfTest extends GridMarshallerAbstractTest { + /** {@inheritDoc} */ + @Override protected Marshaller marshaller() { + return new OptimizedMarshaller(false); + } + + /** + * @throws Exception If failed. + */ + public void testOptimizedMarshaller() throws Exception { + unmarshal(marshal(new TestClass())); + + TestClass2 val = unmarshal(marshal(new TestClass2())); + + assertNull(val.field3); + } + + /** + * Test class with serialPersistentFields fields. + */ + private static class TestClass implements Serializable { + private static final long serialVersionUID = 0L; + + /** For serialization compatibility. */ + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField("field1", Integer.TYPE), + new ObjectStreamField("field2", Integer.TYPE) + }; + + /** + * @param s Object output stream. + */ + private void writeObject(ObjectOutputStream s) throws IOException { + s.putFields().put("field1", 1); + s.putFields().put("field2", 2); + s.writeFields(); + + s.writeObject(null); + } + + /** + * @param s Object input stream. + */ + private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { + s.defaultReadObject(); + + s.readObject(); + } + } + + /** + * Test class with serialPersistentFields fields. + */ + private static class TestClass2 implements Serializable { + private static final long serialVersionUID = 0L; + + private Integer field3 = 1; + + /** For serialization compatibility. */ + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField("field1", Integer.TYPE), + new ObjectStreamField("field2", Integer.TYPE) + }; + + /** + * @param s Object output stream. + */ + private void writeObject(ObjectOutputStream s) throws IOException { + s.putFields().put("field1", 1); + s.putFields().put("field2", 2); + s.writeFields(); + + s.writeObject(null); + } + + /** + * @param s Object input stream. + */ + private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { + s.defaultReadObject(); + + s.readObject(); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/a1b5b8c3/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerTest.java b/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerTest.java new file mode 100644 index 0000000..2698042 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerTest.java @@ -0,0 +1,790 @@ +/* + * 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.marshaller.optimized; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.io.Serializable; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.net.InetSocketAddress; +import java.util.Arrays; +import java.util.Collection; +import java.util.concurrent.ConcurrentMap; +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.compute.ComputeJobAdapter; +import org.apache.ignite.compute.ComputeTask; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.marshaller.GridMarshallerTestInheritedBean; +import org.apache.ignite.marshaller.Marshaller; +import org.apache.ignite.marshaller.MarshallerContextTestImpl; +import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder; +import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinderAdapter; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.jetbrains.annotations.Nullable; + +/** + * + */ +public class OptimizedMarshallerTest extends GridCommonAbstractTest { + /** + * @return Marshaller. + */ + private OptimizedMarshaller marshaller() { + U.clearClassCache(); + + OptimizedMarshaller marsh = new OptimizedMarshaller(); + + marsh.setContext(new MarshallerContextTestImpl()); + + return marsh; + } + + /** + * Tests ability to marshal non-serializable objects. + * + * @throws IgniteCheckedException If marshalling failed. + */ + public void testNonSerializable() throws IgniteCheckedException { + OptimizedMarshaller marsh = marshaller(); + + marsh.setRequireSerializable(false); + + NonSerializable outObj = marsh.unmarshal(marsh.marshal(new NonSerializable(null)), null); + + outObj.checkAfterUnmarshalled(); + } + + /** + * Tests ability to marshal non-serializable objects. + * + * @throws IgniteCheckedException If marshalling failed. + */ + public void testNonSerializable1() throws IgniteCheckedException { + OptimizedMarshaller marsh = marshaller(); + + marsh.setRequireSerializable(false); + + byte[] bytes = marsh.marshal(new TcpDiscoveryVmIpFinder()); + + TcpDiscoveryIpFinder ipFinder = marsh.unmarshal(bytes, null); + + assertFalse(ipFinder.isShared()); + + ipFinder = marsh.unmarshal(marsh.marshal(new TcpDiscoveryVmIpFinder(true)), null); + + assertTrue(ipFinder.isShared()); + } + + /** + * Tests ability to marshal non-serializable objects. + * + * @throws IgniteCheckedException If marshalling failed. + */ + public void testNonSerializable2() throws IgniteCheckedException { + OptimizedMarshaller marsh = marshaller(); + + marsh.setRequireSerializable(false); + + TcpDiscoveryIpFinderAdapter ipFinder = new TcpDiscoveryIpFinderAdapter() { + @Override public Collection<InetSocketAddress> getRegisteredAddresses() { + return null; + } + + @Override public void registerAddresses(Collection<InetSocketAddress> addrs) { + //No-op. + } + + @Override public void unregisterAddresses(Collection<InetSocketAddress> addrs) { + //No-op. + } + }; + + ipFinder.setShared(false); + + byte[] bytes = marsh.marshal(ipFinder); + + ipFinder = marsh.unmarshal(bytes, null); + + assertFalse(ipFinder.isShared()); + } + + /** + * Tests ability to marshal non-serializable objects. + * + * @throws IgniteCheckedException If marshalling failed. + */ + public void testNonSerializable3() throws IgniteCheckedException { + OptimizedMarshaller marsh = marshaller(); + + marsh.setRequireSerializable(false); + + byte[] bytes = marsh.marshal(new TestTcpDiscoveryIpFinderAdapter()); + + TcpDiscoveryIpFinder ipFinder = marsh.unmarshal(bytes, null); + + assertFalse(ipFinder.isShared()); + } + + /** + * Tests ability to marshal non-serializable objects. + * + * @throws IgniteCheckedException If marshalling failed. + */ + public void testNonSerializable4() throws IgniteCheckedException { + OptimizedMarshaller marsh = marshaller(); + + marsh.setRequireSerializable(false); + + byte[] bytes = marsh.marshal(new GridMarshallerTestInheritedBean()); + + info(Arrays.toString(bytes)); + + GridMarshallerTestInheritedBean bean = marsh.unmarshal(bytes, null); + + assertTrue(bean.isFlag()); + } + + /** + * Tests ability to marshal non-serializable objects. + * + * @throws IgniteCheckedException If marshalling failed. + */ + public void testNonSerializable5() throws IgniteCheckedException { + Marshaller marsh = marshaller(); + + byte[] bytes = marsh.marshal(true); + + Boolean val = marsh.unmarshal(bytes, null); + + assertTrue(val); + } + + /** + * Tests ability to marshal serializable objects. + * + * @throws IgniteCheckedException If marshalling failed. + */ + public void testSerializable() throws IgniteCheckedException { + Marshaller marsh = marshaller(); + + SomeSerializable outObj = marsh.unmarshal(marsh.marshal(new SomeSerializable(null)), null); + + outObj.checkAfterUnmarshalled(); + } + + /** + * @throws IgniteCheckedException If failed. + */ + public void testSerializableAfterChangingValue() throws IgniteCheckedException { + Marshaller marsh = marshaller(); + + SomeSimpleSerializable newObj = new SomeSimpleSerializable(); + + assert(newObj.flag); + + newObj.setFlagValue(false); + + assert(! newObj.flag); + + SomeSimpleSerializable outObj = marsh.unmarshal(marsh.marshal(newObj), null); + + assert (! outObj.flag); + } + + /** + * Tests ability to marshal externalizable objects. + * + * @throws IgniteCheckedException If marshalling failed. + */ + public void testExternalizable() throws IgniteCheckedException { + Marshaller marsh = marshaller(); + + ExternalizableA outObj = marsh.unmarshal(marsh.marshal(new ExternalizableA(null, true)), null); + ExternalizableA outObj1 = marsh.unmarshal(marsh.marshal(new ExternalizableA(null, false)), null); + + assertNotNull(outObj); + assertNotNull(outObj1); + } + + /** + * Tests {@link OptimizedMarshaller#setRequireSerializable(boolean)}. + */ + public void testRequireSerializable() { + OptimizedMarshaller marsh = marshaller(); + + marsh.setRequireSerializable(true); + + try { + marsh.marshal(new NonSerializable(null)); + + fail(); + } + catch (IgniteCheckedException ignore) { + // No-op. + } + } + + /** + * Tests {@link Proxy}. + * + * @throws IgniteCheckedException If marshalling failed. + */ + public void testProxy() throws IgniteCheckedException { + OptimizedMarshaller marsh = marshaller(); + + marsh.setRequireSerializable(false); + + SomeItf inItf = (SomeItf)Proxy.newProxyInstance( + OptimizedMarshallerTest.class.getClassLoader(), new Class[] {SomeItf.class}, + new InvocationHandler() { + private NonSerializable obj = new NonSerializable(null); + + @Override public Object invoke(Object proxy, Method mtd, Object[] args) throws Throwable { + obj.checkAfterUnmarshalled(); + + return 17; + } + } + ); + + SomeItf outItf = marsh.unmarshal(marsh.marshal(inItf), null); + + assertEquals(outItf.checkAfterUnmarshalled(), 17); + } + + /** + * @throws Exception If failed. + */ + public void testDescriptorCache() throws Exception { + try { + Ignite ignite = startGridsMultiThreaded(2); + + String taskClsName = "org.apache.ignite.tests.p2p.SingleSplitTestTask"; + String jobClsName = "org.apache.ignite.tests.p2p.SingleSplitTestTask$SingleSplitTestJob"; + + ClassLoader ldr = getExternalClassLoader(); + + Class<? extends ComputeTask<?, ?>> taskCls = (Class<? extends ComputeTask<?, ?>>)ldr.loadClass(taskClsName); + Class<? extends ComputeTask<?, ?>> jobCls = (Class<? extends ComputeTask<?, ?>>)ldr.loadClass(jobClsName); + + ignite.compute().localDeployTask(taskCls, ldr); + + ignite.compute().execute(taskClsName, 2); + + ConcurrentMap<Class<?>, OptimizedClassDescriptor> cache = + U.field(ignite.configuration().getMarshaller(), "clsMap"); + + assertTrue(cache.containsKey(jobCls)); + + ignite.compute().undeployTask(taskClsName); + + // Wait for undeploy. + Thread.sleep(1000); + + assertFalse(cache.containsKey(jobCls)); + } + finally { + stopAllGrids(); + } + } + + /** + * @throws Exception If failed. + */ + public void testPerformance() throws Exception { + System.gc(); + + checkPerformance(10000, 4); + } + + /** + * @param cnt Number of marshalling attempts. + * @param tries Number of retries. + * @throws Exception If failed. + */ + private void checkPerformance(int cnt, int tries) throws Exception { + Marshaller marsh = marshaller(); + + for (int j = 0; j < tries; j++) { + System.gc(); + + long start = System.currentTimeMillis(); + + for (int i = 0; i < cnt; i++) { + TestCacheKey key = new TestCacheKey("key", "id"); + + TestCacheKey outKey = marsh.unmarshal(marsh.marshal(key), null); + + assert key.equals(outKey); + assert key.hashCode() == outKey.hashCode(); + } + + info("Time non-serializable: " + (System.currentTimeMillis() - start)); + + System.gc(); + + start = System.currentTimeMillis(); + + for (int i = 0; i < cnt; i++) { + TestCacheKeySerializable key1 = new TestCacheKeySerializable("key", "id"); + + TestCacheKeySerializable outKey = marsh.unmarshal(marsh.marshal(key1), null); + + assert key1.equals(outKey); + assert key1.hashCode() == outKey.hashCode(); + } + + info("Time serializable: " + (System.currentTimeMillis() - start)); + + System.gc(); + + start = System.currentTimeMillis(); + + for (int i = 0; i < cnt; i++) { + TestCacheKeyExternalizable key2 = new TestCacheKeyExternalizable("key", "id"); + + TestCacheKeyExternalizable outKey = marsh.unmarshal(marsh.marshal(key2), null); + + assert key2.equals(outKey); + assert key2.hashCode() == outKey.hashCode(); + } + + info("Time externalizable: " + (System.currentTimeMillis() - start)); + + info(">>>"); + } + + info(">>> Finished performance check <<<"); + } + + /** + * Some non-serializable class. + */ + @SuppressWarnings( {"PublicField","TransientFieldInNonSerializableClass","FieldMayBeStatic"}) + private static class NonSerializableA { + /** */ + private final long longVal = 0x33445566778899AAL; + + /** */ + protected Short shortVal = (short)0xAABB; + + /** */ + public String[] strArr = {"AA","BB"}; + + /** */ + public boolean flag1 = true; + + /** */ + public boolean flag2; + + /** */ + public Boolean flag3; + + /** */ + public Boolean flag4 = true; + + /** */ + public Boolean flag5 = false; + + /** */ + private transient int intVal = 0xAABBCCDD; + + /** + * @param strArr Array. + * @param shortVal Short value. + */ + @SuppressWarnings( {"UnusedDeclaration"}) + private NonSerializableA(@Nullable String[] strArr, @Nullable Short shortVal) { + // No-op. + } + + /** + * Checks correctness of the state after unmarshalling. + */ + void checkAfterUnmarshalled() { + assertEquals(longVal, 0x33445566778899AAL); + + assertEquals(shortVal.shortValue(), (short)0xAABB); + + assertTrue(Arrays.equals(strArr, new String[] {"AA","BB"})); + + assertEquals(intVal, 0); + + assertTrue(flag1); + assertFalse(flag2); + assertNull(flag3); + assertTrue(flag4); + assertFalse(flag5); + } + } + + /** + * Some non-serializable class. + */ + @SuppressWarnings( {"PublicField","TransientFieldInNonSerializableClass","PackageVisibleInnerClass"}) + static class NonSerializableB extends NonSerializableA { + /** */ + public Short shortVal = 0x1122; + + /** */ + public long longVal = 0x8877665544332211L; + + /** */ + private transient NonSerializableA[] aArr = { + new NonSerializableA(null, null), + new NonSerializableA(null, null), + new NonSerializableA(null, null) + }; + + /** */ + protected Double doubleVal = 123.456; + + /** + * Just to eliminate the default constructor. + */ + private NonSerializableB() { + super(null, null); + } + + /** + * Checks correctness of the state after unmarshalling. + */ + @Override void checkAfterUnmarshalled() { + super.checkAfterUnmarshalled(); + + assertEquals(shortVal.shortValue(), 0x1122); + + assertEquals(longVal, 0x8877665544332211L); + + assertNull(aArr); + + assertEquals(doubleVal, 123.456); + } + } + + /** + * Some non-serializable class. + */ + @SuppressWarnings( {"TransientFieldInNonSerializableClass","PublicField"}) + private static class NonSerializable extends NonSerializableB { + /** */ + private int idVal = -17; + + /** */ + private final NonSerializableA aVal = new NonSerializableB(); + + /** */ + private transient NonSerializableB bVal = new NonSerializableB(); + + /** */ + private NonSerializableA[] bArr = new NonSerializableA[] { + new NonSerializableB(), + new NonSerializableA(null, null) + }; + + /** */ + public float floatVal = 567.89F; + + /** + * Just to eliminate the default constructor. + * + * @param aVal Unused. + */ + @SuppressWarnings( {"UnusedDeclaration"}) + private NonSerializable(NonSerializableA aVal) { + } + + /** + * Checks correctness of the state after unmarshalling. + */ + @Override void checkAfterUnmarshalled() { + super.checkAfterUnmarshalled(); + + assertEquals(idVal, -17); + + aVal.checkAfterUnmarshalled(); + + assertNull(bVal); + + for (NonSerializableA a : bArr) { + a.checkAfterUnmarshalled(); + } + + assertEquals(floatVal, 567.89F); + } + } + + /** + * Some serializable class. + */ + @SuppressWarnings( {"PublicField","TransientFieldInNonSerializableClass","PackageVisibleInnerClass"}) + static class ForSerializableB { + /** */ + public Short shortVal = 0x1122; + + /** */ + public long longVal = 0x8877665544332211L; + + /** */ + private transient NonSerializableA[] aArr; + + /** */ + private transient String strVal = "abc"; + + /** */ + protected Double doubleVal = 123.456; + + /** + */ + protected void init() { + shortVal = 0x1122; + + longVal = 0x8877665544332211L; + + aArr = new NonSerializableA[] { + new NonSerializableA(null, null), + new NonSerializableA(null, null), + new NonSerializableA(null, null) + }; + } + + /** + * Checks correctness of the state after unmarshalling. + */ + void checkAfterUnmarshalled() { + assertEquals(shortVal.shortValue(), 0x1122); + + assertEquals(longVal, 0x8877665544332211L); + + assertNull(aArr); + + assertNull(strVal); + + assertEquals(doubleVal, 123.456); + } + } + + /** + * Some serializable class. + */ + private static class SomeSimpleSerializable extends ComputeJobAdapter { + /** */ + private boolean flag = true; + + /** + * @param newFlagVal - The new value of flag field. + */ + public void setFlagValue(boolean newFlagVal) { + flag = newFlagVal; + } + + /** {@inheritDoc} */ + @Override public Object execute() { + assert false; + + return null; + } + } + /** + * Some serializable class. + */ + private static class SomeSerializable extends ForSerializableB implements Serializable { + /** + * Just to eliminate the default constructor. + * + * @param id Unused. + */ + @SuppressWarnings( {"UnusedDeclaration"}) + private SomeSerializable(Long id) { + init(); + } + } + + /** + */ + private static interface SomeItf { + /** + * @return Check result. + */ + int checkAfterUnmarshalled(); + } + + /** + * Some externalizable class. + */ + @SuppressWarnings( {"UnusedDeclaration", "PublicField"}) + private static class ExternalizableA implements Externalizable { + /** */ + private boolean boolVal; + + /** */ + public String[] strArr; + + /** No-arg constructor is required by externalization. */ + public ExternalizableA() { + // No-op. + } + + /** + * + * @param strArr String array. + * @param boolVal Boolean value. + */ + private ExternalizableA(String[] strArr, boolean boolVal) { + this.strArr = strArr; + this.boolVal = boolVal; + } + + /** {@inheritDoc} */ + @Override public void writeExternal(ObjectOutput out) throws IOException { + out.writeBoolean(false); + out.writeBoolean(false); + out.writeBoolean(false); + out.writeBoolean(false); + out.writeBoolean(false); + out.writeBoolean(false); + } + + /** {@inheritDoc} */ + @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + boolVal = in.readBoolean(); + in.readBoolean(); + in.readBoolean(); + in.readBoolean(); + in.readBoolean(); + in.readBoolean(); + } + } + + /** + * + */ + private static class TestCacheKey implements Serializable { + /** */ + private String key; + + /** */ + @SuppressWarnings({"UnusedDeclaration"}) + private String terminalId; + + /** + * @param key Key. + * @param terminalId Some ID. + */ + TestCacheKey(String key, String terminalId) { + this.key = key; + this.terminalId = terminalId; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return key.hashCode(); + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object obj) { + return obj instanceof TestCacheKey && key.equals(((TestCacheKey)obj).key); + } + } + + /** + * + */ + private static class TestCacheKeySerializable implements Serializable { + /** */ + private String key; + + /** */ + @SuppressWarnings({"UnusedDeclaration"}) + private String terminalId; + + /** + * @param key Key. + * @param terminalId Some ID. + */ + TestCacheKeySerializable(String key, String terminalId) { + this.key = key; + this.terminalId = terminalId; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return key.hashCode(); + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object obj) { + return obj instanceof TestCacheKeySerializable && key.equals(((TestCacheKeySerializable)obj).key); + } + } + + /** + * + */ + private static class TestCacheKeyExternalizable implements Externalizable { + /** */ + private String key; + + /** */ + private String terminalId; + + /** + * + */ + public TestCacheKeyExternalizable() { + // No-op. + } + + /** + * @param key Key. + * @param terminalId Some ID. + */ + TestCacheKeyExternalizable(String key, String terminalId) { + this.key = key; + this.terminalId = terminalId; + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return key.hashCode(); + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object obj) { + return obj instanceof TestCacheKeyExternalizable && key.equals(((TestCacheKeyExternalizable)obj).key); + } + + /** {@inheritDoc} */ + @Override public void writeExternal(ObjectOutput out) throws IOException { + U.writeString(out, key); + U.writeString(out, terminalId); + } + + /** {@inheritDoc} */ + @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + key = U.readString(in); + terminalId = U.readString(in); + } + } +} \ No newline at end of file
