blob: 57b5ff6cd42d22d3b05e68bfd0bb0dbd6cf1a493 [file] [log] [blame]
/*
* 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;
}
}