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:
Peter Portante 2014-04-10 15:37:15 -04:00
parent e0108af54f
commit 4dd2670fb0
5 changed files with 91 additions and 63 deletions

View File

@ -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

View File

@ -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)

View File

@ -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'})

View File

@ -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()

View File

@ -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