Skip to content

Commit bbdbacd

Browse files
committed
Add comments and fix version range check
1 parent dfb3619 commit bbdbacd

File tree

3 files changed

+191
-9
lines changed

3 files changed

+191
-9
lines changed

src/org/labkey/test/tests/upgrade/BaseUpgradeTest.java

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,33 @@
1010
import org.labkey.test.BaseWebDriverTest;
1111
import org.labkey.test.TestProperties;
1212
import org.labkey.test.util.TestLogger;
13+
import org.labkey.test.util.Version;
14+
import org.labkey.test.util.VersionRange;
1315

16+
import java.lang.annotation.ElementType;
17+
import java.lang.annotation.Retention;
18+
import java.lang.annotation.RetentionPolicy;
19+
import java.lang.annotation.Target;
1420
import java.util.Arrays;
1521
import java.util.List;
16-
22+
import java.util.Optional;
23+
24+
import static org.apache.commons.lang3.StringUtils.trimToNull;
25+
26+
/**
27+
* Base test class for tests that setup data and configure a server then verify the persistence or modification of those
28+
* data and configurations after upgrading to a newer version of LabKey.<br>
29+
* The {@code EariestVersion} and {@code LatestVersion} annotations can be used to skip particular tests when they are
30+
* not relevant to the version of LabKey being upgraded from (specified in the {@code webtest.upgradePreviousVersion}
31+
* system property).<br>
32+
* The setup steps will be skipped if the {@code webtest.upgradeSetup} system property is set to {@code false}.
33+
*/
1734
public abstract class BaseUpgradeTest extends BaseWebDriverTest
1835
{
1936

2037
protected static final boolean isUpgradeSetupPhase = TestProperties.getBooleanProperty("webtest.upgradeSetup", true);
21-
protected static final double previousVersion = TestProperties.getDoubleProperty("webtest.upgradePreviousVersion", 0.0);
38+
protected static final Version previousVersion = Optional.ofNullable(trimToNull(System.getProperty("webtest.upgradePreviousVersion")))
39+
.map(Version::new).orElse(null);
2240

2341
@Override
2442
protected boolean skipCleanup(boolean afterTest)
@@ -52,12 +70,26 @@ public List<String> getAssociatedModules()
5270
return Arrays.asList();
5371
}
5472

73+
/**
74+
* Annotates test methods that should only run when upgrading from particular LabKey versions, as specified in
75+
* {@code webtest.upgradePreviousVersion}.<br>
76+
* Specifies the earliest version of the test class that performed the required setup for the annotated method.
77+
*/
78+
@Retention(RetentionPolicy.RUNTIME)
79+
@Target({ElementType.METHOD})
5580
protected @interface EariestVersion {
56-
double value();
81+
String value();
5782
}
5883

84+
/**
85+
* Annotates test methods that should only run when upgrading from particular LabKey versions, as specified in
86+
* {@code webtest.upgradePreviousVersion}.<br>
87+
* Specifies the latest version of the test class that performed the required setup for the annotated method.
88+
*/
89+
@Retention(RetentionPolicy.RUNTIME)
90+
@Target({ElementType.METHOD})
5991
protected @interface LatestVersion {
60-
double value();
92+
String value();
6193
}
6294

6395
private static class UpgradeVersionCheck implements TestRule
@@ -66,9 +98,12 @@ private static class UpgradeVersionCheck implements TestRule
6698
@Override
6799
public @NotNull Statement apply(Statement base, Description description)
68100
{
69-
EariestVersion eariestVersion = description.getAnnotation(EariestVersion.class);
70-
LatestVersion latestVersion = description.getAnnotation(LatestVersion.class);
71-
if (isUpgradeSetupPhase || previousVersion <= 0)
101+
String eariestVersion = Optional.ofNullable(description.getAnnotation(EariestVersion.class))
102+
.map(EariestVersion::value).orElse(null);
103+
String latestVersion = Optional.ofNullable(description.getAnnotation(LatestVersion.class))
104+
.map(LatestVersion::value).orElse(null);
105+
106+
if (isUpgradeSetupPhase || previousVersion == null || (eariestVersion == null && latestVersion == null))
72107
{
73108
return base; // Run the test normally
74109
}
@@ -79,8 +114,7 @@ private static class UpgradeVersionCheck implements TestRule
79114
public void evaluate() throws Throwable
80115
{
81116
Assume.assumeTrue("Test doesn't support upgrading from version: " + previousVersion,
82-
(eariestVersion == null || eariestVersion.value() <= previousVersion) &&
83-
(latestVersion == null || previousVersion <= latestVersion.value())
117+
VersionRange.versionRange(eariestVersion, latestVersion).contains(previousVersion)
84118
);
85119
base.evaluate();
86120
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package org.labkey.test.util;
2+
3+
import org.jetbrains.annotations.NotNull;
4+
import org.junit.Assert;
5+
import org.junit.Test;
6+
7+
import java.util.Arrays;
8+
import java.util.List;
9+
import java.util.stream.Collectors;
10+
11+
/**
12+
* A simple class for parsing and comparing version numbers
13+
*/
14+
public class Version implements Comparable<Version>
15+
{
16+
private final List<Integer> _version;
17+
18+
public Version(Integer... version)
19+
{
20+
_version = validate(version);
21+
}
22+
23+
public Version(String version)
24+
{
25+
this(Arrays.stream(version.split("\\.")).map(Integer::parseInt).toArray(Integer[]::new));
26+
}
27+
28+
public Version(Double version)
29+
{
30+
this(version.toString());
31+
}
32+
33+
private static List<Integer> validate(Integer... versionParts)
34+
{
35+
List<Integer> partList = List.of(versionParts);
36+
if (partList.isEmpty())
37+
{
38+
throw new IllegalArgumentException("Version must have at least one part");
39+
}
40+
for (Integer part : partList)
41+
{
42+
if (part < 0)
43+
{
44+
throw new IllegalArgumentException("Version parts must be non-negative");
45+
}
46+
}
47+
return partList;
48+
}
49+
50+
@Override
51+
public int compareTo(@NotNull Version o)
52+
{
53+
int i = 0;
54+
for (; i < _version.size() && i < o._version.size(); i++)
55+
{
56+
Integer versionPart = _version.get(i);
57+
Integer otherVersionPart = o._version.get(i);
58+
int result = versionPart.compareTo(otherVersionPart);
59+
if (result != 0)
60+
{
61+
return result;
62+
}
63+
}
64+
// Treat the less specific version as higher
65+
if (i < _version.size())
66+
return -1; // this version is more specific
67+
if (i < o._version.size())
68+
return 1; // the other version is more specific
69+
return 0;
70+
}
71+
72+
@Override
73+
public final boolean equals(Object o)
74+
{
75+
if (!(o instanceof Version version)) return false;
76+
77+
return _version.equals(version._version);
78+
}
79+
80+
@Override
81+
public int hashCode()
82+
{
83+
return _version.hashCode();
84+
}
85+
86+
@Override
87+
public String toString()
88+
{
89+
return _version.stream().map(Object::toString).collect(Collectors.joining("."));
90+
}
91+
92+
93+
public static class VersionTest
94+
{
95+
@Test
96+
public void testConstructors()
97+
{
98+
Assert.assertEquals("Integer constructor comparison", new Version("25.7"), new Version(25, 7));
99+
Assert.assertEquals("Integer constructor comparison", new Version("25.7.3"), new Version(25, 7, 3));
100+
Assert.assertEquals("Double constructor comparison", new Version("25.7"), new Version(25.7));
101+
}
102+
103+
@Test
104+
public void testCompareTo()
105+
{
106+
Assert.assertEquals("CompareTo equal version", 0, new Version("25.7").compareTo(new Version("25.7")));
107+
Assert.assertEquals("CompareTo earlier version", 1, new Version("25.7").compareTo(new Version("25.3")));
108+
Assert.assertEquals("CompareTo later version", -1, new Version("25.7").compareTo(new Version("25.11")));
109+
Assert.assertEquals("CompareTo less specific version", -1, new Version("25.7.0").compareTo(new Version("25.7")));
110+
Assert.assertEquals("CompareTo more specific version", 1, new Version("25.7.0").compareTo(new Version("25.7.0.0")));
111+
}
112+
}
113+
114+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.labkey.test.util;
2+
3+
public class VersionRange
4+
{
5+
private final Version eariestVersion;
6+
private final Version latestVersion;
7+
8+
public VersionRange(Version eariestVersion, Version latestVersion)
9+
{
10+
this.eariestVersion = eariestVersion;
11+
this.latestVersion = latestVersion;
12+
}
13+
14+
public static VersionRange from(String version)
15+
{
16+
return new VersionRange(new Version(version), null);
17+
}
18+
19+
public static VersionRange until(String version)
20+
{
21+
return new VersionRange(null, new Version(version));
22+
}
23+
24+
public static VersionRange versionRange(String earliestVersion, String latestVersion)
25+
{
26+
return new VersionRange(new Version(earliestVersion), new Version(latestVersion));
27+
}
28+
29+
public boolean contains(Version version)
30+
{
31+
return (eariestVersion == null || eariestVersion.compareTo(version) <= 0) &&
32+
(latestVersion == null || latestVersion.compareTo(version) >= 0);
33+
}
34+
}

0 commit comments

Comments
 (0)