diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/dataload/Loader.java b/search-services/alfresco-search/src/test/java/org/alfresco/dataload/Loader.java deleted file mode 100644 index f723a4175..000000000 --- a/search-services/alfresco-search/src/test/java/org/alfresco/dataload/Loader.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2005-2017 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.dataload; - -import org.apache.solr.client.solrj.impl.HttpSolrClient; -import org.apache.solr.client.solrj.request.UpdateRequest; -import org.apache.solr.common.SolrInputDocument; - -import java.time.LocalDateTime; -import java.time.ZoneOffset; -import java.time.format.DateTimeFormatter; -import java.util.Random; - -public class Loader { - - public static void main(String args[]) throws Exception { - int num = Integer.parseInt(args[0]); - int start = Integer.parseInt(args[1]); - //String url = "http://localhost:8985/solr/joel"; - String url = "http://localhost:8983/solr/collection1"; - - HttpSolrClient client = new HttpSolrClient(url); - UpdateRequest request = new UpdateRequest(); - int i = start; - LocalDateTime localDate = LocalDateTime.now(); - - Random rand = new Random(); - for(i=start; i 0); } + /** + * Asserts that the input {@link ShardState} and the CoreAdmin.SUMMARY response give the same information. + * + * @param state the {@link ShardState} instance. + * @param core the target {@link SolrCore} instance. + */ + public static void assertShardAndCoreSummaryConsistency(ShardState state, SolrCore core) { + SolrParams params = + new ModifiableSolrParams() + .add(CoreAdminParams.CORE, core.getName()) + .add(CoreAdminParams.ACTION, "SUMMARY"); -} + SolrQueryRequest request = new LocalSolrQueryRequest(core, params); + SolrQueryResponse response = new SolrQueryResponse(); + coreAdminHandler(core).handleRequest(request, response); + + NamedList summary = + ofNullable(response.getValues()) + .map(values -> values.get("Summary")) + .map(NamedList.class::cast) + .map(values -> values.get(core.getName())) + .map(NamedList.class::cast) + .orElseGet(NamedList::new); + + assertEquals(state.getLastIndexedChangeSetId(), summary.get("Id for last Change Set in index")); + assertEquals(state.getLastIndexedChangeSetCommitTime(), summary.get("Last Index Change Set Commit Time")); + assertEquals(state.getLastIndexedTxCommitTime(), summary.get("Last Index TX Commit Time")); + assertEquals(state.getLastIndexedTxId(), summary.get("Id for last TX in index")); + } + + public static AlfrescoCoreAdminHandler coreAdminHandler(SolrCore core) { + return of(core).map(SolrCore::getCoreContainer) + .map(CoreContainer::getMultiCoreHandler) + .map(AlfrescoCoreAdminHandler.class::cast) + .orElseThrow(() -> new IllegalStateException("Cannot retrieve the Core Admin Handler on this test core.")); + } +} \ No newline at end of file diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/TestDataProvider.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/dataload/TestDataProvider.java similarity index 97% rename from search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/TestDataProvider.java rename to search-services/alfresco-search/src/test/java/org/alfresco/solr/dataload/TestDataProvider.java index 466dff0e8..4a98111b7 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/TestDataProvider.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/dataload/TestDataProvider.java @@ -16,10 +16,11 @@ * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see . */ -package org.alfresco.solr.query.afts; +package org.alfresco.solr.dataload; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; +import static java.util.stream.IntStream.range; import static org.alfresco.model.ContentModel.ASSOC_CONTAINS; import static org.alfresco.model.ContentModel.ASSOC_CHILDREN; import static org.alfresco.model.ContentModel.PROP_NAME; @@ -28,6 +29,8 @@ import static org.alfresco.service.namespace.NamespaceService.CONTENT_MODEL_1_0_ import static org.alfresco.solr.AlfrescoSolrUtils.addNode; import static org.alfresco.solr.AlfrescoSolrUtils.createGUID; import static org.alfresco.solr.AlfrescoSolrUtils.addStoreRoot; +import static org.alfresco.solr.AlfrescoSolrUtils.getNode; +import static org.alfresco.solr.AlfrescoSolrUtils.getNodeMetaData; import org.alfresco.model.ContentModel; import org.alfresco.service.cmr.repository.ChildAssociationRef; @@ -39,19 +42,27 @@ import org.alfresco.service.cmr.repository.datatype.Duration; import org.alfresco.service.namespace.QName; import org.alfresco.solr.AlfrescoSolrConstants; import org.alfresco.solr.AlfrescoSolrDataModel; +import org.alfresco.solr.client.Acl; import org.alfresco.solr.client.ContentPropertyValue; import org.alfresco.solr.client.MLTextPropertyValue; import org.alfresco.solr.client.MultiPropertyValue; +import org.alfresco.solr.client.Node; +import org.alfresco.solr.client.NodeMetaData; import org.alfresco.solr.client.PropertyValue; import org.alfresco.solr.client.StringPropertyValue; +import org.alfresco.solr.client.Transaction; import org.alfresco.util.ISO9075; +import org.apache.solr.client.solrj.io.Tuple; import org.apache.solr.core.SolrCore; import org.apache.solr.util.TestHarness; +import java.util.AbstractMap; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.stream.Collectors; /** * Test datasets provider. @@ -855,6 +866,14 @@ public class TestDataProvider implements AlfrescoSolrConstants return testProperties; } + public static Map.Entry, List> nSampleNodesWithSampleContent(Acl acl, Transaction txn, int howManyNodes) { + + List nodes = range(0, howManyNodes).mapToObj(index -> getNode(txn, acl, Node.SolrApiNodeStatus.UPDATED)).collect(Collectors.toList()); + List metadata = nodes.stream().map(node -> getNodeMetaData(node, txn, acl, "mike", null, false)).collect(Collectors.toList()); + + return new AbstractMap.SimpleImmutableEntry<>(nodes, metadata); + } + public NodeRef newNodeRef() { return new NodeRef(new StoreRef("workspace", "SpacesStore"), createGUID()); diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/FieldNameEscapingTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/FieldNameEscapingTest.java index d1d655fb3..6485fd022 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/FieldNameEscapingTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/FieldNameEscapingTest.java @@ -19,7 +19,7 @@ package org.alfresco.solr.query.afts.qparser; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; -import org.alfresco.solr.query.afts.TestDataProvider; +import org.alfresco.solr.dataload.TestDataProvider; import org.alfresco.util.ISO9075; import org.junit.BeforeClass; import org.junit.Test; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/QParserPluginTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/QParserPluginTest.java index 72858fb01..a270280e2 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/QParserPluginTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/qparser/QParserPluginTest.java @@ -30,7 +30,7 @@ import static org.alfresco.model.ContentModel.TYPE_THUMBNAIL; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; import org.alfresco.service.namespace.QName; -import org.alfresco.solr.query.afts.TestDataProvider; +import org.alfresco.solr.dataload.TestDataProvider; import org.alfresco.util.CachingDateFormat; import org.apache.solr.SolrTestCaseJ4; import org.junit.BeforeClass; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDefaultTextQueryTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDefaultTextQueryTest.java index cb49e7fd2..6791bbf32 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDefaultTextQueryTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDefaultTextQueryTest.java @@ -22,7 +22,7 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; import org.alfresco.solr.client.PropertyValue; import org.alfresco.solr.client.StringPropertyValue; -import org.alfresco.solr.query.afts.TestDataProvider; +import org.alfresco.solr.dataload.TestDataProvider; import org.junit.BeforeClass; import org.junit.Test; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDisjunctionTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDisjunctionTest.java index e42d9f9d7..8462d00e3 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDisjunctionTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSDisjunctionTest.java @@ -30,7 +30,7 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; import org.alfresco.solr.client.PropertyValue; import org.alfresco.solr.client.StringPropertyValue; -import org.alfresco.solr.query.afts.TestDataProvider; +import org.alfresco.solr.dataload.TestDataProvider; import org.junit.BeforeClass; import org.junit.Test; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSIdentifierFieldsTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSIdentifierFieldsTest.java index 8a207e463..2dc910b8c 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSIdentifierFieldsTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSIdentifierFieldsTest.java @@ -27,7 +27,7 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; import org.alfresco.solr.client.PropertyValue; import org.alfresco.solr.client.StringPropertyValue; -import org.alfresco.solr.query.afts.TestDataProvider; +import org.alfresco.solr.dataload.TestDataProvider; import org.junit.BeforeClass; import org.junit.Test; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRangeQueryTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRangeQueryTest.java index 6c303b505..ed38a5006 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRangeQueryTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRangeQueryTest.java @@ -28,7 +28,7 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.namespace.QName; import org.alfresco.solr.client.PropertyValue; import org.alfresco.solr.client.StringPropertyValue; -import org.alfresco.solr.query.afts.TestDataProvider; +import org.alfresco.solr.dataload.TestDataProvider; import org.alfresco.util.Pair; import org.junit.BeforeClass; import org.junit.Test; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRequestHandlerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRequestHandlerTest.java index 255c655cd..b6f818791 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRequestHandlerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/AFTSRequestHandlerTest.java @@ -10,7 +10,7 @@ import org.alfresco.repo.search.adaptor.lucene.QueryConstants; import org.alfresco.service.namespace.QName; import org.alfresco.solr.AlfrescoSolrDataModel; import org.alfresco.solr.SolrInformationServer; -import org.alfresco.solr.query.afts.TestDataProvider; +import org.alfresco.solr.dataload.TestDataProvider; import org.apache.lucene.util.LuceneTestCase; import org.apache.solr.SolrTestCaseJ4; import org.junit.BeforeClass; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/MNTTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/MNTTest.java index 25b9c9e9d..a7b0dd5df 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/MNTTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/query/afts/requestHandler/MNTTest.java @@ -1,6 +1,6 @@ package org.alfresco.solr.query.afts.requestHandler; -import org.alfresco.solr.query.afts.TestDataProvider; +import org.alfresco.solr.dataload.TestDataProvider; import org.junit.BeforeClass; import org.junit.Test; diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerStateTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerStateTest.java index b1ba7125d..b3195d50d 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerStateTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/AlfrescoSolrTrackerStateTest.java @@ -19,7 +19,6 @@ package org.alfresco.solr.tracker; -import org.alfresco.repo.index.shard.ShardState; import org.alfresco.repo.search.adaptor.lucene.QueryConstants; import org.alfresco.solr.AbstractAlfrescoSolrTests; import org.alfresco.solr.AlfrescoCoreAdminHandler; @@ -29,135 +28,98 @@ import org.alfresco.solr.client.AclReaders; import org.alfresco.solr.client.Node; import org.alfresco.solr.client.NodeMetaData; import org.alfresco.solr.client.Transaction; +import org.alfresco.solr.dataload.TestDataProvider; +import org.apache.lucene.document.LongPoint; import org.apache.lucene.index.Term; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.LegacyNumericRangeQuery; import org.apache.lucene.search.TermQuery; -import org.apache.solr.common.params.CoreAdminParams; -import org.apache.solr.common.params.ModifiableSolrParams; -import org.apache.solr.common.params.SolrParams; -import org.apache.solr.common.util.NamedList; -import org.apache.solr.core.CoreContainer; import org.apache.solr.core.SolrCore; -import org.apache.solr.request.LocalSolrQueryRequest; -import org.apache.solr.request.SolrQueryRequest; -import org.apache.solr.response.SolrQueryResponse; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import java.util.List; +import java.util.Map; + import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static java.util.Optional.of; -import static java.util.Optional.ofNullable; +import static org.alfresco.solr.AlfrescoSolrUtils.MAX_WAIT_TIME; +import static org.alfresco.solr.AlfrescoSolrUtils.assertShardAndCoreSummaryConsistency; +import static org.alfresco.solr.AlfrescoSolrUtils.coreAdminHandler; import static org.alfresco.solr.AlfrescoSolrUtils.getAcl; import static org.alfresco.solr.AlfrescoSolrUtils.getAclChangeSet; import static org.alfresco.solr.AlfrescoSolrUtils.getAclReaders; -import static org.alfresco.solr.AlfrescoSolrUtils.getNode; -import static org.alfresco.solr.AlfrescoSolrUtils.getNodeMetaData; import static org.alfresco.solr.AlfrescoSolrUtils.getTransaction; import static org.alfresco.solr.AlfrescoSolrUtils.indexAclChangeSet; -import static org.junit.Assert.assertEquals; +/** + * A partial state of {@link org.alfresco.solr.TrackerState} is exposed through two interfaces: AdminHandler.SUMMARY and + * {@link MetadataTracker#getShardState}. + * + * This test makes sure that state is consistent across the two mentioned approaches. That is, properties returned by the + * Core SUMMARY must have the same value of the same properties in the ShardState. + * + * @author agazzarini + */ public class AlfrescoSolrTrackerStateTest extends AbstractAlfrescoSolrTests { - private static long MAX_WAIT_TIME = 80000; - @BeforeClass public static void beforeClass() throws Exception { initAlfrescoCore("schema.xml"); } - private Acl acl; - @Before public void prepare() throws Exception { AclChangeSet aclChangeSet = getAclChangeSet(1); - acl = getAcl(aclChangeSet); + + Acl acl = getAcl(aclChangeSet); Acl acl2 = getAcl(aclChangeSet); AclReaders aclReaders = getAclReaders(aclChangeSet, acl, singletonList("joel"), singletonList("phil"), null); AclReaders aclReaders2 = getAclReaders(aclChangeSet, acl2, singletonList("jim"), singletonList("phil"), null); - indexAclChangeSet(aclChangeSet, - asList(acl, acl2), - asList(aclReaders, aclReaders2)); + indexAclChangeSet(aclChangeSet, asList(acl, acl2), asList(aclReaders, aclReaders2)); - // Check for the ACL state stamp. BooleanQuery.Builder builder = new BooleanQuery.Builder(); builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_SOLR4_ID, "TRACKER!STATE!ACLTX")), BooleanClause.Occur.MUST)); builder.add(new BooleanClause(LegacyNumericRangeQuery.newLongRange(QueryConstants.FIELD_S_ACLTXID, aclChangeSet.getId(), aclChangeSet.getId() + 1, true, false), BooleanClause.Occur.MUST)); BooleanQuery waitForQuery = builder.build(); waitForDocCount(waitForQuery, 1, MAX_WAIT_TIME); + + int howManyTestNodes = 4; + + Transaction txn = getTransaction(0, howManyTestNodes); + Map.Entry, List> data = TestDataProvider.nSampleNodesWithSampleContent(acl, txn, howManyTestNodes); + + indexTransaction(txn, data.getKey(), data.getValue()); + + makeSureTransactionHasBeenIndexed(txn.getId()); + makeSureNodesHaveBeenIndexed(data.getKey().size()); } @Test - public void shardStateMustBeConsistentWithCoreSummaryStats() throws Exception + @SuppressWarnings("deprecated") + public void shardStateMustBeConsistentWithCoreSummaryStats() { - Transaction txn = getTransaction(0, 4); - - Node node1 = getNode(txn, acl, Node.SolrApiNodeStatus.UPDATED); - Node node2 = getNode(txn, acl, Node.SolrApiNodeStatus.UPDATED); - Node node3 = getNode(txn, acl, Node.SolrApiNodeStatus.UPDATED); - Node node4 = getNode(txn, acl, Node.SolrApiNodeStatus.UPDATED); - - NodeMetaData nodeMetaData1 = getNodeMetaData(node1, txn, acl, "mike", null, false); - NodeMetaData nodeMetaData2 = getNodeMetaData(node2, txn, acl, "mike", null, false); - NodeMetaData nodeMetaData3 = getNodeMetaData(node3, txn, acl, "mike", null, false); - NodeMetaData nodeMetaData4 = getNodeMetaData(node4, txn, acl, "mike", null, false); - - indexTransaction(txn, - asList(node1, node2, node3, node4), - asList(nodeMetaData1, nodeMetaData2, nodeMetaData3, nodeMetaData4)); - - makeSureTransactionHasBeenIndexed(txn.getId()); - makeSureNodesHaveBeenIndexed("mike", 4); - SolrCore core = getCore(); - AlfrescoCoreAdminHandler adminHandler = - of(core).map(SolrCore::getCoreContainer) - .map(CoreContainer::getMultiCoreHandler) - .map(AlfrescoCoreAdminHandler.class::cast) - .orElseThrow(() -> new IllegalStateException("Cannot retrieve the Core Admin Handler on this test core.")); MetadataTracker tracker = - of(adminHandler) - .map(AlfrescoCoreAdminHandler::getTrackerRegistry) - .map(registry -> registry.getTrackerForCore(core.getName(), MetadataTracker.class)) - .orElseThrow(() -> new IllegalStateException("Cannot retrieve the Metadata tracker on this test core.")); + of(coreAdminHandler(core)) + .map(AlfrescoCoreAdminHandler::getTrackerRegistry) + .map(registry -> registry.getTrackerForCore(core.getName(), MetadataTracker.class)) + .orElseThrow(() -> new IllegalStateException("Cannot retrieve the Metadata tracker on this test core.")); - ShardState state = tracker.getShardState(); - - SolrParams params = - new ModifiableSolrParams() - .add(CoreAdminParams.CORE, core.getName()) - .add(CoreAdminParams.ACTION, "SUMMARY"); - - SolrQueryRequest request = new LocalSolrQueryRequest(core, params); - SolrQueryResponse response = new SolrQueryResponse(); - adminHandler.handleRequest(request, response); - - NamedList summary = - ofNullable(response.getValues()) - .map(values -> values.get("Summary")) - .map(NamedList.class::cast) - .map(values -> values.get(core.getName())) - .map(NamedList.class::cast) - .orElseGet(NamedList::new); - - assertEquals(state.getLastIndexedChangeSetId(), summary.get("Id for last Change Set in index")); - assertEquals(state.getLastIndexedChangeSetCommitTime(), summary.get("Last Index Change Set Commit Time")); - assertEquals(state.getLastIndexedTxCommitTime(), summary.get("Last Index TX Commit Time")); - assertEquals(state.getLastIndexedTxId(), summary.get("Id for last TX in index")); + assertShardAndCoreSummaryConsistency(tracker.getShardState(), core); } private void makeSureTransactionHasBeenIndexed(long transactionId) throws Exception { - //Check for the TXN state stamp. BooleanQuery.Builder builder = new BooleanQuery.Builder(); builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_SOLR4_ID, "TRACKER!STATE!TX")), BooleanClause.Occur.MUST)); builder.add(new BooleanClause(LegacyNumericRangeQuery.newLongRange(QueryConstants.FIELD_S_TXID, transactionId, transactionId + 1, true, false), BooleanClause.Occur.MUST)); @@ -165,36 +127,14 @@ public class AlfrescoSolrTrackerStateTest extends AbstractAlfrescoSolrTests waitForDocCount(waitForQuery, 1, MAX_WAIT_TIME); } - /** - * Queries the index using a token from the (dummy) text produced by the test framework. - * Once the query returns a positive result we are sure the ContentTracker - * - *
    - *
  1. - * Fetched the text content associated with the test nodes, from Alfresco - *
  2. - *
  3. - * Computed a fingerprint (using the retrieved text) for each node - *
  4. - *
  5. - * Updated the nodes definitions in the (Solr)ContentStore and in Solr - *
  6. - *
- * - * Last but not least, we are also making sure that CommitTracker executed its cycle as well (otherwise documents - * wouldn't be searchable). - * - * @param owner the #FIELD_OWNER which will be used as an additional required query clause. - * @throws Exception in case the MAX_WAIT_TIME is reached and the node is not in results. - */ - private void makeSureNodesHaveBeenIndexed(final String owner, final int expectedCount) throws Exception + private void makeSureNodesHaveBeenIndexed(int expectedCount) throws Exception { waitForDocCount(new TermQuery(new Term(QueryConstants.FIELD_READER, "jim")), 1, MAX_WAIT_TIME); waitForDocCount(new TermQuery(new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "world")), expectedCount, MAX_WAIT_TIME); BooleanQuery.Builder builder = new BooleanQuery.Builder(); builder.add(new BooleanClause(new TermQuery(new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "world")), BooleanClause.Occur.MUST)); - builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_OWNER, owner)), BooleanClause.Occur.MUST)); + builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_OWNER, "mike")), BooleanClause.Occur.MUST)); waitForDocCount(builder.build(), expectedCount, MAX_WAIT_TIME); } } \ No newline at end of file diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerStateTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerStateTest.java new file mode 100644 index 000000000..7f5668184 --- /dev/null +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedAlfrescoSolrTrackerStateTest.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ +package org.alfresco.solr.tracker; + +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static java.util.Optional.of; +import static org.alfresco.solr.AlfrescoSolrUtils.MAX_WAIT_TIME; +import static org.alfresco.solr.AlfrescoSolrUtils.assertShardAndCoreSummaryConsistency; +import static org.alfresco.solr.AlfrescoSolrUtils.coreAdminHandler; +import static org.alfresco.solr.AlfrescoSolrUtils.getAcl; +import static org.alfresco.solr.AlfrescoSolrUtils.getAclChangeSet; +import static org.alfresco.solr.AlfrescoSolrUtils.getAclReaders; +import static org.alfresco.solr.AlfrescoSolrUtils.getTransaction; +import static org.alfresco.solr.AlfrescoSolrUtils.indexAclChangeSet; + +import org.alfresco.repo.search.adaptor.lucene.QueryConstants; +import org.alfresco.solr.AbstractAlfrescoDistributedTest; +import org.alfresco.solr.AlfrescoCoreAdminHandler; +import org.alfresco.solr.client.Acl; +import org.alfresco.solr.client.AclChangeSet; +import org.alfresco.solr.client.AclReaders; +import org.alfresco.solr.client.Node; +import org.alfresco.solr.client.NodeMetaData; +import org.alfresco.solr.client.Transaction; +import org.alfresco.solr.dataload.TestDataProvider; +import org.apache.lucene.document.LongPoint; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.LegacyNumericRangeQuery; +import org.apache.lucene.search.TermQuery; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.List; +import java.util.Map; + +/** + * A partial state of {@link org.alfresco.solr.TrackerState} is exposed through two interfaces: AdminHandler.SUMMARY and + * {@link MetadataTracker#getShardState}. + * This test makes sure that state is consistent across the two mentioned approaches. That is, properties returned by the + * Core SUMMARY must have the same value of the same properties in the ShardState. + * + * Note that this is the distributed version of {@link AlfrescoSolrTrackerStateTest}. + * + * @author agazzarini + */ +public class DistributedAlfrescoSolrTrackerStateTest extends AbstractAlfrescoDistributedTest +{ + @BeforeClass + private static void initData() throws Throwable + { + int howManyShards = 5; + int howManyNodes = 15; + + initSolrServers(howManyShards, getClassName(),null); + + AclChangeSet aclChangeSet = getAclChangeSet(1); + + Acl acl = getAcl(aclChangeSet); + Acl acl2 = getAcl(aclChangeSet); + + AclReaders aclReaders = getAclReaders(aclChangeSet, acl, singletonList("joel"), singletonList("phil"), null); + AclReaders aclReaders2 = getAclReaders(aclChangeSet, acl2, singletonList("jim"), singletonList("phil"), null); + + indexAclChangeSet(aclChangeSet, asList(acl, acl2), asList(aclReaders, aclReaders2)); + + BooleanQuery.Builder builder = new BooleanQuery.Builder(); + builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_SOLR4_ID, "TRACKER!STATE!ACLTX")), BooleanClause.Occur.MUST)); + builder.add(new BooleanClause(LongPoint.newExactQuery(QueryConstants.FIELD_S_ACLTXID, aclChangeSet.getId()), BooleanClause.Occur.MUST)); + BooleanQuery waitForQuery = builder.build(); + waitForDocCountAllCores(waitForQuery, 1, MAX_WAIT_TIME); + + Transaction txn = getTransaction(0, howManyNodes); + Map.Entry, List> data = TestDataProvider.nSampleNodesWithSampleContent(acl, txn, howManyNodes); + + indexTransaction(txn, data.getKey(), data.getValue()); + builder = new BooleanQuery.Builder(); + builder.add(new BooleanClause(new TermQuery(new Term(QueryConstants.FIELD_SOLR4_ID, "TRACKER!STATE!TX")), BooleanClause.Occur.MUST)); + builder.add(new BooleanClause(LongPoint.newExactQuery(QueryConstants.FIELD_S_TXID, txn.getId()), BooleanClause.Occur.MUST)); + waitForQuery = builder.build(); + + waitForDocCountAllCores(waitForQuery, 1, MAX_WAIT_TIME); + waitForDocCountAllCores(new TermQuery(new Term(QueryConstants.FIELD_READER, "jim")), 1, MAX_WAIT_TIME); + waitForDocCount(new TermQuery(new Term("content@s___t@{http://www.alfresco.org/model/content/1.0}content", "world")), howManyNodes, MAX_WAIT_TIME); + } + + @AfterClass + private static void destroyData() + { + dismissSolrServers(); + } + + @Test + public void shardStateMustBeConsistentWithCoreSummaryStats() + { + putHandleDefaults(); + + getJettyCores(solrShards).forEach(core -> { + MetadataTracker tracker = + of(coreAdminHandler(core)) + .map(AlfrescoCoreAdminHandler::getTrackerRegistry) + .map(registry -> registry.getTrackerForCore(core.getName(), MetadataTracker.class)) + .orElseThrow(() -> new IllegalStateException("Cannot retrieve the Metadata tracker on this test core.")); + + assertShardAndCoreSummaryConsistency(tracker.getShardState(), core); + }); + } +} \ No newline at end of file diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateMonthAlfrescoSolrTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateMonthAlfrescoSolrTrackerTest.java index 9bae66994..ed5e49fb2 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateMonthAlfrescoSolrTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/DistributedDateMonthAlfrescoSolrTrackerTest.java @@ -118,7 +118,9 @@ public class DistributedDateMonthAlfrescoSolrTrackerTest extends AbstractAlfresc Date[] dates = new Date[5]; Calendar cal = new GregorianCalendar(); + cal.setTimeZone(TimeZone.getTimeZone("UTC")); for (int i = 0; i < dates.length; i++) { + cal.set(1980, i, 21); dates[i] = cal.getTime(); }