adding double quarantine support for db replication

This commit is contained in:
David Goetz 2011-04-18 15:00:59 -07:00
parent 92dc9fa448
commit 2d9103f9e0
2 changed files with 44 additions and 1 deletions

View File

@ -20,6 +20,8 @@ import random
import math
import time
import shutil
import uuid
import errno
from eventlet import GreenPool, sleep, Timeout, TimeoutError
from eventlet.green import subprocess
@ -49,6 +51,12 @@ def quarantine_db(object_file, server_type):
quarantine_dir = os.path.abspath(os.path.join(object_dir, '..',
'..', '..', '..', 'quarantined', server_type + 's',
os.path.basename(object_dir)))
try:
renamer(object_dir, quarantine_dir)
except OSError, e:
if e.errno not in (errno.EEXIST, errno.ENOTEMPTY):
raise
quarantine_dir = "%s-%s" % (quarantine_dir, uuid.uuid4().hex)
renamer(object_dir, quarantine_dir)

View File

@ -17,8 +17,10 @@ import unittest
from contextlib import contextmanager
import os
import logging
import errno
from swift.common import db_replicator
from swift.common import utils
from swift.common.utils import normalize_timestamp
from swift.container import server as container_server
@ -86,6 +88,8 @@ class ChangingMtimesOs:
class FakeBroker:
db_file = __file__
get_repl_missing_table = False
db_type = 'container'
def __init__(self, *args, **kwargs):
return None
@contextmanager
@ -104,6 +108,8 @@ class FakeBroker:
def merge_items(self, *args):
self.args = args
def get_replication_info(self):
if self.get_repl_missing_table:
raise Exception('no such table')
return {'delete_timestamp': 0, 'put_timestamp': 1, 'count': 0}
def reclaim(self, item_timestamp, sync_timestamp):
pass
@ -202,6 +208,35 @@ class TestDBReplicator(unittest.TestCase):
replicator = TestReplicator({})
replicator._replicate_object('0', 'file', 'node_id')
def test_replicate_object_quarantine(self):
replicator = TestReplicator({})
was_db_file = replicator.brokerclass.db_file
try:
def mock_renamer(was, new, cause_colision=False):
if cause_colision and '-' not in new:
raise OSError(errno.EEXIST, "File already exists")
self.assertEquals('/a/b/c/d/e', was)
if '-' in new:
self.assert_(
new.startswith('/a/quarantined/containers/e-'))
else:
self.assertEquals('/a/quarantined/containers/e', new)
def mock_renamer_error(was, new):
return mock_renamer(was, new, cause_colision=True)
was_renamer = db_replicator.renamer
db_replicator.renamer = mock_renamer
db_replicator.lock_parent_directory = lock_parent_directory
replicator.brokerclass.get_repl_missing_table = True
replicator.brokerclass.db_file = '/a/b/c/d/e/hey'
replicator._replicate_object('0', 'file', 'node_id')
# try the double quarantine
db_replicator.renamer = mock_renamer_error
replicator._replicate_object('0', 'file', 'node_id')
finally:
replicator.brokerclass.db_file = was_db_file
db_replicator.renamer = was_renamer
# def test_dispatch(self):
# rpc = db_replicator.ReplicatorRpc('/', '/', FakeBroker, False)