refactor probe tests

* refactor probe tests to use probe.common.ProbeTest
* move reset_environment functionality to ProbeTest.setUp()
* choose rings and policies that meet the criteria - raise SkipTest if
nothing matches
* replace all AssertionErrors in setup with SkipTest

Change-Id: Id56c497d58083f5fd55f5283cdd346840df039d3
This commit is contained in:
Leah Klearman 2015-02-12 11:30:21 -08:00
parent ca90be414e
commit 2c1b5af062
14 changed files with 151 additions and 195 deletions

View File

@ -19,6 +19,7 @@ from subprocess import Popen, PIPE
import sys
from time import sleep, time
from collections import defaultdict
import unittest
from nose import SkipTest
from swiftclient import get_auth, head_account
@ -141,18 +142,20 @@ def kill_nonprimary_server(primary_nodes, port2server, pids):
return port
def get_ring(ring_name, server=None, force_validate=None):
def get_ring(ring_name, required_replicas, required_devices,
server=None, force_validate=None):
if not server:
server = ring_name
ring = Ring('/etc/swift', ring_name=ring_name)
if not VALIDATE_RSYNC and not force_validate:
return ring
# easy sanity checks
if ring.replica_count != 3:
print 'WARNING: %s has %s replicas instead of 3' % (
ring.serialized_path, ring.replica_count)
assert 4 == len(ring.devs), '%s has %s devices instead of 4' % (
ring.serialized_path, len(ring.devs))
if ring.replica_count != required_replicas:
raise SkipTest('%s has %s replicas instead of %s' % (
ring.serialized_path, ring.replica_count, required_replicas))
if len(ring.devs) != required_devices:
raise SkipTest('%s has %s devices instead of %s' % (
ring.serialized_path, len(ring.devs), required_devices))
# map server to config by port
port_to_config = {}
for server_ in Manager([server]):
@ -167,12 +170,13 @@ def get_ring(ring_name, server=None, force_validate=None):
if device == dev['device']:
dev_path = os.path.join(conf['devices'], device)
full_path = os.path.realpath(dev_path)
assert os.path.exists(full_path), \
'device %s in %s was not found (%s)' % (
device, conf['devices'], full_path)
if not os.path.exists(full_path):
raise SkipTest(
'device %s in %s was not found (%s)' %
(device, conf['devices'], full_path))
break
else:
raise AssertionError(
raise SkipTest(
"unable to find ring device %s under %s's devices (%s)" % (
dev['device'], server, conf['devices']))
# verify server is exposing rsync device
@ -184,57 +188,33 @@ def get_ring(ring_name, server=None, force_validate=None):
p = Popen(cmd, shell=True, stdout=PIPE)
stdout, _stderr = p.communicate()
if p.returncode:
raise AssertionError('unable to connect to rsync '
raise SkipTest('unable to connect to rsync '
'export %s (%s)' % (rsync_export, cmd))
for line in stdout.splitlines():
if line.rsplit(None, 1)[-1] == dev['device']:
break
else:
raise AssertionError("unable to find ring device %s under rsync's "
"exported devices for %s (%s)" % (
dev['device'], rsync_export, cmd))
raise SkipTest("unable to find ring device %s under rsync's "
"exported devices for %s (%s)" %
(dev['device'], rsync_export, cmd))
return ring
def reset_environment():
p = Popen("resetswift 2>&1", shell=True, stdout=PIPE)
stdout, _stderr = p.communicate()
print stdout
Manager(['all']).stop()
pids = {}
def get_policy(**kwargs):
kwargs.setdefault('is_deprecated', False)
# go thru the policies and make sure they match the requirements of kwargs
for policy in POLICIES:
# TODO: for EC, pop policy type here and check it first
matches = True
for key, value in kwargs.items():
try:
account_ring = get_ring('account')
container_ring = get_ring('container')
policy = POLICIES.default
object_ring = get_ring(policy.ring_name, 'object')
Manager(['main']).start(wait=False)
port2server = {}
for server, port in [('account', 6002), ('container', 6001),
('object', 6000)]:
for number in xrange(1, 9):
port2server[port + (number * 10)] = '%s%d' % (server, number)
for port in port2server:
check_server(port, port2server, pids)
port2server[8080] = 'proxy'
url, token, account = check_server(8080, port2server, pids)
config_dict = defaultdict(dict)
for name in ('account', 'container', 'object'):
for server_name in (name, '%s-replicator' % name):
for server in Manager([server_name]):
for i, conf in enumerate(server.conf_files(), 1):
config_dict[server.server][i] = conf
except BaseException:
try:
raise
except AssertionError as e:
raise SkipTest(e)
finally:
try:
kill_servers(port2server, pids)
except Exception:
pass
return pids, port2server, account_ring, container_ring, object_ring, \
policy, url, token, account, config_dict
if getattr(policy, key) != value:
matches = False
except AttributeError:
matches = False
if matches:
return policy
raise SkipTest('No policy matching %s' % kwargs)
def get_to_final_state():
@ -249,16 +229,84 @@ def get_to_final_state():
replicators.once()
class ProbeTest(unittest.TestCase):
"""
Don't instantiate this directly, use a child class instead.
"""
def setUp(self):
p = Popen("resetswift 2>&1", shell=True, stdout=PIPE)
stdout, _stderr = p.communicate()
print stdout
Manager(['all']).stop()
self.pids = {}
try:
self.account_ring = get_ring(
'account',
self.acct_cont_required_replicas,
self.acct_cont_required_devices)
self.container_ring = get_ring(
'container',
self.acct_cont_required_replicas,
self.acct_cont_required_devices)
self.policy = get_policy(**self.policy_requirements)
self.object_ring = get_ring(
self.policy.ring_name,
self.obj_required_replicas,
self.obj_required_devices,
server='object')
Manager(['main']).start(wait=False)
self.port2server = {}
for server, port in [('account', 6002), ('container', 6001),
('object', 6000)]:
for number in xrange(1, 9):
self.port2server[port + (number * 10)] = \
'%s%d' % (server, number)
for port in self.port2server:
check_server(port, self.port2server, self.pids)
self.port2server[8080] = 'proxy'
self.url, self.token, self.account = \
check_server(8080, self.port2server, self.pids)
self.configs = defaultdict(dict)
for name in ('account', 'container', 'object'):
for server_name in (name, '%s-replicator' % name):
for server in Manager([server_name]):
for i, conf in enumerate(server.conf_files(), 1):
self.configs[server.server][i] = conf
except BaseException:
try:
raise
finally:
try:
kill_servers(self.port2server, self.pids)
except Exception:
pass
def tearDown(self):
kill_servers(self.port2server, self.pids)
class ReplProbeTest(ProbeTest):
acct_cont_required_replicas = 3
acct_cont_required_devices = 4
obj_required_replicas = 3
obj_required_devices = 4
policy_requirements = {'is_default': True}
if __name__ == "__main__":
for server in ('account', 'container'):
try:
get_ring(server, force_validate=True)
except AssertionError as err:
get_ring(server, 3, 4,
force_validate=True)
except SkipTest as err:
sys.exit('%s ERROR: %s' % (server, err))
print '%s OK' % server
for policy in POLICIES:
try:
get_ring(policy.ring_name, server='object', force_validate=True)
except AssertionError as err:
get_ring(policy.ring_name, 3, 4,
server='object', force_validate=True)
except SkipTest as err:
sys.exit('object ERROR (%s): %s' % (policy.name, err))
print 'object OK (%s)' % policy.name

View File

@ -14,25 +14,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from unittest import main, TestCase
from unittest import main
from swiftclient import client
from swift.common import direct_client
from swift.common.manager import Manager
from test.probe.common import get_to_final_state, kill_nonprimary_server, \
kill_server, kill_servers, reset_environment, start_server
kill_server, ReplProbeTest, start_server
class TestAccountFailures(TestCase):
def setUp(self):
(self.pids, self.port2server, self.account_ring, self.container_ring,
self.object_ring, self.policy, self.url, self.token,
self.account, self.configs) = reset_environment()
def tearDown(self):
kill_servers(self.port2server, self.pids)
class TestAccountFailures(ReplProbeTest):
def test_main(self):
# Create container1 and container2

View File

@ -19,22 +19,17 @@ import re
import unittest
from swiftclient import get_auth
from test.probe.common import kill_servers, reset_environment
from test.probe.common import ReplProbeTest
from urlparse import urlparse
class TestAccountGetFakeResponsesMatch(unittest.TestCase):
class TestAccountGetFakeResponsesMatch(ReplProbeTest):
def setUp(self):
(self.pids, self.port2server, self.account_ring, self.container_ring,
self.object_ring, self.policy, self.url, self.token,
self.account, self.configs) = reset_environment()
super(TestAccountGetFakeResponsesMatch, self).setUp()
self.url, self.token = get_auth(
'http://127.0.0.1:8080/auth/v1.0', 'admin:admin', 'admin')
def tearDown(self):
kill_servers(self.port2server, self.pids)
def _account_path(self, account):
_, _, path, _, _, _ = urlparse(self.url)

View File

@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import uuid
import unittest
from swiftclient import client
@ -21,19 +21,11 @@ from swift.common.storage_policy import POLICIES
from swift.common.manager import Manager
from swift.common.direct_client import direct_delete_account, \
direct_get_object, direct_head_container, ClientException
from test.probe.common import kill_servers, reset_environment, \
from test.probe.common import ReplProbeTest, \
get_to_final_state, ENABLED_POLICIES
class TestAccountReaper(unittest.TestCase):
def setUp(self):
(self.pids, self.port2server, self.account_ring, self.container_ring,
self.object_ring, self.policy, self.url, self.token,
self.account, self.configs) = reset_environment()
def tearDown(self):
kill_servers(self.port2server, self.pids)
class TestAccountReaper(ReplProbeTest):
def test_sync(self):
all_objects = []

View File

@ -16,7 +16,7 @@
from os import listdir
from os.path import join as path_join
from unittest import main, TestCase
from unittest import main
from uuid import uuid4
from eventlet import GreenPool, Timeout
@ -28,7 +28,7 @@ from swift.common import direct_client
from swift.common.exceptions import ClientException
from swift.common.utils import hash_path, readconf
from test.probe.common import get_to_final_state, kill_nonprimary_server, \
kill_server, kill_servers, reset_environment, start_server
kill_server, ReplProbeTest, start_server
eventlet.monkey_patch(all=False, socket=True)
@ -40,15 +40,7 @@ def get_db_file_path(obj_dir):
return path_join(obj_dir, filename)
class TestContainerFailures(TestCase):
def setUp(self):
(self.pids, self.port2server, self.account_ring, self.container_ring,
self.object_ring, self.policy, self.url, self.token,
self.account, self.configs) = reset_environment()
def tearDown(self):
kill_servers(self.port2server, self.pids)
class TestContainerFailures(ReplProbeTest):
def test_one_node_fails(self):
# Create container1

View File

@ -14,9 +14,9 @@
from hashlib import md5
import time
import unittest
import uuid
import random
import unittest
from nose import SkipTest
@ -26,7 +26,7 @@ from swift.common import utils, direct_client
from swift.common.storage_policy import POLICIES
from swift.common.http import HTTP_NOT_FOUND
from test.probe.brain import BrainSplitter
from test.probe.common import reset_environment, get_to_final_state, \
from test.probe.common import ReplProbeTest, get_to_final_state, \
ENABLED_POLICIES
from swiftclient import client, ClientException
@ -34,14 +34,12 @@ from swiftclient import client, ClientException
TIMEOUT = 60
class TestContainerMergePolicyIndex(unittest.TestCase):
class TestContainerMergePolicyIndex(ReplProbeTest):
def setUp(self):
if len(ENABLED_POLICIES) < 2:
raise SkipTest()
(self.pids, self.port2server, self.account_ring, self.container_ring,
self.object_ring, self.policy, self.url, self.token,
self.account, self.configs) = reset_environment()
raise SkipTest('Need more than one policy')
super(TestContainerMergePolicyIndex, self).setUp()
self.container_name = 'container-%s' % uuid.uuid4()
self.object_name = 'object-%s' % uuid.uuid4()
self.brain = BrainSplitter(self.url, self.token, self.container_name,

View File

@ -12,16 +12,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import uuid
from urlparse import urlparse
import random
from nose import SkipTest
import unittest
from swiftclient import client
from swift.common.manager import Manager
from test.probe.common import kill_servers, reset_environment, ENABLED_POLICIES
from test.probe.common import ReplProbeTest, ENABLED_POLICIES
def get_current_realm_cluster(url):
@ -43,17 +43,12 @@ def get_current_realm_cluster(url):
raise SkipTest('Unable find current realm cluster')
class TestContainerSync(unittest.TestCase):
class TestContainerSync(ReplProbeTest):
def setUp(self):
(self.pids, self.port2server, self.account_ring, self.container_ring,
self.object_ring, self.policy, self.url, self.token,
self.account, self.configs) = reset_environment()
super(TestContainerSync, self).setUp()
self.realm, self.cluster = get_current_realm_cluster(self.url)
def tearDown(self):
kill_servers(self.port2server, self.pids)
def test_sync(self):
base_headers = {'X-Container-Sync-Key': 'secret'}
@ -95,5 +90,4 @@ class TestContainerSync(unittest.TestCase):
if __name__ == "__main__":
get_current_realm_cluster('http://localhost:8080')
unittest.main()

View File

@ -18,7 +18,7 @@ import os
import shutil
import time
from unittest import main, TestCase
from unittest import main
from uuid import uuid4
from swiftclient import client
@ -26,21 +26,12 @@ from swiftclient import client
from swift.common import direct_client
from swift.obj.diskfile import get_data_dir
from swift.common.exceptions import ClientException
from test.probe.common import kill_server, kill_servers, reset_environment,\
start_server
from test.probe.common import kill_server, ReplProbeTest, start_server
from swift.common.utils import readconf
from swift.common.manager import Manager
class TestEmptyDevice(TestCase):
def setUp(self):
(self.pids, self.port2server, self.account_ring, self.container_ring,
self.object_ring, self.policy, self.url, self.token,
self.account, self.configs) = reset_environment()
def tearDown(self):
kill_servers(self.port2server, self.pids)
class TestEmptyDevice(ReplProbeTest):
def _get_objects_dir(self, onode):
device = onode['device']

View File

@ -14,26 +14,18 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from unittest import main, TestCase
from unittest import main
from uuid import uuid4
from swiftclient import client
from swift.common import direct_client
from swift.common.manager import Manager
from test.probe.common import kill_nonprimary_server, kill_server, \
kill_servers, reset_environment, start_server
from test.probe.common import kill_nonprimary_server, \
kill_server, ReplProbeTest, start_server
class TestObjectAsyncUpdate(TestCase):
def setUp(self):
(self.pids, self.port2server, self.account_ring, self.container_ring,
self.object_ring, self.policy, self.url, self.token,
self.account, self.configs) = reset_environment()
def tearDown(self):
kill_servers(self.port2server, self.pids)
class TestObjectAsyncUpdate(ReplProbeTest):
def test_main(self):
# Create container

View File

@ -13,8 +13,8 @@
# limitations under the License.
import random
import unittest
import uuid
import unittest
from nose import SkipTest
@ -22,14 +22,14 @@ from swift.common.internal_client import InternalClient
from swift.common.manager import Manager
from swift.common.utils import Timestamp
from test.probe.common import reset_environment, get_to_final_state, \
from test.probe.common import ReplProbeTest, get_to_final_state, \
ENABLED_POLICIES
from test.probe.test_container_merge_policy_index import BrainSplitter
from swiftclient import client
class TestObjectExpirer(unittest.TestCase):
class TestObjectExpirer(ReplProbeTest):
def setUp(self):
if len(ENABLED_POLICIES) < 2:
@ -47,9 +47,7 @@ class TestObjectExpirer(unittest.TestCase):
conf_file = conf_files[0]
self.client = InternalClient(conf_file, 'probe-test', 3)
(self.pids, self.port2server, self.account_ring, self.container_ring,
self.object_ring, self.policy, self.url, self.token,
self.account, self.configs) = reset_environment()
super(TestObjectExpirer, self).setUp()
self.container_name = 'container-%s' % uuid.uuid4()
self.object_name = 'object-%s' % uuid.uuid4()
self.brain = BrainSplitter(self.url, self.token, self.container_name,

View File

@ -17,7 +17,7 @@
import time
from os import listdir, unlink
from os.path import join as path_join
from unittest import main, TestCase
from unittest import main
from uuid import uuid4
from swiftclient import client
@ -26,7 +26,7 @@ from swift.common import direct_client
from swift.common.exceptions import ClientException
from swift.common.utils import hash_path, readconf
from swift.obj.diskfile import write_metadata, read_metadata, get_data_dir
from test.probe.common import kill_servers, reset_environment
from test.probe.common import ReplProbeTest
RETRIES = 5
@ -49,15 +49,7 @@ def get_data_file_path(obj_dir):
return path_join(obj_dir, filename)
class TestObjectFailures(TestCase):
def setUp(self):
(self.pids, self.port2server, self.account_ring, self.container_ring,
self.object_ring, self.policy, self.url, self.token,
self.account, self.configs) = reset_environment()
def tearDown(self):
kill_servers(self.port2server, self.pids)
class TestObjectFailures(ReplProbeTest):
def _setup_data_file(self, container, obj, data):
client.put_container(self.url, self.token, container)

View File

@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from unittest import main, TestCase
from unittest import main
from uuid import uuid4
from swiftclient import client
@ -22,19 +22,10 @@ from swiftclient import client
from swift.common import direct_client
from swift.common.exceptions import ClientException
from swift.common.manager import Manager
from test.probe.common import kill_server, kill_servers, reset_environment, \
start_server
from test.probe.common import kill_server, ReplProbeTest, start_server
class TestObjectHandoff(TestCase):
def setUp(self):
(self.pids, self.port2server, self.account_ring, self.container_ring,
self.object_ring, self.policy, self.url, self.token,
self.account, self.configs) = reset_environment()
def tearDown(self):
kill_servers(self.port2server, self.pids)
class TestObjectHandoff(ReplProbeTest):
def test_main(self):
# Create container

View File

@ -17,17 +17,16 @@ from io import StringIO
from tempfile import mkdtemp
from textwrap import dedent
import functools
import unittest
import os
import shutil
import unittest
import uuid
from swift.common import internal_client, utils
from test.probe.brain import BrainSplitter
from test.probe.common import kill_servers, reset_environment, \
get_to_final_state
from test.probe.common import ReplProbeTest, get_to_final_state
def _sync_methods(object_server_config_paths):
@ -65,14 +64,12 @@ def expected_failure_with_ssync(m):
return wrapper
class Test(unittest.TestCase):
class Test(ReplProbeTest):
def setUp(self):
"""
Reset all environment and start all servers.
"""
(self.pids, self.port2server, self.account_ring, self.container_ring,
self.object_ring, self.policy, self.url, self.token,
self.account, self.configs) = reset_environment()
super(Test, self).setUp()
self.container_name = 'container-%s' % uuid.uuid4()
self.object_name = 'object-%s' % uuid.uuid4()
self.brain = BrainSplitter(self.url, self.token, self.container_name,
@ -101,10 +98,7 @@ class Test(unittest.TestCase):
self.int_client = internal_client.InternalClient(conf_path, 'test', 1)
def tearDown(self):
"""
Stop all servers.
"""
kill_servers(self.port2server, self.pids)
super(Test, self).tearDown()
shutil.rmtree(self.tempdir)
def _put_object(self, headers=None):

View File

@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from unittest import main, TestCase
from unittest import main
from uuid import uuid4
import os
import time
@ -24,7 +24,7 @@ from swiftclient import client
from swift.common.storage_policy import POLICIES
from swift.obj.diskfile import get_data_dir
from test.probe.common import kill_servers, reset_environment
from test.probe.common import ReplProbeTest
from swift.common.utils import readconf
from swift.common.manager import Manager
@ -68,7 +68,7 @@ def find_max_occupancy_node(dir_list):
return number
class TestReplicatorFunctions(TestCase):
class TestReplicatorFunctions(ReplProbeTest):
"""
Class for testing replicators and replication servers.
@ -77,19 +77,6 @@ class TestReplicatorFunctions(TestCase):
ring's files using set_info command or new ring's files with
different port values.
"""
def setUp(self):
"""
Reset all environment and start all servers.
"""
(self.pids, self.port2server, self.account_ring, self.container_ring,
self.object_ring, self.policy, self.url, self.token,
self.account, self.configs) = reset_environment()
def tearDown(self):
"""
Stop all servers.
"""
kill_servers(self.port2server, self.pids)
def test_main(self):
# Create one account, container and object file.