diff --git a/application/src/main/java/org/thingsboard/server/service/install/lts/LtsVersion.java b/application/src/main/java/org/thingsboard/server/service/install/lts/LtsVersion.java new file mode 100644 index 0000000000..f9a38d9aca --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/install/lts/LtsVersion.java @@ -0,0 +1,46 @@ +package org.thingsboard.server.service.install.lts; + +public record LtsVersion(int major, int minor, int maintenance, int patch) implements Comparable { + + public static LtsVersion parse(String version) { + if (version == null) { + throw new IllegalArgumentException("Version is null"); + } + String[] parts = version.split("\\."); + try { + int major = Integer.parseInt(parts[0]); + int minor = parts.length > 1 ? Integer.parseInt(parts[1]) : 0; + int maintenance = parts.length > 2 ? Integer.parseInt(parts[2]) : 0; + int patch = parts.length > 3 ? Integer.parseInt(parts[3]) : 0; + return new LtsVersion(major, minor, maintenance, patch); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Invalid version: " + version, e); + } + } + + public boolean sameFamily(LtsVersion other) { + return major == other.major && minor == other.minor; + } + + @Override + public int compareTo(LtsVersion o) { + int c = Integer.compare(major, o.major); + if (c != 0) { + return c; + } + c = Integer.compare(minor, o.minor); + if (c != 0) { + return c; + } + c = Integer.compare(maintenance, o.maintenance); + if (c != 0) { + return c; + } + return Integer.compare(patch, o.patch); + } + + @Override + public String toString() { + return major + "." + minor + "." + maintenance + "." + patch; + } +} diff --git a/application/src/test/java/org/thingsboard/server/service/install/lts/LtsVersionTest.java b/application/src/test/java/org/thingsboard/server/service/install/lts/LtsVersionTest.java new file mode 100644 index 0000000000..c2db4b448e --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/service/install/lts/LtsVersionTest.java @@ -0,0 +1,63 @@ +package org.thingsboard.server.service.install.lts; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class LtsVersionTest { + + @ParameterizedTest + @CsvSource({ + "4.2.1, 4, 2, 1, 0", + "4.2.0, 4, 2, 0, 0", + "4.2, 4, 2, 0, 0", + "4.0.1.2, 4, 0, 1, 2", + "4, 4, 0, 0, 0", + "10.20.30.40, 10, 20, 30, 40" + }) + void parsesValidVersions(String input, int major, int minor, int maintenance, int patch) { + LtsVersion v = LtsVersion.parse(input); + assertEquals(major, v.major()); + assertEquals(minor, v.minor()); + assertEquals(maintenance, v.maintenance()); + assertEquals(patch, v.patch()); + } + + @ParameterizedTest + @ValueSource(strings = {"invalid", "a.b.c", "1.2.y.x", "1.x.3", ""}) + void throwsOnInvalidVersions(String input) { + assertThrows(IllegalArgumentException.class, () -> LtsVersion.parse(input)); + } + + @Test + void throwsOnNull() { + assertThrows(IllegalArgumentException.class, () -> LtsVersion.parse(null)); + } + + @Test + void comparesByEachComponent() { + assertTrue(LtsVersion.parse("4.2.2.3").compareTo(LtsVersion.parse("4.2.2.2")) > 0); + assertTrue(LtsVersion.parse("4.2.2.0").compareTo(LtsVersion.parse("4.2.1.9")) > 0); + assertTrue(LtsVersion.parse("4.3.0.0").compareTo(LtsVersion.parse("4.2.9.9")) > 0); + assertEquals(0, LtsVersion.parse("4.2.2.3").compareTo(LtsVersion.parse("4.2.2.3"))); + } + + @Test + void sameFamilyComparesMajorAndMinorOnly() { + assertTrue(LtsVersion.parse("4.2.2.3").sameFamily(LtsVersion.parse("4.2.0.0"))); + assertFalse(LtsVersion.parse("4.3.0.0").sameFamily(LtsVersion.parse("4.2.9.9"))); + assertFalse(LtsVersion.parse("5.2.0.0").sameFamily(LtsVersion.parse("4.2.0.0"))); + } + + @Test + void toStringIsFourComponentDotForm() { + assertEquals("4.2.2.3", LtsVersion.parse("4.2.2.3").toString()); + assertEquals("4.2.0.0", LtsVersion.parse("4.2").toString()); + } +}