]> git.basschouten.com Git - openhab-addons.git/commitdiff
[knx] Increase test coverage (#16511)
authorHolger Friedrich <mail@holger-friedrich.de>
Sat, 16 Mar 2024 10:51:53 +0000 (11:51 +0100)
committerGitHub <noreply@github.com>
Sat, 16 Mar 2024 10:51:53 +0000 (11:51 +0100)
Signed-off-by: Holger Friedrich <mail@holger-friedrich.de>
bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/dpt/ValueDecoder.java
bundles/org.openhab.binding.knx/src/test/java/org/openhab/binding/knx/internal/dpt/DPTTest.java
bundles/org.openhab.binding.knx/src/test/java/org/openhab/binding/knx/internal/i18n/KNXTranslationProviderTest.java
bundles/org.openhab.binding.knx/src/test/java/org/openhab/binding/knx/internal/itests/Back2BackTest.java

index 1d3109b8a50f3ef1cb05cb4463044e81f66086d4..757d48ec6d5f87773b2d6dae9e03ae045ace3f8d 100644 (file)
@@ -231,7 +231,8 @@ public class ValueDecoder {
         } catch (NumberFormatException | KNXFormatException | KNXIllegalArgumentException | ParseException e) {
             LOGGER.info("Translator couldn't parse data '{}' for datapoint type '{}' ({}).", data, dptId, e.getClass());
         } catch (KNXException e) {
-            LOGGER.warn("Failed creating a translator for datapoint type '{}'.", dptId, e);
+            // should never happen unless Calimero changes
+            LOGGER.warn("Failed creating a translator for datapoint type '{}'. Please open an issue.", dptId, e);
         }
 
         return null;
@@ -280,7 +281,8 @@ public class ValueDecoder {
             case "008":
                 return translator3BitControlled.getControlBit() ? UpDownType.DOWN : UpDownType.UP;
             default:
-                LOGGER.warn("DPT3, subtype '{}' is unknown.", subType);
+                // should never happen unless Calimero introduces new subtypes
+                LOGGER.warn("DPT3, subtype '{}' is unknown. Please open an issue.", subType);
                 return null;
         }
     }
@@ -324,7 +326,12 @@ public class ValueDecoder {
         if (translatorDateTime.isValidField(DPTXlatorDateTime.YEAR)
                 && !translatorDateTime.isValidField(DPTXlatorDateTime.TIME)) {
             // Pure date format, no time information
-            cal.setTimeInMillis(translatorDateTime.getValueMilliseconds());
+            try {
+                cal.setTimeInMillis(translatorDateTime.getValueMilliseconds());
+            } catch (KNXFormatException e) {
+                LOGGER.debug("KNX clock msg ignored: {}", e.getMessage());
+                throw e;
+            }
             String value = new SimpleDateFormat(DateTimeType.DATE_PATTERN).format(cal.getTime());
             return DateTimeType.valueOf(value);
         } else if (!translatorDateTime.isValidField(DPTXlatorDateTime.YEAR)
index d20b550472449b0c06fbae8cfc4d5974bb2b31c5..8c1fbde69be09f9b0a186b5e29fd564ba395f71f 100644 (file)
@@ -26,14 +26,18 @@ import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.MethodSource;
+import org.openhab.binding.knx.internal.itests.Back2BackTest;
 import org.openhab.core.library.types.DateTimeType;
 import org.openhab.core.library.types.DecimalType;
 import org.openhab.core.library.types.HSBType;
+import org.openhab.core.library.types.IncreaseDecreaseType;
 import org.openhab.core.library.types.QuantityType;
 import org.openhab.core.library.types.StringType;
 import org.openhab.core.library.unit.SIUnits;
 import org.openhab.core.library.unit.Units;
 import org.openhab.core.util.ColorUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import tuwien.auto.calimero.dptxlator.DPTXlator2ByteUnsigned;
 import tuwien.auto.calimero.dptxlator.DPTXlator4ByteFloat;
@@ -50,6 +54,13 @@ import tuwien.auto.calimero.dptxlator.DptXlator2ByteSigned;
  */
 @NonNullByDefault
 class DPTTest {
+    public static final Logger LOGGER = LoggerFactory.getLogger(Back2BackTest.class);
+
+    @Test
+    void testDptBroken() {
+        assertNull(ValueEncoder.encode(new DecimalType(), "9.042.1"));
+        assertNotNull(DPTUtil.getAllowedTypes("9.042.1"));
+    }
 
     @Test
     void testToDPTValueTrailingZeroesStrippedOff() {
@@ -62,6 +73,21 @@ class DPTTest {
         assertEquals("23.1", ValueEncoder.encode(new DecimalType("23.1"), "9.001"));
     }
 
+    @Test
+    public void dpt1Value() {
+        // unknown subtype
+        assertNull(ValueDecoder.decode("1.091", new byte[] { 0 }, DecimalType.class));
+        assertNotNull(ValueEncoder.encode(new DecimalType(), "1.001"));
+    }
+
+    @Test
+    public void dpt3Value() {
+        // unknown subtype
+        assertNull(ValueDecoder.decode("3.042", new byte[] { 0 }, IncreaseDecreaseType.class));
+        assertNotNull(ValueEncoder.encode(new HSBType(), "5.003"));
+        assertNotNull(ValueEncoder.encode(new HSBType(), "5.001"));
+    }
+
     @Test
     void testToDPT5ValueFromQuantityType() {
         assertEquals("80", ValueEncoder.encode(new QuantityType<>("80 %"), "5.001"));
@@ -72,6 +98,22 @@ class DPTTest {
         assertEquals("80", ValueEncoder.encode(new QuantityType<>("80 %"), "5.004"));
     }
 
+    @Test
+    public void dpt6Value() {
+        assertEquals("42", ValueEncoder.encode(new DecimalType(42), "6.001"));
+
+        assertEquals("42", ValueEncoder.encode(new DecimalType(42), "6.010"));
+
+        assertEquals("0/0/0/0/1 0", Objects.toString(ValueDecoder.decode("6.020", new byte[] { 9 }, StringType.class)));
+        assertEquals("0/0/0/0/0 1", Objects.toString(ValueDecoder.decode("6.020", new byte[] { 2 }, StringType.class)));
+        assertEquals("1/1/1/1/1 2",
+                Objects.toString(ValueDecoder.decode("6.020", new byte[] { (byte) 0xfc }, StringType.class)));
+        assertEquals("0/0/0/0/1 0", ValueEncoder.encode(StringType.valueOf("0/0/0/0/1 0"), "6.020"));
+
+        // unknown subtype
+        assertNull(ValueDecoder.decode("6.200", new byte[] { 0 }, IncreaseDecreaseType.class));
+    }
+
     @Test
     void testToDPT7ValueFromQuantityType() {
         assertEquals("1000", ValueEncoder.encode(new QuantityType<>("1000 ms"), "7.002"));
@@ -155,6 +197,11 @@ class DPTTest {
         assertEquals("10", ValueEncoder.encode(new QuantityType<>("10 km/h"), "9.028"));
         assertEquals("1", ValueEncoder.encode(new QuantityType<>("1 g/m³"), "9.029"));
         assertEquals("1", ValueEncoder.encode(new QuantityType<>("1 µg/m³"), "9.030"));
+
+        // w/o unit
+        ValueEncoder.encode(new QuantityType<>("1"), "9.030");
+        // wrong unit
+        ValueEncoder.encode(new QuantityType<>("1 kg"), "9.030");
     }
 
     @Test
@@ -297,6 +344,30 @@ class DPTTest {
     void testToDPT19ValueFromQuantityType() {
         // DateTimeType, not QuantityType
         assertEquals("2019-06-12 17:30:00", ValueEncoder.encode(new DateTimeType("2019-06-12T17:30:00Z"), "19.001"));
+        // special: clock fault
+        assertNull(ValueDecoder.decode("19.001", new byte[] { (byte) (2019 - 1900), 1, 15, 17, 30, 0, (byte) 0x80, 0 },
+                DateTimeType.class));
+        // special: no year, but month/day
+        assertNull(ValueDecoder.decode("19.001", new byte[] { (byte) (2019 - 1900), 1, 15, 17, 30, 0, (byte) 0x10, 0 },
+                DateTimeType.class));
+        // special: no day, but year
+        assertNull(ValueDecoder.decode("19.001", new byte[] { (byte) (2019 - 1900), 1, 15, 17, 30, 0, (byte) 0x08, 0 },
+                DateTimeType.class));
+        // special: no date, no time, no year
+        assertNull(ValueDecoder.decode("19.001", new byte[] { (byte) (2019 - 1900), 1, 15, 17, 30, 0, (byte) 0x1A, 0 },
+                DateTimeType.class));
+        // special: no time, but year etc. -> works if weekday is matching
+        assertNotNull(ValueDecoder.decode("19.001",
+                new byte[] { (byte) (2019 - 1900), 1, 15, 0x51, 30, 0, (byte) 0x02, 0 }, DateTimeType.class));
+        // special: no time, but year etc. -> weekday is not matching
+        assertNull(ValueDecoder.decode("19.001", new byte[] { (byte) (2019 - 1900), 1, 15, 17, 30, 0, (byte) 0x02, 0 },
+                DateTimeType.class));
+        // special: no time, no year
+        assertNull(ValueDecoder.decode("19.001", new byte[] { (byte) (2019 - 1900), 1, 15, 17, 30, 0, (byte) 0x12, 0 },
+                DateTimeType.class));
+        // special: no date, no year
+        assertNotNull(ValueDecoder.decode("19.001",
+                new byte[] { (byte) (2019 - 1900), 1, 15, 17, 30, 0, (byte) 0x18, 0 }, DateTimeType.class));
     }
 
     @Test
@@ -306,19 +377,6 @@ class DPTTest {
         assertEquals("42", ValueEncoder.encode(new QuantityType<>("42 varh"), "29.012"));
     }
 
-    @Test
-    public void dpt6Value() {
-        assertEquals("42", ValueEncoder.encode(new DecimalType(42), "6.001"));
-
-        assertEquals("42", ValueEncoder.encode(new DecimalType(42), "6.010"));
-
-        assertEquals("0/0/0/0/1 0", Objects.toString(ValueDecoder.decode("6.020", new byte[] { 9 }, StringType.class)));
-        assertEquals("0/0/0/0/0 1", Objects.toString(ValueDecoder.decode("6.020", new byte[] { 2 }, StringType.class)));
-        assertEquals("1/1/1/1/1 2",
-                Objects.toString(ValueDecoder.decode("6.020", new byte[] { (byte) 0xfc }, StringType.class)));
-        assertEquals("0/0/0/0/1 0", ValueEncoder.encode(StringType.valueOf("0/0/0/0/1 0"), "6.020"));
-    }
-
     @Test
     public void dpt232RgbValue() {
         // input data
@@ -374,6 +432,18 @@ class DPTTest {
         byte[] negativeEnergy = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00,
                 (byte) 0x02 };
         assertEquals(new QuantityType<>("-1 Wh"), ValueDecoder.decode("235.001", negativeEnergy, QuantityType.class));
+
+        // invalid frame size
+        byte[] frameSizeTooSmall = new byte[] {};
+        assertNull(ValueDecoder.decode("235.001", frameSizeTooSmall, DecimalType.class));
+        assertNull(ValueDecoder.decode("235.001", frameSizeTooSmall, QuantityType.class));
+        assertNull(ValueDecoder.decode("235.61001", frameSizeTooSmall, DecimalType.class));
+        assertNull(ValueDecoder.decode("235.61001", frameSizeTooSmall, QuantityType.class));
+        byte[] frameSizeTooLong = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
+        assertNull(ValueDecoder.decode("235.001", frameSizeTooLong, DecimalType.class));
+        assertNull(ValueDecoder.decode("235.001", frameSizeTooLong, QuantityType.class));
+        assertNull(ValueDecoder.decode("235.61001", frameSizeTooLong, DecimalType.class));
+        assertNull(ValueDecoder.decode("235.61001", frameSizeTooLong, QuantityType.class));
     }
 
     @Test
index 836a84e213ae2cf111189da5851bc150975e0d5e..a24b3bae8635e2653a07b21aa719b71a0cfa78df 100644 (file)
@@ -97,6 +97,7 @@ class KNXTranslationProviderTest {
         final Exception se = new KNXLinkClosedException("connection closed", e);
         assertNotNull(KNXTranslationProvider.I18N.getLocalizedException(e));
         assertNotNull(KNXTranslationProvider.I18N.getLocalizedException(se));
+        assertNotNull(KNXTranslationProvider.I18N.getLocalizedException(new Exception()));
         assertEquals("KNXException, error 1", KNXTranslationProvider.I18N.getLocalizedException(e));
 
         // use mockup classes with known dictionary
index 3d96e7bcfa16c53cabc9b5f14eed3ee40040cdda..8b3cd0446066f48cc3c6d1edc781412421edde80 100644 (file)
@@ -301,7 +301,8 @@ public class Back2BackTest {
     @Test
     void testDpt2() {
         for (int subType = 1; subType <= 12; subType++) {
-            helper("2." + String.format("%03d", subType), new byte[] { 3 }, new DecimalType(3));
+            helper("2." + String.format("%03d", subType), new byte[] { (byte) (subType % 4) },
+                    new DecimalType(subType % 4));
         }
     }