From a368f0c811528162299efa2e2daa4ecffe681a10 Mon Sep 17 00:00:00 2001 From: Trey Chadick Date: Tue, 6 Jan 2026 15:10:51 -0800 Subject: [PATCH 1/2] Add convenience methods for conditionalizing upgrade checks (#2834) --- .../test/tests/upgrade/BaseUpgradeTest.java | 34 +++++++++++-- src/org/labkey/test/util/VersionRange.java | 50 +++++++++++++++++-- 2 files changed, 75 insertions(+), 9 deletions(-) diff --git a/src/org/labkey/test/tests/upgrade/BaseUpgradeTest.java b/src/org/labkey/test/tests/upgrade/BaseUpgradeTest.java index 33fe474029..a7e3b20568 100644 --- a/src/org/labkey/test/tests/upgrade/BaseUpgradeTest.java +++ b/src/org/labkey/test/tests/upgrade/BaseUpgradeTest.java @@ -35,8 +35,9 @@ public abstract class BaseUpgradeTest extends BaseWebDriverTest { protected static final boolean isUpgradeSetupPhase = TestProperties.getBooleanProperty("webtest.upgradeSetup", true); - protected static final Version previousVersion = Optional.ofNullable(trimToNull(System.getProperty("webtest.upgradePreviousVersion"))) - .map(Version::new).orElse(TestProperties.getProductVersion()); + protected static final Version setupVersion = isUpgradeSetupPhase ? TestProperties.getProductVersion() : + Optional.ofNullable(trimToNull(System.getProperty("webtest.upgradePreviousVersion"))).map(Version::new) + .orElse(TestProperties.getProductVersion()); @Override protected boolean skipCleanup(boolean afterTest) @@ -70,6 +71,29 @@ public List getAssociatedModules() return Arrays.asList(); } + /** + * Checks if the setup for the current test was performed in a version prior to the specified version. + * + * @param version The version to check against. + * @return {@code true} if the setup version is earlier than the specified version. + */ + protected boolean wasSetupBefore(String version) + { + return !wasSetupWithin(version, null); + } + + /** + * Checks if the setup for the current test was performed within the specified version range (inclusive). + * + * @param earliestVersion The earliest version in the range (inclusive). + * @param latestVersion The latest version in the range (inclusive). + * @return {@code true} if the setup version is within the specified range. + */ + protected boolean wasSetupWithin(String earliestVersion, String latestVersion) + { + return VersionRange.versionRange(earliestVersion, latestVersion).contains(setupVersion); + } + /** * Annotates test methods that should only run when upgrading from particular LabKey versions, as specified in * {@code webtest.upgradePreviousVersion}.
@@ -104,7 +128,7 @@ private static class UpgradeVersionCheck implements TestRule String latestVersion = Optional.ofNullable(description.getAnnotation(LatestVersion.class)) .map(LatestVersion::value).orElse(null); - if (isUpgradeSetupPhase || previousVersion == null || (earliestVersion == null && latestVersion == null)) + if (isUpgradeSetupPhase || setupVersion == null || (earliestVersion == null && latestVersion == null)) { return base; // Run the test normally } @@ -114,8 +138,8 @@ private static class UpgradeVersionCheck implements TestRule @Override public void evaluate() throws Throwable { - Assume.assumeTrue("Test not valid when upgrading from version: " + previousVersion, - VersionRange.versionRange(earliestVersion, latestVersion).contains(previousVersion) + Assume.assumeTrue("Test not valid when upgrading from version: " + setupVersion, + VersionRange.versionRange(earliestVersion, latestVersion).contains(setupVersion) ); base.evaluate(); } diff --git a/src/org/labkey/test/util/VersionRange.java b/src/org/labkey/test/util/VersionRange.java index 0fe8220e5a..865974783e 100644 --- a/src/org/labkey/test/util/VersionRange.java +++ b/src/org/labkey/test/util/VersionRange.java @@ -1,26 +1,62 @@ package org.labkey.test.util; +/** + * Represents a range of LabKey versions. + * Used for checking if a specific version falls within an inclusive range. + */ public class VersionRange { - private final Version eariestVersion; + private final Version earliestVersion; private final Version latestVersion; - public VersionRange(Version eariestVersion, Version latestVersion) + /** + * Constructs a version range. + * + * @param earliestVersion The earliest version in the range (inclusive). If null, there is no lower bound. + * @param latestVersion The latest version in the range (inclusive). If null, there is no upper bound. + * @throws IllegalArgumentException if both versions are null, or if earliestVersion is after latestVersion. + */ + public VersionRange(Version earliestVersion, Version latestVersion) { - this.eariestVersion = eariestVersion; + this.earliestVersion = earliestVersion; this.latestVersion = latestVersion; + + if (earliestVersion == null && latestVersion == null) + throw new IllegalArgumentException("Version range requires at least one version"); + if (earliestVersion != null && latestVersion != null && earliestVersion.compareTo(latestVersion) > 0) + throw new IllegalArgumentException("%s is after %s".formatted(earliestVersion, latestVersion)); + } + /** + * Creates a version range starting from the specified version with no upper bound. + * + * @param version The earliest version (inclusive). + * @return A new {@link VersionRange}. + */ public static VersionRange from(String version) { return new VersionRange(new Version(version), null); } + /** + * Creates a version range ending at the specified version with no lower bound. + * + * @param version The latest version (inclusive). + * @return A new {@link VersionRange}. + */ public static VersionRange until(String version) { return new VersionRange(null, new Version(version)); } + /** + * Creates a version range with specified bounds. + * + * @param earliestVersion The earliest version (inclusive). If null, there is no lower bound. + * @param latestVersion The latest version (inclusive). If null, there is no upper bound. + * @return A new {@link VersionRange}. + */ public static VersionRange versionRange(String earliestVersion, String latestVersion) { Version earliest = earliestVersion == null ? null : new Version(earliestVersion); @@ -28,9 +64,15 @@ public static VersionRange versionRange(String earliestVersion, String latestVer return new VersionRange(earliest, latest); } + /** + * Checks if the specified version is within this range (inclusive). + * + * @param version The version to check. + * @return {@code true} if the version is within the range. + */ public boolean contains(Version version) { - return (eariestVersion == null || eariestVersion.compareTo(version) <= 0) && + return (earliestVersion == null || earliestVersion.compareTo(version) <= 0) && (latestVersion == null || latestVersion.compareTo(version) >= 0); } } From 4f4adf05831194de6d2c78afdef6798b0345c1f6 Mon Sep 17 00:00:00 2001 From: labkey-tchad Date: Thu, 15 Jan 2026 09:04:24 -0800 Subject: [PATCH 2/2] Add SimpleFormCommand --- .../labkey/remoteapi/SimpleFormCommand.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/org/labkey/remoteapi/SimpleFormCommand.java diff --git a/src/org/labkey/remoteapi/SimpleFormCommand.java b/src/org/labkey/remoteapi/SimpleFormCommand.java new file mode 100644 index 0000000000..e49a74dbd0 --- /dev/null +++ b/src/org/labkey/remoteapi/SimpleFormCommand.java @@ -0,0 +1,43 @@ +package org.labkey.remoteapi; + +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.classic.methods.HttpUriRequest; +import org.apache.hc.client5.http.entity.UrlEncodedFormEntity; +import org.apache.hc.core5.http.NameValuePair; +import org.apache.hc.core5.http.message.BasicNameValuePair; + +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class SimpleFormCommand extends Command +{ + private final Map _formData; + + public SimpleFormCommand(String controller, String action, Map formData) + { + super(controller, action); + _formData = formData; + } + + public CommandResponse execute(Connection connection) throws IOException, CommandException + { + return execute(connection, null); + } + + @Override + protected HttpUriRequest createRequest(URI uri) + { + HttpPost post = new HttpPost(uri); + + List args = new ArrayList<>(); + for (Map.Entry reportVal : _formData.entrySet()) + { + args.add(new BasicNameValuePair(reportVal.getKey(), reportVal.getValue())); + } + post.setEntity(new UrlEncodedFormEntity(args)); + return post; + } +}