| /* |
| * 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.lang; |
| |
| import java.io.IOException; |
| import java.net.ConnectException; |
| import java.util.Arrays; |
| import org.apache.ignite.IgniteCheckedException; |
| import org.apache.ignite.IgniteException; |
| import org.apache.ignite.internal.util.typedef.X; |
| import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; |
| import org.apache.ignite.testframework.junits.common.GridCommonTest; |
| import org.junit.Test; |
| |
| /** |
| * Tests for {@link X}. |
| */ |
| @GridCommonTest(group = "Lang") |
| public class GridXSelfTest extends GridCommonAbstractTest { |
| /** |
| * |
| */ |
| @Test |
| public void testHasCause() { |
| ConnectException conEx = new ConnectException(); |
| |
| IOException ioEx = new IOException(conEx); |
| |
| IgniteCheckedException gridEx = new IgniteCheckedException(ioEx); |
| |
| assert X.hasCause(gridEx, IOException.class, NumberFormatException.class); |
| assert !X.hasCause(gridEx, NumberFormatException.class); |
| |
| assert X.cause(gridEx, IOException.class) == ioEx; |
| assert X.cause(gridEx, ConnectException.class) == conEx; |
| assert X.cause(gridEx, NumberFormatException.class) == null; |
| |
| assert gridEx.getCause(IOException.class) == ioEx; |
| assert gridEx.getCause(ConnectException.class) == conEx; |
| assert gridEx.getCause(NumberFormatException.class) == null; |
| } |
| |
| /** |
| * Checks that using function with Throwable that contains circular reference in {@code getSuppressed()} |
| * does not cause {@link StackOverflowError}. |
| */ |
| @Test |
| public void testCauseDoesNotRaiseStackOverflowWhenCircularReferenceInSuppressed() { |
| NullPointerException npe = new NullPointerException(); |
| |
| IOException ioExc = new IOException(npe); |
| |
| IgniteException exc = new IgniteException(ioExc); |
| |
| ioExc.addSuppressed(exc); |
| |
| assertEquals(npe, X.cause(exc, NullPointerException.class)); |
| |
| assertTrue(X.hasCause(exc, NullPointerException.class)); |
| |
| assertNull(X.cause(exc, ArithmeticException.class)); |
| |
| assertFalse(X.hasCause(exc, ArithmeticException.class)); |
| } |
| |
| /** |
| * Checks that using function with Throwable that contains circular reference in {@code getCaused()} |
| * does not cause {@link StackOverflowError}. |
| */ |
| @Test |
| public void testCauseDoesNotRaiseStackOverflowWhenCircularReferenceInCaused() { |
| NullPointerException npe = new NullPointerException(); |
| |
| IOException ioExc = new IOException(npe); |
| |
| IgniteException exc = new IgniteException(ioExc); |
| |
| npe.initCause(exc); |
| |
| assertEquals(npe, X.cause(exc, NullPointerException.class)); |
| |
| assertTrue(X.hasCause(exc, NullPointerException.class)); |
| |
| assertNull(X.cause(exc, ArithmeticException.class)); |
| |
| assertFalse(X.hasCause(exc, ArithmeticException.class)); |
| } |
| |
| /** |
| * Tests string presentation of given time. |
| */ |
| @Test |
| public void testTimeSpan() { |
| assertEquals(X.timeSpan2DHMSM(86400001L), "1 day, 00:00:00.001"); |
| |
| assertEquals(X.timeSpan2DHMSM(172800004L), "2 days, 00:00:00.004"); |
| |
| assertEquals(X.timeSpan2DHMSM(1L), "00:00:00.001"); |
| |
| assertEquals(X.timeSpan2HMSM(172800004L), "00:00:00.004"); |
| } |
| |
| /** |
| * |
| */ |
| @Test |
| public void testShallowClone() { |
| // Single not cloneable object |
| Object obj = new Object(); |
| |
| Object objClone = X.cloneObject(obj, false, true); |
| |
| assert objClone == obj; |
| |
| // Single cloneable object |
| TestCloneable cloneable = new TestCloneable("Some string value"); |
| |
| TestCloneable cloneableClone = X.cloneObject(cloneable, false, true); |
| |
| assert cloneableClone != null; |
| assert cloneableClone != cloneable; |
| assert cloneable.field.equals(cloneableClone.field); |
| |
| // Integer array. |
| int[] intArr = {1, 2, 3}; |
| |
| int[] intArrClone = X.cloneObject(intArr, false, true); |
| |
| assert intArrClone != null; |
| assert intArrClone != intArr; |
| assert Arrays.equals(intArrClone, intArr); |
| |
| // Boolean array. |
| boolean[] boolArr = {true, false, true}; |
| |
| boolean[] boolArrClone = X.cloneObject(boolArr, false, true); |
| |
| assert boolArrClone != null; |
| assert boolArrClone != boolArr; |
| assert Arrays.equals(boolArrClone, boolArr); |
| |
| // String array. |
| String[] strArr = {"str1", "str2", "str3"}; |
| |
| String[] strArrClone = X.cloneObject(strArr, false, true); |
| |
| assert strArrClone != null; |
| assert strArrClone != strArr; |
| assert Arrays.equals(strArrClone, strArr); |
| } |
| |
| /** |
| * |
| */ |
| @SuppressWarnings({"StringEquality"}) |
| @Test |
| public void testDeepCloner() { |
| // Single not cloneable object |
| Object obj = new Object(); |
| |
| Object objClone = X.cloneObject(obj, true, true); |
| |
| assert objClone != null; |
| assert objClone != obj; |
| |
| // Single cloneable object |
| TestCloneable cloneable = new TestCloneable("Some string value"); |
| |
| TestCloneable cloneableClone = X.cloneObject(cloneable, true, false); |
| |
| assert cloneableClone != null; |
| assert cloneableClone != cloneable; |
| assert cloneable.field.equals(cloneableClone.field); |
| assert cloneable.field != cloneableClone.field; |
| |
| // Single cloneable object |
| TestCloneable1 cloneable1 = new TestCloneable1("Some string value"); |
| |
| TestCloneable1 cloneableClone1 = X.cloneObject(cloneable1, true, false); |
| |
| assert cloneableClone1 != null; |
| assert cloneableClone1 != cloneable1; |
| assert cloneable1.field.equals(cloneableClone1.field); |
| assert cloneable1.field != cloneableClone1.field; |
| |
| // Integer array. |
| int[] intArr = {1, 2, 3}; |
| |
| int[] intArrClone = X.cloneObject(intArr, true, false); |
| |
| assert intArrClone != null; |
| assert intArrClone != intArr; |
| assert Arrays.equals(intArrClone, intArr); |
| |
| // Boolean array. |
| boolean[] boolArr = {true, false, true}; |
| |
| boolean[] boolArrClone = X.cloneObject(boolArr, true, false); |
| |
| assert boolArrClone != null; |
| assert boolArrClone != boolArr; |
| assert Arrays.equals(boolArrClone, boolArr); |
| |
| // String array. |
| String[] strArr = {"str1", "str2", "str3"}; |
| |
| String[] strArrClone = X.cloneObject(strArr, true, false); |
| |
| assert strArrClone != null; |
| assert strArrClone != strArr; |
| assert Arrays.equals(strArrClone, strArr); |
| |
| for (int i = 0; i < strArr.length; i++) { |
| assert strArr[i] != strArrClone[i]; |
| assert strArr[i].equals(strArrClone[i]); |
| } |
| |
| // Cycles |
| TestCycled testCycled = new TestCycled(); |
| TestCycled testCycledClone = X.cloneObject(testCycled, true, false); |
| |
| assert testCycledClone != null; |
| assert testCycledClone != testCycled; |
| assert testCycledClone == testCycledClone.cycle; |
| |
| // Cycles and hierarchy |
| TestCycledChild testCycledChild = new TestCycledChild(); |
| TestCycledChild testCycledChildClone = X.cloneObject(testCycledChild, true, false); |
| |
| assert testCycledChildClone != null; |
| assert testCycledChildClone != testCycledChild; |
| assert testCycledChildClone == testCycledChildClone.cycle; |
| assert testCycledChildClone == testCycledChildClone.anotherCycle; |
| |
| // Cloneable honored |
| TestCloneable cloneable2 = new TestCloneable("Some string value"); |
| |
| TestCloneable cloneableClone2 = X.cloneObject(cloneable2, true, true); |
| |
| assert cloneableClone2 != null; |
| assert cloneableClone2 != cloneable2; |
| assert cloneable2.field.equals(cloneableClone2.field); |
| |
| // Try clone class. |
| X.cloneObject(Integer.class, true, true); |
| } |
| |
| /** |
| * Test cloneable class. |
| */ |
| private static class TestCloneable implements Cloneable { |
| /** */ |
| private String field; |
| |
| /** */ |
| @SuppressWarnings({"unused"}) |
| private String field1; |
| |
| /** */ |
| @SuppressWarnings({"unused"}) |
| private final Class cls = Integer.class; |
| |
| /** |
| * @param val Field value. |
| */ |
| private TestCloneable(String val) { |
| field = val; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override protected Object clone() throws CloneNotSupportedException { |
| return super.clone(); |
| } |
| } |
| |
| /** |
| * Test cloneable class. |
| */ |
| private static class TestCloneable1 { |
| /** */ |
| private String field; |
| |
| /** |
| * @param val Field value. |
| */ |
| private TestCloneable1(String val) { |
| field = val; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public int hashCode() { |
| return field.hashCode(); |
| } |
| } |
| |
| /** |
| * Class to test deep cloning with cycles. |
| */ |
| private static class TestCycled { |
| /** */ |
| protected final TestCycled cycle = this; |
| } |
| |
| /** |
| * Class to test hierarchy init. |
| */ |
| private static class TestCycledChild extends TestCycled { |
| /** */ |
| @SuppressWarnings({"unused"}) |
| private final TestCycled anotherCycle = this; |
| } |
| } |