From b1ea64230aa875f17a4a42136fe602359f1eb20d Mon Sep 17 00:00:00 2001 From: Eamonn Mansour <47121388+eamansour@users.noreply.github.com> Date: Thu, 15 Aug 2024 10:25:52 +0100 Subject: [PATCH] Stop going through artifact documents when querying CouchDB for several runs (#263) * Avoid loading artifact paths when getting several runs Signed-off-by: Eamonn Mansour <47121388+eamansour@users.noreply.github.com> * Increase couchdb query results limit to 100 instead of 25 Signed-off-by: Eamonn Mansour <47121388+eamansour@users.noreply.github.com> * Move code to build runs queries into a separate function Signed-off-by: Eamonn Mansour <47121388+eamansour@users.noreply.github.com> * Empty commit to kick off build Signed-off-by: Eamonn Mansour <47121388+eamansour@users.noreply.github.com> * Add more search criteria to unit test Signed-off-by: Eamonn Mansour <47121388+eamansour@users.noreply.github.com> --------- Signed-off-by: Eamonn Mansour <47121388+eamansour@users.noreply.github.com> --- .../internal/CouchdbDirectoryService.java | 125 +++---- .../internal/CouchdbDirectoryServiceTest.java | 328 ++++++++++++++++++ .../internal/mocks/CouchdbTestFixtures.java | 10 +- 3 files changed, 404 insertions(+), 59 deletions(-) create mode 100644 galasa-extensions-parent/dev.galasa.ras.couchdb/src/test/java/dev/galasa/ras/couchdb/internal/CouchdbDirectoryServiceTest.java diff --git a/galasa-extensions-parent/dev.galasa.ras.couchdb/src/main/java/dev/galasa/ras/couchdb/internal/CouchdbDirectoryService.java b/galasa-extensions-parent/dev.galasa.ras.couchdb/src/main/java/dev/galasa/ras/couchdb/internal/CouchdbDirectoryService.java index 326fc68c..b66aceeb 100644 --- a/galasa-extensions-parent/dev.galasa.ras.couchdb/src/main/java/dev/galasa/ras/couchdb/internal/CouchdbDirectoryService.java +++ b/galasa-extensions-parent/dev.galasa.ras.couchdb/src/main/java/dev/galasa/ras/couchdb/internal/CouchdbDirectoryService.java @@ -68,6 +68,8 @@ public class CouchdbDirectoryService implements IResultArchiveStoreDirectoryServ private final CouchdbRasStore store; + private static final int COUCHDB_RESULTS_LIMIT_PER_QUERY = 100; + public CouchdbDirectoryService(CouchdbRasStore store, LogFactory logFactory, HttpRequestFactory requestFactory) { this.store = store; this.logFactory = logFactory; @@ -85,10 +87,13 @@ public boolean isLocal() { return false; } - private Path getRunArtifactPath(TestStructureCouchdb ts) throws CouchdbRasException { - + private CouchdbRasFileSystemProvider createFileSystemProvider() { ResultArchiveStoreFileStore fileStore = new ResultArchiveStoreFileStore(); - CouchdbRasFileSystemProvider runProvider = new CouchdbRasFileSystemProvider(fileStore, store, logFactory); + return new CouchdbRasFileSystemProvider(fileStore, store, logFactory); + } + + private Path getRunArtifactPath(TestStructureCouchdb ts) throws CouchdbRasException { + CouchdbRasFileSystemProvider runProvider = createFileSystemProvider(); if (ts.getArtifactRecordIds() == null || ts.getArtifactRecordIds().isEmpty()) { return runProvider.getRoot(); } @@ -327,58 +332,10 @@ private CouchdbRunResult fetchRun(String id) throws ParseException, IOException, HttpPost httpPost = requestFactory.getHttpPostRequest(store.getCouchdbUri() + "/galasa_run/_find"); - JsonObject selector = new JsonObject(); - JsonArray and = new JsonArray(); - selector.add("$and", and); - - for(IRasSearchCriteria searchCriteria : searchCriterias) { - if (searchCriteria instanceof RasSearchCriteriaRequestor) { - RasSearchCriteriaRequestor sRequestor = (RasSearchCriteriaRequestor) searchCriteria; - - inArray(and, "requestor", sRequestor.getRequestors()); - } else if (searchCriteria instanceof RasSearchCriteriaRunName) { - RasSearchCriteriaRunName sRunName = (RasSearchCriteriaRunName) searchCriteria; - - inArray(and, "runName", sRunName.getRunNames()); - } else if (searchCriteria instanceof RasSearchCriteriaQueuedFrom) { - RasSearchCriteriaQueuedFrom sFrom = (RasSearchCriteriaQueuedFrom) searchCriteria; - - JsonObject criteria = new JsonObject(); - JsonObject jFrom = new JsonObject(); - jFrom.addProperty("$gte", sFrom.getFrom().toString()); - criteria.add("queued", jFrom); - and.add(criteria); - } else if (searchCriteria instanceof RasSearchCriteriaQueuedTo) { - RasSearchCriteriaQueuedTo sTo = (RasSearchCriteriaQueuedTo) searchCriteria; - - JsonObject criteria = new JsonObject(); - JsonObject jTo = new JsonObject(); - jTo.addProperty("$lt", sTo.getTo().toString()); - criteria.add("queued", jTo); - and.add(criteria); - } else if (searchCriteria instanceof RasSearchCriteriaTestName) { - RasSearchCriteriaTestName sTestName = (RasSearchCriteriaTestName) searchCriteria; - - inArray(and, "testName", sTestName.getTestNames()); - } else if (searchCriteria instanceof RasSearchCriteriaBundle) { - RasSearchCriteriaBundle sBundle = (RasSearchCriteriaBundle) searchCriteria; - - inArray(and, "bundle", sBundle.getBundles()); - } else if (searchCriteria instanceof RasSearchCriteriaResult) { - RasSearchCriteriaResult sResult = (RasSearchCriteriaResult) searchCriteria; - - inArray(and, "result", sResult.getResults()); - } else if(searchCriteria instanceof RasSearchCriteriaStatus){ - RasSearchCriteriaStatus sStatus = (RasSearchCriteriaStatus) searchCriteria; - inArray(and, "status", sStatus.getStatusesAsStrings()); - } else { - throw new ResultArchiveStoreException("Unrecognised search criteria class " + searchCriteria.getClass().getName()); - } - } - Find find = new Find(); - find.selector = selector; + find.selector = buildGetRunsQuery(searchCriterias); find.execution_stats = true; + find.limit = COUCHDB_RESULTS_LIMIT_PER_QUERY; while (true) { String requestContent = store.getGson().toJson(find); @@ -407,12 +364,12 @@ private CouchdbRunResult fetchRun(String id) throws ParseException, IOException, } for (TestStructureCouchdb ts : found.docs) { - Path runArtifactPath = getRunArtifactPath(ts); - - // *** Add this run to the results - CouchdbRunResult cdbrr = new CouchdbRunResult(store, ts, runArtifactPath); if (ts.isValid()) { - runs.add(cdbrr); + // Don't load the artifacts for the found runs, just set a root location for artifacts + CouchdbRasFileSystemProvider runProvider = createFileSystemProvider(); + + // Add this run to the results + runs.add(new CouchdbRunResult(store, ts, runProvider.getRoot())); } } @@ -501,6 +458,58 @@ private String getRevision(String databaseName, String id) throws ResultArchiveS } } + private JsonObject buildGetRunsQuery(IRasSearchCriteria... searchCriterias) throws ResultArchiveStoreException { + JsonObject selector = new JsonObject(); + JsonArray and = new JsonArray(); + selector.add("$and", and); + + for(IRasSearchCriteria searchCriteria : searchCriterias) { + if (searchCriteria instanceof RasSearchCriteriaRequestor) { + RasSearchCriteriaRequestor sRequestor = (RasSearchCriteriaRequestor) searchCriteria; + + inArray(and, "requestor", sRequestor.getRequestors()); + } else if (searchCriteria instanceof RasSearchCriteriaRunName) { + RasSearchCriteriaRunName sRunName = (RasSearchCriteriaRunName) searchCriteria; + + inArray(and, "runName", sRunName.getRunNames()); + } else if (searchCriteria instanceof RasSearchCriteriaQueuedFrom) { + RasSearchCriteriaQueuedFrom sFrom = (RasSearchCriteriaQueuedFrom) searchCriteria; + + JsonObject criteria = new JsonObject(); + JsonObject jFrom = new JsonObject(); + jFrom.addProperty("$gte", sFrom.getFrom().toString()); + criteria.add("queued", jFrom); + and.add(criteria); + } else if (searchCriteria instanceof RasSearchCriteriaQueuedTo) { + RasSearchCriteriaQueuedTo sTo = (RasSearchCriteriaQueuedTo) searchCriteria; + + JsonObject criteria = new JsonObject(); + JsonObject jTo = new JsonObject(); + jTo.addProperty("$lt", sTo.getTo().toString()); + criteria.add("queued", jTo); + and.add(criteria); + } else if (searchCriteria instanceof RasSearchCriteriaTestName) { + RasSearchCriteriaTestName sTestName = (RasSearchCriteriaTestName) searchCriteria; + + inArray(and, "testName", sTestName.getTestNames()); + } else if (searchCriteria instanceof RasSearchCriteriaBundle) { + RasSearchCriteriaBundle sBundle = (RasSearchCriteriaBundle) searchCriteria; + + inArray(and, "bundle", sBundle.getBundles()); + } else if (searchCriteria instanceof RasSearchCriteriaResult) { + RasSearchCriteriaResult sResult = (RasSearchCriteriaResult) searchCriteria; + + inArray(and, "result", sResult.getResults()); + } else if(searchCriteria instanceof RasSearchCriteriaStatus) { + RasSearchCriteriaStatus sStatus = (RasSearchCriteriaStatus) searchCriteria; + inArray(and, "status", sStatus.getStatusesAsStrings()); + } else { + throw new ResultArchiveStoreException("Unrecognised search criteria class " + searchCriteria.getClass().getName()); + } + } + return selector; + } + private void inArray(JsonArray and, String field, String[] inArray) { if (inArray == null || inArray.length < 1) { return; diff --git a/galasa-extensions-parent/dev.galasa.ras.couchdb/src/test/java/dev/galasa/ras/couchdb/internal/CouchdbDirectoryServiceTest.java b/galasa-extensions-parent/dev.galasa.ras.couchdb/src/test/java/dev/galasa/ras/couchdb/internal/CouchdbDirectoryServiceTest.java new file mode 100644 index 00000000..0bc8f9cf --- /dev/null +++ b/galasa-extensions-parent/dev.galasa.ras.couchdb/src/test/java/dev/galasa/ras/couchdb/internal/CouchdbDirectoryServiceTest.java @@ -0,0 +1,328 @@ +/* + * Copyright contributors to the Galasa project + * + * SPDX-License-Identifier: EPL-2.0 + */ +package dev.galasa.ras.couchdb.internal; + +import static org.assertj.core.api.Assertions.*; + +import java.io.IOException; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import javax.validation.constraints.NotNull; + +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.util.EntityUtils; +import org.junit.Test; + +import dev.galasa.extensions.common.impl.HttpRequestFactoryImpl; +import dev.galasa.extensions.mocks.BaseHttpInteraction; +import dev.galasa.extensions.mocks.HttpInteraction; +import dev.galasa.framework.TestRunLifecycleStatus; +import dev.galasa.framework.spi.IRunResult; +import dev.galasa.framework.spi.ResultArchiveStoreException; +import dev.galasa.framework.spi.ras.IRasSearchCriteria; +import dev.galasa.framework.spi.ras.RasSearchCriteriaBundle; +import dev.galasa.framework.spi.ras.RasSearchCriteriaQueuedFrom; +import dev.galasa.framework.spi.ras.RasSearchCriteriaQueuedTo; +import dev.galasa.framework.spi.ras.RasSearchCriteriaRequestor; +import dev.galasa.framework.spi.ras.RasSearchCriteriaResult; +import dev.galasa.framework.spi.ras.RasSearchCriteriaRunName; +import dev.galasa.framework.spi.ras.RasSearchCriteriaStatus; +import dev.galasa.framework.spi.ras.RasSearchCriteriaTestName; +import dev.galasa.framework.spi.teststructure.TestStructure; +import dev.galasa.ras.couchdb.internal.mocks.CouchdbTestFixtures; +import dev.galasa.ras.couchdb.internal.mocks.MockLogFactory; +import dev.galasa.ras.couchdb.internal.pojos.FoundRuns; +import dev.galasa.ras.couchdb.internal.pojos.TestStructureCouchdb; + +public class CouchdbDirectoryServiceTest { + + private CouchdbTestFixtures fixtures = new CouchdbTestFixtures(); + + class PostCouchdbFindRunsInteraction extends BaseHttpInteraction { + + private String[] expectedRequestBodyParts; + + public PostCouchdbFindRunsInteraction(String expectedUri, FoundRuns foundRuns, String... expectedRequestBodyParts) { + this(expectedUri, HttpStatus.SC_OK, foundRuns, expectedRequestBodyParts); + } + + public PostCouchdbFindRunsInteraction(String expectedUri, int statusCode, FoundRuns foundRuns, String... expectedRequestBodyParts) { + super(expectedUri, statusCode); + setResponsePayload(foundRuns); + this.expectedRequestBodyParts = expectedRequestBodyParts; + } + + @Override + public void validateRequest(HttpHost host, HttpRequest request) throws RuntimeException { + super.validateRequest(host,request); + assertThat(request.getRequestLine().getMethod()).isEqualTo("POST"); + if (expectedRequestBodyParts.length > 0) { + validatePostRequestBody((HttpPost) request); + } + } + + private void validatePostRequestBody(HttpPost postRequest) { + try { + String requestBody = EntityUtils.toString(postRequest.getEntity()); + assertThat(requestBody).contains(expectedRequestBodyParts); + + } catch (IOException ex) { + fail("Failed to parse POST request body"); + } + } + } + + private TestStructureCouchdb createRunTestStructure(String runName) { + TestStructureCouchdb mockTestStructure = new TestStructureCouchdb(); + mockTestStructure._id = runName; + mockTestStructure.setRunName(runName); + return mockTestStructure; + } + + @Test + public void testGetRunsByQueuedFromOnePageReturnsRunsOk() throws Exception { + // Given... + TestStructureCouchdb mockRun1 = createRunTestStructure("run1"); + TestStructureCouchdb mockRun2 = createRunTestStructure("run2"); + + Instant queuedFromTime = Instant.EPOCH; + RasSearchCriteriaQueuedFrom queuedFrom = new RasSearchCriteriaQueuedFrom(queuedFromTime); + + FoundRuns findRunsResponse = new FoundRuns(); + findRunsResponse.docs = List.of(mockRun1, mockRun2); + findRunsResponse.bookmark = "bookmark!"; + + FoundRuns emptyRunsResponse = new FoundRuns(); + emptyRunsResponse.docs = new ArrayList<>(); + + String expectedUri = "http://my.uri/galasa_run/_find"; + List interactions = List.of( + new PostCouchdbFindRunsInteraction(expectedUri, findRunsResponse, "queued", "$gte", queuedFromTime.toString()), + new PostCouchdbFindRunsInteraction(expectedUri, emptyRunsResponse, "queued", "$gte", queuedFromTime.toString(), findRunsResponse.bookmark) + ); + + MockLogFactory mockLogFactory = new MockLogFactory(); + CouchdbRasStore mockRasStore = fixtures.createCouchdbRasStore(interactions, mockLogFactory); + CouchdbDirectoryService directoryService = new CouchdbDirectoryService(mockRasStore, mockLogFactory, new HttpRequestFactoryImpl()); + + // When... + List runs = directoryService.getRuns(queuedFrom); + + // Then... + assertThat(runs).hasSize(2); + assertThat(runs.get(0).getTestStructure().getRunName()).isEqualTo(mockRun1.getRunName()); + assertThat(runs.get(1).getTestStructure().getRunName()).isEqualTo(mockRun2.getRunName()); + } + + @Test + public void testGetRunsMultiplePagesReturnsRunsOk() throws Exception { + // Given... + TestStructureCouchdb mockRun1 = createRunTestStructure("run1"); + TestStructureCouchdb mockRun2 = createRunTestStructure("run2"); + TestStructureCouchdb mockRun3 = createRunTestStructure("run3"); + + Instant queuedFromTime = Instant.EPOCH; + RasSearchCriteriaQueuedFrom queuedFrom = new RasSearchCriteriaQueuedFrom(queuedFromTime); + + FoundRuns findRunsResponsePage1 = new FoundRuns(); + findRunsResponsePage1.docs = List.of(mockRun1, mockRun2); + findRunsResponsePage1.bookmark = "bookmark1"; + + FoundRuns findRunsResponsePage2 = new FoundRuns(); + findRunsResponsePage2.docs = List.of(mockRun3); + findRunsResponsePage2.bookmark = "bookmark2"; + + FoundRuns emptyRunsResponse = new FoundRuns(); + emptyRunsResponse.docs = new ArrayList<>(); + + String expectedUri = "http://my.uri/galasa_run/_find"; + List interactions = List.of( + new PostCouchdbFindRunsInteraction(expectedUri, findRunsResponsePage1, "queued", "$gte", queuedFromTime.toString()), + new PostCouchdbFindRunsInteraction(expectedUri, findRunsResponsePage2, "queued", "$gte", queuedFromTime.toString(), findRunsResponsePage1.bookmark), + new PostCouchdbFindRunsInteraction(expectedUri, emptyRunsResponse, "queued", "$gte", queuedFromTime.toString(), findRunsResponsePage2.bookmark) + ); + + MockLogFactory mockLogFactory = new MockLogFactory(); + CouchdbRasStore mockRasStore = fixtures.createCouchdbRasStore(interactions, mockLogFactory); + CouchdbDirectoryService directoryService = new CouchdbDirectoryService(mockRasStore, mockLogFactory, new HttpRequestFactoryImpl()); + + // When... + List runs = directoryService.getRuns(queuedFrom); + + // Then... + assertThat(runs).hasSize(3); + assertThat(runs.get(0).getTestStructure().getRunName()).isEqualTo(mockRun1.getRunName()); + assertThat(runs.get(1).getTestStructure().getRunName()).isEqualTo(mockRun2.getRunName()); + assertThat(runs.get(2).getTestStructure().getRunName()).isEqualTo(mockRun3.getRunName()); + } + + @Test + public void testGetRunsWithInvalidRunIgnoresRunOk() throws Exception { + // Given... + String runName1 = "run1"; + TestStructureCouchdb mockRun1 = createRunTestStructure(runName1); + + // No run name is set, so this is not a valid run + TestStructureCouchdb invalidRun = createRunTestStructure(null); + + FoundRuns findRunsResponse = new FoundRuns(); + findRunsResponse.docs = List.of(mockRun1, invalidRun); + findRunsResponse.warning = "this response contains an invalid run!"; + findRunsResponse.bookmark = "bookmark!"; + + FoundRuns emptyRunsResponse = new FoundRuns(); + emptyRunsResponse.docs = new ArrayList<>(); + + String expectedUri = "http://my.uri/galasa_run/_find"; + List interactions = List.of( + new PostCouchdbFindRunsInteraction(expectedUri, findRunsResponse, "runName", runName1), + new PostCouchdbFindRunsInteraction(expectedUri, emptyRunsResponse, "runName", runName1, findRunsResponse.bookmark) + ); + + MockLogFactory mockLogFactory = new MockLogFactory(); + CouchdbRasStore mockRasStore = fixtures.createCouchdbRasStore(interactions, mockLogFactory); + CouchdbDirectoryService directoryService = new CouchdbDirectoryService(mockRasStore, mockLogFactory, new HttpRequestFactoryImpl()); + RasSearchCriteriaRunName runNameCriteria = new RasSearchCriteriaRunName(runName1); + + // When... + List runs = directoryService.getRuns(runNameCriteria); + + // Then... + assertThat(runs).hasSize(1); + assertThat(runs.get(0).getTestStructure().getRunName()).isEqualTo(mockRun1.getRunName()); + } + + @Test + public void testGetRunsWithErrorResponseCodeThrowsError() throws Exception { + // Given... + String expectedUri = "http://my.uri/galasa_run/_find"; + List interactions = List.of( + new PostCouchdbFindRunsInteraction(expectedUri, HttpStatus.SC_INTERNAL_SERVER_ERROR, null) + ); + + MockLogFactory mockLogFactory = new MockLogFactory(); + CouchdbRasStore mockRasStore = fixtures.createCouchdbRasStore(interactions, mockLogFactory); + CouchdbDirectoryService directoryService = new CouchdbDirectoryService(mockRasStore, mockLogFactory, new HttpRequestFactoryImpl()); + RasSearchCriteriaQueuedFrom queuedFrom = new RasSearchCriteriaQueuedFrom(Instant.EPOCH); + + // When... + CouchdbRasException thrown = catchThrowableOfType(() -> directoryService.getRuns(queuedFrom), CouchdbRasException.class); + + // Then... + assertThat(thrown).isNotNull(); + assertThat(thrown.getMessage()).contains("Unable to find runs"); + } + + @Test + public void testGetRunsWithInvalidResponseThrowsError() throws Exception { + // Given... + FoundRuns findRunsResponse = new FoundRuns(); + findRunsResponse.docs = null; + findRunsResponse.bookmark = "bookmark!"; + + FoundRuns emptyRunsResponse = new FoundRuns(); + emptyRunsResponse.docs = new ArrayList<>(); + + String expectedUri = "http://my.uri/galasa_run/_find"; + List interactions = List.of( + new PostCouchdbFindRunsInteraction(expectedUri, findRunsResponse), + new PostCouchdbFindRunsInteraction(expectedUri, emptyRunsResponse) + ); + + MockLogFactory mockLogFactory = new MockLogFactory(); + CouchdbRasStore mockRasStore = fixtures.createCouchdbRasStore(interactions, mockLogFactory); + CouchdbDirectoryService directoryService = new CouchdbDirectoryService(mockRasStore, mockLogFactory, new HttpRequestFactoryImpl()); + RasSearchCriteriaQueuedFrom queuedFrom = new RasSearchCriteriaQueuedFrom(Instant.EPOCH); + + // When... + CouchdbRasException thrown = catchThrowableOfType(() -> directoryService.getRuns(queuedFrom), CouchdbRasException.class); + + // Then... + assertThat(thrown).isNotNull(); + assertThat(thrown.getMessage()).contains("Unable to find runs", "Invalid JSON response"); + } + + @Test + public void testGetRunsMultipleCriteriaReturnsRunsOk() throws Exception { + // Given... + TestStructureCouchdb mockRun1 = createRunTestStructure("run1"); + TestStructureCouchdb mockRun2 = createRunTestStructure("run2"); + + Instant queuedFromTime = Instant.MAX; + Instant queuedToTime = Instant.MAX; + String resultStr = "Passed"; + String requestorName = "me"; + String testNameStr = "mytest"; + String bundleName = "my.bundle"; + RasSearchCriteriaQueuedFrom queuedFrom = new RasSearchCriteriaQueuedFrom(queuedFromTime); + RasSearchCriteriaQueuedTo queuedTo = new RasSearchCriteriaQueuedTo(queuedToTime); + RasSearchCriteriaResult result = new RasSearchCriteriaResult(resultStr); + RasSearchCriteriaRequestor requestor = new RasSearchCriteriaRequestor(requestorName); + RasSearchCriteriaTestName testName = new RasSearchCriteriaTestName(testNameStr); + RasSearchCriteriaBundle bundle = new RasSearchCriteriaBundle(bundleName); + RasSearchCriteriaStatus status = new RasSearchCriteriaStatus(List.of(TestRunLifecycleStatus.FINISHED)); + + FoundRuns findRunsResponse = new FoundRuns(); + findRunsResponse.docs = List.of(mockRun1, mockRun2); + findRunsResponse.bookmark = "bookmark!"; + + FoundRuns emptyRunsResponse = new FoundRuns(); + emptyRunsResponse.docs = new ArrayList<>(); + + String expectedUri = "http://my.uri/galasa_run/_find"; + String[] expectedRequestBodyParts = new String[] { + "queued", "$gte", queuedFromTime.toString(), "$lt", queuedToTime.toString(), "result", resultStr, + "testName", testNameStr, "bundle", bundleName, "status", TestRunLifecycleStatus.FINISHED.toString() + }; + + List interactions = List.of( + new PostCouchdbFindRunsInteraction(expectedUri, findRunsResponse, expectedRequestBodyParts), + new PostCouchdbFindRunsInteraction(expectedUri, emptyRunsResponse, expectedRequestBodyParts) + ); + + MockLogFactory mockLogFactory = new MockLogFactory(); + CouchdbRasStore mockRasStore = fixtures.createCouchdbRasStore(interactions, mockLogFactory); + CouchdbDirectoryService directoryService = new CouchdbDirectoryService(mockRasStore, mockLogFactory, new HttpRequestFactoryImpl()); + + // When... + List runs = directoryService.getRuns(queuedFrom, queuedTo, result, requestor, testName, bundle, status); + + // Then... + assertThat(runs).hasSize(2); + assertThat(runs.get(0).getTestStructure().getRunName()).isEqualTo(mockRun1.getRunName()); + assertThat(runs.get(1).getTestStructure().getRunName()).isEqualTo(mockRun2.getRunName()); + } + + + @Test + public void testGetRunsWithInvalidCriteriaThrowsError() throws Exception { + // Given... + IRasSearchCriteria unknownCriteria = new IRasSearchCriteria() { + @Override + public boolean criteriaMatched(@NotNull TestStructure testStructure) { + return false; + } + }; + + List interactions = new ArrayList<>(); + + MockLogFactory mockLogFactory = new MockLogFactory(); + CouchdbRasStore mockRasStore = fixtures.createCouchdbRasStore(interactions, mockLogFactory); + CouchdbDirectoryService directoryService = new CouchdbDirectoryService(mockRasStore, mockLogFactory, new HttpRequestFactoryImpl()); + + // When... + ResultArchiveStoreException thrown = catchThrowableOfType(() -> directoryService.getRuns(unknownCriteria), ResultArchiveStoreException.class); + + // Then... + assertThat(thrown).isNotNull(); + assertThat(thrown.getMessage()).contains("Unrecognised search criteria"); + } +} diff --git a/galasa-extensions-parent/dev.galasa.ras.couchdb/src/test/java/dev/galasa/ras/couchdb/internal/mocks/CouchdbTestFixtures.java b/galasa-extensions-parent/dev.galasa.ras.couchdb/src/test/java/dev/galasa/ras/couchdb/internal/mocks/CouchdbTestFixtures.java index e8c6f940..a1500657 100644 --- a/galasa-extensions-parent/dev.galasa.ras.couchdb/src/test/java/dev/galasa/ras/couchdb/internal/mocks/CouchdbTestFixtures.java +++ b/galasa-extensions-parent/dev.galasa.ras.couchdb/src/test/java/dev/galasa/ras/couchdb/internal/mocks/CouchdbTestFixtures.java @@ -210,10 +210,18 @@ public CouchdbRasStore createCouchdbRasStore( Map inputProps, Lis IRun mockIRun = new MockIRun(runName1); + return createCouchdbRasStore(mockCps, mockIRun, allInteractions, logFactory); + } + + public CouchdbRasStore createCouchdbRasStore(List allInteractions, MockLogFactory logFactory) throws Exception { + return createCouchdbRasStore(null, null, allInteractions, logFactory); + } + + public CouchdbRasStore createCouchdbRasStore(MockConfigurationPropertyStoreService mockCps, IRun mockRun, List allInteractions , MockLogFactory logFactory ) throws Exception { IFramework mockFramework = new MockFramework() { @Override public IRun getTestRun() { - return mockIRun; + return mockRun; } @Override public @NotNull IConfigurationPropertyStoreService getConfigurationPropertyService(