-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathAssayTransformMissingParentDirTest.java
More file actions
113 lines (101 loc) · 5.82 KB
/
AssayTransformMissingParentDirTest.java
File metadata and controls
113 lines (101 loc) · 5.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package org.labkey.test.tests.assay;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.labkey.api.util.FileUtil;
import org.labkey.test.Locator;
import org.labkey.test.TestFileUtils;
import org.labkey.test.categories.Assays;
import org.labkey.test.categories.Daily;
import org.labkey.test.components.assay.AssayConstants;
import org.labkey.test.pages.ReactAssayDesignerPage;
import org.labkey.test.pages.assay.AssayImportPage;
import org.labkey.test.pages.assay.AssayRunsPage;
import org.labkey.test.params.assay.GeneralAssayDesign;
import java.io.File;
import java.io.IOException;
import java.nio.file.AccessDeniedException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
/**
* Issue 54156: Regression test to ensure a reasonable error message is shown when an assay design references
* a transform script whose parent directory has since been deleted, and that the assay design can be fixed by removing the script.
*/
@Category({Assays.class, Daily.class})
public class AssayTransformMissingParentDirTest extends AbstractAssayTransformTest
{
@Test
public void testMissingParentDirectoryRegression() throws Exception
{
// Create a nested directory and an R transform script within it
String assayName = "missingParentDirAssay";
Path parentDir = Files.createTempDirectory("assay-transform-parent-");
Path nestedDir = FileUtil.createDirectories(parentDir.resolve("child"), false);
String scriptName = "transformMissingParent.R";
String transformContent = "library(Rlabkey);";
File transformFile = nestedDir.resolve(scriptName).toFile();
TestFileUtils.writeFile(transformFile, transformContent);
// Create a General assay and add the transform by absolute path (not upload)
var protocolResponse = new GeneralAssayDesign(assayName).setBatchFields(List.of(), false).createAssay(getProjectName(), createDefaultConnection());
var assayDesignerPage = ReactAssayDesignerPage.beginAt(this, getProjectName(), protocolResponse.getProtocolId(),
"general", "");
// add by path so the absolute path is stored; this allows reproducing the missing parent dir scenario
assayDesignerPage.addTransformScript(transformFile);
assayDesignerPage.clickSave();
// Now delete the parent dir to ensure we handle it reasonably. On Windows something locks the directory, maybe
// an external process. If that happens sleep for a second and try again.
for (int attempt = 1; attempt <= 10; attempt++) {
try
{
FileUtils.deleteDirectory(parentDir.toFile());
log(String.format("Deletion of directory %s was successful.", parentDir));
break;
} catch (AccessDeniedException deniedException) {
// Yes I know AccessDeniedException is a subset of an IOException, but I wanted to log explicitly a
// failure and retry because of an AccessDeniedException from some other IOException.
log(String.format("Access denied trying to delete directory %s. Error: %s. Waiting 10s and retrying. Attempt %d of 10.",
parentDir, deniedException.getMessage(), attempt));
if (attempt == 10) throw deniedException;
sleep(10_000);
}
catch (IOException ioException) {
log(String.format("IOException trying to delete directory %s. Error: %s. Waiting 10s and retrying. Attempt %d of 10.",
parentDir, ioException.getMessage(), attempt));
if (attempt == 10) throw ioException;
sleep(10_000);
}
}
// Attempt to import data and verify a reasonable error message is shown
String importData = """
VisitID\tParticipantID\tComment
1\tP1\timport after parent deleted
""";
new AssayRunsPage(getDriver()).getTable().clickHeaderButtonAndWait("Import Data");
var importPage = new AssayImportPage(getDriver());
importPage.setNamedInputText("Name", "missingParentImport");
importPage.setNamedTextAreaValue(AssayConstants.TEXT_AREA_DATA_COLLECTOR_TEXT_AREA_NAME, importData);
importPage.clickSaveAndFinish();
// Expect an error page/message indicating the transform script path cannot be used
// Be tolerant to platform-specific phrasing; assert any of these appear
String expectedPath = transformFile.getAbsolutePath();
checker().withScreenshot("missing-parent-error")
.verifyTrue("Expect an error message about the transform script path not being found",
isTextPresent("transformMissingParent.R, configured for this assay does not exist."));
// Fix the assay design by removing the transform script
goToProjectHome();
assayDesignerPage = ReactAssayDesignerPage.beginAt(this, getProjectName(), protocolResponse.getProtocolId(),
"general", getURL().toString());
assayDesignerPage.removeTransformScript(scriptName);
assayDesignerPage.clickSave();
// Retry the import and verify it succeeds without the transform
clickAndWait(Locator.linkWithText(assayName));
new AssayRunsPage(getDriver()).getTable().clickHeaderButtonAndWait("Import Data");
importPage = new AssayImportPage(getDriver());
importPage.setNamedInputText("Name", "fixedAssayImport");
importPage.setNamedTextAreaValue(AssayConstants.TEXT_AREA_DATA_COLLECTOR_TEXT_AREA_NAME, importData);
importPage.clickSaveAndFinish();
// Verify we land on the run details page and can see the run name (no transform needed)
new AssayRunsPage(getDriver()).clickAssayIdLink("fixedAssayImport");
}
}