You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2015/08/06 15:51:51 UTC

svn commit: r1694496 - in /jackrabbit/oak/trunk/oak-run: run_concurrent_addmembers.sh src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java src/main/java/org/apache/jackrabbit/oak/benchmark/ManyGroupMembersTest.java

Author: angela
Date: Thu Aug  6 13:51:51 2015
New Revision: 1694496

URL: http://svn.apache.org/r1694496
Log:
OAK-3190 : Benchmark for adding group members

Added:
    jackrabbit/oak/trunk/oak-run/run_concurrent_addmembers.sh
      - copied, changed from r1694257, jackrabbit/oak/trunk/oak-run/run_concurrent_login.sh
    jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/ManyGroupMembersTest.java
Modified:
    jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java

Copied: jackrabbit/oak/trunk/oak-run/run_concurrent_addmembers.sh (from r1694257, jackrabbit/oak/trunk/oak-run/run_concurrent_login.sh)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/run_concurrent_addmembers.sh?p2=jackrabbit/oak/trunk/oak-run/run_concurrent_addmembers.sh&p1=jackrabbit/oak/trunk/oak-run/run_concurrent_login.sh&r1=1694257&r2=1694496&rev=1694496&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/run_concurrent_login.sh (original)
+++ jackrabbit/oak/trunk/oak-run/run_concurrent_addmembers.sh Thu Aug  6 13:51:51 2015
@@ -15,45 +15,39 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-TITLE=LoginTest
-BENCH="LoginWithMembersTest LoginWithMembershipTest" # LoginTest LoginLogoutTest LoginGetRootLogoutTest"
-USER="user" # admin anonymous"
-USE_TOKEN=false # true
-HASH_ITERATIONS="-1"
-NO_GROUPS="1 10 100 1000"
-USE_NESTED_GROUPS=true # false
+TITLE=ManyGroupMembersTest
+BENCH="ManyGroupMembersTest"
+BATCH_SIZE="1"
+IMPORT_BEHAVIORS="besteffort ignore" #abort"
+MEMBERS_CNT="1 10 100 1000"
 RUNTIME=5
-FIXS="Oak-Tar" # Jackrabbit"
+FIXS="Oak-Tar"
 THREADS="1,10,20,50" #"1,2,4,8,10,15,20,50"
 PROFILE=false
-NUM_ITEMS=1000
 
 LOG=$TITLE"_$(date +'%Y%m%d_%H%M%S').csv"
 echo "Benchmarks: $BENCH" > $LOG
-echo "Fixtures: $FIXS" >> $LOG
+echo "Fixture: $FIXS" >> $LOG
 echo "Runtime: $RUNTIME" >> $LOG
 echo "Concurrency: $THREADS" >> $LOG
 echo "Profiling: $PROFILE" >> $LOG
 
-echo "User: $USER" >> $LOG
-echo "Run with Token: $USE_TOKEN" >> $LOG
-echo "Hash Iterations: $HASH_ITERATIONS" >> $LOG
-echo "Number of Groups: $NO_GROUPS" >> $LOG
-echo "Use Nested Groups: $USE_NESTED_GROUPS" >> $LOG
+echo "Batch Size: $BATCH_SIZE" >> $LOG
+echo "Import Behavior(s): $IMPORT_BEHAVIORS" >> $LOG
+echo "Number of Members: $MEMBERS_CNT" >> $LOG
 
 echo "--------------------------------------" >> $LOG
 
 for bm in $BENCH
     do
-    for noGroups in $NO_GROUPS
+    for importBehavior in $IMPORT_BEHAVIORS
         do
-        # we start new VMs for each fixture to minimize memory impacts between them
-        for fix in $FIXS
+        for noMembers in $MEMBERS_CNT
         do
-            echo "Executing benchmarks as user: $USER with $noGroups groups (nested = $USE_NESTED_GROUPS) on $fix" | tee -a $LOG
+            echo "Executing benchmarks with $noMembers members on $importBehavior" | tee -a $LOG
         echo "-----------------------------------------------------------" | tee -a $LOG
             rm -rf target/Jackrabbit-* target/Oak-Tar-*
-            cmd="java -Xmx2048m -Dprofile=$PROFILE -Druntime=$RUNTIME -Dwarmup=10 -jar target/oak-run-*-SNAPSHOT.jar benchmark --noIterations $HASH_ITERATIONS --runWithToken $USE_TOKEN --numberOfGroups $noGroups --nestedGroups $USE_NESTED_GROUPS --csvFile $LOG --concurrency $THREADS --runAsUser $USER --report false $bm $fix"
+            cmd="java -Xmx2048m -Dprofile=$PROFILE -Druntime=$RUNTIME -Dwarmup=1 -jar target/oak-run-*-SNAPSHOT.jar benchmark --batchSize $BATCH_SIZE --importBehavior $importBehavior --numberOfUsers $noMembers --csvFile $LOG --concurrency $THREADS --report false $bm $FIXS"
             echo $cmd
             $cmd
         done

Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java?rev=1694496&r1=1694495&r2=1694496&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java Thu Aug  6 13:51:51 2015
@@ -37,6 +37,7 @@ import org.apache.jackrabbit.oak.benchma
 import org.apache.jackrabbit.oak.fixture.JackrabbitRepositoryFixture;
 import org.apache.jackrabbit.oak.fixture.OakRepositoryFixture;
 import org.apache.jackrabbit.oak.fixture.RepositoryFixture;
+import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
 
 public class BenchmarkRunner {
 
@@ -95,6 +96,10 @@ public class BenchmarkRunner {
                         .withOptionalArg().ofType(Integer.class).defaultsTo(LoginWithMembershipTest.NUMBER_OF_GROUPS_DEFAULT);
         OptionSpec<Boolean> nestedGroups = parser.accepts("nestedGroups", "Use nested groups.")
                         .withOptionalArg().ofType(Boolean.class).defaultsTo(false);
+        OptionSpec<Integer> batchSize = parser.accepts("batchSize", "Batch size before persisting operations.")
+                .withOptionalArg().ofType(Integer.class).defaultsTo(ManyGroupMembersTest.DEFAULT_BATCH_SIZE);
+        OptionSpec<String> importBehavior = parser.accepts("importBehavior", "Protected Item Import Behavior")
+                                .withOptionalArg().ofType(String.class).defaultsTo(ImportBehavior.NAME_BESTEFFORT);
         OptionSpec<Integer> itemsToRead = parser.accepts("itemsToRead", "Number of items to read")
                 .withRequiredArg().ofType(Integer.class).defaultsTo(1000);
         OptionSpec<Integer> concurrency = parser.accepts("concurrency", "Number of test threads.")
@@ -289,6 +294,10 @@ public class BenchmarkRunner {
             new GetGroupPrincipalsTest(
                     numberOfGroups.value(options),
                     nestedGroups.value(options)),
+            new ManyGroupMembersTest(
+                    numberOfUsers.value(options),
+                    batchSize.value(options),
+                    importBehavior.value(options)),
             new FullTextSearchTest(
                     wikipedia.value(options),
                     flatStructure.value(options),

Added: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/ManyGroupMembersTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/ManyGroupMembersTest.java?rev=1694496&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/ManyGroupMembersTest.java (added)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/ManyGroupMembersTest.java Thu Aug  6 13:51:51 2015
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.benchmark;
+
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import javax.annotation.Nonnull;
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.security.auth.Subject;
+
+import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.oak.Oak;
+import org.apache.jackrabbit.oak.fixture.JcrCreator;
+import org.apache.jackrabbit.oak.fixture.OakRepositoryFixture;
+import org.apache.jackrabbit.oak.fixture.RepositoryFixture;
+import org.apache.jackrabbit.oak.jcr.Jcr;
+import org.apache.jackrabbit.oak.security.SecurityProviderImpl;
+import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
+import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
+import org.apache.jackrabbit.oak.spi.security.authentication.SystemSubject;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
+import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
+import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
+import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
+import org.apache.jackrabbit.util.Text;
+
+/**
+ * Test the performance of adding a configured number of members to groups. The
+ * following parameters can be used to run the benchmark:
+ *
+ * - numberOfMembers : the number of members that should be added in the test run
+ * - batchSize : the number of members that should be added before calling Session.save
+ * - importBehavior : the {@link org.apache.jackrabbit.oak.spi.xml.ImportBehavior}; valid options are "besteffort", "ignore" and "abort"
+ *
+ * For simplicity this benchmark makes use of {@link Group#addMembers(String...)}.
+ * An importbehavior of "ignore" and "abort" will required the members to exist
+ * and will resolve each ID to the corresponding authorizble first. Those are
+ * consequently almost equivalent to calling {@link Group#addMember(org.apache.jackrabbit.api.security.user.Authorizable)}.
+ * In case of "besteffort" the member is not resolved to an authorizable.
+ */
+public class ManyGroupMembersTest extends AbstractTest {
+
+    private final Random random = new Random();
+
+    private static final String USER = "user";
+    private static final String GROUP = "group";
+    private static final int GROUP_CNT = 100;
+
+    static final int DEFAULT_BATCH_SIZE = 1;
+
+    private final int numberOfMembers;
+    private final int batchSize;
+    private final String importBehavior;
+
+    public ManyGroupMembersTest(int numberOfMembers, int batchSize, @Nonnull String importBehavior) {
+        this.numberOfMembers = numberOfMembers;
+        this.batchSize = batchSize;
+        this.importBehavior = importBehavior;
+    }
+
+    @Override
+    public void setUp(Repository repository, Credentials credentials) throws Exception {
+        super.setUp(repository, credentials);
+
+        Session s = loginAdministrative();
+        try {
+            UserManager userManager = ((JackrabbitSession) s).getUserManager();
+            for (int i = 0; i <= GROUP_CNT; i++) {
+                userManager.createGroup(new PrincipalImpl(GROUP + i));
+            }
+
+            if (!ImportBehavior.NAME_BESTEFFORT.equals(importBehavior)) {
+                for (int i = 0; i <= numberOfMembers; i++) {
+                    userManager.createUser(USER + i, null);
+                }
+            }
+
+        } finally {
+            s.save();
+            s.logout();
+        }
+        System.out.println("setup done");
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        try {
+            Session s = loginAdministrative();
+
+            Authorizable authorizable = ((JackrabbitSession) s).getUserManager().getAuthorizable(GROUP + "0");
+            if (authorizable != null) {
+                Node n = s.getNode(Text.getRelativeParent(authorizable.getPath(), 1));
+                n.remove();
+            }
+
+            if (!ImportBehavior.NAME_BESTEFFORT.equals(importBehavior)) {
+                authorizable = ((JackrabbitSession) s).getUserManager().getAuthorizable(USER + "0");
+                if (authorizable != null) {
+                    Node n = s.getNode(Text.getRelativeParent(authorizable.getPath(), 1));
+                    n.remove();
+                }
+            }
+            s.save();
+            s.logout();
+
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    @Override
+    protected Repository[] createRepository(RepositoryFixture fixture) throws Exception {
+        if (fixture instanceof OakRepositoryFixture) {
+            return ((OakRepositoryFixture) fixture).setUpCluster(1, new JcrCreator() {
+                @Override
+                public Jcr customize(Oak oak) {
+                    SecurityProvider sp = new SecurityProviderImpl(ConfigurationParameters.of(UserConfiguration.NAME, ConfigurationParameters.of(ProtectedItemImporter.PARAM_IMPORT_BEHAVIOR, importBehavior)));
+                    return new Jcr(oak).with(sp);
+                }
+            });
+        } else {
+            return super.createRepository(fixture);
+        }
+    }
+
+    @Override
+    public void runTest() throws Exception {
+        Session s = null;
+        try {
+            // use system session login to avoid measuring the login-performance here
+            s = Subject.doAsPrivileged(SystemSubject.INSTANCE, new PrivilegedExceptionAction<Session>() {
+                @Override
+                public Session run() throws Exception {
+                    return getRepository().login(null, null);
+                }
+            }, null);
+            UserManager userManager = ((JackrabbitSession) s).getUserManager();
+            String groupId = GROUP + random.nextInt(GROUP_CNT);
+            Group g = userManager.getAuthorizable(groupId, Group.class);
+            for (int i = 0; i <= numberOfMembers; i++) {
+                if (batchSize <= DEFAULT_BATCH_SIZE) {
+                    g.addMembers(USER + i);
+                } else {
+                    List<String> ids = new ArrayList<String>(batchSize);
+                    for (int j = 0; j < batchSize && i <= numberOfMembers; j++) {
+                        ids.add(USER + i);
+                        i++;
+                    }
+                    g.addMembers(ids.toArray(new String[ids.size()]));
+                }
+                s.save();
+            }
+        } catch (RepositoryException e) {
+            System.out.println(e.getMessage());
+            if (s.hasPendingChanges()) {
+                s.refresh(false);
+            }
+        } finally {
+            if (s != null) {
+                s.logout();
+            }
+        }
+    }
+}