Last active
January 13, 2022 15:58
-
-
Save geminicaprograms/b2cae199793f0f2b18759a803000447f to your computer and use it in GitHub Desktop.
Accounts operations setup and test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| USERS=$1 | |
| GERRIT_WAR=$2 | |
| JAVAMELODY_PLUGIN=$3 | |
| LIB_MODULE=$4 | |
| #parameters | |
| REPO=test_repo | |
| CHANGES=200 | |
| MIN_REVIEWERS=5 | |
| MAX_REVIEWERS=10 | |
| QUERY_CHANGES_TIMES=2000 | |
| if [ -z "$USERS" ]; then | |
| USERS=1024 | |
| echo "### Using default no of accounts [${USERS}]" | |
| else | |
| echo "### Using provided no of accounts [${USERS}]" | |
| fi | |
| # prepare test dir | |
| TEST_SITE=$(mktemp -d || $(echo >&2 "Could not create temp dir" && exit 1)) | |
| echo "### Setting up the Gerrit site [${TEST_SITE}]..." | |
| cd "$TEST_SITE" | |
| # download Gerrit | |
| if [ -z "$GERRIT_WAR" ]; then | |
| echo "### Downloadnig release: gerrit-3.2.12.war..." | |
| wget https://gerrit-releases.storage.googleapis.com/gerrit-3.2.12.war | |
| else | |
| echo "### Using Gerrit release from [${GERRIT_WAR}]" | |
| cp "$GERRIT_WAR" gerrit.war | |
| fi | |
| GERRIT_WAR_FILENAME=$(find . -name 'gerrit*') | |
| echo "### Running tests against the Gerrit: $(java -jar ${GERRIT_WAR_FILENAME} version) version" | |
| # setup site | |
| GERRIT_PORT=8091 | |
| GERRIT_SSH=29418 | |
| GERRIT_DIR="gerrit" | |
| GERRIT_ETC_DIR="${GERRIT_DIR}/etc" | |
| mkdir -p ${GERRIT_ETC_DIR} | |
| mkdir -p ${GERRIT_DIR}/plugins | |
| if [ -z "$JAVAMELODY_PLUGIN" ]; then | |
| echo "### Downloadnig javamelody plugin from stable-3.2 plugins..." | |
| wget https://gerrit-ci.gerritforge.com/view/Plugins-stable-3.2/job/plugin-javamelody-bazel-stable-3.2/lastSuccessfulBuild/artifact/bazel-bin/plugins/javamelody/javamelody.jar \ | |
| -O "${GERRIT_DIR}/plugins/javamelody.jar" | |
| else | |
| echo "### Using javamelody plugin from [${JAVAMELODY_PLUGIN}]" | |
| cp "$JAVAMELODY_PLUGIN" "${GERRIT_DIR}/plugins/javamelody.jar" | |
| fi | |
| if [ ! -z "$LIB_MODULE" ]; then | |
| echo "### Installing the lib module from [${LIB_MODULE}]" | |
| #cp "$LIB_MODULE" "${GERRIT_DIR}/plugins/" | |
| mkdir -p "${GERRIT_DIR}/lib" | |
| cp "$LIB_MODULE" "${GERRIT_DIR}/lib/" | |
| git config --file ${GERRIT_ETC_DIR}/gerrit.config gerrit.installDbModule "com.googlesource.gerrit.plugins.gerritcachedrefdb.LibDbModule" | |
| git config --file ${GERRIT_ETC_DIR}/gerrit.config gerrit.installModule "com.googlesource.gerrit.plugins.gerritcachedrefdb.LibSysModule" | |
| #git config --file ${GERRIT_ETC_DIR}/gerrit.config cache."gerrit-cached-refdb.ref_by_name".memoryLimit $(( ${USERS} + ( ${CHANGES} * 4) + 700 )) | |
| git config --file ${GERRIT_ETC_DIR}/gerrit.config cache.ref_by_name.memoryLimit $(( ( ${USERS} * 4 ) + ( ${CHANGES} * 4) )) | |
| fi | |
| # configure Gerrit | |
| git config --file ${GERRIT_ETC_DIR}/gerrit.config gerrit.basePath git | |
| git config --file ${GERRIT_ETC_DIR}/gerrit.config gerrit.canonicalWebUrl "http://localhost:${GERRIT_PORT}" | |
| git config --file ${GERRIT_ETC_DIR}/gerrit.config auth.type DEVELOPMENT_BECOME_ANY_ACCOUNT | |
| git config --file ${GERRIT_ETC_DIR}/gerrit.config auth.httpPasswordSettingsEnabled true | |
| git config --file ${GERRIT_ETC_DIR}/gerrit.config container.user $(whoami) | |
| git config --file ${GERRIT_ETC_DIR}/gerrit.config container.javaOptions "-agentlib:jdwp=transport=dt_socket,server=y,address=6667,suspend=n" | |
| git config --file ${GERRIT_ETC_DIR}/gerrit.config sshd.listenAddress "*:${GERRIT_SSH}" | |
| git config --file ${GERRIT_ETC_DIR}/gerrit.config httpd.listenUrl "http://*:${GERRIT_PORT}/" | |
| git config --file ${GERRIT_ETC_DIR}/gerrit.config sendemail.enable false | |
| git config --file ${GERRIT_ETC_DIR}/gerrit.config cache.accounts.memoryLimit $(( ${USERS} + 1 )) | |
| git config --file ${GERRIT_ETC_DIR}/gerrit.config cache.web_sessions.memoryLimit $(( ${USERS} + 1 )) | |
| # init site and start | |
| echo "### Calling Gerrit init and start..." | |
| java -jar ${GERRIT_WAR_FILENAME} init -d "$GERRIT_DIR" --install-all-plugins --batch | |
| ${GERRIT_DIR}/bin/gerrit.sh start | |
| # prepare site for testing | |
| export GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" | |
| export GIT_REDIRECT_STDERR='2>&1' | |
| SSH_OPTIONS="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" | |
| # create repo and upload changes for review | |
| echo "### Creating $REPO and pushing $CHANGES changes for review..." | |
| ssh $SSH_OPTIONS -p $GERRIT_SSH admin@localhost gerrit create-project test_repo --empty-commit | |
| git clone "ssh://admin@localhost:${GERRIT_SSH}/${REPO}" && scp $SSH_OPTIONS -p -P $GERRIT_SSH admin@localhost:hooks/commit-msg "${REPO}/.git/hooks/" | |
| cd ${REPO} | |
| git config user.name Admin | |
| git config user.email admin@email | |
| time for i in $(seq 1 ${CHANGES}); do | |
| echo "some content ${i}" >> README.md | |
| git add README.md | |
| git commit -qm "update content ${i}" | |
| git push -q origin HEAD:refs/for/master | |
| done | |
| cd - | |
| echo "### $CHANGES changes pushed for review" | |
| ssh $SSH_OPTIONS -p $GERRIT_SSH admin@localhost gerrit show-caches -w 90 | |
| # create users | |
| echo "### Creating ${USERS} users..." | |
| time for i in $(seq 1 ${USERS}); do | |
| printf -v paddedId "%04g" $i | |
| ssh -q $SSH_OPTIONS -p $GERRIT_SSH admin@localhost gerrit create-account --full-name test_${paddedId} --email test_${paddedId}@example.com test_${paddedId} | |
| # get gerrit cookies | |
| GERRIT_ACCOUNT=$(curl -s -o /dev/null -D - http://localhost:${GERRIT_PORT}/login/%2Fq%2Fstatus%3Aopen%2B-is%3Awip\?account_id\=100${paddedId} | grep -Fi Set-Cookie | cut -d" " -f2) | |
| XSRF_TOKEN=$(curl -H "Cookie: ${GERRIT_ACCOUNT}" -s -o /dev/null -D - http://localhost:${GERRIT_PORT}/q/status:open+-is:wip | grep -Fi Set-Cookie | cut -d" " -f2) | |
| GERRIT_COOKIES="Cookie: ${GERRIT_ACCOUNT} ${XSRF_TOKEN}" | |
| COOKIES[${i}]="$GERRIT_COOKIES" | |
| done | |
| echo "### Creating ${USERS} users done" | |
| ssh $SSH_OPTIONS -p $GERRIT_SSH admin@localhost gerrit show-caches -w 90 | |
| # add reviewers | |
| echo "### Adding ${MIN_REVIEWERS} - ${MAX_REVIEWERS} random reviewers to $CHANGES changes..." | |
| time for i in $(seq 1 ${CHANGES}); do | |
| unset REVIEWERS | |
| USER_INDEX=$(( $RANDOM % (${USERS} - ${MAX_REVIEWERS}) + 1 )) | |
| for j in $(seq 1 $(( ($RANDOM % (${MAX_REVIEWERS} - ${MIN_REVIEWERS})) + $MIN_REVIEWERS )) ); do | |
| printf -v paddedId "%04g" $USER_INDEX | |
| REVIEWERS="${REVIEWERS} -a 100$paddedId" | |
| USER_INDEX=$(( $USER_INDEX + 1 )) | |
| done | |
| ssh -q $SSH_OPTIONS -p $GERRIT_SSH admin@localhost gerrit set-reviewers -p $REPO $REVIEWERS -- $i | |
| done | |
| echo "### Adding reviewers done" | |
| ssh $SSH_OPTIONS -p $GERRIT_SSH admin@localhost gerrit show-caches -w 90 | |
| # query changes | |
| echo '%{time_total}\n' > .curl-total-inline-format.txt | |
| echo 'time_total(s)' > query_change.log | |
| echo "### Getting change details ${QUERY_CHANGES_TIMES} times for random 1 to ${CHANGES} changes, by random 1 to ${USERS} users..." | |
| time for i in $(seq 1 ${QUERY_CHANGES_TIMES}); do | |
| curl -w "@./.curl-total-inline-format.txt" -H "${COOKIES[($RANDOM % ${USERS}) + 1]}" \ | |
| -o /dev/null -s http://localhost:${GERRIT_PORT}/a/changes/${REPO}\~$(( ($RANDOM % ${CHANGES}) + 1 ))/detail\?O\=916314 >> query_change.log | |
| done | |
| echo "### Getting changes done" | |
| # preparing script to call get changes in parallel | |
| PATH_FILE="${TEST_SITE}/path.lua" | |
| echo "local changes = ${CHANGES}" > ${PATH_FILE} | |
| cat >> ${PATH_FILE} << EOM | |
| function init(args) | |
| local r = {} | |
| local path = "/a/changes/test_repo~%d/detail?O=916314" | |
| for i = 1, 90 do | |
| r[i] = wrk.format(nil, path:format(math.random(changes - 1) + 1)) | |
| end | |
| req = table.concat(r) | |
| end | |
| function request() | |
| return req | |
| end | |
| EOM | |
| echo "Script to call get change details in parallel" | |
| echo "${TEST_SITE}/gerrit/bin/gerrit.sh start" | |
| echo "GERRIT_ACCOUNT=\$(curl -s -o /dev/null -D - http://localhost:${GERRIT_PORT}/login/%2Fq%2Fstatus%3Aopen%2B-is%3Awip\?account_id\=1000000 | grep -Fi Set-Cookie | cut -d\" \" -f2)" | |
| echo "XSRF_TOKEN=\$(curl -H \"Cookie: \${GERRIT_ACCOUNT}\" -s -o /dev/null -D - http://localhost:${GERRIT_PORT}/q/status:open+-is:wip | grep -Fi Set-Cookie | cut -d\" \" -f2)" | |
| echo "wrk -t8 -c8 -d60s -H \"Cookie: \${GERRIT_ACCOUNT} \${XSRF_TOKEN}\" -s \"${PATH_FILE}\" 'http://localhost:${GERRIT_PORT}'" | |
| echo "### Stopping Gerrit..." | |
| ssh $SSH_OPTIONS -p $GERRIT_SSH admin@localhost gerrit show-caches -w 90 | |
| ${GERRIT_DIR}/bin/gerrit.sh stop | |
| echo "### Test directory [${TEST_SITE}]" |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
TLDR;
Gerrit 3.1.16 performs account-heavy operations 2 (4 when
trustFolderStat = false) times faster than vanilla Gerrit 3.2.12.Gerrit 3.2.12 with RFC: Cache All-Users object ids by ref performs account-heavy operations 2-4 (7-8 when
trustFolderStat = false) times faster than vanilla Gerrit 3.2.12. (unfortunately this change will never get accepted as a core solution)Gerrit 3.2.14 with RefDB backed by Gerrit cache loaded though lib module performs account/change operations 2 (9 when
trustFolderStat = false) times faster then vanilla 3.2.14. (this change, due to its minimal impact on Gerrit core, has a chance to get accepted as a core solution for Gerrit from 3.2 to 3.5 versions)Explanation
The
accounts_test.shscript gathers stats from a few typical operations that require interaction withaccount_cache.Calling the
accounts_test.shscriptWhen called without any parameters it assumes that
1024accounts will be created, downloadsgerrit-3.2.12.warand the correspondingjavamelody.jarplugin. It can be also called with three positional parameters:1024)warfile (any version can be used, note that getting change detail REST API was used with version 3.2 and as such might require some modifications if different version is not compatible with)javamelody.jarplugin (any version matching with Gerritwarfile can be used).The testing procedure
# configure Gerritsection) and startedtest_repogets created and cloned by Admin (over SSH)200changes get created and pushed for review sequentially by Admin (over SSH)1024accounts get created sequentially by Admin (over SSH), each account has username, full name and email; note that Gerrit cookies are obtained for each account (2 HTTP GET calls)200changes5to10reviewers get added sequentially by Admin (single SSH call to add varying number of reviewers per change)2000times (sequentially) to get random change details by random user (over HTTP) - curl'stime_totalbenchmark is captured for each call and stored inquery_change.logfilepath.lua) and sequence of commands to call wrk benchmarking tool to test getting random change details in parallel. Thepath.luais awrkinput script that generates random sequence of 90 changes to be queried by single thread (each thread gets its own queue). The output sequence of commands look like the following:and means that 8 threads in parallel is going to gat as often as possible random change details during 300s period of time.
Results
Hardware:
The test script and
wrkwas called against:stable-3.1in the results)stable-3.2in the results)stable-3.2-cachein the results)stable-3.2-libCachein the results)Steps 3 - 6 totals:
Lib-cached version with regards to totals performs sometimes better a bit than
stable-3.1(changes creation and adding reviewers) and a bit slower thenstable-3.2(for accounts creation).Notes:
stable-3.2(typically the slowest),stable-3.1,stable-3.2-cache,stable-3.2-libCache.Get random change details 2000 times step details (unless specified values are given in
ms):Note that the all following pictures have

log(2)scale.The
stable-3.1version is typically~2times more performant in all aspects butmaxwhere it is closer to~1.5whereas libCached version is typically~1/4faster thanstable-3.2and seems to be better in responding to load asmaxis~2times faster thanstable-3.1.Adding concurrency to the picture with
wrkbenchmarking toolThe following
wrkcommand was usedNote that in order to avoid resources cannibalisation by client the
wrkcommand was called from the different machine in LAN.The following table shows the summary of the
wrkcommand run whereTRSisReqs/Secfor eachThreadThe average
Regs/Secfor eachThreadfor libCached version is106and forstable-3.1is109which is~2correspondingly times higher thanstable-3.2Gerrit.Adding NFS-like behaviour by setting
trustFolderStat = falseThe same
wrkcommand as previously was called but this timetrustFolderStatwas disabled (and Gerrit restarted to pickup the change).In this test both
stable-3.1gets~2times slower in comparison to whentrustFolderStat = trueandstable-3.2-libCachedversion maintains the performance howeverstable-3.2gets substantially worse:~4times slower thenstable-3.1~9times slower thenstable-3.2-libCachestable-3.2-libCacheis visibly faster thenstable-3.1(by factor~2).Resource consumption during the whole testing
CPUconsumption:
* stable-3.2
* stable-3.2-cacheWith the same resource consumption
stable-3.1version offers easily2(4whentrustFolderStat = false) times better performance for account-heavy operations. Thestable-3.2-libCacheperforms comparable tostable-3.1being even better (9times faster) whentrustFolderStat = false.