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 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}]" |
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.sh
script gathers stats from a few typical operations that require interaction withaccount_cache
.Calling the
accounts_test.sh
scriptWhen called without any parameters it assumes that
1024
accounts will be created, downloadsgerrit-3.2.12.war
and the correspondingjavamelody.jar
plugin. It can be also called with three positional parameters:1024
)war
file (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.jar
plugin (any version matching with Gerritwar
file can be used).The testing procedure
# configure Gerrit
section) and startedtest_repo
gets created and cloned by Admin (over SSH)200
changes get created and pushed for review sequentially by Admin (over SSH)1024
accounts 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)200
changes5
to10
reviewers get added sequentially by Admin (single SSH call to add varying number of reviewers per change)2000
times (sequentially) to get random change details by random user (over HTTP) - curl'stime_total
benchmark is captured for each call and stored inquery_change.log
filepath.lua
) and sequence of commands to call wrk benchmarking tool to test getting random change details in parallel. Thepath.lua
is awrk
input 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
wrk
was called against:stable-3.1
in the results)stable-3.2
in the results)stable-3.2-cache
in the results)stable-3.2-libCache
in 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.1
version is typically~2
times more performant in all aspects butmax
where it is closer to~1.5
whereas libCached version is typically~1/4
faster thanstable-3.2
and seems to be better in responding to load asmax
is~2
times faster thanstable-3.1
.Adding concurrency to the picture with
wrk
benchmarking toolThe following
wrk
command was usedNote that in order to avoid resources cannibalisation by client the
wrk
command was called from the different machine in LAN.The following table shows the summary of the
wrk
command run whereTRS
isReqs/Sec
for eachThread
The average
Regs/Sec
for eachThread
for libCached version is106
and forstable-3.1
is109
which is~2
correspondingly times higher thanstable-3.2
Gerrit.Adding NFS-like behaviour by setting
trustFolderStat = false
The same
wrk
command as previously was called but this timetrustFolderStat
was disabled (and Gerrit restarted to pickup the change).In this test both
stable-3.1
gets~2
times slower in comparison to whentrustFolderStat = true
andstable-3.2-libCached
version maintains the performance howeverstable-3.2
gets substantially worse:~4
times slower thenstable-3.1
~9
times slower thenstable-3.2-libCache
stable-3.2-libCache
is visibly faster thenstable-3.1
(by factor~2
).Resource consumption during the whole testing
CPU
consumption:* stable-3.2
* stable-3.2-cache
With the same resource consumption
stable-3.1
version offers easily2
(4
whentrustFolderStat = false
) times better performance for account-heavy operations. Thestable-3.2-libCache
performs comparable tostable-3.1
being even better (9
times faster) whentrustFolderStat = false
.