Load constraints from cluster info dictionary
Use constrainst from the new "swift-constraints" section of test.conf, fall back to those found in the response to the /info API call, ultimately falling back to the constraints module's effective constraints. Change-Id: Iea01c9c4b5148faa10004a240df411cbe7336a6a
This commit is contained in:
parent
e0108af54f
commit
4dd2670fb0
@ -28,7 +28,7 @@ from swift.common import constraints
|
|||||||
from swiftclient import get_auth, http_connection
|
from swiftclient import get_auth, http_connection
|
||||||
|
|
||||||
from test import get_config
|
from test import get_config
|
||||||
from test.functional.swift_test_client import Connection
|
from test.functional.swift_test_client import Connection, ResponseError
|
||||||
|
|
||||||
|
|
||||||
config = {}
|
config = {}
|
||||||
@ -47,24 +47,51 @@ skip, skip2, skip3 = False, False, False
|
|||||||
|
|
||||||
orig_collate = ''
|
orig_collate = ''
|
||||||
|
|
||||||
|
cluster_info = {}
|
||||||
|
|
||||||
|
|
||||||
|
def get_cluster_info():
|
||||||
|
# The fallback constraints used for testing will come from the current
|
||||||
|
# effective constraints.
|
||||||
|
eff_constraints = dict(constraints.EFFECTIVE_CONSTRAINTS)
|
||||||
|
|
||||||
|
# We'll update those constraints based on what the /info API provides, if
|
||||||
|
# anything.
|
||||||
|
global cluster_info
|
||||||
|
try:
|
||||||
|
conn = Connection(config)
|
||||||
|
conn.authenticate()
|
||||||
|
cluster_info.update(conn.cluster_info())
|
||||||
|
except (ResponseError, socket.error):
|
||||||
|
# Failed to get cluster_information via /info API, so fall back on
|
||||||
|
# test.conf data
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
eff_constraints.update(cluster_info['swift'])
|
||||||
|
|
||||||
|
# Finally, we'll allow any constraint present in the swift-constraints
|
||||||
|
# section of test.conf to override everything. Note that only those
|
||||||
|
# constraints defined in the constraints module are converted to integers.
|
||||||
|
test_constraints = get_config('swift-constraints')
|
||||||
|
for k in constraints.DEFAULT_CONSTRAINTS:
|
||||||
|
try:
|
||||||
|
test_constraints[k] = int(test_constraints[k])
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
except ValueError:
|
||||||
|
print >>sys.stderr, "Invalid constraint value: %s = %s" % (
|
||||||
|
k, test_constraints[k])
|
||||||
|
eff_constraints.update(test_constraints)
|
||||||
|
|
||||||
|
# Just make it look like these constraints were loaded from a /info call,
|
||||||
|
# even if the /info call failed, or when they are overridden by values
|
||||||
|
# from the swift-constraints section of test.conf
|
||||||
|
cluster_info['swift'] = eff_constraints
|
||||||
|
|
||||||
|
|
||||||
def setup_package():
|
def setup_package():
|
||||||
global config
|
global config
|
||||||
config.update(get_config('func_test'))
|
config.update(get_config('func_test'))
|
||||||
for k in constraints.DEFAULT_CONSTRAINTS:
|
|
||||||
if k in config:
|
|
||||||
# prefer what's in test.conf
|
|
||||||
config[k] = int(config[k])
|
|
||||||
elif constraints.SWIFT_CONSTRAINTS_LOADED:
|
|
||||||
# swift.conf exists, so use what's defined there (or swift
|
|
||||||
# defaults) This normally happens when the test is running locally
|
|
||||||
# to the cluster as in a SAIO.
|
|
||||||
config[k] = constraints.EFFECTIVE_CONSTRAINTS[k]
|
|
||||||
else:
|
|
||||||
# .functests don't know what the constraints of the tested cluster
|
|
||||||
# are, so the tests can't reliably pass or fail. Therefore, skip
|
|
||||||
# those tests.
|
|
||||||
config[k] = '%s constraint is not defined' % k
|
|
||||||
|
|
||||||
global web_front_end
|
global web_front_end
|
||||||
web_front_end = config.get('web_front_end', 'integral')
|
web_front_end = config.get('web_front_end', 'integral')
|
||||||
@ -160,6 +187,8 @@ def setup_package():
|
|||||||
print >>sys.stderr, \
|
print >>sys.stderr, \
|
||||||
'SKIPPING THIRD ACCOUNT FUNCTIONAL TESTS DUE TO NO CONFIG FOR THEM'
|
'SKIPPING THIRD ACCOUNT FUNCTIONAL TESTS DUE TO NO CONFIG FOR THEM'
|
||||||
|
|
||||||
|
get_cluster_info()
|
||||||
|
|
||||||
|
|
||||||
def teardown_package():
|
def teardown_package():
|
||||||
global orig_collate
|
global orig_collate
|
||||||
@ -249,21 +278,14 @@ def check_response(conn):
|
|||||||
|
|
||||||
|
|
||||||
def load_constraint(name):
|
def load_constraint(name):
|
||||||
global config
|
|
||||||
c = config[name]
|
|
||||||
if not isinstance(c, int):
|
|
||||||
raise SkipTest(c)
|
|
||||||
return c
|
|
||||||
|
|
||||||
|
|
||||||
cluster_info = {}
|
|
||||||
|
|
||||||
|
|
||||||
def get_cluster_info():
|
|
||||||
conn = Connection(config)
|
|
||||||
conn.authenticate()
|
|
||||||
global cluster_info
|
global cluster_info
|
||||||
cluster_info = conn.cluster_info()
|
try:
|
||||||
|
c = cluster_info['swift'][name]
|
||||||
|
except KeyError:
|
||||||
|
raise SkipTest("Missing constraint: %s" % name)
|
||||||
|
if not isinstance(c, int):
|
||||||
|
raise SkipTest("Bad value, %r, for constraint: %s" % (c, name))
|
||||||
|
return c
|
||||||
|
|
||||||
|
|
||||||
def reset_acl():
|
def reset_acl():
|
||||||
@ -280,10 +302,8 @@ def reset_acl():
|
|||||||
def requires_acls(f):
|
def requires_acls(f):
|
||||||
@functools.wraps(f)
|
@functools.wraps(f)
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
if skip:
|
if skip or not cluster_info:
|
||||||
raise SkipTest
|
raise SkipTest
|
||||||
if not cluster_info:
|
|
||||||
get_cluster_info()
|
|
||||||
# Determine whether this cluster has account ACLs; if not, skip test
|
# Determine whether this cluster has account ACLs; if not, skip test
|
||||||
if not cluster_info.get('tempauth', {}).get('account_acls'):
|
if not cluster_info.get('tempauth', {}).get('account_acls'):
|
||||||
raise SkipTest
|
raise SkipTest
|
||||||
|
@ -103,7 +103,8 @@ class Connection(object):
|
|||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
for key in 'auth_host auth_port auth_ssl username password'.split():
|
for key in 'auth_host auth_port auth_ssl username password'.split():
|
||||||
if key not in config:
|
if key not in config:
|
||||||
raise SkipTest
|
raise SkipTest(
|
||||||
|
"Missing required configuration parameter: %s" % key)
|
||||||
|
|
||||||
self.auth_host = config['auth_host']
|
self.auth_host = config['auth_host']
|
||||||
self.auth_port = int(config['auth_port'])
|
self.auth_port = int(config['auth_port'])
|
||||||
@ -117,6 +118,7 @@ class Connection(object):
|
|||||||
|
|
||||||
self.storage_host = None
|
self.storage_host = None
|
||||||
self.storage_port = None
|
self.storage_port = None
|
||||||
|
self.storage_url = None
|
||||||
|
|
||||||
self.conn_class = None
|
self.conn_class = None
|
||||||
|
|
||||||
@ -278,8 +280,6 @@ class Connection(object):
|
|||||||
(request, len(fail_messages), fail_messages))
|
(request, len(fail_messages), fail_messages))
|
||||||
|
|
||||||
def put_start(self, path, hdrs={}, parms={}, cfg={}, chunked=False):
|
def put_start(self, path, hdrs={}, parms={}, cfg={}, chunked=False):
|
||||||
self.http_connect()
|
|
||||||
|
|
||||||
path = self.make_path(path, cfg)
|
path = self.make_path(path, cfg)
|
||||||
headers = self.make_headers(hdrs, cfg=cfg)
|
headers = self.make_headers(hdrs, cfg=cfg)
|
||||||
|
|
||||||
|
@ -894,14 +894,6 @@ class TestObject(unittest.TestCase):
|
|||||||
if tf.skip:
|
if tf.skip:
|
||||||
raise SkipTest
|
raise SkipTest
|
||||||
|
|
||||||
def is_strict_mode(url, token, parsed, conn):
|
|
||||||
conn.request('GET', '/info')
|
|
||||||
resp = conn.getresponse()
|
|
||||||
if resp.status // 100 == 2:
|
|
||||||
info = json.loads(resp.read())
|
|
||||||
return info.get('swift', {}).get('strict_cors_mode', False)
|
|
||||||
return False
|
|
||||||
|
|
||||||
def put_cors_cont(url, token, parsed, conn, orig):
|
def put_cors_cont(url, token, parsed, conn, orig):
|
||||||
conn.request(
|
conn.request(
|
||||||
'PUT', '%s/%s' % (parsed.path, self.container),
|
'PUT', '%s/%s' % (parsed.path, self.container),
|
||||||
@ -924,8 +916,6 @@ class TestObject(unittest.TestCase):
|
|||||||
'', headers)
|
'', headers)
|
||||||
return conn.getresponse()
|
return conn.getresponse()
|
||||||
|
|
||||||
strict_cors = retry(is_strict_mode)
|
|
||||||
|
|
||||||
resp = retry(put_cors_cont, '*')
|
resp = retry(put_cors_cont, '*')
|
||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status // 100, 2)
|
self.assertEquals(resp.status // 100, 2)
|
||||||
@ -977,6 +967,11 @@ class TestObject(unittest.TestCase):
|
|||||||
resp.read()
|
resp.read()
|
||||||
self.assertEquals(resp.status, 401)
|
self.assertEquals(resp.status, 401)
|
||||||
|
|
||||||
|
try:
|
||||||
|
strict_cors = tf.cluster_info['swift']['strict_cors_mode']
|
||||||
|
except KeyError:
|
||||||
|
strict_cors = False
|
||||||
|
|
||||||
if strict_cors:
|
if strict_cors:
|
||||||
resp = retry(check_cors,
|
resp = retry(check_cors,
|
||||||
'GET', 'cat', {'Origin': 'http://m.com'})
|
'GET', 'cat', {'Origin': 'http://m.com'})
|
||||||
|
@ -31,7 +31,7 @@ from nose import SkipTest
|
|||||||
|
|
||||||
from swift.common.utils import get_hub
|
from swift.common.utils import get_hub
|
||||||
|
|
||||||
from test.functional import normalized_urls, load_constraint
|
from test.functional import normalized_urls, load_constraint, cluster_info
|
||||||
import test.functional as tf
|
import test.functional as tf
|
||||||
from test.functional.swift_test_client import Account, Connection, File, \
|
from test.functional.swift_test_client import Account, Connection, File, \
|
||||||
ResponseError
|
ResponseError
|
||||||
@ -1790,7 +1790,6 @@ class TestSloEnv(object):
|
|||||||
cls.conn.authenticate()
|
cls.conn.authenticate()
|
||||||
|
|
||||||
if cls.slo_enabled is None:
|
if cls.slo_enabled is None:
|
||||||
cluster_info = cls.conn.cluster_info()
|
|
||||||
cls.slo_enabled = 'slo' in cluster_info
|
cls.slo_enabled = 'slo' in cluster_info
|
||||||
if not cls.slo_enabled:
|
if not cls.slo_enabled:
|
||||||
return
|
return
|
||||||
@ -2138,7 +2137,6 @@ class TestTempurlEnv(object):
|
|||||||
cls.conn.authenticate()
|
cls.conn.authenticate()
|
||||||
|
|
||||||
if cls.tempurl_enabled is None:
|
if cls.tempurl_enabled is None:
|
||||||
cluster_info = cls.conn.cluster_info()
|
|
||||||
cls.tempurl_enabled = 'tempurl' in cluster_info
|
cls.tempurl_enabled = 'tempurl' in cluster_info
|
||||||
if not cls.tempurl_enabled:
|
if not cls.tempurl_enabled:
|
||||||
return
|
return
|
||||||
@ -2313,7 +2311,6 @@ class TestSloTempurlEnv(object):
|
|||||||
cls.conn.authenticate()
|
cls.conn.authenticate()
|
||||||
|
|
||||||
if cls.enabled is None:
|
if cls.enabled is None:
|
||||||
cluster_info = cls.conn.cluster_info()
|
|
||||||
cls.enabled = 'tempurl' in cluster_info and 'slo' in cluster_info
|
cls.enabled = 'tempurl' in cluster_info and 'slo' in cluster_info
|
||||||
|
|
||||||
cls.tempurl_key = Utils.create_name()
|
cls.tempurl_key = Utils.create_name()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[func_test]
|
[func_test]
|
||||||
# sample config
|
# sample config for Swift with tempauth
|
||||||
auth_host = 127.0.0.1
|
auth_host = 127.0.0.1
|
||||||
auth_port = 8080
|
auth_port = 8080
|
||||||
auth_ssl = no
|
auth_ssl = no
|
||||||
@ -25,11 +25,32 @@ password2 = testing2
|
|||||||
username3 = tester3
|
username3 = tester3
|
||||||
password3 = testing3
|
password3 = testing3
|
||||||
|
|
||||||
# If not defined here, the test runner will try to use the default constraint
|
collate = C
|
||||||
# values as constructed by the constraints module, which will attempt to get
|
|
||||||
# them from /etc/swift/swift.conf, if possible. Then, if the swift.conf file
|
[unit_test]
|
||||||
# isn't found, the test runner will skip tests that depend on those values.
|
fake_syslog = False
|
||||||
# Note that the cluster must have "sane" values for the test suite to pass.
|
|
||||||
|
[probe_test]
|
||||||
|
# check_server_timeout = 30
|
||||||
|
# validate_rsync = false
|
||||||
|
|
||||||
|
[swift-constraints]
|
||||||
|
# The functional test runner will try to use the constraint values provided in
|
||||||
|
# the swift-constraints section of test.conf.
|
||||||
|
#
|
||||||
|
# If a constraint value does not exist in that section, or because the
|
||||||
|
# swift-constraints section does not exist, the constraints values found in
|
||||||
|
# the /info API call (if successful) will be used.
|
||||||
|
#
|
||||||
|
# If a constraint value cannot be found in the /info results, either because
|
||||||
|
# the /info API call failed, or a value is not present, the constraint value
|
||||||
|
# used will fall back to those loaded by the constraints module at time of
|
||||||
|
# import (which will attempt to load /etc/swift/swift.conf, see the
|
||||||
|
# swift.common.constraints module for more information).
|
||||||
|
#
|
||||||
|
# Note that the cluster must have "sane" values for the test suite to pass
|
||||||
|
# (for some definition of sane).
|
||||||
|
#
|
||||||
#max_file_size = 5368709122
|
#max_file_size = 5368709122
|
||||||
#max_meta_name_length = 128
|
#max_meta_name_length = 128
|
||||||
#max_meta_value_length = 256
|
#max_meta_value_length = 256
|
||||||
@ -42,11 +63,6 @@ password3 = testing3
|
|||||||
#max_account_name_length = 256
|
#max_account_name_length = 256
|
||||||
#max_container_name_length = 256
|
#max_container_name_length = 256
|
||||||
|
|
||||||
collate = C
|
# Newer swift versions default to strict cors mode, but older ones were the
|
||||||
|
# opposite.
|
||||||
[unit_test]
|
#strict_cors_mode = true
|
||||||
fake_syslog = False
|
|
||||||
|
|
||||||
[probe_test]
|
|
||||||
# check_server_timeout = 30
|
|
||||||
# validate_rsync = false
|
|
||||||
|
Loading…
Reference in New Issue
Block a user