diff --git a/app/save-and-restore/util/src/main/java/org/phoebus/saveandrestore/util/Utilities.java b/app/save-and-restore/util/src/main/java/org/phoebus/saveandrestore/util/Utilities.java index 082bc4a192..9d6283cc69 100644 --- a/app/save-and-restore/util/src/main/java/org/phoebus/saveandrestore/util/Utilities.java +++ b/app/save-and-restore/util/src/main/java/org/phoebus/saveandrestore/util/Utilities.java @@ -655,13 +655,13 @@ public static VTypeComparison valueToCompareString(VType value, VType baseValue, String str = valueToString(value); boolean b = ((VBoolean) value).getValue(); boolean c = ((VBoolean) baseValue).getValue(); - return new VTypeComparison(str, Boolean.compare(b, c), b == c); + return new VTypeComparison(str, Boolean.compare(b, c), b == c, Math.abs(Boolean.compare(b, c))); } else if (value instanceof VEnum && baseValue instanceof VEnum) { String str = valueToString(value); String b = ((VEnum) value).getValue(); String c = ((VEnum) baseValue).getValue(); int diff = b == null ? (c == null ? 0 : 1) : (c == null ? -1 : b.compareTo(c)); - return new VTypeComparison(str, diff, diff == 0); + return new VTypeComparison(str, diff, diff == 0, Math.abs(diff)); } else if (value instanceof VString && baseValue instanceof VString) { String b = ((VString) value).getValue(); String c = ((VString) baseValue).getValue(); @@ -670,7 +670,7 @@ public static VTypeComparison valueToCompareString(VType value, VType baseValue, } else if (value instanceof VNumberArray && baseValue instanceof VNumberArray) { String sb = valueToString(value); boolean equal = areValuesEqual(value, baseValue, Optional.empty()); - return new VTypeComparison(sb, equal ? 0 : 1, equal); + return new VTypeComparison(sb, equal ? 0 : 1, equal, equal ? 0 : 1); } else { String str = valueToString(value); boolean valuesEqual = areValuesEqual(value, baseValue, Optional.empty()); @@ -970,7 +970,7 @@ public static boolean areValuesEqual(VType v1, VType v2, Optional> if (threshold.isPresent()) { return ((Threshold) threshold.get()).isWithinThreshold(data, base); } - return data.compareTo(base) == 0; + return data == base; } else if (v1 instanceof VLong) { long data = ((VLong) v1).getValue(); long base = ((VNumber) v2).getValue().longValue(); diff --git a/app/save-and-restore/util/src/test/java/org/phoebus/saveandrestore/util/UtilitiesTest.java b/app/save-and-restore/util/src/test/java/org/phoebus/saveandrestore/util/UtilitiesTest.java index 7996343335..73f0a7f7e8 100644 --- a/app/save-and-restore/util/src/test/java/org/phoebus/saveandrestore/util/UtilitiesTest.java +++ b/app/save-and-restore/util/src/test/java/org/phoebus/saveandrestore/util/UtilitiesTest.java @@ -4,14 +4,61 @@ package org.phoebus.saveandrestore.util; -import org.epics.pva.data.*; -import org.epics.util.array.*; -import org.epics.vtype.*; +import org.epics.pva.data.PVABoolArray; +import org.epics.pva.data.PVAByteArray; +import org.epics.pva.data.PVADoubleArray; +import org.epics.pva.data.PVAFloatArray; +import org.epics.pva.data.PVAIntArray; +import org.epics.pva.data.PVALongArray; +import org.epics.pva.data.PVAShortArray; +import org.epics.pva.data.PVAStringArray; +import org.epics.util.array.ArrayBoolean; +import org.epics.util.array.ArrayByte; +import org.epics.util.array.ArrayDouble; +import org.epics.util.array.ArrayFloat; +import org.epics.util.array.ArrayInteger; +import org.epics.util.array.ArrayLong; +import org.epics.util.array.ArrayShort; +import org.epics.util.array.ArrayUByte; +import org.epics.util.array.ArrayUInteger; +import org.epics.util.array.ArrayULong; +import org.epics.util.array.ArrayUShort; +import org.epics.vtype.Alarm; +import org.epics.vtype.AlarmSeverity; +import org.epics.vtype.AlarmStatus; +import org.epics.vtype.Display; +import org.epics.vtype.EnumDisplay; +import org.epics.vtype.Time; +import org.epics.vtype.VBoolean; +import org.epics.vtype.VBooleanArray; +import org.epics.vtype.VByte; +import org.epics.vtype.VByteArray; +import org.epics.vtype.VDouble; +import org.epics.vtype.VDoubleArray; +import org.epics.vtype.VEnum; +import org.epics.vtype.VFloat; +import org.epics.vtype.VFloatArray; +import org.epics.vtype.VInt; +import org.epics.vtype.VIntArray; +import org.epics.vtype.VLong; +import org.epics.vtype.VLongArray; +import org.epics.vtype.VShort; +import org.epics.vtype.VShortArray; +import org.epics.vtype.VString; +import org.epics.vtype.VStringArray; +import org.epics.vtype.VTable; +import org.epics.vtype.VType; +import org.epics.vtype.VUByte; +import org.epics.vtype.VUByteArray; +import org.epics.vtype.VUInt; +import org.epics.vtype.VUIntArray; +import org.epics.vtype.VULong; +import org.epics.vtype.VULongArray; +import org.epics.vtype.VUShort; +import org.epics.vtype.VUShortArray; import org.junit.jupiter.api.Test; import org.phoebus.core.vtypes.VDisconnectedData; import org.phoebus.core.vtypes.VTypeHelper; -import org.phoebus.saveandrestore.util.Threshold; -import org.phoebus.saveandrestore.util.Utilities; import java.time.temporal.ChronoUnit; import java.util.ArrayList; @@ -19,7 +66,15 @@ import java.util.List; import java.util.Optional; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; public class UtilitiesTest { @@ -145,61 +200,61 @@ public void testValueFromString() { VType val = VDouble.of(5d, alarm, time, display); VType result = Utilities.valueFromString("5.0", val); - assertTrue(result instanceof VDouble); + assertInstanceOf(VDouble.class, result); assertEquals(5.0, ((VDouble) result).getValue(), 0); result = Utilities.valueFromString("", val); - assertTrue(result instanceof VDouble); + assertInstanceOf(VDouble.class, result); assertEquals(5.0, ((VDouble) result).getValue(), 0); val = VFloat.of(5f, alarm, time, display); result = Utilities.valueFromString("5.0", val); - assertTrue(result instanceof VFloat); + assertInstanceOf(VFloat.class, result); assertEquals(5.0f, ((VFloat) result).getValue(), 0); val = VLong.of(5L, alarm, time, display); result = Utilities.valueFromString("5", val); - assertTrue(result instanceof VLong); + assertInstanceOf(VLong.class, result); assertEquals(5L, ((VLong) result).getValue().longValue()); val = VULong.of(5L, alarm, time, display); result = Utilities.valueFromString("5", val); - assertTrue(result instanceof VULong); + assertInstanceOf(VULong.class, result); assertEquals(5L, ((VULong) result).getValue().longValue()); val = VUInt.of(5, alarm, time, display); result = Utilities.valueFromString("5", val); - assertTrue(result instanceof VUInt); + assertInstanceOf(VUInt.class, result); assertEquals(5, ((VUInt) result).getValue().intValue()); val = VInt.of(5, alarm, time, display); result = Utilities.valueFromString("5", val); - assertTrue(result instanceof VInt); + assertInstanceOf(VInt.class, result); assertEquals(5, ((VInt) result).getValue().intValue()); val = VShort.of((short) 5, alarm, time, display); result = Utilities.valueFromString("5", val); - assertTrue(result instanceof VShort); + assertInstanceOf(VShort.class, result); assertEquals((short) 5, ((VShort) result).getValue().shortValue()); val = VUShort.of((short) 5, alarm, time, display); result = Utilities.valueFromString("5", val); - assertTrue(result instanceof VUShort); + assertInstanceOf(VUShort.class, result); assertEquals((short) 5, ((VUShort) result).getValue().shortValue()); val = VByte.of((byte) 5, alarm, time, display); result = Utilities.valueFromString("5", val); - assertTrue(result instanceof VByte); + assertInstanceOf(VByte.class, result); assertEquals((byte) 5, ((VByte) result).getValue().byteValue()); val = VUByte.of((byte) 5, alarm, time, display); result = Utilities.valueFromString("5", val); - assertTrue(result instanceof VUByte); + assertInstanceOf(VUByte.class, result); assertEquals((byte) 5, ((VUByte) result).getValue().byteValue()); val = VEnum.of(1, EnumDisplay.of("first", "second", "third"), alarm, time); result = Utilities.valueFromString("second", val); - assertTrue(result instanceof VEnum); + assertInstanceOf(VEnum.class, result); assertEquals("second", ((VEnum) result).getValue()); val = VEnum.of(1, EnumDisplay.of("first", "second", "third"), alarm, time); @@ -212,12 +267,12 @@ public void testValueFromString() { val = VBoolean.of(false, alarm, time); result = Utilities.valueFromString("false", val); - assertTrue(result instanceof VBoolean); + assertInstanceOf(VBoolean.class, result); assertEquals(false, ((VBoolean) result).getValue()); val = VString.of("third", alarm, time); result = Utilities.valueFromString("third", val); - assertTrue(result instanceof VString); + assertInstanceOf(VString.class, result); assertEquals("third", ((VString) result).getValue()); @@ -267,30 +322,30 @@ public void testValueFromString() { val = VStringArray.of(Arrays.asList("first", "second", "third"), alarm, time); result = Utilities.valueFromString("[\"first\", \"second\", \"third\"]", val); - assertTrue(result instanceof VStringArray); + assertInstanceOf(VStringArray.class, result); assertArrayEquals(new String[]{"first", "second", "third"}, ((VStringArray) result).getData().toArray(new String[0])); val = VLongArray.of(ArrayLong.of(1, 2, 3, 4, 5), alarm, time, display); result = Utilities.valueFromString("1, 2, 3, 4, 5", val); - assertTrue(result instanceof VLongArray); + assertInstanceOf(VLongArray.class, result); assertNotNull(((VLongArray) result).getData()); val = VBooleanArray.of(ArrayBoolean.of(true, true, false, true), alarm, time); result = Utilities.valueFromString("[1, 1, 0, 2]", val); - assertTrue(result instanceof VBooleanArray); + assertInstanceOf(VBooleanArray.class, result); assertNotNull(((VBooleanArray) result).getData()); val = VDisconnectedData.INSTANCE; result = Utilities.valueFromString("5", val); - assertTrue(result instanceof VLong); + assertInstanceOf(VLong.class, result); assertEquals(5L, ((VLong) result).getValue().longValue()); result = Utilities.valueFromString("5.1", val); - assertTrue(result instanceof VDouble); + assertInstanceOf(VDouble.class, result); assertEquals(5.1, ((VDouble) result).getValue(), 0); result = Utilities.valueFromString("string", val); - assertTrue(result instanceof VString); + assertInstanceOf(VString.class, result); assertEquals("string", ((VString) result).getValue()); } @@ -499,7 +554,7 @@ public void testValueToCompareString() { assertEquals("[1.0, 2.0, 3.0]", result.getString()); assertNotEquals(0, result.getValuesEqual()); assertFalse(result.isWithinThreshold()); - assertEquals(0, result.getAbsoluteDelta(), 0.0); + assertEquals(1, result.getAbsoluteDelta(), 0.0); //compare long values: equal, first less than second, second less than first val1 = VLong.of(6L, alarm, time, display); @@ -631,7 +686,7 @@ public void testValueToCompareString() { assertEquals("val2", result.getString()); assertTrue(result.getValuesEqual() < 0); assertFalse(result.isWithinThreshold()); - assertEquals(0, result.getAbsoluteDelta(), 0.0); + assertEquals(1, result.getAbsoluteDelta(), 0.0); val1 = VEnum.of(2, labels, alarm, time); val2 = VEnum.of(1, labels, alarm, time); @@ -639,7 +694,7 @@ public void testValueToCompareString() { assertEquals("val3", result.getString()); assertTrue(result.getValuesEqual() > 0); assertFalse(result.isWithinThreshold()); - assertEquals(0, result.getAbsoluteDelta(), 0.0); + assertEquals(1, result.getAbsoluteDelta(), 0.0); val1 = VByte.of((byte) 5, alarm, time, display); val2 = VByte.of((byte) 6, alarm, time, display); @@ -696,6 +751,14 @@ public void testValueToCompareString() { assertTrue(result.isWithinThreshold()); assertEquals(0, result.getAbsoluteDelta(), 0.0); + val1 = VBoolean.of(false, alarm, time); + val2 = VBoolean.of(true, alarm, time); + result = Utilities.valueToCompareString(val1, val2, Optional.empty()); + assertEquals("false", result.getString()); + assertEquals(-1, result.getValuesEqual()); + assertFalse(result.isWithinThreshold()); + assertEquals(1, result.getAbsoluteDelta(), 0.0); + val1 = VString.of("a", alarm, time); val2 = VString.of("b", alarm, time); result = Utilities.valueToCompareString(val1, val2, Optional.empty()); @@ -1555,4 +1618,19 @@ public void testToPVArrayType() { assertArrayEquals(new String[]{"a", "b", "c"}, ((PVAStringArray) converted).get()); assertEquals("strings", ((PVAStringArray) converted).getName()); } + + @Test + public void testSorting() { + VLongArray longs1 = VLongArray.of(ArrayLong.of(-1, 2, 3), Alarm.none(), Time.now(), Display.none()); + VLongArray longs2 = VLongArray.of(ArrayLong.of(1, 2, 3), Alarm.none(), Time.now(), Display.none()); + + Utilities.VTypeComparison vtc1 = Utilities.valueToCompareString(longs1, longs2, Optional.empty()); + + VEnum vEnum1 = VEnum.of(0, EnumDisplay.of("negative", "b"), Alarm.none(), Time.now()); + VEnum vEnum2 = VEnum.of(0, EnumDisplay.of("negative", "b"), Alarm.none(), Time.now()); + + Utilities.VTypeComparison vtc2 = Utilities.valueToCompareString(vEnum1, vEnum2, Optional.empty()); + + assertEquals(1, Double.compare(vtc1.getAbsoluteDelta(), vtc2.getAbsoluteDelta())); + } }