Skip to content

Commit 3dfdf65

Browse files
Merge pull request #147 from matyasselmeci/wip/sw3360-stashcache
StashCache tests (SOFTWARE-3360)
2 parents 1ebf5ea + 037bad5 commit 3dfdf65

File tree

10 files changed

+355
-6
lines changed

10 files changed

+355
-6
lines changed

files/test_sequence

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ test_110_condor_cron
99
test_130_gridftp
1010
test_140_lcmaps
1111
test_150_xrootd
12+
test_155_stashcache
1213
test_160_rsv
1314
test_170_pbs
1415
test_180_cvmfs
@@ -32,6 +33,7 @@ test_420_gridftp
3233
test_430_uberftp
3334
test_440_glexec
3435
test_450_xrootd
36+
test_460_stashcache
3537
test_470_rsv
3638
test_490_jobs
3739
test_510_edgmkgridmap
@@ -50,6 +52,7 @@ test_790_condorce
5052
test_800_gratia
5153
test_820_cvmfs
5254
test_830_rsv
55+
test_835_stashcache
5356
test_840_xrootd
5457
test_850_lcmaps
5558
test_860_gridftp

osg-test

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ if __name__ == '__main__':
229229

230230
# Check for osg-ca-generator, which may have been forgotten in a source install
231231
try:
232-
__import__('cagen')
232+
import cagen
233233
except ImportError:
234234
sys.exit("Cannot find 'cagen' library. Please install osg-ca-generator")
235235

@@ -254,5 +254,6 @@ if __name__ == '__main__':
254254
signal.signal(signal.SIGALRM, signal.SIG_DFL)
255255
else:
256256
print('No tests to run.')
257+
EXIT_CODE = 1
257258
wrap_up()
258259
sys.exit(EXIT_CODE)

osgtest/library/core.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,13 +416,17 @@ def version_compare(evr1, evr2):
416416
as a 3-element tuple or list.
417417
418418
"""
419-
if isinstance(evr1, basestring):
419+
if is_string(evr1):
420420
epoch1, version1, release1 = stringToVersion(evr1)
421+
elif isinstance(evr1, bytes):
422+
epoch1, version1, release1 = stringToVersion(evr1.decode())
421423
else:
422424
epoch1, version1, release1 = evr1
423425

424-
if isinstance(evr2, basestring):
426+
if is_string(evr2):
425427
epoch2, version2, release2 = stringToVersion(evr2)
428+
elif isinstance(evr2, bytes):
429+
epoch2, version2, release2 = stringToVersion(evr2.decode())
426430
else:
427431
epoch2, version2, release2 = evr2
428432

@@ -755,3 +759,12 @@ def run_fn_if_el_release_ok(*args, **kwargs):
755759
return run_fn_if_el_release_ok
756760
return el_release_decorator
757761

762+
763+
try:
764+
unicode
765+
except NameError: # python 3
766+
unicode = str
767+
768+
769+
def is_string(var):
770+
return isinstance(var, (str, unicode))

osgtest/library/files.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,12 @@ def filesBackedup(path, owner):
237237
return True
238238
else:
239239
return False
240+
241+
242+
def safe_makedirs(directory, mode=0o777):
243+
"""Create a directory and all its parent directories, unless it already
244+
exists.
245+
246+
"""
247+
if not os.path.isdir(directory):
248+
os.makedirs(directory, mode)

osgtest/library/osgunittest.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,19 @@
1212
import unittest
1313
import time
1414

15+
16+
# Copied from unittest.util, Python 3.6
17+
_MAX_LENGTH = 80
18+
def safe_repr(obj, short=False):
19+
try:
20+
result = repr(obj)
21+
except Exception:
22+
result = object.__repr__(obj)
23+
if not short or len(result) < _MAX_LENGTH:
24+
return result
25+
return result[:_MAX_LENGTH] + ' [truncated]...'
26+
27+
1528
# Define the classes we need to handle the two new types of test results: ok
1629
# skip, and bad skip.
1730

@@ -111,6 +124,14 @@ def failIfSubsetOf(self, a, b, message=None):
111124
if set(a).issubset(set(b)):
112125
raise AssertionError(message)
113126

127+
def assertEqualVerbose(self, actual, expected, message=None):
128+
aftermessage = "actual %s != expected %s" % (safe_repr(actual), safe_repr(expected))
129+
if message:
130+
fullmessage = "%s (%s)" % (message, aftermessage)
131+
else:
132+
fullmessage = aftermessage
133+
self.assertEqual(actual, expected, fullmessage)
134+
114135
# This is mostly a copy of the method from unittest in python 2.4.
115136
# There is some code here to test if the 'result' object accepts 'skips',
116137
# since the original TestResult object does not. If it does not, an

osgtest/tests/test_150_xrootd.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import osgtest.library.service as service
66
import osgtest.library.osgunittest as osgunittest
77

8+
9+
XROOTD_PORT = 1096 # chosen so it doesn't conflict w/ the stashcache instances
10+
811
XROOTD_CFG_TEXT = """\
912
cms.space min 2g 5g
1013
xrootd.seclib /usr/lib64/libXrdSec-4.so
@@ -17,6 +20,7 @@
1720
%s
1821
acc.authdb /etc/xrootd/auth_file
1922
ofs.authorize
23+
xrd.port %d
2024
"""
2125

2226
AUTHFILE_TEXT = """\
@@ -32,6 +36,7 @@ def test_01_start_xrootd(self):
3236
core.config['certs.xrootdcert'] = '/etc/grid-security/xrd/xrdcert.pem'
3337
core.config['certs.xrootdkey'] = '/etc/grid-security/xrd/xrdkey.pem'
3438
core.config['xrootd.config'] = '/etc/xrootd/xrootd-clustered.cfg'
39+
core.config['xrootd.port'] = XROOTD_PORT
3540
core.config['xrootd.gsi'] = "ON"
3641
core.state['xrootd.started-server'] = False
3742
core.state['xrootd.backups-exist'] = False
@@ -58,7 +63,9 @@ def test_01_start_xrootd(self):
5863
owner="xrootd",
5964
chown=(user.pw_uid, user.pw_gid))
6065

61-
files.append(core.config['xrootd.config'], XROOTD_CFG_TEXT % sec_protocol, owner='xrootd', backup=True)
66+
files.append(core.config['xrootd.config'],
67+
XROOTD_CFG_TEXT % (sec_protocol, core.config['xrootd.port']),
68+
owner='xrootd', backup=True)
6269
authfile = '/etc/xrootd/auth_file'
6370
files.write(authfile, AUTHFILE_TEXT, owner="xrootd", chown=(user.pw_uid, user.pw_gid))
6471

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import os
2+
import pwd
3+
4+
from osgtest.library import core
5+
from osgtest.library import files
6+
from osgtest.library.osgunittest import OSGTestCase
7+
from osgtest.library import service
8+
9+
10+
CACHE_DIR = "/tmp/sccache"
11+
CACHE_XROOT_PORT = 1094 # can't change this - stashcp doesn't allow you to specify port
12+
CACHE_HTTP_PORT = 8001
13+
ORIGIN_XROOT_PORT = 1095
14+
ORIGIN_DIR = "/tmp/scorigin"
15+
CACHE_AUTHFILE_PATH = "/etc/xrootd/Authfile-cache"
16+
CACHE_CONFIG_PATH = "/etc/xrootd/xrootd-stashcache-cache-server.cfg"
17+
ORIGIN_CONFIG_PATH = "/etc/xrootd/xrootd-stashcache-origin-server.cfg"
18+
CACHES_JSON_PATH = "/etc/stashcache/caches.json"
19+
20+
21+
# TODO Set up authenticated stashcache as well
22+
CACHE_CONFIG_TEXT = """\
23+
all.export /
24+
set cachedir = {CACHE_DIR}
25+
xrd.allow host *
26+
sec.protocol host
27+
all.adminpath /var/spool/xrootd
28+
29+
xrootd.trace emsg login stall redirect
30+
ofs.trace all
31+
xrd.trace all
32+
cms.trace all
33+
34+
ofs.osslib libXrdPss.so
35+
# normally this is the redirector but we don't have one in this environment
36+
pss.origin localhost:{ORIGIN_XROOT_PORT}
37+
pss.cachelib libXrdFileCache.so
38+
pss.setopt DebugLevel 1
39+
40+
oss.localroot $(cachedir)
41+
42+
pfc.blocksize 512k
43+
pfc.ram 1024m
44+
# ^ xrootd won't start without a gig
45+
pfc.prefetch 10
46+
pfc.diskusage 0.90 0.95
47+
48+
ofs.authorize 1
49+
acc.audit deny grant
50+
51+
acc.authdb {CACHE_AUTHFILE_PATH}
52+
sec.protbind * none
53+
xrd.protocol http:{CACHE_HTTP_PORT} libXrdHttp.so
54+
55+
xrd.port {CACHE_XROOT_PORT}
56+
57+
http.listingdeny yes
58+
http.staticpreload http://static/robots.txt /etc/xrootd/stashcache-robots.txt
59+
60+
# Tune the client timeouts to more aggressively timeout.
61+
pss.setopt ParallelEvtLoop 10
62+
pss.setopt RequestTimeout 25
63+
#pss.setopt TimeoutResolution 1
64+
pss.setopt ConnectTimeout 25
65+
pss.setopt ConnectionRetry 2
66+
#pss.setopt StreamTimeout 35
67+
68+
all.sitename osgtest
69+
70+
xrootd.diglib * /etc/xrootd/digauth.cf
71+
""".format(**globals())
72+
73+
74+
CACHE_AUTHFILE_TEXT = """\
75+
u * / rl
76+
"""
77+
78+
79+
ORIGIN_CONFIG_TEXT = """\
80+
xrd.allow host *
81+
sec.protocol host
82+
sec.protbind * none
83+
all.adminpath /var/spool/xrootd
84+
all.pidpath /var/run/xrootd
85+
86+
# The directory on local disk containing the files to share, e.g. "/stash".
87+
oss.localroot {ORIGIN_DIR}
88+
all.export /
89+
90+
xrd.port {ORIGIN_XROOT_PORT}
91+
all.role server
92+
93+
xrootd.trace emsg login stall redirect
94+
ofs.trace all
95+
xrd.trace all
96+
cms.trace all
97+
""".format(**globals())
98+
99+
100+
CACHES_JSON_TEXT = """\
101+
[
102+
{"name":"root://localhost", "status":1, "longitude":-89.4012, "latitude":43.0731}
103+
]
104+
"""
105+
106+
107+
_NAMESPACE = "stashcache"
108+
109+
110+
def _getcfg(key):
111+
return core.config["%s.%s" % (_NAMESPACE, key)]
112+
113+
114+
def _setcfg(key, val):
115+
core.config["%s.%s" % (_NAMESPACE, key)] = val
116+
117+
118+
class TestStartStashCache(OSGTestCase):
119+
@core.elrelease(7,8)
120+
def setUp(self):
121+
core.skip_ok_unless_installed("stashcache-origin-server", "stashcache-cache-server", "stashcache-client")
122+
123+
def test_01_configure(self):
124+
for key, val in [
125+
("cache_authfile_path", CACHE_AUTHFILE_PATH),
126+
("cache_config_path", CACHE_CONFIG_PATH),
127+
("origin_config_path", ORIGIN_CONFIG_PATH),
128+
("caches_json_path", CACHES_JSON_PATH),
129+
("cache_http_port", CACHE_HTTP_PORT),
130+
("origin_dir", ORIGIN_DIR),
131+
("cache_dir", CACHE_DIR),
132+
("origin_xroot_port", ORIGIN_XROOT_PORT),
133+
("cache_xroot_port", CACHE_XROOT_PORT)
134+
]:
135+
_setcfg(key, val)
136+
137+
xrootd_user = pwd.getpwnam("xrootd")
138+
for d in [_getcfg("origin_dir"), _getcfg("cache_dir"),
139+
os.path.dirname(_getcfg("caches_json_path"))]:
140+
files.safe_makedirs(d)
141+
os.chown(d, xrootd_user.pw_uid, xrootd_user.pw_gid)
142+
143+
for key, text in [
144+
("cache_config_path", CACHE_CONFIG_TEXT),
145+
("cache_authfile_path", CACHE_AUTHFILE_TEXT),
146+
("origin_config_path", ORIGIN_CONFIG_TEXT),
147+
("caches_json_path", CACHES_JSON_TEXT)
148+
]:
149+
files.write(_getcfg(key), text, owner=_NAMESPACE, chmod=0o644)
150+
151+
def test_02_start_origin(self):
152+
if not service.is_running("xrootd@stashcache-origin-server"):
153+
service.check_start("xrootd@stashcache-origin-server")
154+
155+
def test_03_start_cache(self):
156+
if not service.is_running("xrootd@stashcache-cache-server"):
157+
service.check_start("xrootd@stashcache-cache-server")

osgtest/tests/test_450_xrootd.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def test_01_xrdcp_local_to_server(self):
3030
else:
3131
temp_dir = tempfile.mkdtemp()
3232
os.chmod(temp_dir, 0o777)
33-
xrootd_url = 'root://%s/%s/copied_file.txt' % (hostname, temp_dir)
33+
xrootd_url = 'root://%s:%d/%s/copied_file.txt' % (hostname, core.config['xrootd.port'], temp_dir)
3434
command = ('xrdcp', '--debug', '3', TestXrootd.__data_path, xrootd_url)
3535

3636
status, stdout, stderr = core.system(command, user=True)
@@ -57,7 +57,7 @@ def test_02_xrdcp_server_to_local(self):
5757
f = open(temp_source_dir + "/copied_file.txt", "w")
5858
f.write("This is some test data for an xrootd test.")
5959
f.close()
60-
xrootd_url = 'root://%s/%s/copied_file.txt' % (hostname, temp_source_dir)
60+
xrootd_url = 'root://%s:%d/%s/copied_file.txt' % (hostname, core.config['xrootd.port'], temp_source_dir)
6161
local_path = temp_target_dir + '/copied_file.txt'
6262
command = ('xrdcp', '--debug', '3', xrootd_url, local_path)
6363

0 commit comments

Comments
 (0)