Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/org/labkey/test/params/ContainerInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ protected ContainerInfo(String name, ContainerInfo parentContainer, String folde
{
if (TestProperties.isTestRunningOnTeamCity())
{
String name = TestDataGenerator.randomName(folderName, TestDataGenerator.randomInt(0, 5), 5, RANDOM_CHARSET, null);
String name = TestDataGenerator.randomName(folderName, TestDataGenerator.randomInt(0, 5), 5, RANDOM_CHARSET, null).name();
if (name.startsWith("@"))
{
// Folder name may not begin with '@'
Expand Down
26 changes: 26 additions & 0 deletions src/org/labkey/test/util/RandomName.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.labkey.test.util;

import org.jetbrains.annotations.NotNull;

import java.util.Objects;

/**
* Record for a randomly generated name
*
* @param part The test-provided portion of the name
* @param name The full, randomly generated name
*/
public record RandomName(String part, String name)
{
public RandomName(String part, String name)
{
this.part = part == null ? "" : part; // Don't trim
this.name = Objects.requireNonNull(name);
}

@Override
public @NotNull String toString()
{
return name;
}
}
48 changes: 28 additions & 20 deletions src/org/labkey/test/util/TestDataGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -546,9 +546,9 @@ public static String randomMultiLineString(int size, @Nullable String exclusion)
* @param exclusions characters that are to be excluded from the random parts of the name
* @return a name with given characters that will be displayed as returned in the UI.
*/
public static String randomName(@NotNull String part, int numStartChars, int numEndChars, String charSet, @Nullable String exclusions)
public static RandomName randomName(@NotNull String part, int numStartChars, int numEndChars, String charSet, @Nullable String exclusions)
{
return (randomString(numStartChars, exclusions, charSet) + part + randomString(numEndChars, exclusions, charSet)).trim();
return new RandomName(part, (randomString(numStartChars, exclusions, charSet) + part + randomString(numEndChars, exclusions, charSet)).trim());
}

public static String randomDomainName()
Expand All @@ -563,7 +563,7 @@ public static String randomDomainName(@Nullable String part)

public static String randomInvalidDomainName(@Nullable String namePart, int numStartChars, int numEndChars)
{
String domainName = randomName(namePart == null ? "" : namePart, numStartChars, numEndChars, ILLEGAL_DOMAIN_NAME_CHARSET, null);
String domainName = randomName(namePart == null ? "" : namePart, numStartChars, numEndChars, ILLEGAL_DOMAIN_NAME_CHARSET, null).name();
TestLogger.log("Generated random invalid domain name: " + domainName);
return domainName;
}
Expand All @@ -583,20 +583,20 @@ public static String randomDomainName(@Nullable String namePart, @Nullable Domai
*/
public static String randomDomainName(@Nullable String namePart, @Nullable Integer numStartChars, @Nullable Integer numEndChars, @Nullable DomainKind domainKind)
{
String _namePart = namePart == null ? "" : namePart;
namePart = namePart == null ? "" : namePart;
DomainKind _domainKind = domainKind == null ? DomainKind.SampleSet : domainKind;
String charSet = ALPHANUMERIC_STRING + DOMAIN_SPECIAL_STRING;
int currentTries = 0;
String domainName = randomName(_namePart, getNumChars(numStartChars, 5), getNumChars(numEndChars, 50), charSet, null);
while (isDomainAndFieldNameInvalid(_domainKind, domainName, null))
RandomName randomName = randomName(namePart, getNumChars(numStartChars, 5), getNumChars(numEndChars, 50), charSet, null);
while (isDomainAndFieldNameInvalid(_domainKind, randomName, null))
{
domainName = randomName(_namePart, getNumChars(numStartChars, 5), getNumChars(numEndChars, 50), charSet, null);
randomName = randomName(namePart, getNumChars(numStartChars, 5), getNumChars(numEndChars, 50), charSet, null);
if (++currentTries >= MAX_RANDOM_TRIES)
throw new IllegalStateException("Failed to generate a valid domain name after " + MAX_RANDOM_TRIES + " tries. Last generated name: " + domainName);
throw new IllegalStateException("Failed to generate a valid domain name after " + MAX_RANDOM_TRIES + " tries. Last generated name: " + randomName);
}

// Multiple spaces in the UI are collapsed into a single space. If we need to test for handling of multiple spaces, we'll not use this generator
domainName = domainName.replaceAll("\\s+", " ");
String domainName = randomName.name().replaceAll("\\s+", " ");

TestLogger.log("Generated random domain name for domainKind " + _domainKind + ": " + domainName);
return domainName;
Expand Down Expand Up @@ -632,7 +632,7 @@ public static String randomFieldName(@NotNull String part, @Nullable Integer num
+ WIDE_PLACEHOLDER + REPEAT_PLACEHOLDER + ALL_CHARS_PLACEHOLDER;

int currentTries = 0;
String randomFieldName = randomName(part, getNumChars(numStartChars, 5), getNumChars(numEndChars, 50), chars, exclusion);
RandomName randomFieldName = randomName(part, getNumChars(numStartChars, 5), getNumChars(numEndChars, 50), chars, exclusion);
while (isDomainAndFieldNameInvalid(_domainKind, null, randomFieldName))
{
randomFieldName = randomName(part, getNumChars(numStartChars, 5), getNumChars(numEndChars, 50), chars, exclusion);
Expand All @@ -641,12 +641,13 @@ public static String randomFieldName(@NotNull String part, @Nullable Integer num
}

TestLogger.log("Generated random field name for domainKind " + _domainKind + ": " + randomFieldName);
return randomFieldName;
return randomFieldName.name();
}

private static boolean isDomainAndFieldNameInvalid(DomainKind domainKind, @Nullable String domainName, @Nullable String fieldName)
private static boolean isDomainAndFieldNameInvalid(DomainKind domainKind, @Nullable RandomName domainName, @Nullable RandomName fieldName)
{
if (fieldName != null && fieldName.length() > 64 && fieldName.toLowerCase().contains("key")) // Not guaranteed but likely a list key
// TODO: remove when merging to develop
if (fieldName != null && fieldName.name().length() > 64 && fieldName.part().toLowerCase().contains("key")) // Not guaranteed but likely a list key
return true; // Issue 53706: List key field name length is limited to 64 characters

if (TestProperties.isRemoteNameValidationEnabled())
Expand All @@ -659,7 +660,7 @@ private static boolean isDomainAndFieldNameInvalid(DomainKind domainKind, @Nulla
}
}

private static boolean isNameInvalidRemote(DomainKind domainKind, @Nullable String domainName, @Nullable String fieldName)
private static boolean isNameInvalidRemote(DomainKind domainKind, @Nullable RandomName domainName, @Nullable RandomName fieldName)
{
SimplePostCommand command = new SimplePostCommand("property", "validateDomainAndFieldNames");
JSONObject domainDesign = new JSONObject();
Expand Down Expand Up @@ -696,13 +697,14 @@ private static boolean isNameInvalidRemote(DomainKind domainKind, @Nullable Stri
}
}

public static boolean isNameInvalidLocal(DomainKind domainKind, @Nullable String domainName, @Nullable String fieldName)
private static final Pattern COLON_NAME_PATTERN = Pattern.compile(":[a-zA-Z]{3}"); // Avoid illegal patterns like ":Date"
private static boolean isNameInvalidLocal(DomainKind domainKind, @Nullable RandomName domainName, @Nullable RandomName fieldName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:
I realize this is not a new method, but in Java, when naming methods that return a boolean value to indicate validity, the convention generally favors positive phrasing. isNameValid vs. isNameInvalid

{
if (domainName != null)
{
if (!Character.isLetterOrDigit(domainName.charAt(0)))
if (!Character.isLetterOrDigit(domainName.name().charAt(0)))
return true; // domain needs to start with alphanumeric char
if (Pattern.matches("(.*\\s--[^ ].*)|(.*\\s-[^- ].*)", domainName))
if (Pattern.matches("(.*\\s--[^ ].*)|(.*\\s-[^- ].*)", domainName.name()))
return true; // domain name must not contain space followed by dash. (command like: Issue 49161)

int maxLength = switch (domainKind)
Expand All @@ -711,14 +713,20 @@ public static boolean isNameInvalidLocal(DomainKind domainKind, @Nullable String
case SampleSet -> 100;
default -> 200; // Sources, lists, and datasets allow 200 character names
};
if (domainName.length() > maxLength)
if (domainName.name().length() > maxLength)
return true;
if (COLON_NAME_PATTERN.matcher(domainName.name())
.results().map(mr -> mr.group(0))
.anyMatch(s -> !domainName.part().contains(s))) // Only check random portion of the name
return true;
}
if (fieldName != null)
{
if (fieldName.length() > 200)
if (fieldName.name().length() > 200)
return true;
if (Pattern.matches(".*:[a-zA-Z]{3}.*", fieldName)) // Avoid illegal patterns like ":Date"
if (COLON_NAME_PATTERN.matcher(fieldName.name())
.results().map(mr -> mr.group(0))
.anyMatch(s -> !fieldName.part().contains(s))) // Only check random portion of the name
return true;
}

Expand Down