summaryrefslogtreecommitdiff
path: root/test/probe/test_object_expirer.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/probe/test_object_expirer.py')
-rw-r--r--test/probe/test_object_expirer.py131
1 files changed, 131 insertions, 0 deletions
diff --git a/test/probe/test_object_expirer.py b/test/probe/test_object_expirer.py
new file mode 100644
index 000000000..4e336483c
--- /dev/null
+++ b/test/probe/test_object_expirer.py
@@ -0,0 +1,131 @@
+#!/usr/bin/python -u
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import random
+import unittest
+import uuid
+
+from nose import SkipTest
+
+from swift.common.internal_client import InternalClient
+from swift.common.manager import Manager
+from swift.common.storage_policy import POLICIES
+
+from test.probe.common import reset_environment, get_to_final_state
+from test.probe.test_container_merge_policy_index import BrainSplitter
+
+from swiftclient import client
+
+
+class TestObjectExpirer(unittest.TestCase):
+
+ def setUp(self):
+ if len(POLICIES) < 2:
+ raise SkipTest('Need more than one policy')
+
+ self.expirer = Manager(['object-expirer'])
+ self.expirer.start()
+ err = self.expirer.stop()
+ if err:
+ raise SkipTest('Unable to verify object-expirer service')
+
+ conf_files = []
+ for server in self.expirer.servers:
+ conf_files.extend(server.conf_files())
+ 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()
+ self.container_name = 'container-%s' % uuid.uuid4()
+ self.object_name = 'object-%s' % uuid.uuid4()
+ self.brain = BrainSplitter(self.url, self.token, self.container_name,
+ self.object_name)
+
+ def test_expirer_object_split_brain(self):
+ old_policy = random.choice(list(POLICIES))
+ wrong_policy = random.choice([p for p in POLICIES if p != old_policy])
+ # create an expiring object and a container with the wrong policy
+ self.brain.stop_primary_half()
+ self.brain.put_container(int(old_policy))
+ self.brain.put_object(headers={'X-Delete-After': 1})
+ # get the object timestamp
+ metadata = self.client.get_object_metadata(
+ self.account, self.container_name, self.object_name,
+ headers={'X-Backend-Storage-Policy-Index': int(old_policy)})
+ create_timestamp = metadata['x-timestamp']
+ self.brain.start_primary_half()
+ # get the expiring object updates in their queue, while we have all
+ # the servers up
+ Manager(['object-updater']).once()
+ self.brain.stop_handoff_half()
+ self.brain.put_container(int(wrong_policy))
+ # don't start handoff servers, only wrong policy is available
+
+ # make sure auto-created containers get in the account listing
+ Manager(['container-updater']).once()
+ # this guy should no-op since it's unable to expire the object
+ self.expirer.once()
+
+ self.brain.start_handoff_half()
+ get_to_final_state()
+
+ # validate object is expired
+ found_in_policy = None
+ metadata = self.client.get_object_metadata(
+ self.account, self.container_name, self.object_name,
+ acceptable_statuses=(4,),
+ headers={'X-Backend-Storage-Policy-Index': int(old_policy)})
+ self.assert_('x-backend-timestamp' in metadata)
+ self.assertEqual(metadata['x-backend-timestamp'],
+ create_timestamp)
+
+ # but it is still in the listing
+ for obj in self.client.iter_objects(self.account,
+ self.container_name):
+ if self.object_name == obj['name']:
+ break
+ else:
+ self.fail('Did not find listing for %s' % self.object_name)
+
+ # clear proxy cache
+ client.post_container(self.url, self.token, self.container_name, {})
+ # run the expirier again after replication
+ self.expirer.once()
+
+ # object is not in the listing
+ for obj in self.client.iter_objects(self.account,
+ self.container_name):
+ if self.object_name == obj['name']:
+ self.fail('Found listing for %s' % self.object_name)
+
+ # and validate object is tombstoned
+ found_in_policy = None
+ for policy in POLICIES:
+ metadata = self.client.get_object_metadata(
+ self.account, self.container_name, self.object_name,
+ acceptable_statuses=(4,),
+ headers={'X-Backend-Storage-Policy-Index': int(policy)})
+ if 'x-backend-timestamp' in metadata:
+ if found_in_policy:
+ self.fail('found object in %s and also %s' %
+ (found_in_policy, policy))
+ found_in_policy = policy
+ self.assert_('x-backend-timestamp' in metadata)
+ self.assert_(float(metadata['x-backend-timestamp']) >
+ float(create_timestamp))
+
+if __name__ == "__main__":
+ unittest.main()