From 01f6e860066640a2ba1406a23c93a72b34ec495e Mon Sep 17 00:00:00 2001 From: Clay Gerrard Date: Fri, 21 Nov 2014 17:28:13 -0800 Subject: [PATCH] Add Expected Failure for ssync with sys-meta Sysmeta included with an object PUT persists with the PUT data - if an internal operation such as POST-as-copy during partial failure, or ssync with fast-POST (not supported), causes that data to be lost then the associated sysmeta will also be lost. Since object sys-meta persistence in the face of a POST when the original .data is unavailable requires fast-POST with .meta files the probetest that validates object sys-meta persistence of a POST when the most up-to-date copy of the object with sys-meta is unavailable configures an InternalClient with object_post_as_copy = false. This non-default configuration option is not supported by ssync and results in a loss of sys-meta very similar to the object sys-meta failure you would see with object_post_as_copy = true when the COPY part of the POST is unable to retrieve the most recently written object with sys-meta. Until we can fix the default POST behavior to make metadata updates without stomping on newer data file timestamps we should expect object sys-meta to be "very very best possible but not really guaranteed effort". Until we can fix ssync to replicate metadata updates without stomping on newer data file timestamps we should expect this test to fail. When ssync replication of fast-POST metadata update is fixed this test will fail signaling that the expected failure cruft should be removed, but other parts of ssync replication will still work and some other bugs can be fixed while we wait. Change-Id: Ifc5d49514de79b78f7715408e0fe0908357771d3 --- .../probe/test_object_metadata_replication.py | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/test/probe/test_object_metadata_replication.py b/test/probe/test_object_metadata_replication.py index 23ed2db193..45e6efcb87 100644 --- a/test/probe/test_object_metadata_replication.py +++ b/test/probe/test_object_metadata_replication.py @@ -16,18 +16,55 @@ from io import StringIO from tempfile import mkdtemp from textwrap import dedent +import functools import os import shutil import unittest import uuid -from swift.common import internal_client + +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 +def _sync_methods(object_server_config_paths): + """ + Get the set of all configured sync_methods for the object-replicator + sections in the list of config paths. + """ + sync_methods = set() + for config_path in object_server_config_paths: + options = utils.readconf(config_path, 'object-replicator') + sync_methods.add(options.get('sync_method', 'rsync')) + return sync_methods + + +def expected_failure_with_ssync(m): + """ + Wrapper for probetests that don't pass if you use ssync + """ + @functools.wraps(m) + def wrapper(self, *args, **kwargs): + obj_conf = self.configs['object-server'] + config_paths = [v for k, v in obj_conf.items() + if k in self.brain.handoff_numbers] + using_ssync = 'ssync' in _sync_methods(config_paths) + failed = False + try: + return m(self, *args, **kwargs) + except AssertionError: + failed = True + if not using_ssync: + raise + finally: + if using_ssync and not failed: + self.fail('This test is expected to fail with ssync') + return wrapper + + class Test(unittest.TestCase): def setUp(self): """ @@ -85,6 +122,7 @@ class Test(unittest.TestCase): self.container_name, self.object_name) + @expected_failure_with_ssync def test_sysmeta_after_replication_with_subsequent_post(self): sysmeta = {'x-object-sysmeta-foo': 'sysmeta-foo'} usermeta = {'x-object-meta-bar': 'meta-bar'}