mirror of
https://github.com/haiwen/seafile-server.git
synced 2025-04-27 11:10:49 +00:00
parent
fa1e439633
commit
b2d058badc
2
.gitignore
vendored
2
.gitignore
vendored
@ -93,3 +93,5 @@ tests/conf/PeerMgr
|
||||
/test-driver
|
||||
*.dmp
|
||||
/symbols
|
||||
__pycache__/
|
||||
.cache/
|
||||
|
@ -4,7 +4,6 @@ sudo: false
|
||||
language: python
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
@ -21,11 +20,10 @@ cache:
|
||||
directories:
|
||||
- $HOME/.cache/pip
|
||||
- $HOME/.ccache
|
||||
- $HOME/downloads
|
||||
before_install:
|
||||
- ccache -s
|
||||
- export PATH=/usr/lib/ccache:${PATH}
|
||||
install:
|
||||
- ./integration-tests/install-deps.sh
|
||||
- ./ci/install-deps.sh
|
||||
script:
|
||||
- ./integration-tests/run.py
|
||||
- ./ci/run.py
|
||||
|
18
ci/install-deps.sh
Executable file
18
ci/install-deps.sh
Executable file
@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e -x
|
||||
|
||||
SCRIPT=${BASH_SOURCE[0]}
|
||||
TESTS_DIR=$(dirname "${SCRIPT}")/..
|
||||
SETUP_DIR=${TESTS_DIR}/ci
|
||||
|
||||
cd $SETUP_DIR
|
||||
|
||||
pip install -r requirements.txt
|
||||
|
||||
# download precompiled libevhtp
|
||||
# TODO(lins05): we should consider build from source with https://github.com/criticalstack/libevhtp in the future
|
||||
libevhtp_bin=libevhtp-bin_1.2.0.tar.gz
|
||||
wget https://dl.bintray.com/lins05/generic/libevhtp-bin/$libevhtp_bin
|
||||
# tar xvf $libevhtp_bin --strip-components=3 -C /usr
|
||||
tar xf $libevhtp_bin -C $HOME
|
6
ci/requirements.txt
Normal file
6
ci/requirements.txt
Normal file
@ -0,0 +1,6 @@
|
||||
termcolor>=1.1.0
|
||||
requests>=2.8.0
|
||||
httpie>=0.9.9
|
||||
pytest>=3.3.2
|
||||
backports.functools_lru_cache>=1.4
|
||||
tenacity>=4.8.0
|
199
ci/run.py
Executable file
199
ci/run.py
Executable file
@ -0,0 +1,199 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Install dir: ~/opt/local
|
||||
Data dir: /tmp/haiwen
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import glob
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from os.path import abspath, basename, exists, expanduser, join
|
||||
|
||||
import requests
|
||||
import termcolor
|
||||
|
||||
from serverctl import MYSQL_ROOT_PASSWD, ServerCtl
|
||||
from utils import (
|
||||
cd, chdir, debug, green, info, lru_cache, mkdirs, on_travis, red,
|
||||
setup_logging, shell, warning
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
TOPDIR = abspath(join(os.getcwd(), '..'))
|
||||
if on_travis():
|
||||
PREFIX = expanduser('~/opt/local')
|
||||
else:
|
||||
PREFIX = os.environ.get('SEAFILE_INSTALL_PREFIX', '/usr/local')
|
||||
INSTALLDIR = '/tmp/seafile-tests'
|
||||
|
||||
|
||||
def num_jobs():
|
||||
return int(os.environ.get('NUM_JOBS', 2))
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def make_build_env():
|
||||
env = dict(os.environ)
|
||||
libsearpc_dir = abspath(join(TOPDIR, 'libsearpc'))
|
||||
ccnet_dir = abspath(join(TOPDIR, 'ccnet-server'))
|
||||
|
||||
def _env_add(*a, **kw):
|
||||
kw['env'] = env
|
||||
return prepend_env_value(*a, **kw)
|
||||
|
||||
_env_add('CPPFLAGS', '-I%s' % join(PREFIX, 'include'), seperator=' ')
|
||||
|
||||
_env_add('LDFLAGS', '-L%s' % join(PREFIX, 'lib'), seperator=' ')
|
||||
|
||||
_env_add('LDFLAGS', '-L%s' % join(PREFIX, 'lib64'), seperator=' ')
|
||||
|
||||
_env_add('PATH', join(PREFIX, 'bin'))
|
||||
_env_add('PYTHONPATH', join(PREFIX, 'lib/python2.7/site-packages'))
|
||||
_env_add('PKG_CONFIG_PATH', join(PREFIX, 'lib', 'pkgconfig'))
|
||||
_env_add('PKG_CONFIG_PATH', join(PREFIX, 'lib64', 'pkgconfig'))
|
||||
_env_add('PKG_CONFIG_PATH', libsearpc_dir)
|
||||
_env_add('PKG_CONFIG_PATH', ccnet_dir)
|
||||
_env_add('LD_LIBRARY_PATH', join(PREFIX, 'lib'))
|
||||
|
||||
for key in ('PATH', 'PKG_CONFIG_PATH', 'CPPFLAGS', 'LDFLAGS', 'PYTHONPATH'):
|
||||
info('%s: %s', key, env.get(key, ''))
|
||||
return env
|
||||
|
||||
|
||||
def prepend_env_value(name, value, seperator=':', env=None):
|
||||
'''append a new value to a list'''
|
||||
env = env or os.environ
|
||||
current_value = env.get(name, '')
|
||||
new_value = value
|
||||
if current_value:
|
||||
new_value += seperator + current_value
|
||||
|
||||
env[name] = new_value
|
||||
return env
|
||||
|
||||
|
||||
@lru_cache()
|
||||
def get_branch_json_file():
|
||||
url = 'https://raw.githubusercontent.com/haiwen/seafile-test-deploy/master/branches.json'
|
||||
return requests.get(url).json()
|
||||
|
||||
|
||||
def get_project_branch(project, default_branch='master'):
|
||||
travis_branch = os.environ.get('TRAVIS_BRANCH', 'master')
|
||||
if project.name == 'seafile-server':
|
||||
return travis_branch
|
||||
conf = get_branch_json_file()
|
||||
return conf.get(travis_branch, {}).get(project.name, default_branch)
|
||||
|
||||
|
||||
class Project(object):
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.version = ''
|
||||
|
||||
@property
|
||||
def url(self):
|
||||
return 'https://www.github.com/haiwen/{}.git'.format(self.name)
|
||||
|
||||
@property
|
||||
def projectdir(self):
|
||||
return join(TOPDIR, self.name)
|
||||
|
||||
@property
|
||||
def branch(self):
|
||||
return get_project_branch(self)
|
||||
|
||||
def clone(self):
|
||||
if exists(self.name):
|
||||
with cd(self.name):
|
||||
shell('git fetch origin --tags')
|
||||
else:
|
||||
shell(
|
||||
'git clone --depth=1 --branch {} {}'.
|
||||
format(self.branch, self.url)
|
||||
)
|
||||
|
||||
@chdir
|
||||
def compile_and_install(self):
|
||||
cmds = [
|
||||
'./autogen.sh',
|
||||
'./configure --prefix={}'.format(PREFIX),
|
||||
'make -j{}'.format(num_jobs()),
|
||||
'make install',
|
||||
]
|
||||
for cmd in cmds:
|
||||
shell(cmd)
|
||||
|
||||
@chdir
|
||||
def use_branch(self, branch):
|
||||
shell('git checkout {}'.format(branch))
|
||||
|
||||
|
||||
class Libsearpc(Project):
|
||||
def __init__(self):
|
||||
super(Libsearpc, self).__init__('libsearpc')
|
||||
|
||||
|
||||
class CcnetServer(Project):
|
||||
def __init__(self):
|
||||
super(CcnetServer, self).__init__('ccnet-server')
|
||||
|
||||
|
||||
class SeafileServer(Project):
|
||||
def __init__(self):
|
||||
super(SeafileServer, self).__init__('seafile-server')
|
||||
|
||||
|
||||
def fetch_and_build():
|
||||
libsearpc = Project('libsearpc')
|
||||
ccnet = CcnetServer()
|
||||
seafile = SeafileServer()
|
||||
|
||||
libsearpc.clone()
|
||||
libsearpc.compile_and_install()
|
||||
|
||||
ccnet.clone()
|
||||
ccnet.compile_and_install()
|
||||
|
||||
seafile.compile_and_install()
|
||||
|
||||
|
||||
def parse_args():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument('-v', '--verbose', action='store_true')
|
||||
ap.add_argument('-t', '--test-only', action='store_true')
|
||||
|
||||
return ap.parse_args()
|
||||
|
||||
|
||||
def main():
|
||||
mkdirs(INSTALLDIR)
|
||||
os.environ.update(make_build_env())
|
||||
args = parse_args()
|
||||
if on_travis() and not args.test_only:
|
||||
fetch_and_build()
|
||||
# for db in ('sqlite3', 'mysql'):
|
||||
for db in ('sqlite3', ):
|
||||
shell('rm -rf {}/*'.format(INSTALLDIR))
|
||||
start_and_test_with_db(db)
|
||||
|
||||
|
||||
def start_and_test_with_db(db):
|
||||
info('Setting up seafile server with %s database', db)
|
||||
server = ServerCtl(INSTALLDIR, db)
|
||||
server.setup()
|
||||
with server.run():
|
||||
info('Testing with %s database', db)
|
||||
with cd(SeafileServer().projectdir):
|
||||
shell('py.test', env=server.get_seaserv_envs())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
os.chdir(TOPDIR)
|
||||
setup_logging()
|
||||
main()
|
162
ci/serverctl.py
Executable file
162
ci/serverctl.py
Executable file
@ -0,0 +1,162 @@
|
||||
#!/usr/bin/env python
|
||||
#coding: UTF-8
|
||||
|
||||
import argparse
|
||||
import glob
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from collections import namedtuple
|
||||
from contextlib import contextmanager
|
||||
from os.path import abspath, basename, dirname, exists, join
|
||||
|
||||
import requests
|
||||
from tenacity import TryAgain, retry, stop_after_attempt, wait_fixed
|
||||
|
||||
from utils import (
|
||||
cd, chdir, debug, green, info, mkdirs, red, setup_logging, shell, warning
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
MYSQL_ROOT_PASSWD = 's123'
|
||||
|
||||
|
||||
class ServerCtl(object):
|
||||
def __init__(self, datadir, db='sqlite3'):
|
||||
self.db = db
|
||||
self.datadir = datadir
|
||||
self.central_conf_dir = join(datadir, 'conf')
|
||||
self.seafile_conf_dir = join(datadir, 'seafile-data')
|
||||
self.ccnet_conf_dir = join(datadir, 'ccnet')
|
||||
|
||||
self.log_dir = join(datadir, 'logs')
|
||||
mkdirs(self.log_dir)
|
||||
self.ccnet_log = join(self.log_dir, 'ccnet.log')
|
||||
self.seafile_log = join(self.log_dir, 'seafile.log')
|
||||
|
||||
self.ccnet_proc = None
|
||||
self.seafile_proc = None
|
||||
|
||||
def setup(self):
|
||||
if self.db == 'mysql':
|
||||
create_mysql_dbs()
|
||||
|
||||
self.init_ccnet()
|
||||
self.init_seafile()
|
||||
|
||||
def init_ccnet(self):
|
||||
cmd = [
|
||||
'ccnet-init',
|
||||
'-F',
|
||||
self.central_conf_dir,
|
||||
'-c',
|
||||
self.ccnet_conf_dir,
|
||||
'--name',
|
||||
'test',
|
||||
'--host',
|
||||
'test.seafile.com',
|
||||
]
|
||||
shell(cmd)
|
||||
|
||||
def init_seafile(self):
|
||||
cmd = [
|
||||
'seaf-server-init',
|
||||
'--central-config-dir',
|
||||
self.central_conf_dir,
|
||||
'--seafile-dir',
|
||||
self.seafile_conf_dir,
|
||||
'--fileserver-port',
|
||||
'8082',
|
||||
]
|
||||
|
||||
shell(cmd)
|
||||
|
||||
@contextmanager
|
||||
def run(self):
|
||||
try:
|
||||
self.start()
|
||||
yield self
|
||||
except:
|
||||
self.print_logs()
|
||||
raise
|
||||
finally:
|
||||
self.stop()
|
||||
|
||||
def print_logs(self):
|
||||
for logfile in self.ccnet_log, self.seafile_log:
|
||||
if exists(logfile):
|
||||
shell('cat {0}'.format(logfile))
|
||||
|
||||
@retry(wait=wait_fixed(1), stop=stop_after_attempt(10))
|
||||
def wait_ccnet_ready(self):
|
||||
if not exists(join(self.ccnet_conf_dir, 'ccnet.sock')):
|
||||
raise TryAgain
|
||||
|
||||
def start(self):
|
||||
logger.info('Starting ccnet server')
|
||||
self.start_ccnet()
|
||||
self.wait_ccnet_ready()
|
||||
logger.info('Starting seafile server')
|
||||
self.start_seafile()
|
||||
|
||||
def start_ccnet(self):
|
||||
cmd = [
|
||||
"ccnet-server",
|
||||
"-F",
|
||||
self.central_conf_dir,
|
||||
"-c",
|
||||
self.ccnet_conf_dir,
|
||||
"-f",
|
||||
self.ccnet_log,
|
||||
]
|
||||
self.ccnet_proc = shell(cmd, wait=False)
|
||||
|
||||
def start_seafile(self):
|
||||
cmd = [
|
||||
"seaf-server",
|
||||
"-F",
|
||||
self.central_conf_dir,
|
||||
"-c",
|
||||
self.ccnet_conf_dir,
|
||||
"-d",
|
||||
self.seafile_conf_dir,
|
||||
"-l",
|
||||
self.seafile_log,
|
||||
]
|
||||
self.seafile_proc = shell(cmd, wait=False)
|
||||
|
||||
def stop(self):
|
||||
if self.ccnet_proc:
|
||||
logger.info('Stopping ccnet server')
|
||||
self.ccnet_proc.terminate()
|
||||
if self.seafile_proc:
|
||||
logger.info('Stopping seafile server')
|
||||
self.seafile_proc.terminate()
|
||||
|
||||
def get_seaserv_envs(self):
|
||||
envs = dict(os.environ)
|
||||
envs.update({
|
||||
'SEAFILE_CENTRAL_CONF_DIR': self.central_conf_dir,
|
||||
'CCNET_CONF_DIR': self.ccnet_conf_dir,
|
||||
'SEAFILE_CONF_DIR': self.seafile_conf_dir,
|
||||
})
|
||||
return envs
|
||||
|
||||
|
||||
def create_mysql_dbs():
|
||||
shell('mysqladmin -u root password %s' % MYSQL_ROOT_PASSWD)
|
||||
sql = '''\
|
||||
create database `ccnet-existing` character set = 'utf8';
|
||||
create database `seafile-existing` character set = 'utf8';
|
||||
create database `seahub-existing` character set = 'utf8';
|
||||
|
||||
create user 'seafile'@'localhost' identified by 'seafile';
|
||||
|
||||
GRANT ALL PRIVILEGES ON `ccnet-existing`.* to `seafile`@localhost;
|
||||
GRANT ALL PRIVILEGES ON `seafile-existing`.* to `seafile`@localhost;
|
||||
GRANT ALL PRIVILEGES ON `seahub-existing`.* to `seafile`@localhost;
|
||||
'''
|
||||
|
||||
shell('mysql -u root -p%s' % MYSQL_ROOT_PASSWD, inputdata=sql)
|
@ -1,18 +1,23 @@
|
||||
#coding: UTF-8
|
||||
|
||||
import os
|
||||
from os.path import abspath, basename, exists, expanduser, join
|
||||
import sys
|
||||
import re
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from contextlib import contextmanager
|
||||
from subprocess import Popen, PIPE, CalledProcessError
|
||||
from os.path import abspath, basename, exists, expanduser, join
|
||||
from subprocess import PIPE, CalledProcessError, Popen
|
||||
|
||||
import termcolor
|
||||
import requests
|
||||
from pexpect import spawn
|
||||
import termcolor
|
||||
|
||||
try:
|
||||
from functools import lru_cache
|
||||
except ImportError:
|
||||
from backports.functools_lru_cache import lru_cache
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
logger = logging.getLogger(__file__)
|
||||
|
||||
def _color(s, color):
|
||||
return s if not os.isatty(sys.stdout.fileno()) \
|
||||
@ -39,16 +44,19 @@ def warning(fmt, *a):
|
||||
logger.warn(red(fmt), *a)
|
||||
|
||||
|
||||
def shell(cmd, inputdata=None, **kw):
|
||||
def shell(cmd, inputdata=None, wait=True, **kw):
|
||||
info('calling "%s" in %s', cmd, kw.get('cwd', os.getcwd()))
|
||||
kw['shell'] = not isinstance(cmd, list)
|
||||
kw['stdin'] = PIPE if inputdata else None
|
||||
p = Popen(cmd, **kw)
|
||||
if inputdata:
|
||||
p.communicate(inputdata)
|
||||
p.wait()
|
||||
if p.returncode:
|
||||
raise CalledProcessError(p.returncode, cmd)
|
||||
if wait:
|
||||
p.wait()
|
||||
if p.returncode:
|
||||
raise CalledProcessError(p.returncode, cmd)
|
||||
else:
|
||||
return p
|
||||
|
||||
|
||||
@contextmanager
|
||||
@ -68,6 +76,7 @@ def chdir(func):
|
||||
|
||||
return wrapped
|
||||
|
||||
|
||||
def setup_logging():
|
||||
kw = {
|
||||
'format': '[%(asctime)s][%(module)s]: %(message)s',
|
||||
@ -77,5 +86,24 @@ def setup_logging():
|
||||
}
|
||||
|
||||
logging.basicConfig(**kw)
|
||||
logging.getLogger('requests.packages.urllib3.connectionpool').setLevel(
|
||||
logging.WARNING)
|
||||
logging.getLogger('requests.packages.urllib3.connectionpool'
|
||||
).setLevel(logging.WARNING)
|
||||
|
||||
|
||||
def mkdirs(*paths):
|
||||
for path in paths:
|
||||
if not exists(path):
|
||||
os.mkdir(path)
|
||||
|
||||
def on_travis():
|
||||
return 'TRAVIS_BUILD_NUMBER' in os.environ
|
||||
|
||||
@contextmanager
|
||||
def cd(path):
|
||||
path = expanduser(path)
|
||||
olddir = os.getcwd()
|
||||
os.chdir(path)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
os.chdir(olddir)
|
@ -1,3 +0,0 @@
|
||||
### Seafile Integration Tests
|
||||
|
||||
The purpose of integration tests is to build a seafile release package and run tests against it.
|
@ -1,259 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#coding: UTF-8
|
||||
|
||||
import os
|
||||
from os.path import abspath, basename, exists, dirname, join
|
||||
import sys
|
||||
import argparse
|
||||
import re
|
||||
from collections import namedtuple
|
||||
|
||||
import requests
|
||||
from pexpect import spawn
|
||||
|
||||
from utils import green, red, debug, info, warning, cd, shell, chdir, setup_logging
|
||||
|
||||
USERNAME = 'test@seafiletest.com'
|
||||
PASSWORD = 'testtest'
|
||||
ADMIN_USERNAME = 'admin@seafiletest.com'
|
||||
ADMIN_PASSWORD = 'adminadmin'
|
||||
MYSQL_ROOT_PASSWD = 's123'
|
||||
|
||||
ServerConfig = namedtuple('ServerConfig', [
|
||||
'installdir',
|
||||
'tarball',
|
||||
'version',
|
||||
'initmode',
|
||||
])
|
||||
|
||||
|
||||
def setup_server(cfg, db):
|
||||
'''Setup seafile server with the setup-seafile.sh script. We use pexpect to
|
||||
interactive with the setup process of the script.
|
||||
'''
|
||||
info('uncompressing server tarball')
|
||||
shell('tar xf seafile-server_{}_x86-64.tar.gz -C {}'
|
||||
.format(cfg.version, cfg.installdir))
|
||||
if db == 'mysql':
|
||||
autosetup_mysql(cfg)
|
||||
else:
|
||||
autosetup_sqlite3(cfg)
|
||||
|
||||
with open(join(cfg.installdir, 'conf/seahub_settings.py'), 'a') as fp:
|
||||
fp.write('\n')
|
||||
fp.write('DEBUG = True')
|
||||
fp.write('\n')
|
||||
fp.write('''\
|
||||
REST_FRAMEWORK = {
|
||||
'DEFAULT_THROTTLE_RATES': {
|
||||
'ping': '600/minute',
|
||||
'anon': '1000/minute',
|
||||
'user': '1000/minute',
|
||||
},
|
||||
}''')
|
||||
fp.write('\n')
|
||||
|
||||
|
||||
def autosetup_sqlite3(cfg):
|
||||
setup_script = get_script(cfg, 'setup-seafile.sh')
|
||||
shell('''sed -i -e '/^check_root;.*/d' "{}"'''.format(setup_script))
|
||||
|
||||
if cfg.initmode == 'prompt':
|
||||
setup_sqlite3_prompt(setup_script)
|
||||
else:
|
||||
setup_sqlite3_auto(setup_script)
|
||||
|
||||
def setup_sqlite3_prompt(setup_script):
|
||||
info('setting up seafile server with pexepct, script %s', setup_script)
|
||||
answers = [
|
||||
('ENTER', ''),
|
||||
# server name
|
||||
('server name', 'my-seafile'),
|
||||
# ip or domain
|
||||
('ip or domain', '127.0.0.1'),
|
||||
# seafile data dir
|
||||
('seafile-data', ''),
|
||||
# fileserver port
|
||||
('seafile fileserver', ''),
|
||||
('ENTER', ''),
|
||||
('ENTER', ''),
|
||||
]
|
||||
_answer_questions(setup_script, answers)
|
||||
|
||||
def setup_sqlite3_auto(setup_script):
|
||||
info('setting up seafile server in auto mode, script %s', setup_script)
|
||||
env = os.environ.copy()
|
||||
env['SERVER_IP'] = '127.0.0.1'
|
||||
shell('%s auto -n my-seafile' % setup_script, env=env)
|
||||
|
||||
def createdbs():
|
||||
sql = '''\
|
||||
create database `ccnet-existing` character set = 'utf8';
|
||||
create database `seafile-existing` character set = 'utf8';
|
||||
create database `seahub-existing` character set = 'utf8';
|
||||
|
||||
create user 'seafile'@'localhost' identified by 'seafile';
|
||||
|
||||
GRANT ALL PRIVILEGES ON `ccnet-existing`.* to `seafile`@localhost;
|
||||
GRANT ALL PRIVILEGES ON `seafile-existing`.* to `seafile`@localhost;
|
||||
GRANT ALL PRIVILEGES ON `seahub-existing`.* to `seafile`@localhost;
|
||||
'''
|
||||
|
||||
shell('mysql -u root -p%s' % MYSQL_ROOT_PASSWD, inputdata=sql)
|
||||
|
||||
|
||||
def autosetup_mysql(cfg):
|
||||
setup_script = get_script(cfg, 'setup-seafile-mysql.sh')
|
||||
if not exists(setup_script):
|
||||
print 'please specify seafile script path'
|
||||
|
||||
if cfg.initmode == 'prompt':
|
||||
createdbs()
|
||||
setup_mysql_prompt(setup_script)
|
||||
else :
|
||||
# in auto mode, test create new db
|
||||
setup_mysql_auto(setup_script)
|
||||
|
||||
def setup_mysql_prompt(setup_script):
|
||||
info('setting up seafile server with pexepct, script %s', setup_script)
|
||||
answers = [
|
||||
('ENTER', ''),
|
||||
# server name
|
||||
('server name', 'my-seafile'),
|
||||
# ip or domain
|
||||
('ip or domain', '127.0.0.1'),
|
||||
# seafile data dir
|
||||
('seafile-data', ''),
|
||||
# fileserver port
|
||||
('seafile fileserver', ''),
|
||||
# use existing
|
||||
('choose a way to initialize seafile databases', '2'),
|
||||
('host of mysql server', ''),
|
||||
('port of mysql server', ''),
|
||||
('Which mysql user', 'seafile'),
|
||||
('password for mysql user', 'seafile'),
|
||||
('ccnet database', 'ccnet-existing'),
|
||||
('seafile database', 'seafile-existing'),
|
||||
('seahub database', 'seahub-existing'),
|
||||
('ENTER', ''),
|
||||
]
|
||||
_answer_questions(abspath(setup_script), answers)
|
||||
|
||||
def setup_mysql_auto(setup_script):
|
||||
info('setting up seafile server in auto mode, script %s', setup_script)
|
||||
env = os.environ.copy()
|
||||
env['MYSQL_USER'] = 'seafile-new'
|
||||
env['MYSQL_USER_PASSWD'] = 'seafile'
|
||||
env['MYSQL_ROOT_PASSWD']= MYSQL_ROOT_PASSWD
|
||||
env['CCNET_DB'] = 'ccnet-new'
|
||||
env['SEAFILE_DB'] = 'seafile-new'
|
||||
env['SEAHUB_DB'] = 'seahub-new'
|
||||
shell('%s auto -n my-seafile -e 0' % setup_script, env=env)
|
||||
|
||||
def start_server(cfg):
|
||||
with cd(cfg.installdir):
|
||||
shell('find . -maxdepth 2 | sort | xargs ls -lhd')
|
||||
seafile_sh = get_script(cfg, 'seafile.sh')
|
||||
shell('{} start'.format(seafile_sh))
|
||||
|
||||
info('starting seahub')
|
||||
seahub_sh = get_script(cfg, 'seahub.sh')
|
||||
answers = [
|
||||
# admin email/pass
|
||||
('admin email', ADMIN_USERNAME),
|
||||
('admin password', ADMIN_PASSWORD),
|
||||
('admin password again', ADMIN_PASSWORD),
|
||||
]
|
||||
_answer_questions('{} start'.format(abspath(seahub_sh)), answers)
|
||||
with cd(cfg.installdir):
|
||||
shell('find . -maxdepth 2 | sort | xargs ls -lhd')
|
||||
# shell('sqlite3 ccnet/PeerMgr/usermgr.db "select * from EmailUser"', cwd=INSTALLDIR)
|
||||
shell('http -v localhost:8000/api2/server-info/ || true')
|
||||
# shell('http -v -f POST localhost:8000/api2/auth-token/ username=admin@seafiletest.com password=adminadmin || true')
|
||||
shell('netstat -nltp')
|
||||
|
||||
|
||||
def _answer_questions(cmd, answers):
|
||||
info('expect: spawing %s', cmd)
|
||||
child = spawn(cmd)
|
||||
child.logfile = sys.stdout
|
||||
|
||||
def autofill(pattern, line):
|
||||
child.expect(pattern)
|
||||
child.sendline(line)
|
||||
|
||||
for k, v in answers:
|
||||
autofill(k, v)
|
||||
child.sendline('')
|
||||
child.logfile = None
|
||||
child.interact()
|
||||
|
||||
|
||||
def get_script(cfg, path):
|
||||
"""
|
||||
:type cfg: ServerConfig
|
||||
"""
|
||||
return join(server_dir(cfg), path)
|
||||
|
||||
|
||||
def server_dir(cfg):
|
||||
"""
|
||||
:type cfg: ServerConfig
|
||||
"""
|
||||
return join(cfg.installdir, 'seafile-server-{}'.format(cfg.version))
|
||||
|
||||
|
||||
def apiurl(path):
|
||||
path = path.lstrip('/')
|
||||
root = os.environ.get('SEAFILE_SERVER', 'http://127.0.0.1:8000')
|
||||
return '{}/api2/{}'.format(root, path)
|
||||
|
||||
|
||||
def create_test_user(cfg):
|
||||
data = {'username': ADMIN_USERNAME, 'password': ADMIN_PASSWORD, }
|
||||
res = requests.post(apiurl('/auth-token/'), data=data)
|
||||
debug('%s %s', res.status_code, res.text)
|
||||
token = res.json()['token']
|
||||
data = {'password': PASSWORD, }
|
||||
headers = {'Authorization': 'Token ' + token}
|
||||
res = requests.put(
|
||||
apiurl('/accounts/{}/'.format(USERNAME)),
|
||||
data=data,
|
||||
headers=headers)
|
||||
assert res.status_code == 201
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument('-v', '--verbose', action='store_true')
|
||||
ap.add_argument('--db', choices=('sqlite3', 'mysql'), default='sqlite3')
|
||||
ap.add_argument('installdir')
|
||||
ap.add_argument('tarball')
|
||||
args = ap.parse_args()
|
||||
|
||||
if not exists(args.installdir):
|
||||
print 'directory {} does not exist'.format(args.installdir)
|
||||
sys.exit(1)
|
||||
|
||||
if os.listdir(args.installdir):
|
||||
print 'directory {} is not empty'.format(args.installdir)
|
||||
sys.exit(1)
|
||||
|
||||
if not exists(args.tarball):
|
||||
print 'file {} does not exist'.format(args.tarball)
|
||||
sys.exit(1)
|
||||
|
||||
m = re.match(r'^.*?_([\d\.]+).*?\.tar\.gz$', basename(args.tarball))
|
||||
version = m.group(1)
|
||||
|
||||
cfg = ServerConfig(installdir=args.installdir,
|
||||
tarball=args.tarball,
|
||||
version=version)
|
||||
setup_server(cfg, args.db)
|
||||
start_server(cfg)
|
||||
create_test_user(cfg)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setup_logging()
|
||||
main()
|
@ -1,56 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e -x
|
||||
|
||||
pip install -r ./integration-tests/requirements.txt
|
||||
|
||||
pushd $HOME
|
||||
|
||||
# download precompiled libevhtp
|
||||
libevhtp_bin=libevhtp-bin_1.2.0.tar.gz
|
||||
wget https://dl.bintray.com/lins05/generic/libevhtp-bin/$libevhtp_bin
|
||||
tar xf $libevhtp_bin
|
||||
find $HOME/opt
|
||||
|
||||
# download seahub thirdpart python libs
|
||||
WGET="wget --no-check-certificate"
|
||||
downloads=$HOME/downloads
|
||||
thirdpart=$HOME/thirdpart
|
||||
|
||||
mkdir -p $downloads $thirdpart
|
||||
cd $thirdpart
|
||||
save_pythonpath=$PYTHONPATH
|
||||
export PYTHONPATH=.
|
||||
urls=(
|
||||
https://pypi.python.org/packages/source/p/pytz/pytz-2016.1.tar.gz
|
||||
https://www.djangoproject.com/m/releases/1.8/Django-1.8.10.tar.gz
|
||||
https://pypi.python.org/packages/source/d/django-statici18n/django-statici18n-1.1.3.tar.gz
|
||||
https://pypi.python.org/packages/source/d/djangorestframework/djangorestframework-3.3.2.tar.gz
|
||||
https://pypi.python.org/packages/source/d/django_compressor/django_compressor-1.4.tar.gz
|
||||
|
||||
https://pypi.python.org/packages/source/j/jsonfield/jsonfield-1.0.3.tar.gz
|
||||
https://pypi.python.org/packages/source/d/django-post_office/django-post_office-2.0.6.tar.gz
|
||||
|
||||
http://pypi.python.org/packages/source/g/gunicorn/gunicorn-19.4.5.tar.gz
|
||||
http://pypi.python.org/packages/source/f/flup/flup-1.0.2.tar.gz
|
||||
https://pypi.python.org/packages/source/c/chardet/chardet-2.3.0.tar.gz
|
||||
https://labix.org/download/python-dateutil/python-dateutil-1.5.tar.gz
|
||||
https://pypi.python.org/packages/source/s/six/six-1.9.0.tar.gz
|
||||
|
||||
https://pypi.python.org/packages/source/d/django-picklefield/django-picklefield-0.3.2.tar.gz
|
||||
https://pypi.python.org/packages/source/d/django-constance/django-constance-1.0.1.tar.gz
|
||||
|
||||
https://pypi.python.org/packages/source/j/jdcal/jdcal-1.2.tar.gz
|
||||
https://pypi.python.org/packages/source/e/et_xmlfile/et_xmlfile-1.0.1.tar.gz
|
||||
https://pypi.python.org/packages/source/o/openpyxl/openpyxl-2.3.0.tar.gz
|
||||
)
|
||||
for url in ${urls[*]}; do
|
||||
path="${downloads}/$(basename $url)"
|
||||
if [[ ! -e $path ]]; then
|
||||
$WGET -O $path $url
|
||||
fi
|
||||
easy_install -d . $path
|
||||
done
|
||||
export PYTHONPATH=$save_pythonpath
|
||||
|
||||
popd
|
@ -1,8 +0,0 @@
|
||||
Pillow==4.1.0
|
||||
termcolor==1.1.0
|
||||
prettytable==0.7.2
|
||||
pexpect==4.0
|
||||
requests==2.8.0
|
||||
httpie
|
||||
django-constance[database]
|
||||
MySQL-python==1.2.5
|
@ -1,307 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
from os.path import abspath, basename, exists, expanduser, join
|
||||
import sys
|
||||
import re
|
||||
import glob
|
||||
import json
|
||||
import logging
|
||||
import requests
|
||||
|
||||
import termcolor
|
||||
from pexpect import spawn
|
||||
from utils import green, red, debug, info, warning, cd, shell, chdir, setup_logging
|
||||
from autosetup import (setup_server, ServerConfig, get_script, server_dir,
|
||||
start_server, create_test_user, MYSQL_ROOT_PASSWD)
|
||||
|
||||
TOPDIR = abspath(join(os.getcwd(), '..'))
|
||||
PREFIX = expanduser('~/opt/local')
|
||||
SRCDIR = '/tmp/src'
|
||||
INSTALLDIR = '/tmp/haiwen'
|
||||
THIRDPARTDIR = expanduser('~/thirdpart')
|
||||
|
||||
logger = logging.getLogger(__file__)
|
||||
seafile_version = ''
|
||||
|
||||
TRAVIS_BRANCH = os.environ.get('TRAVIS_BRANCH', 'master')
|
||||
|
||||
|
||||
def make_build_env():
|
||||
env = dict(os.environ)
|
||||
libsearpc_dir = abspath(join(TOPDIR, 'libsearpc'))
|
||||
ccnet_dir = abspath(join(TOPDIR, 'ccnet-server'))
|
||||
|
||||
def _env_add(*a, **kw):
|
||||
kw['env'] = env
|
||||
return prepend_env_value(*a, **kw)
|
||||
|
||||
_env_add('CPPFLAGS', '-I%s' % join(PREFIX, 'include'), seperator=' ')
|
||||
|
||||
_env_add('LDFLAGS', '-L%s' % os.path.join(PREFIX, 'lib'), seperator=' ')
|
||||
|
||||
_env_add('LDFLAGS', '-L%s' % os.path.join(PREFIX, 'lib64'), seperator=' ')
|
||||
|
||||
_env_add('PATH', os.path.join(PREFIX, 'bin'))
|
||||
_env_add('PATH', THIRDPARTDIR)
|
||||
_env_add('PKG_CONFIG_PATH', os.path.join(PREFIX, 'lib', 'pkgconfig'))
|
||||
_env_add('PKG_CONFIG_PATH', os.path.join(PREFIX, 'lib64', 'pkgconfig'))
|
||||
_env_add('PKG_CONFIG_PATH', libsearpc_dir)
|
||||
_env_add('PKG_CONFIG_PATH', ccnet_dir)
|
||||
|
||||
for key in ('PATH', 'PKG_CONFIG_PATH', 'CPPFLAGS', 'LDFLAGS',
|
||||
'PYTHONPATH'):
|
||||
info('%s: %s', key, env.get(key, ''))
|
||||
return env
|
||||
|
||||
|
||||
def prepend_env_value(name, value, seperator=':', env=None):
|
||||
'''append a new value to a list'''
|
||||
env = env or os.environ
|
||||
current_value = env.get(name, '')
|
||||
new_value = value
|
||||
if current_value:
|
||||
new_value += seperator + current_value
|
||||
|
||||
env[name] = new_value
|
||||
return env
|
||||
|
||||
|
||||
def get_project_branch(project, default_branch='master'):
|
||||
if project.name == 'seafile-server':
|
||||
return TRAVIS_BRANCH
|
||||
conf = json.loads(requests.get(
|
||||
'https://raw.githubusercontent.com/haiwen/seafile-test-deploy/master/branches.json').text)
|
||||
return conf.get(TRAVIS_BRANCH, {}).get(project.name,
|
||||
default_branch)
|
||||
|
||||
|
||||
class Project(object):
|
||||
configure_cmd = './configure'
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.version = ''
|
||||
|
||||
@property
|
||||
def url(self):
|
||||
return 'https://www.github.com/haiwen/{}.git'.format(self.name)
|
||||
|
||||
@property
|
||||
def projectdir(self):
|
||||
return join(TOPDIR, self.name)
|
||||
|
||||
@property
|
||||
def branch(self):
|
||||
return get_project_branch(self)
|
||||
|
||||
def clone(self):
|
||||
if exists(self.name):
|
||||
with cd(self.name):
|
||||
shell('git fetch origin --tags')
|
||||
else:
|
||||
shell('git clone --depth=1 --branch {} {}'.format(self.branch,
|
||||
self.url))
|
||||
|
||||
@chdir
|
||||
def make_dist(self):
|
||||
info('making tarball for %s', self.name)
|
||||
if exists('./autogen.sh'):
|
||||
shell('./autogen.sh')
|
||||
shell(self.configure_cmd, env=make_build_env())
|
||||
shell('make dist')
|
||||
|
||||
@chdir
|
||||
def copy_dist(self):
|
||||
self.make_dist()
|
||||
tarball = glob.glob('*.tar.gz')[0]
|
||||
info('copying %s to %s', tarball, SRCDIR)
|
||||
shell('cp {} {}'.format(tarball, SRCDIR))
|
||||
if self.name == 'seafile-server':
|
||||
name = 'seafile'
|
||||
elif self.name == 'ccnet-server':
|
||||
name = 'ccnet'
|
||||
else:
|
||||
name = self.name
|
||||
m = re.match('{}-(.*).tar.gz'.format(name), basename(tarball))
|
||||
if m:
|
||||
self.version = m.group(1)
|
||||
|
||||
@chdir
|
||||
def use_branch(self, branch):
|
||||
shell('git checkout {}'.format(branch))
|
||||
|
||||
|
||||
class CcnetServer(Project):
|
||||
def __init__(self):
|
||||
super(CcnetServer, self).__init__('ccnet-server')
|
||||
|
||||
|
||||
class SeafileServer(Project):
|
||||
configure_cmd = './configure'
|
||||
|
||||
def __init__(self):
|
||||
super(SeafileServer, self).__init__('seafile-server')
|
||||
|
||||
@chdir
|
||||
def copy_dist(self):
|
||||
super(SeafileServer, self).copy_dist()
|
||||
global seafile_version
|
||||
seafile_version = self.version
|
||||
|
||||
|
||||
class Seahub(Project):
|
||||
def __init__(self):
|
||||
super(Seahub, self).__init__('seahub')
|
||||
|
||||
@chdir
|
||||
def make_dist(self):
|
||||
cmds = [
|
||||
# 'git add -f media/css/*.css',
|
||||
# 'git commit -a -m "%s"' % msg,
|
||||
'./tools/gen-tarball.py --version={} --branch=HEAD >/dev/null'
|
||||
.format(seafile_version),
|
||||
]
|
||||
for cmd in cmds:
|
||||
shell(cmd, env=make_build_env())
|
||||
|
||||
|
||||
class SeafDAV(Project):
|
||||
def __init__(self):
|
||||
super(SeafDAV, self).__init__('seafdav')
|
||||
|
||||
@chdir
|
||||
def make_dist(self):
|
||||
shell('make')
|
||||
|
||||
|
||||
class SeafObj(Project):
|
||||
def __init__(self):
|
||||
super(SeafObj, self).__init__('seafobj')
|
||||
|
||||
@chdir
|
||||
def make_dist(self):
|
||||
shell('make dist')
|
||||
|
||||
|
||||
def build_server(libsearpc, ccnet, seafile):
|
||||
cmd = [
|
||||
'python',
|
||||
join(TOPDIR, 'seafile-server/scripts/build/build-server.py'),
|
||||
'--yes',
|
||||
'--version=%s' % seafile.version,
|
||||
'--libsearpc_version=%s' % libsearpc.version,
|
||||
'--ccnet_version=%s' % ccnet.version,
|
||||
'--seafile_version=%s' % seafile.version,
|
||||
'--thirdpartdir=%s' % THIRDPARTDIR,
|
||||
'--srcdir=%s' % SRCDIR,
|
||||
'--jobs=4',
|
||||
]
|
||||
shell(cmd, shell=False, env=make_build_env())
|
||||
|
||||
|
||||
def fetch_and_build():
|
||||
libsearpc = Project('libsearpc')
|
||||
ccnet = CcnetServer()
|
||||
seafile = SeafileServer()
|
||||
seahub = Seahub()
|
||||
seafobj = SeafObj()
|
||||
seafdav = SeafDAV()
|
||||
|
||||
for project in (libsearpc, ccnet, seafile, seahub, seafdav, seafobj):
|
||||
if project.name != 'seafile-server':
|
||||
project.clone()
|
||||
project.copy_dist()
|
||||
|
||||
build_server(libsearpc, ccnet, seafile)
|
||||
|
||||
|
||||
def run_tests(cfg):
|
||||
# run_python_seafile_tests()
|
||||
# run_seafdav_tests(cfg)
|
||||
# must stop seafile server before running seaf-gc
|
||||
shell('{} stop'.format(get_script(cfg, 'seafile.sh')))
|
||||
shell('{} stop'.format(get_script(cfg, 'seahub.sh')))
|
||||
shell('{} --verbose --rm-deleted'.format(get_script(cfg, 'seaf-gc.sh')))
|
||||
|
||||
|
||||
def run_python_seafile_tests():
|
||||
python_seafile = Project('python-seafile')
|
||||
if not exists(python_seafile.projectdir):
|
||||
python_seafile.clone()
|
||||
shell('pip install -r {}/requirements.txt'.format(
|
||||
python_seafile.projectdir))
|
||||
|
||||
with cd(python_seafile.projectdir):
|
||||
# install python-seafile because seafdav tests needs it
|
||||
shell('python setup.py install')
|
||||
shell('py.test')
|
||||
|
||||
|
||||
def _seafdav_env(cfg):
|
||||
env = dict(os.environ)
|
||||
env['CCNET_CONF_DIR'] = join(INSTALLDIR, 'ccnet')
|
||||
env['SEAFILE_CONF_DIR'] = join(INSTALLDIR, 'seafile-data')
|
||||
env['SEAFILE_CENTRAL_CONF_DIR'] = join(INSTALLDIR, 'conf')
|
||||
for path in glob.glob(join(
|
||||
server_dir(cfg), 'seafile/lib*/python*/*-packages')):
|
||||
prepend_env_value('PYTHONPATH', path, env=env)
|
||||
return env
|
||||
|
||||
|
||||
def run_seafdav_tests(cfg):
|
||||
seafdav = SeafDAV()
|
||||
shell('pip install -r {}/test-requirements.txt'.format(seafdav.projectdir))
|
||||
with cd(seafdav.projectdir):
|
||||
shell('nosetests -v -s', env=_seafdav_env(cfg))
|
||||
|
||||
|
||||
def _mkdirs(*paths):
|
||||
for path in paths:
|
||||
if not exists(path):
|
||||
os.mkdir(path)
|
||||
|
||||
|
||||
def main():
|
||||
_mkdirs(SRCDIR, INSTALLDIR)
|
||||
setup_logging()
|
||||
fetch_and_build()
|
||||
for db in ('sqlite3', 'mysql'):
|
||||
if db == 'mysql':
|
||||
shell('mysqladmin -u root password %s' % MYSQL_ROOT_PASSWD)
|
||||
for i in ('prompt', 'auto'):
|
||||
shell('rm -rf {}/*'.format(INSTALLDIR))
|
||||
setup_and_test(db, i)
|
||||
|
||||
|
||||
def setup_and_test(db, initmode):
|
||||
cfg = ServerConfig(
|
||||
installdir=INSTALLDIR,
|
||||
tarball=join(TOPDIR, 'seafile-server_{}_x86-64.tar.gz'.format(
|
||||
seafile_version)),
|
||||
version=seafile_version,
|
||||
initmode=initmode)
|
||||
info('Setting up seafile server with %s database', db)
|
||||
setup_server(cfg, db)
|
||||
# enable webdav, we're going to seafdav tests later
|
||||
shell('''sed -i -e "s/enabled = false/enabled = true/g" {}'''
|
||||
.format(join(INSTALLDIR, 'conf/seafdav.conf')))
|
||||
try:
|
||||
start_server(cfg)
|
||||
info('Testing seafile server with %s database', db)
|
||||
create_test_user(cfg)
|
||||
run_tests(cfg)
|
||||
except:
|
||||
for logfile in glob.glob('{}/logs/*.log'.format(INSTALLDIR)):
|
||||
shell('echo {0}; cat {0}'.format(logfile))
|
||||
for logfile in glob.glob('{}/seafile-server-{}/runtime/*.log'.format(
|
||||
INSTALLDIR, seafile_version)):
|
||||
shell('echo {0}; cat {0}'.format(logfile))
|
||||
raise
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
os.chdir(TOPDIR)
|
||||
# Add the location where libevhtp is installed so ldd can know it.
|
||||
prepend_env_value('LD_LIBRARY_PATH', os.path.expanduser('~/opt/local/lib'))
|
||||
main()
|
5
pytest.ini
Normal file
5
pytest.ini
Normal file
@ -0,0 +1,5 @@
|
||||
[pytest]
|
||||
addopts = -vv -s
|
||||
log_format = %(asctime)s:%(name)s:%(levelname)s:%(message)s
|
||||
log_date_format = %Y-%m-%d %H:%M:%S
|
||||
# log_cli_level = info
|
12
run_tests.sh
Executable file
12
run_tests.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT=${BASH_SOURCE[0]}
|
||||
PROJECT_DIR=$(dirname "${SCRIPT}")
|
||||
|
||||
cd $PROJECT_DIR
|
||||
|
||||
export PYTHONPATH=$PROJECT_DIR:$PYTHONPATH
|
||||
|
||||
ci/run.py --test-only
|
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
@ -1,11 +0,0 @@
|
||||
[General]
|
||||
USER_NAME = server
|
||||
ID = 8e4b13b49ca79f35732d9f44a0804940d985627c
|
||||
NAME = server
|
||||
SERVICE_URL = http://127.0.0.1
|
||||
|
||||
[Network]
|
||||
PORT = 10002
|
||||
|
||||
[Client]
|
||||
PORT = 9999
|
@ -1,27 +0,0 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAuZFwgxkKQGaqYyFMxIUz1JHnZPaOgEQ+fX/jRVYbGMiHkSbX
|
||||
K9X3XUHUGEjUt8b3zW6UZJGjgyV5S08YuaN0eE5z6Q6bnuWEhkTmgZgXaybc9Hiu
|
||||
y2WAHpKj+qbXcmewE0WEys/Ov9AIe0TRXmvL6r1793VcLSzgb/aIQA2WFg97DfEA
|
||||
hGAHo5BesKRfEEvXL6ZB9cGxXP9qIy0ObTvLXlOgbYchfV4rrXJk0u9xWjRyXABv
|
||||
2Myv3fgxmGmTR+TAw2G5GCKeh9IoIuWVMGPyjSlERGMqQYymNz3NgyWFayyZ5HQS
|
||||
tihCnflOGEiMHRkOwIczB16YZhan2YqKpsjHGwIBIwKCAQEArvbXzBBLfoyvR4XM
|
||||
Cb9rYgXozOh3usQAZ7MYHM2HQ0C6VahHN/WgFhl+1RF4Gv1tTKoW4nqwHJEL9oxn
|
||||
xPkzTNxBZrYAcT7NaKdc/diLG+LQVDdFuHWkrxyL+vUUR0vR5kjcSjGlrYmhmMvb
|
||||
WQaNEIbFVwhA92TTnMPfjNmcI2wRKI1K9NEKDAMIPSwW/sgkls2h4KW3Y7DooJ0k
|
||||
l0apjN/rlaR4ohZp6oMVifW8GFY43Xau+4dIrYTnvvSyvGvtB+8cWuhqqvWHRZdM
|
||||
rFjgOJoZH5l0zxt2dYW2WFiqgT7xXsvu6L+nylXktEMxC33rehYdPrd427J409A6
|
||||
caO5cwKBgQDyrBQ8UXu7cDAktiKTwH7+pA0wNyTvKsGYw0RcFILccpxty2r5gYhI
|
||||
eLFPVyjoYxwauW6vX3cSAYLKR+2PlYvkPpEvBQIJbaurx++ejez/KxYD65ZeFTfs
|
||||
Kb9A08hgMxCvJmnRvojhez1OZmmmWYPT57XeZXnCiNoyJWKA0mMNvwKBgQDDwn02
|
||||
o5n7ugetXIlV1PiStVogPPTBobh9jsXooQFh4fB+lsrO082hapMlbVVNG1gLzvTY
|
||||
V0oDM/AzdnC6feZlAEdM+IcruinVnMnbnhiwPVDInCJIhvmJ/XScvkTsgHwRiAss
|
||||
Tlf8wH/uGXiaeVV/KMlkKRK6h54znTPq37/VpQKBgQDkziG1NuJgRTS05j3bxB/3
|
||||
Z3omJV1Wh2YTsMtswuHIiVGpWWTcnrOyC2VZb2+2iVUDQR83oycfmwZJsYg27BYu
|
||||
+SnNPzxvSiWEtTJiS00rGf7QfwoeMUNbAspEb+jPux5b/6WZ34hfkXRRO/02cagu
|
||||
Mj3DDzhJtDtxG+8pAOEM9QKBgQC+KqWFiPv72UlJUpQKPJmzFpIQsD44cTbgXs7h
|
||||
+32viwbhX0irqS4nxp2SEnAfBJ6sYqS05xSyp3uftOKJRxpTfJ0I8W1drYe5kP6a
|
||||
1Bf7qUcpRzc/JAhaKWn3Wb9MJQrPM7MVGOfCVJmINgAhCCcrEa2xwX/oZnxsp1cB
|
||||
a6RpIwKBgQDW15IebNwVOExTqtfh6UvIjMSrk9OoHDyjoPLI3eyPt3ujKdXFJ8qF
|
||||
CWg9ianQyE5Y8vfDI+x1YRCOwq2WapeXzkSO8CzVFHgz5kFqJQolr4+o6wr5mLLC
|
||||
+6iW9u81/X3bMAWshtNfsWbRSFLT1WNVTKRg+xO7YG/3wcyeIeqigA==
|
||||
-----END RSA PRIVATE KEY-----
|
9
tests/config.py
Normal file
9
tests/config.py
Normal file
@ -0,0 +1,9 @@
|
||||
USER = 'testuser@test.seafile.com'
|
||||
PASSWORD = 'testuser'
|
||||
USER2 = 'testuser2@test.seafile.com'
|
||||
PASSWORD2 = 'testuser2'
|
||||
ADMIN_USER = 'adminuser@test.seafile.com'
|
||||
ADMIN_PASSWORD = 'adminuser'
|
||||
|
||||
INACTIVE_USER = 'inactiveuser@test.seafile.com'
|
||||
INACTIVE_PASSWORD = 'inactiveuser'
|
51
tests/conftest.py
Normal file
51
tests/conftest.py
Normal file
@ -0,0 +1,51 @@
|
||||
#coding: UTF-8
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
import pytest
|
||||
from tenacity import retry, stop_after_attempt, wait_fixed
|
||||
from tests.config import (
|
||||
ADMIN_PASSWORD, ADMIN_USER, INACTIVE_PASSWORD, INACTIVE_USER, PASSWORD,
|
||||
PASSWORD2, USER, USER2
|
||||
)
|
||||
from tests.utils import create_and_get_repo, randstring
|
||||
|
||||
from seaserv import ccnet_api, seafile_api
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@retry(wait=wait_fixed(2), stop=stop_after_attempt(10))
|
||||
def wait_for_server():
|
||||
seafile_api.get_repo_list(0, 1)
|
||||
|
||||
|
||||
@pytest.fixture(scope='session', autouse=True)
|
||||
def create_users():
|
||||
"""
|
||||
Create an admin user and a normal user
|
||||
"""
|
||||
wait_for_server()
|
||||
logger.info('preparing users for testing')
|
||||
ccnet_api.add_emailuser(USER, PASSWORD, is_staff=False, is_active=True)
|
||||
ccnet_api.add_emailuser(USER2, PASSWORD2, is_staff=False, is_active=True)
|
||||
ccnet_api.add_emailuser(
|
||||
INACTIVE_USER, INACTIVE_PASSWORD, is_staff=False, is_active=False
|
||||
)
|
||||
ccnet_api.add_emailuser(
|
||||
ADMIN_USER, ADMIN_PASSWORD, is_staff=True, is_active=True
|
||||
)
|
||||
|
||||
|
||||
@pytest.yield_fixture(scope='function')
|
||||
def repo():
|
||||
repo = create_and_get_repo(
|
||||
'testrepo测试-{}'.format(randstring(10)), '', USER, passwd=None
|
||||
)
|
||||
try:
|
||||
yield repo
|
||||
finally:
|
||||
if seafile_api.get_repo(repo.id):
|
||||
# The repo may be deleted in the test case
|
||||
seafile_api.remove_repo(repo.id)
|
19
tests/test_sharing.py
Normal file
19
tests/test_sharing.py
Normal file
@ -0,0 +1,19 @@
|
||||
import pytest
|
||||
from seaserv import seafile_api as api
|
||||
from seaserv import ccnet_api
|
||||
|
||||
from tests.config import ADMIN_USER, USER, USER2
|
||||
|
||||
|
||||
@pytest.mark.parametrize('permission', ['r', 'rw'])
|
||||
def test_share_repo(repo, permission):
|
||||
assert api.check_permission(repo.id, USER2) is None
|
||||
|
||||
api.share_repo(repo.id, USER, USER2, permission)
|
||||
assert api.check_permission(repo.id, USER2) == permission
|
||||
|
||||
repos = api.get_share_in_repo_list(USER2, 0, 1)
|
||||
assert len(repos) == 1
|
||||
r = repos[0]
|
||||
assert r.id == repo.id
|
||||
assert r.permission == permission
|
15
tests/utils.py
Normal file
15
tests/utils.py
Normal file
@ -0,0 +1,15 @@
|
||||
import os
|
||||
import random
|
||||
import string
|
||||
|
||||
from seaserv import ccnet_api, seafile_api
|
||||
|
||||
|
||||
def create_and_get_repo(*a, **kw):
|
||||
repo_id = seafile_api.create_repo(*a, **kw)
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
return repo
|
||||
|
||||
|
||||
def randstring(length=12):
|
||||
return ''.join(random.choice(string.lowercase) for i in range(length))
|
Loading…
Reference in New Issue
Block a user