Skip to content

Commit

Permalink
initial import
Browse files Browse the repository at this point in the history
  • Loading branch information
moscicki committed Nov 18, 2013
1 parent 5a938e3 commit b65bcc4
Show file tree
Hide file tree
Showing 21 changed files with 4,310 additions and 0 deletions.
113 changes: 113 additions & 0 deletions client/compile-owncloud-sync-client
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#
# The _open_SmashBox Project.
#
# Author: Jakub T. Moscicki, CERN, 2013
# License: AGPL
#
# this script compiles and downloads the owncloud clients automatically
# versions are controlled by variables below
# - src: download sources
# - build: contains build directories
# - patches: applied patches (if any)

# if a patch is applied the name of a build directory is changed to reflect that fact

# offical version of the client
# previous verions: 0.80, 1.3
export OCSYNC=ocsync-0.90.2
export MIRALL=mirall-1.4.1
export DOWNLOAD_PATH=

# latest development preview (with a different download path on the server)
#export OCSYNC=ocsync-0.82.0
#export MIRALL=mirall-1.4.0beta2
#export DOWNLOAD_PATH=testing


# this specifies if to apply patches
# $PATCH is also appended to build directory name to distguish patched from vanilla builds
#export PATCH=
export PATCH=ssl-patch

#############################################################################################

# workspace is the directory where this script resides

# http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in
PREFIX="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

PREFIX=`readlink -f $PREFIX` # this is to remove any symlinks that may be local (such as /b)

cat << EOF
======================================================"
compiling owncloud client
-------------------------
PREFIX=$PREFIX
PATCH=$PATCH
OCSYNC=$OCSYNC
MIRALL=$MIRALL
-------------------------
EOF

cd $PREFIX

# download sources if needed

mkdir -p src

cd src

test -f ${OCSYNC}.tar.bz2 || wget http://download.owncloud.com/download/${DOWNLOAD_PATH}/${OCSYNC}.tar.bz2
test -f ${MIRALL}.tar.bz2 || wget http://download.owncloud.com/download/${DOWNLOAD_PATH}/${MIRALL}.tar.bz2

test -d ${OCSYNC} || tar fvxj ${OCSYNC}.tar.bz2
test -d ${MIRALL} || tar fvxj ${MIRALL}.tar.bz2

cd ..

# patch sources if needed

if [ $PATCH ]; then
echo Patching: "$PATCH"
cd src

# adjust source directory names

rm -rf ${OCSYNC}-${PATCH}
rm -rf ${MIRALL}-${PATCH}
mv ${OCSYNC} ${OCSYNC}-${PATCH}
mv ${MIRALL} ${MIRALL}-${PATCH}

# adjust build directory names

export OCSYNC=${OCSYNC}-${PATCH}
export MIRALL=${MIRALL}-${PATCH}
cd ..

# patch sources

patch --backup ${PREFIX}/src/${OCSYNC}/modules/csync_owncloud.c patches/ocsync-ssl.patch
fi

# BUILD

mkdir -p build
cd build

rm -rf build-${OCSYNC}
mkdir build-${OCSYNC}
cd build-${OCSYNC}
cmake -DCMAKE_BUILD_TYPE=Debug ${PREFIX}/src/${OCSYNC}
make

mkdir include
cp csync_version.h include
cp ${PREFIX}/src/${OCSYNC}/src/*.h include
cd ..

rm -rf build-${MIRALL}
mkdir build-${MIRALL}
cd build-${MIRALL}
cmake -DCMAKE_BUILD_TYPE="Debug" ${PREFIX}/src/${MIRALL} -DCSYNC_BUILD_PATH=${PREFIX}/build/build-${OCSYNC} -DCSYNC_INCLUDE_PATH=${PREFIX}/build/build-${OCSYNC}/include/
make

83 changes: 83 additions & 0 deletions etc/smashbox.conf.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#
# The _open_SmashBox Project.
#
# Author: Jakub T. Moscicki, CERN, 2013
# License: AGPL
#
# this is the main config file template: copy to smashbox.conf and adjust the settings
#
# this template should work without changes if you are running your tests directly on the owncloud application server
#

# this is the top directory where all local working files are kept (test working direcotires, test logs, test data, temporary filesets, ..)
smashdir = "~/smashdir"

# name of the account used for testing
# if None then account name is chosen automatically (based on the test name)
oc_account_name=None

# password for test accounts: all test account will have the same password
# if not set then it's an error
oc_account_password=""

# owncloud test server
# if left blank or "localhost" then the real hostname of the localhost will be set
oc_server = ''

# should we use protocols with SSL (https, ownclouds)
oc_ssl_enabled = True

# how to invoke shell commands on the server
# for localhost there is no problem - leave it blank
# for remote host it may be set like this: "ssh -t -l root " + oc_server
# note: configure ssh for passwordless login
# note: -t option is to make it possible to run sudo
oc_server_shell_cmd = ""

# Data directory on the owncloud server.
#
oc_server_datadirectory = "/var/www/html/owncloud/data"

# a path to server side tools (create_user.php, ...)
#
# it may be specified as relative path "dir" and then resolves to
# <smashbox>/dir where <smashbox> is the top-level of of the tree
# containing THIS configuration file
#

oc_server_tools_path = "server-tools"

# a path to ocsync command with options
# this path should work for all client hosts
#
# it may be specified as relative path "dir" and then resolves to
# <smashbox>/dir where <smashbox> is the top-level of of the tree
# containing THIS configuration file
#
oc_sync_cmd = "client/build/build-ocsync-0.82.0-ssl-patch/client/ocsync -d 100 -c "

# number of times to repeat ocsync run every time
oc_sync_repeat = 1

####################################

# unique identifier of your test run
# if None then the runid is chosen automatically (and stored in this variable)
runid = None

# if True then the local working directory path will have the runid added to it automatically
workdir_runid_enabled=False

# if True then the runid will be part of the oc_account_name automatically
oc_account_runid_enabled=False

####################################

# this defines the default account cleanup procedure
# - "account_delete": delete account if exists and then create a new account with the same name
#
# these are not implemeted yet:
# - "sync_delete": delete all files via a sync run
# - "webdav_delete": delete all files via webdav DELETE request
# - "filesystem_delete": delete all files directly on the server's filesystem
oc_account_cleanup_procedure = "account_delete"
157 changes: 157 additions & 0 deletions lib/test_basicSync.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
from smashbox.utilities import *

__doc__ = """ Test basic sync and conflicts: files are modified and deleted by one or both workers (winner and loser); optionally remove local state db on one of the clients (loser).
There are four clients (workers):
- creator - populates the directory initially and also performs a final check
- winner - is syncing its local changes first
- loser - is syncing its local changes second (and optionally it looses the local sync database before doing the sync)
- checker - only performs a final check (without having interacted with the system before)
FIXME: file exclusion list should be prvided correctly (from mirall or owncloudcmd) - otherwise test conflict files are demonstrated to be uploaded to the server
"""

filesizeKB = int(config.get('basicSync_filesizeKB',10000))

# True => remove local sync db on the loser
# False => keep the loser
rmLocalStateDB = bool(config.get('basicSync_rmLocalStateDB',False))

@add_worker
def creator(step):

reset_owncloud_account()
reset_rundir()

step(1,'create initial content and sync')

d = make_workdir()

# files *_NONE are not modified by anyone after initial sync
# files *_LOSER are modified by the loser but not by the winner
# files *_WINNER are modified by the winner but not by the loser
# files *_BOTH are modified both by the winner and by the loser (always conflict on the loser)

createfile(os.path.join(d,'TEST_FILE_MODIFIED_NONE.dat'),'0',count=1000,bs=filesizeKB)
createfile(os.path.join(d,'TEST_FILE_MODIFIED_LOSER.dat'),'0',count=1000,bs=filesizeKB)
createfile(os.path.join(d,'TEST_FILE_MODIFIED_WINNER.dat'),'0',count=1000,bs=filesizeKB)
createfile(os.path.join(d,'TEST_FILE_MODIFIED_BOTH.dat'),'0',count=1000,bs=filesizeKB)
createfile(os.path.join(d,'TEST_FILE_DELETED_LOSER.dat'),'0',count=1000,bs=filesizeKB)
createfile(os.path.join(d,'TEST_FILE_DELETED_WINNER.dat'),'0',count=1000,bs=filesizeKB)
createfile(os.path.join(d,'TEST_FILE_DELETED_BOTH.dat'),'0',count=1000,bs=filesizeKB)

run_ocsync(d)

step(7,'download the repository')
run_ocsync(d)

final_check(d)

@add_worker
def winner(step):
step(2,'initial sync')

d = make_workdir()
run_ocsync(d)

step(3,'modify locally and sync to server')

removeFile(os.path.join(d,'TEST_FILE_DELETED_WINNER.dat'))
removeFile(os.path.join(d,'TEST_FILE_DELETED_BOTH.dat'))

createfile(os.path.join(d,'TEST_FILE_MODIFIED_WINNER.dat'),'1',count=1000,bs=filesizeKB)
createfile(os.path.join(d,'TEST_FILE_MODIFIED_BOTH.dat'),'1',count=1000,bs=filesizeKB)

run_ocsync(d)

step(5,'final sync')

run_ocsync(d,N=3)

final_check(d)

# this is the loser which lost it's local state db after initial sync

@add_worker
def loser(step):

step(2,'initial sync')

d = make_workdir()
run_ocsync(d)

step(4,'modify locally and sync to the server')

# now do the local changes

removeFile(os.path.join(d,'TEST_FILE_DELETED_LOSER.dat'))
removeFile(os.path.join(d,'TEST_FILE_DELETED_BOTH.dat'))

createfile(os.path.join(d,'TEST_FILE_MODIFIED_LOSER.dat'),'1',count=1000,bs=filesizeKB)
createfile(os.path.join(d,'TEST_FILE_MODIFIED_BOTH.dat'),'2',count=1000,bs=filesizeKB)

# remove the sync db
if rmLocalStateDB:
removeFile(os.path.join(d,'.csync_journal.db'))

run_ocsync(d,N=3) # conflict file will be synced to the server but it requires more than one sync run

step(6,'final sync')
run_ocsync(d)

final_check(d)

@add_worker
def checker(step):

step(7,'download the repository for final verification')
d = make_workdir()
run_ocsync(d)

final_check(d)


def final_check(d):
""" Final verification: all local sync folders should look the same. We expect conflicts and handling of deleted files depending on the rmLocalStateDB option. See code for details.
"""
import glob

list_files(d)

conflict_files = glob.glob(os.path.join(d,'*_conflict-*-*'))

logger.debug('conflict files in %s: %s',d,conflict_files)

if not rmLocalStateDB:
# we expect exactly 1 conflict file

logger.warning("FIXME: currently winner gets a conflict file - exclude list should be updated and this assert modified for the winner")

error_check(len(conflict_files) == 1, "there should be exactly 1 conflict file (%d)"%len(conflict_files))
else:
# we expect exactly 3 conflict files
error_check(len(conflict_files) == 3, "there should be exactly 3 conflict files (%d)"%len(conflict_files))

for fn in conflict_files:

if not rmLocalStateDB:
error_check('_BOTH' in fn, """only files modified in BOTH workers have a conflict - all other files should be conflict-free""")

else:
error_check('_BOTH' in fn or '_LOSER' in fn or '_WINNER' in fn, """files which are modified by ANY worker have a conflict now; files which are not modified should not have a conflict""")

deleted_files = glob.glob(os.path.join(d,'*_DELETED*'))

logger.debug('deleted files in %s: %s',d,deleted_files)

if not rmLocalStateDB:
error_check(len(deleted_files) == 0, 'deleted files should not be there normally')
else:
# deleted files "reappear" if local sync db is lost on the loser, the only file that does not reappear is the DELETED_BOTH which was deleted on *all* local clients

error_check(len(deleted_files) == 2, "we expect exactly 2 deleted files")

for fn in deleted_files:
error_check('_LOSER' in fn or '_WINNER' in fn, "deleted files should only reappear if delete on only one client (but not on both at the same time) ")
Loading

0 comments on commit b65bcc4

Please sign in to comment.