Skip to content

Commit 15872c1

Browse files
authored
File Content, S3 & WebDav Issues Needs Automation (#2579)
- Regression test - Issue 51569: Can't customize Files webpart in a container with spaces - Update `FilesWebpartFileRootTest` to cover subfolder with spaces - Regression test - Issue 51815: FileRootMaintenanceTask throws RuntimeException for S3-backed folders - `FileContentUploadTest.testCalculateFileRootSize` (inherited by `S3FileContentUploadTest`) - Create `ConfigureSystemMaintenancePage` with minimal functionality
1 parent 728eeb0 commit 15872c1

8 files changed

Lines changed: 288 additions & 21 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.labkey.serverapi.util;
2+
3+
/**
4+
* org.labkey.api.util.UsageReportingLevel
5+
*/
6+
public enum UsageReportingLevel
7+
{
8+
NONE,
9+
ON,
10+
ON_WITHOUT_UPGRADE_MESSAGE
11+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.labkey.test.pages.admin;
2+
3+
import org.labkey.test.Locator;
4+
import org.labkey.test.WebDriverWrapper;
5+
import org.labkey.test.WebTestHelper;
6+
import org.labkey.test.pages.LabKeyPage;
7+
import org.labkey.test.pages.pipeline.PipelineStatusDetailsPage;
8+
import org.openqa.selenium.WebDriver;
9+
10+
public class ConfigureSystemMaintenancePage extends LabKeyPage<ConfigureSystemMaintenancePage.ElementCache>
11+
{
12+
public ConfigureSystemMaintenancePage(WebDriver driver)
13+
{
14+
super(driver);
15+
}
16+
17+
public static ConfigureSystemMaintenancePage beginAt(WebDriverWrapper webDriverWrapper)
18+
{
19+
webDriverWrapper.beginAt(WebTestHelper.buildURL("admin", "configureSystemMaintenance"));
20+
return new ConfigureSystemMaintenancePage(webDriverWrapper.getDriver());
21+
}
22+
23+
/**
24+
* Run the specified maintenance task and switch to the window that opens
25+
* @param description task description
26+
*/
27+
public PipelineStatusDetailsPage runMaintenanceTask(String description)
28+
{
29+
click(Locator.tagWithAttribute("input", "type", "checkbox")
30+
.followingSibling("a").withText(description));
31+
getDriver().switchTo().window("systemMaintenance");
32+
33+
PipelineStatusDetailsPage pipelineStatusDetailsPage = new PipelineStatusDetailsPage(getDriver());
34+
pipelineStatusDetailsPage.waitForComplete();
35+
return pipelineStatusDetailsPage;
36+
}
37+
38+
@Override
39+
protected ElementCache newElementCache()
40+
{
41+
return new ElementCache();
42+
}
43+
44+
protected class ElementCache extends LabKeyPage<ElementCache>.ElementCache
45+
{
46+
}
47+
}

src/org/labkey/test/pages/core/admin/ShowAdminPage.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.labkey.test.components.DomainDesignerPage;
2222
import org.labkey.test.pages.ConfigureReportsAndScriptsPage;
2323
import org.labkey.test.pages.LabKeyPage;
24+
import org.labkey.test.pages.admin.ConfigureSystemMaintenancePage;
2425
import org.labkey.test.pages.admin.ExternalSourcesPage;
2526
import org.labkey.test.pages.compliance.ComplianceSettingsAccountsPage;
2627
import org.labkey.test.pages.core.login.LoginConfigurePage;
@@ -230,10 +231,11 @@ public void clickSiteWideTerms()
230231
clickAndWait(elementCache().siteWideTermsLink);
231232
}
232233

233-
public void clickSystemMaintenance()
234+
public ConfigureSystemMaintenancePage clickSystemMaintenance()
234235
{
235236
goToSettingsSection();
236237
clickAndWait(elementCache().systemMaintenanceLink);
238+
return new ConfigureSystemMaintenancePage(getDriver());
237239
}
238240

239241
public void clickSystemProperties()

src/org/labkey/test/tests/filecontent/FileContentUploadTest.java

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@
1616

1717
package org.labkey.test.tests.filecontent;
1818

19+
import org.assertj.core.api.Assertions;
1920
import org.hamcrest.CoreMatchers;
2021
import org.jetbrains.annotations.NotNull;
2122
import org.junit.BeforeClass;
2223
import org.junit.Test;
2324
import org.junit.experimental.categories.Category;
25+
import org.labkey.remoteapi.CommandException;
2426
import org.labkey.test.BaseWebDriverTest;
2527
import org.labkey.test.Locator;
2628
import org.labkey.test.TestFileUtils;
@@ -31,6 +33,7 @@
3133
import org.labkey.test.components.domain.DomainFieldRow;
3234
import org.labkey.test.components.ext4.ComboBox;
3335
import org.labkey.test.components.ext4.Window;
36+
import org.labkey.test.pages.admin.UsageStatisticsPage;
3437
import org.labkey.test.pages.files.WebDavPage;
3538
import org.labkey.test.params.FieldDefinition;
3639
import org.labkey.test.params.FieldDefinition.ColumnType;
@@ -46,8 +49,9 @@
4649
import org.labkey.test.util.PortalHelper;
4750
import org.labkey.test.util.SearchHelper;
4851
import org.labkey.test.util.Timer;
52+
import org.labkey.test.util.core.admin.ServerUsageUtils;
4953
import org.labkey.test.util.core.webdav.WebDavUtils;
50-
import org.openqa.selenium.WebElement;
54+
import org.labkey.test.util.data.JSONUtils;
5155

5256
import java.io.File;
5357
import java.io.IOException;
@@ -241,7 +245,7 @@ public void testAbsoluteFilePath() throws Exception
241245
_fileBrowserHelper.goToConfigureButtonsTab();
242246
_fileBrowserHelper.unhideGridColumn(FileBrowserHelper.ABSOLUTE_FILE_PATH_COLUMN_ID);
243247
click(Ext4Helper.Locators.ext4Button("submit"));
244-
WebElement columnHeader = waitForElement(Locator.byClass("x4-column-header").withText("Absolute File Path").notHidden());
248+
waitForElement(Locator.byClass("x4-column-header").withText("Absolute File Path").notHidden());
245249

246250
String absolutePath = FileBrowserHelper.Locators.gridRowWithNodeId(filename)
247251
.append(Locator.byClass("x4-grid-cell").last()).findElement(getDriver()).getText();
@@ -283,6 +287,7 @@ public void testFolderNameCharacters()
283287
Set<String> folders = new HashSet<>(_fileBrowserHelper.getFileList());
284288
assertEquals("Didn't create expected folders", expectedFolders, folders);
285289
}
290+
286291
@Test
287292
public void testFileNameCharacters() throws IOException
288293
{
@@ -343,6 +348,35 @@ public void testDrop()
343348
assertElementPresent(Locator.tagWithText("span", testFile.getName()));
344349
}
345350

351+
@Test
352+
public void testCalculateFileRootSize() throws Exception
353+
{
354+
String calculateFileRootSizeTask = "Calculate file root sizes";
355+
goToAdminConsole().clickSystemMaintenance().runMaintenanceTask(calculateFileRootSizeTask);
356+
Integer initialFileRootSize = getFileRootSize();
357+
358+
goToProjectHome();
359+
File testFile = TestFileUtils.getSampleData("fileTypes/tsv_sample.tsv");
360+
361+
log("Dropping the file object in drop zone");
362+
_fileBrowserHelper.uploadFile(testFile);
363+
364+
goToAdminConsole().clickSystemMaintenance().runMaintenanceTask(calculateFileRootSizeTask);
365+
Integer finalFileRootSize = getFileRootSize();
366+
if (!checker().wrapAssertion(() -> Assertions.assertThat(finalFileRootSize)
367+
.as("Crawled file root size").isGreaterThan(initialFileRootSize)))
368+
{
369+
UsageStatisticsPage.beginAt(this).setJsonPathInput("modules.FileContent");
370+
checker().screenShotIfNewError("file_root_size");
371+
}
372+
}
373+
374+
private @NotNull Integer getFileRootSize() throws IOException, CommandException
375+
{
376+
return JSONUtils.getProperty("fileRootsTotalSize",
377+
ServerUsageUtils.getModuleMetrics(createDefaultConnection(), "FileContent"));
378+
}
379+
346380
@NotNull
347381
protected List<String> folderSubstringsToVerify()
348382
{
@@ -367,7 +401,7 @@ private void setupNotifications()
367401
table.checkCheckbox(table.getRowIndex("Email", TEST_USER));
368402
shortWait().until(LabKeyExpectedConditions.elementIsEnabled(Locator.lkButton(MessagesLongTest.USERS_UPDATE_BUTTON)));
369403
table.clickHeaderMenu(MessagesLongTest.USERS_UPDATE_BUTTON, false, MessagesLongTest.FILES_MENU_ITEM);
370-
final Window window = Window(getDriver()).withTitle("Update user settings for files").waitFor();
404+
final Window<?> window = Window(getDriver()).withTitle("Update user settings for files").waitFor();
371405
ComboBox.ComboBox(getDriver()).withLabel(MessagesLongTest.NEW_SETTING_LABEL).find(window).selectComboBoxItem("No Email");
372406
window.clickButton(MessagesLongTest.POPUP_UPDATE_BUTTON, true);
373407
table.doAndWaitForUpdate(() -> Window(getDriver()).withTitle("Update selected users").waitFor().

src/org/labkey/test/tests/filecontent/FileRootMigrationTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ private void doSetup()
7777
public void cleanFiles() throws IOException
7878
{
7979
FileUtils.deleteDirectory(targetFileRoot);
80-
targetFileRoot.mkdirs();
80+
FileUtils.forceMkdir(targetFileRoot);
8181
FileRootsManagementPage.beginAt(this, getProjectName())
8282
.useDefaultFileRoot()
8383
.clickSave();
@@ -101,7 +101,7 @@ public void testMigrateMove()
101101
final File folderFile2 = TestFileUtils.getSampleData("fileTypes/cmd_sample.cmd");
102102
List<File> sourceFiles = new ArrayList<>();
103103

104-
String folderName = "folder \u2603";// + TRICKY_CHARACTERS_FOR_PROJECT_NAMES;
104+
String folderName = "folder " + TRICKY_CHARACTERS_FOR_PROJECT_NAMES;
105105

106106
log("Upload files to project");
107107
goToProjectHome();
@@ -165,7 +165,7 @@ public void testMigrateCopy()
165165
File folderFile2 = TestFileUtils.getSampleData("fileTypes/cmd_sample.cmd");
166166
List<File> sourceFiles = new ArrayList<>();
167167

168-
String folderName = "folder \u2603";// + TRICKY_CHARACTERS_FOR_PROJECT_NAMES;
168+
String folderName = "folder " + TRICKY_CHARACTERS_FOR_PROJECT_NAMES;
169169

170170
log("Upload files to project");
171171
goToProjectHome();
@@ -238,7 +238,7 @@ public void testMigrateToNonExistentFolder()
238238
}
239239

240240
@Test
241-
public void testMigratingProjectWithNonInheritingSubfolder()
241+
public void testMigratingProjectWithNonInheritingSubfolder() throws IOException
242242
{
243243
final File projFile1 = TestFileUtils.getSampleData("fileTypes/sample.txt");
244244
final File projFile2 = TestFileUtils.getSampleData("fileTypes/rtf_sample.rtf");
@@ -247,9 +247,9 @@ public void testMigratingProjectWithNonInheritingSubfolder()
247247
List<File> sourceFiles = new ArrayList<>();
248248
File nonInheritingFileRoot = new File(TestFileUtils.getTestTempDir(), "custom");
249249
TestFileUtils.deleteDir(nonInheritingFileRoot);
250-
nonInheritingFileRoot.mkdirs();
250+
FileUtils.forceMkdir(nonInheritingFileRoot);
251251

252-
String folderName = "folder \u2603";// + TRICKY_CHARACTERS_FOR_PROJECT_NAMES;
252+
String folderName = "folder " + TRICKY_CHARACTERS_FOR_PROJECT_NAMES;
253253

254254
log("Upload files to project");
255255
goToProjectHome();

src/org/labkey/test/tests/filecontent/FilesWebpartFileRootTest.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import org.jetbrains.annotations.Nullable;
1919
import org.junit.Assert;
20-
import org.junit.Before;
2120
import org.junit.BeforeClass;
2221
import org.junit.Test;
2322
import org.junit.experimental.categories.Category;
@@ -38,7 +37,10 @@
3837
@BaseWebDriverTest.ClassTimeout(minutes = 5)
3938
public class FilesWebpartFileRootTest extends BaseWebDriverTest
4039
{
41-
private static final String CHILD_CONTAINER = "ChildContainerNotForFileRootSelection";
40+
private static final String PROJECT_NAME = "FilesWebpartFileRoot Project" + TRICKY_CHARACTERS_FOR_PROJECT_NAMES;
41+
private static final String WORK_FOLDER = "Work Folder" + TRICKY_CHARACTERS_FOR_PROJECT_NAMES;
42+
private static final String WORK_CONTAINER_PATH = PROJECT_NAME + "/" + WORK_FOLDER;
43+
private static final String GRANDCHILD_CONTAINER = "ChildContainerNotForFileRootSelection";
4244
PortalHelper portalHelper = new PortalHelper(this);
4345
FileBrowserHelper fileBrowserHelper = new FileBrowserHelper(this);
4446

@@ -51,7 +53,7 @@ public List<String> getAssociatedModules()
5153
@Override
5254
protected @Nullable String getProjectName()
5355
{
54-
return "FilesWebpartFileRoot Project" + TRICKY_CHARACTERS_FOR_PROJECT_NAMES;
56+
return PROJECT_NAME;
5557
}
5658

5759
@BeforeClass
@@ -64,16 +66,16 @@ public static void initTest()
6466
private void doInit()
6567
{
6668
_containerHelper.createProject(getProjectName(), null);
67-
_containerHelper.createSubfolder(getProjectName(), CHILD_CONTAINER);
69+
_containerHelper.createSubfolder(getProjectName(), WORK_FOLDER);
70+
_containerHelper.createSubfolder(WORK_CONTAINER_PATH, GRANDCHILD_CONTAINER);
6871

69-
goToProjectHome();
72+
goToWorkFolder();
7073
portalHelper.addWebPart("Files");
7174
}
7275

73-
@Before
74-
public void preTest()
76+
private void goToWorkFolder()
7577
{
76-
goToProjectHome();
78+
goToProjectHome(WORK_CONTAINER_PATH);
7779
}
7880

7981
@Test
@@ -82,6 +84,8 @@ public void testCustomFileRoot()
8284
String folderName = "Folder " + TRICKY_CHARACTERS_FOR_PROJECT_NAMES;
8385
File testFile = TestFileUtils.getSampleData("fileTypes/sample.txt");
8486

87+
goToWorkFolder();
88+
8589
_fileBrowserHelper.createFolder(folderName);
8690
_fileBrowserHelper.selectFileBrowserItem(folderName + "/");
8791
_fileBrowserHelper.uploadFile(testFile);
@@ -92,17 +96,17 @@ public void testCustomFileRoot()
9296
customizePage.setFileRoot("@files", folderName);
9397
Assert.assertEquals("File in custom file root", List.of(testFile.getName()), _fileBrowserHelper.getFileList());
9498

95-
goToProjectHome();
99+
goToWorkFolder();
96100

97101
portalHelper.clickWebpartMenuItem("Files", true, "Customize");
98-
customizePage.verifyFileRootNodeNotPresent(CHILD_CONTAINER); //child container shouldn't show up as file root options
102+
customizePage.verifyFileRootNodeNotPresent(GRANDCHILD_CONTAINER); //child container shouldn't show up as file root options
99103
customizePage.setFileRoot("@files");
100104
Locator.XPathLocator importDataBtn = Locator.tagWithClass("a", "importDataBtn");
101105
Assert.assertTrue("Import Data button should be present when file root is @files and no pipeline override exists", isElementPresent(importDataBtn));
102106

103107
log("Override pipeline root for project");
104108
setPipelineRoot(TestFileUtils.getSampleData("AssayAPI").getParentFile().getAbsolutePath());
105-
goToProjectHome();
109+
goToWorkFolder();
106110
Assert.assertTrue("Import Data button should not be present when file root is @files and pipeline override exists", !isElementPresent(importDataBtn));
107111

108112
log("Set webpart file root to @pipeline");
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package org.labkey.test.util.core.admin;
2+
3+
import org.jetbrains.annotations.NotNull;
4+
import org.jetbrains.annotations.Nullable;
5+
import org.labkey.remoteapi.CommandException;
6+
import org.labkey.remoteapi.CommandResponse;
7+
import org.labkey.remoteapi.Connection;
8+
import org.labkey.remoteapi.SimpleGetCommand;
9+
import org.labkey.serverapi.util.UsageReportingLevel;
10+
import org.labkey.test.WebTestHelper;
11+
import org.labkey.test.util.data.JSONUtils;
12+
13+
import java.io.IOException;
14+
import java.util.HashMap;
15+
import java.util.Map;
16+
import java.util.NoSuchElementException;
17+
18+
public class ServerUsageUtils
19+
{
20+
public static Map<String, Object> getUsageReportJson(Connection connection) throws IOException, CommandException
21+
{
22+
SimpleGetCommand command = new SimpleGetCommand("admin", "testMothershipReport");
23+
command.setParameters(getMothershipReportParams("CheckForUpdates", UsageReportingLevel.ON, false, null));
24+
CommandResponse response = command.execute(connection, "/");
25+
return response.getParsedData();
26+
}
27+
28+
public static Map<String, Object> getUsageMetrics(Connection connection) throws IOException, CommandException
29+
{
30+
return JSONUtils.getProperty("jsonMetrics", getUsageReportJson(connection));
31+
}
32+
33+
public static Map<String, Object> getModuleMetrics(Connection connection, String module) throws IOException, CommandException
34+
{
35+
Map<String, Object> modules = JSONUtils.getProperty("jsonMetrics.modules", getUsageReportJson(connection));
36+
if (modules.containsKey(module))
37+
return JSONUtils.getProperty(module, modules);
38+
else
39+
throw new NoSuchElementException("Server metrics for " + module + " module do not exist. Found: " + modules.keySet());
40+
}
41+
42+
@NotNull
43+
public static String getTestMothershipReportUrl(String type, UsageReportingLevel level, boolean submit, @Nullable String forwardedFor)
44+
{
45+
Map<String, Object> params = getMothershipReportParams(type, level, submit, forwardedFor);
46+
return WebTestHelper.buildURL("admin", "testMothershipReport", params);
47+
}
48+
49+
@NotNull
50+
private static Map<String, Object> getMothershipReportParams(String type, UsageReportingLevel level, boolean submit, @Nullable String forwardedFor)
51+
{
52+
Map<String, Object> params = new HashMap<>();
53+
params.put("type", type);
54+
params.put("level", level.toString());
55+
params.put("submit", submit);
56+
params.put("testMode", true);
57+
if (null != forwardedFor)
58+
params.put("forwardedFor", forwardedFor);
59+
return params;
60+
}
61+
62+
}

0 commit comments

Comments
 (0)