From 30d182f645e6011b0ade3dd86e513f5a4340674d Mon Sep 17 00:00:00 2001 From: Jan Vonka Date: Tue, 7 Sep 2010 16:05:44 +0000 Subject: [PATCH] ALF-4291: PostgreSQL - AVM index/search (wip) - oops ... add new file ! git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@22308 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../repo/avm/AVMServiceConcurrentTest.java | 590 ++++++++++++++++++ 1 file changed, 590 insertions(+) create mode 100644 source/java/org/alfresco/repo/avm/AVMServiceConcurrentTest.java diff --git a/source/java/org/alfresco/repo/avm/AVMServiceConcurrentTest.java b/source/java/org/alfresco/repo/avm/AVMServiceConcurrentTest.java new file mode 100644 index 0000000000..478d498526 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/AVMServiceConcurrentTest.java @@ -0,0 +1,590 @@ +/* + * Copyright (C) 2005-2010 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.repo.avm; + +import java.util.List; +import java.util.SortedMap; + +import javax.transaction.UserTransaction; + +import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; +import org.alfresco.service.cmr.avm.AVMNodeDescriptor; +import org.alfresco.service.cmr.avmsync.AVMDifference; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.search.ResultSet; +import org.alfresco.service.cmr.search.ResultSetRow; +import org.alfresco.service.cmr.search.SearchService; + +/** + * AVM concurrency and search + * + * @author andyh, janv + */ +public class AVMServiceConcurrentTest extends AVMServiceTestBase +{ + public void testSetup() throws Exception + { + super.testSetup(); + } + + public void test_CreateDelete() throws Exception + { + int threads= 4; + + int loops = 10; + + //int snapshotsPerLoop = 4; + int snapshotsPerLoop = 1; + + fService.createDirectory("main:/", "test"); + + int startVersion = fService.createSnapshot("main", null, null).get("main"); + + assertEquals(0, fService.getDirectoryListing(-1, "main:/test").size()); + + UserTransaction testTX = fTransactionService.getUserTransaction(); + testTX.begin(); + + StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); + SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true); + ResultSet results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\""); + assertEquals(0, results.length()); + results.close(); + + testTX.commit(); + + Thread runner = null; + for (int i = 0; i < threads; i++) + { + runner = new Nester("Concurrent-" + i, runner, false, snapshotsPerLoop, Nester.Mode.CREATE, loops); + } + + if (runner != null) + { + runner.start(); + + try + { + runner.join(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + SortedMap listing = fService.getDirectoryListing(-1, "main:/test"); + assertEquals(loops, listing.size()); + + for(AVMNodeDescriptor node : listing.values()) + { + System.out.println("Listed: "+node.getPath()+" "+node.getVersionID()); + } + List diffs = fSyncService.compare(startVersion, "main:/", -1, "main:/", null); + assertEquals(loops, diffs.size()); + for(AVMDifference diff : diffs) + { + AVMNodeDescriptor desc = fService.lookup(diff.getDestinationVersion(), diff.getDestinationPath(), true); + assertFalse(desc.isDeleted()); + } + + testTX = fTransactionService.getUserTransaction(); + testTX.begin(); + + searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true); + results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\""); + for(ResultSetRow row : results) + { + System.out.println("Found: "+row.getNodeRef()); + } + assertEquals(loops, results.length()); + results.close(); + + testTX.commit(); + + + // delete + + runner = null; + for (int i = 0; i < threads; i++) + { + runner = new Nester("Concurrent-" + i, runner, false, snapshotsPerLoop, Nester.Mode.DELETE, loops); + } + if (runner != null) + { + runner.start(); + + try + { + runner.join(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + assertEquals(0, fService.getDirectoryListing(-1, "main:/test").size()); + + testTX = fTransactionService.getUserTransaction(); + testTX.begin(); + + searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true); + results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\""); + for(ResultSetRow row : results) + { + System.out.println("Found: "+row.getNodeRef()); + } + assertEquals(0, results.length()); + results.close(); + + testTX.commit(); + } + + public void test_ALF_786() throws Exception + { + //int threads= 4; + int threads= 2; + + int loops = 10; + + //int snapshotsPerLoop = 4; + int snapshotsPerLoop = 1; + + fService.createDirectory("main:/", "test"); + + int startVersion = fService.createSnapshot("main", null, null).get("main"); + + assertEquals(0, fService.getDirectoryListing(-1, "main:/test").size()); + + UserTransaction testTX = fTransactionService.getUserTransaction(); + testTX.begin(); + + StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); + SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true); + ResultSet results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\""); + assertEquals(0, results.length()); + results.close(); + + testTX.commit(); + + Thread runner = null; + for (int i = 0; i < threads; i++) + { + runner = new Nester("Concurrent-" + i, runner, false, snapshotsPerLoop, Nester.Mode.CREATE, loops); + } + + if (runner != null) + { + runner.start(); + + try + { + runner.join(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + SortedMap listing = fService.getDirectoryListing(-1, "main:/test"); + assertEquals(loops, listing.size()); + + for(AVMNodeDescriptor node : listing.values()) + { + System.out.println("Listed: "+node.getPath()+" "+node.getVersionID()); + } + List diffs = fSyncService.compare(startVersion, "main:/", -1, "main:/", null); + assertEquals(loops, diffs.size()); + for(AVMDifference diff : diffs) + { + AVMNodeDescriptor desc = fService.lookup(diff.getDestinationVersion(), diff.getDestinationPath(), true); + assertFalse(desc.isDeleted()); + } + + testTX = fTransactionService.getUserTransaction(); + testTX.begin(); + + searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true); + results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\""); + for(ResultSetRow row : results) + { + System.out.println("Found: "+row.getNodeRef()); + } + assertEquals(loops, results.length()); + results.close(); + + testTX.commit(); + + // update + + runner = null; + for (int i = 0; i < threads; i++) + { + runner = new Nester("Concurrent-" + i, runner, false, snapshotsPerLoop, Nester.Mode.UPDATE, loops); + } + + if (runner != null) + { + runner.start(); + + try + { + runner.join(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + testTX = fTransactionService.getUserTransaction(); + testTX.begin(); + + searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true); + results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\""); + for(ResultSetRow row : results) + { + System.out.println("Found: "+row.getNodeRef()); + } + assertEquals(loops, results.length()); + + results.close(); + testTX.commit(); + + // delete + + runner = null; + for (int i = 0; i < threads; i++) + { + runner = new Nester("Concurrent-" + i, runner, false, snapshotsPerLoop, Nester.Mode.DELETE, loops); + } + if (runner != null) + { + runner.start(); + + try + { + runner.join(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + assertEquals(0, fService.getDirectoryListing(-1, "main:/test").size()); + + testTX = fTransactionService.getUserTransaction(); + testTX.begin(); + + searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true); + results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\""); + for(ResultSetRow row : results) + { + System.out.println("Found: "+row.getNodeRef()); + } + assertEquals(0, results.length()); + results.close(); + + testTX.commit(); + + // recreate + + runner = null; + for (int i = 0; i < threads; i++) + { + runner = new Nester("Concurrent-" + i, runner, false, snapshotsPerLoop, Nester.Mode.CREATE, loops); + } + if (runner != null) + { + runner.start(); + + try + { + runner.join(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + testTX = fTransactionService.getUserTransaction(); + testTX.begin(); + + searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true); + results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\""); + for(ResultSetRow row : results) + { + System.out.println("Found: "+row.getNodeRef()); + } + assertEquals(loops, results.length()); + results.close(); + + testTX.commit(); + + //move + + runner = null; + for (int i = 0; i < threads; i++) + { + runner = new Nester("Concurrent-" + i, runner, false, snapshotsPerLoop, Nester.Mode.MOVE, loops); + } + if (runner != null) + { + runner.start(); + + try + { + runner.join(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + testTX = fTransactionService.getUserTransaction(); + testTX.begin(); + + searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true); + results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\""); + for(ResultSetRow row : results) + { + System.out.println("Found: "+row.getNodeRef()); + } + assertEquals(loops, results.length()); + results.close(); + + testTX.commit(); + } + + public void xtest_ALF_786_PLUS() throws Exception + { + int startVersion; + UserTransaction testTX = fTransactionService.getUserTransaction(); + testTX.begin(); + fService.createDirectory("main:/", "test"); + startVersion = fService.createSnapshot("main", null, null).get("main"); + + testTX.commit(); + testTX = fTransactionService.getUserTransaction(); + testTX.begin(); + + + StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); + SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true); + ResultSet results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\""); + assertEquals(0, results.length()); + results.close(); + testTX.commit(); + + Thread runner = null; + + for (int i = 0; i < 10; i++) + { + runner = new Nester("Concurrent-" + i, runner, true, 10, Nester.Mode.CREATE, 10 ); + } + if (runner != null) + { + runner.start(); + + try + { + runner.join(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + testTX = fTransactionService.getUserTransaction(); + testTX.begin(); + // snap + testTX.commit(); + testTX = fTransactionService.getUserTransaction(); + testTX.begin();; + SortedMap listing = fService.getDirectoryListing(-1, "main:/test"); + assertEquals(100, listing.size()); + for(AVMNodeDescriptor node : listing.values()) + { + System.out.println("Listed: "+node.getPath()+" "+node.getVersionID()); + } + List diffs = fSyncService.compare(startVersion, "main:/", -1, "main:/", null); + assertEquals(100, diffs.size()); + for(AVMDifference diff : diffs) + { + AVMNodeDescriptor desc = fService.lookup(diff.getDestinationVersion(), diff.getDestinationPath(), true); + assertFalse(desc.isDeleted()); + } + + + + searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true); + results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\""); + for(ResultSetRow row : results) + { + System.out.println("Found: "+row.getNodeRef()); + } + assertEquals(100, results.length()); + results.close(); + testTX.commit(); + } + + static class Nester extends Thread + { + enum Mode {CREATE, UPDATE, DELETE, MOVE}; + + Thread waiter; + + int i; + + boolean multiThread; + + int snapshotCount; + + Mode mode; + + int loopCount; + + Nester(String name, Thread waiter, boolean multiThread, int snapshotCount, Mode mode, int loopCount) + { + super(name); + this.setDaemon(true); + this.waiter = waiter; + this.multiThread = multiThread; + this.snapshotCount = snapshotCount; + this.mode = mode; + this.loopCount = loopCount; + } + + public void run() + { + fAuthenticationComponent.setSystemUserAsCurrentUser(); + if (waiter != null) + { + waiter.start(); + } + try + { + System.out.println("Start " + this.getName()); + for(i = 0; i < loopCount; i++) + { + RetryingTransactionCallback create = new RetryingTransactionCallback() + { + public Void execute() throws Throwable + { + fService.createFile("main:/test", getName()+"-"+i).close(); + + return null; + } + }; + RetryingTransactionCallback update = new RetryingTransactionCallback() + { + public Void execute() throws Throwable + { + fService.setMimeType("main:/test/"+getName()+"-"+i, "text/plain"); + + return null; + } + }; + RetryingTransactionCallback delete = new RetryingTransactionCallback() + { + public Void execute() throws Throwable + { + fService.removeNode("main:/test/"+getName()+"-"+i); + + return null; + } + }; + RetryingTransactionCallback move = new RetryingTransactionCallback() + { + public Void execute() throws Throwable + { + fService.rename("main:/test/", getName()+"-"+i, "main:/test/", "MOVED-"+getName()+"-"+i); + + return null; + } + }; + if(multiThread || (waiter == null)) + { + // only one thread creates for 786 + switch(mode) + { + case CREATE: + fRetryingTransactionHelper.doInTransaction(create); + System.out.println(getName()+i); + break; + case UPDATE: + fRetryingTransactionHelper.doInTransaction(update); + break; + case DELETE: + fRetryingTransactionHelper.doInTransaction(delete); + break; + case MOVE: + fRetryingTransactionHelper.doInTransaction(move); + break; + default: + } + + } + + RetryingTransactionCallback snap = new RetryingTransactionCallback() + { + public Void execute() throws Throwable + { + fService.createSnapshot("main", null, null); + + return null; + } + }; + for(int s = 0; s < snapshotCount; s++) + { + fRetryingTransactionHelper.doInTransaction(snap); + } + } + System.out.println("End " + this.getName()); + } + catch (Exception e) + { + System.out.println("End " + this.getName() + " with error " + e.getMessage()); + e.printStackTrace(); + } + finally + { + fAuthenticationComponent.clearCurrentSecurityContext(); + } + if (waiter != null) + { + try + { + waiter.join(); + System.out.println("Waited for " + waiter.getName()+" by "+this.getName()); + } + catch (InterruptedException e) + { + } + } + } + } +}