Skip to content

Commit 399c044

Browse files
authored
Avoid known issues with random name generation (#2674)
- Avoid creating long list key field names - Stop using the server to validate random field and domain names
1 parent 0d1ba00 commit 399c044

File tree

5 files changed

+77
-9
lines changed

5 files changed

+77
-9
lines changed

src/org/labkey/test/TestProperties.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,11 @@ public static boolean isTrialServer()
257257
return getBooleanProperty("webtest.server.trial", false);
258258
}
259259

260+
public static boolean isRemoteNameValidationEnabled()
261+
{
262+
return getBooleanProperty("webtest.remote.domain.validation", false);
263+
}
264+
260265
public static boolean isCheckerFatal()
261266
{
262267
return "true".equals(System.getProperty("webtest.checker.fatal"));

src/org/labkey/test/tests/DomainDesignerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ public void testInvalidLookupDomainField() throws IOException, CommandException
316316
public void testInvalidSampleFieldFromDelete() throws Exception
317317
{
318318
String listName = TestDataGenerator.randomDomainName("Sample Lookups List", DomainUtils.DomainKind.IntList);
319-
String listKey = TestDataGenerator.randomFieldName("Id", null, 10, null, DomainUtils.DomainKind.IntList);
319+
String listKey = DomainUtils.DomainKind.IntList.randomFieldName("Key");
320320
String sampleType1 = TestDataGenerator.randomDomainName("Sample Type 1");
321321
String sampleType2 = TestDataGenerator.randomDomainName("Sample Type 2");
322322
SampleTypeAPIHelper.createEmptySampleType(getProjectName(), new SampleTypeDefinition(sampleType1));

src/org/labkey/test/tests/query/QueryLookupTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class QueryLookupTest extends BaseWebDriverTest
2929
private static final String PROJECT_NAME = "QueryLookupTest" + TRICKY_CHARACTERS_FOR_PROJECT_NAMES;
3030
private static final String LIST_NAME = "l&ist q";
3131

32-
private static final FieldInfo NAME_COLUMN = FieldInfo.random("Name", FieldDefinition.ColumnType.String, DomainUtils.DomainKind.VarList);
32+
private static final FieldInfo NAME_COLUMN = FieldInfo.random("Key", FieldDefinition.ColumnType.String, DomainUtils.DomainKind.VarList);
3333
private static final FieldInfo TSHIRT_COLUMN = FieldInfo.random("TShirt", FieldDefinition.ColumnType.String, DomainUtils.DomainKind.VarList);
3434

3535
@Override

src/org/labkey/test/util/DomainUtils.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import org.labkey.remoteapi.domain.DropDomainCommand;
77
import org.labkey.remoteapi.domain.GetDomainDetailsCommand;
88
import org.labkey.test.WebTestHelper;
9+
import org.labkey.test.params.FieldDefinition;
10+
import org.labkey.test.params.FieldInfo;
911

1012
import java.io.IOException;
1113

@@ -108,5 +110,20 @@ public String randomName(String namePart)
108110
{
109111
return TestDataGenerator.randomDomainName(namePart, this);
110112
}
113+
114+
public String randomFieldName(String namePart)
115+
{
116+
return randomField(namePart).getName();
117+
}
118+
119+
public FieldInfo randomField(String namePart)
120+
{
121+
return randomField(namePart, null);
122+
}
123+
124+
public FieldInfo randomField(String namePart, FieldDefinition.ColumnType columnType)
125+
{
126+
return FieldInfo.random(namePart, columnType, this);
127+
}
111128
}
112129
}

src/org/labkey/test/util/TestDataGenerator.java

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@
3737
import org.labkey.remoteapi.query.SelectRowsResponse;
3838
import org.labkey.remoteapi.query.Sort;
3939
import org.labkey.serverapi.reader.TabLoader;
40+
import org.labkey.test.TestProperties;
4041
import org.labkey.test.WebTestHelper;
4142
import org.labkey.test.params.FieldDefinition;
43+
import org.labkey.test.util.DomainUtils.DomainKind;
4244
import org.labkey.test.util.data.ColumnNameMapper;
4345
import org.labkey.test.util.data.TestDataUtils;
4446
import org.labkey.test.util.query.QueryApiHelper;
@@ -566,7 +568,7 @@ public static String randomInvalidDomainName(@Nullable String namePart, int numS
566568
return domainName;
567569
}
568570

569-
public static String randomDomainName(@Nullable String namePart, @Nullable DomainUtils.DomainKind domainKind)
571+
public static String randomDomainName(@Nullable String namePart, @Nullable DomainKind domainKind)
570572
{
571573
return randomDomainName(namePart, null, null, domainKind);
572574
}
@@ -579,10 +581,10 @@ public static String randomDomainName(@Nullable String namePart, @Nullable Domai
579581
* @param numEndChars Number of random characters at end of name
580582
* @return name containing the given name part and appended random characters that should be a valid domain name
581583
*/
582-
public static String randomDomainName(@Nullable String namePart, @Nullable Integer numStartChars, @Nullable Integer numEndChars, @Nullable DomainUtils.DomainKind domainKind)
584+
public static String randomDomainName(@Nullable String namePart, @Nullable Integer numStartChars, @Nullable Integer numEndChars, @Nullable DomainKind domainKind)
583585
{
584586
String _namePart = namePart == null ? "" : namePart;
585-
DomainUtils.DomainKind _domainKind = domainKind == null ? DomainUtils.DomainKind.SampleSet : domainKind;
587+
DomainKind _domainKind = domainKind == null ? DomainKind.SampleSet : domainKind;
586588
String charSet = ALPHANUMERIC_STRING + DOMAIN_SPECIAL_STRING;
587589
int currentTries = 0;
588590
String domainName = randomName(_namePart, getNumChars(numStartChars, 5), getNumChars(numEndChars, 50), charSet, null);
@@ -615,14 +617,14 @@ public static String randomFieldName(String part, @Nullable String exclusion)
615617
return randomFieldName(part, exclusion, null);
616618
}
617619

618-
public static String randomFieldName(String part, @Nullable String exclusion, DomainUtils.DomainKind domainKind)
620+
public static String randomFieldName(String part, @Nullable String exclusion, DomainKind domainKind)
619621
{
620622
return randomFieldName(part, null, null, exclusion, domainKind);
621623
}
622624

623-
public static String randomFieldName(@NotNull String part, @Nullable Integer numStartChars, @Nullable Integer numEndChars, @Nullable String exclusion, @Nullable DomainUtils.DomainKind domainKind)
625+
public static String randomFieldName(@NotNull String part, @Nullable Integer numStartChars, @Nullable Integer numEndChars, @Nullable String exclusion, @Nullable DomainKind domainKind)
624626
{
625-
DomainUtils.DomainKind _domainKind = domainKind == null ? DomainUtils.DomainKind.SampleSet : domainKind;
627+
DomainKind _domainKind = domainKind == null ? DomainKind.SampleSet : domainKind;
626628

627629
// use the characters that we know are encoded in fieldKeys plus characters that we know clients are using
628630
// Issue 53197: Field name with double byte character can cause client side exception in Firefox when trying to customize grid view.
@@ -642,7 +644,22 @@ public static String randomFieldName(@NotNull String part, @Nullable Integer num
642644
return randomFieldName;
643645
}
644646

645-
private static boolean isDomainAndFieldNameInvalid(DomainUtils.DomainKind domainKind, @Nullable String domainName, @Nullable String fieldName)
647+
private static boolean isDomainAndFieldNameInvalid(DomainKind domainKind, @Nullable String domainName, @Nullable String fieldName)
648+
{
649+
if (fieldName != null && fieldName.length() > 64 && fieldName.toLowerCase().contains("key")) // Not guaranteed but likely a list key
650+
return true; // Issue 53706: List key field name length is limited to 64 characters
651+
652+
if (TestProperties.isRemoteNameValidationEnabled())
653+
{
654+
return isNameInvalidRemote(domainKind, domainName, fieldName);
655+
}
656+
else
657+
{
658+
return isNameInvalidLocal(domainKind, domainName, fieldName);
659+
}
660+
}
661+
662+
private static boolean isNameInvalidRemote(DomainKind domainKind, @Nullable String domainName, @Nullable String fieldName)
646663
{
647664
SimplePostCommand command = new SimplePostCommand("property", "validateDomainAndFieldNames");
648665
JSONObject domainDesign = new JSONObject();
@@ -679,6 +696,35 @@ private static boolean isDomainAndFieldNameInvalid(DomainUtils.DomainKind domain
679696
}
680697
}
681698

699+
public static boolean isNameInvalidLocal(DomainKind domainKind, @Nullable String domainName, @Nullable String fieldName)
700+
{
701+
if (domainName != null)
702+
{
703+
if (!Character.isLetterOrDigit(domainName.charAt(0)))
704+
return true; // domain needs to start with alphanumeric char
705+
if (Pattern.matches("(.*\\s--[^ ].*)|(.*\\s-[^- ].*)", domainName))
706+
return true; // domain name must not contain space followed by dash. (command like: Issue 49161)
707+
708+
int maxLength = switch (domainKind)
709+
{
710+
case Assay -> 200 - 13; // Make room for "{$domainName} Batch Fields" domain
711+
case SampleSet -> 100;
712+
default -> 200; // Sources, lists, and datasets allow 200 character names
713+
};
714+
if (domainName.length() > maxLength)
715+
return true;
716+
}
717+
if (fieldName != null)
718+
{
719+
if (fieldName.length() > 200)
720+
return true;
721+
if (Pattern.matches(".*:[a-zA-Z]{3}.*", fieldName)) // Avoid illegal patterns like ":Date"
722+
return true;
723+
}
724+
725+
return false;
726+
}
727+
682728
public static <T> T randomChoice(List<T> choices)
683729
{
684730
return choices.get(randomInt(0, choices.size() - 1));

0 commit comments

Comments
 (0)