Revert "Refactor common/utils methods to common/ondisk"
This reverts commit 7760f41c3c
Change-Id: I95e57a2563784a8cd5e995cc826afeac0eadbe62
Signed-off-by: Peter Portante <peter.portante@redhat.com>
This commit is contained in:
parent
111ebb9a4b
commit
9411a24ba7
@ -19,7 +19,7 @@ import sys
|
||||
import urllib
|
||||
|
||||
from swift.common.ring import Ring
|
||||
from swift.common.ondisk import hash_path
|
||||
from swift.common.utils import hash_path
|
||||
|
||||
|
||||
parser = optparse.OptionParser()
|
||||
|
@ -20,7 +20,7 @@ from hashlib import md5
|
||||
|
||||
from swift.common.ring import Ring
|
||||
from swift.obj.diskfile import read_metadata
|
||||
from swift.common.ondisk import hash_path
|
||||
from swift.common.utils import hash_path
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) <= 1:
|
||||
|
@ -33,15 +33,6 @@ Utils
|
||||
:members:
|
||||
:show-inheritance:
|
||||
|
||||
.. _ondisk:
|
||||
|
||||
OnDisk
|
||||
======
|
||||
|
||||
.. automodule:: swift.common.ondisk
|
||||
:members:
|
||||
:show-inheritance:
|
||||
|
||||
.. _common_tempauth:
|
||||
|
||||
TempAuth
|
||||
|
@ -21,9 +21,8 @@ from random import random
|
||||
import swift.common.db
|
||||
from swift.account import server as account_server
|
||||
from swift.account.backend import AccountBroker
|
||||
from swift.common.utils import get_logger, config_true_value, \
|
||||
dump_recon_cache, ratelimit_sleep
|
||||
from swift.common.ondisk import audit_location_generator
|
||||
from swift.common.utils import get_logger, audit_location_generator, \
|
||||
config_true_value, dump_recon_cache, ratelimit_sleep
|
||||
from swift.common.daemon import Daemon
|
||||
|
||||
from eventlet import Timeout
|
||||
|
@ -25,8 +25,7 @@ import errno
|
||||
|
||||
import sqlite3
|
||||
|
||||
from swift.common.utils import lock_parent_directory
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import normalize_timestamp, lock_parent_directory
|
||||
from swift.common.db import DatabaseBroker, DatabaseConnectionError, \
|
||||
PENDING_CAP, PICKLE_PROTOCOL, utf8encode
|
||||
|
||||
|
@ -28,10 +28,9 @@ from swift.account.utils import account_listing_response
|
||||
from swift.common.db import DatabaseConnectionError, DatabaseAlreadyExists
|
||||
from swift.common.request_helpers import get_param, get_listing_content_type, \
|
||||
split_and_validate_path
|
||||
from swift.common.utils import get_logger, public, config_true_value, \
|
||||
from swift.common.utils import get_logger, hash_path, public, \
|
||||
normalize_timestamp, storage_directory, config_true_value, \
|
||||
json, timing_stats, replication
|
||||
from swift.common.ondisk import hash_path, normalize_timestamp, \
|
||||
storage_directory
|
||||
from swift.common.constraints import ACCOUNT_LISTING_LIMIT, \
|
||||
check_mount, check_float, check_utf8
|
||||
from swift.common.db_replicator import ReplicatorRpc
|
||||
|
@ -17,8 +17,7 @@ import time
|
||||
from xml.sax import saxutils
|
||||
|
||||
from swift.common.swob import HTTPOk, HTTPNoContent
|
||||
from swift.common.utils import json
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import json, normalize_timestamp
|
||||
|
||||
|
||||
class FakeAccountBroker(object):
|
||||
|
@ -22,7 +22,6 @@ from re import sub
|
||||
import eventlet.debug
|
||||
|
||||
from swift.common import utils
|
||||
from swift.common import ondisk
|
||||
|
||||
|
||||
class Daemon(object):
|
||||
@ -42,7 +41,7 @@ class Daemon(object):
|
||||
|
||||
def run(self, once=False, **kwargs):
|
||||
"""Run the daemon"""
|
||||
ondisk.validate_configuration()
|
||||
utils.validate_configuration()
|
||||
utils.drop_privileges(self.conf.get('user', 'swift'))
|
||||
utils.capture_stdio(self.logger, **kwargs)
|
||||
|
||||
|
@ -30,9 +30,8 @@ from tempfile import mkstemp
|
||||
from eventlet import sleep, Timeout
|
||||
import sqlite3
|
||||
|
||||
from swift.common.utils import json, renamer, mkdirs, lock_parent_directory, \
|
||||
fallocate
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import json, normalize_timestamp, renamer, \
|
||||
mkdirs, lock_parent_directory, fallocate
|
||||
from swift.common.exceptions import LockTimeout
|
||||
|
||||
|
||||
|
@ -30,10 +30,9 @@ import simplejson
|
||||
|
||||
import swift.common.db
|
||||
from swift.common.direct_client import quote
|
||||
from swift.common.utils import get_logger, whataremyips, renamer, mkdirs, \
|
||||
lock_parent_directory, config_true_value, unlink_older_than, \
|
||||
dump_recon_cache, rsync_ip
|
||||
from swift.common.ondisk import storage_directory
|
||||
from swift.common.utils import get_logger, whataremyips, storage_directory, \
|
||||
renamer, mkdirs, lock_parent_directory, config_true_value, \
|
||||
unlink_older_than, dump_recon_cache, rsync_ip
|
||||
from swift.common import ring
|
||||
from swift.common.http import HTTP_NOT_FOUND, HTTP_INSUFFICIENT_STORAGE
|
||||
from swift.common.bufferedhttp import BufferedHTTPConnection
|
||||
|
@ -27,8 +27,7 @@ from eventlet import sleep, Timeout
|
||||
|
||||
from swift.common.bufferedhttp import http_connect
|
||||
from swiftclient import ClientException, json_loads
|
||||
from swift.common.utils import FileLikeIter
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import normalize_timestamp, FileLikeIter
|
||||
from swift.common.http import HTTP_NO_CONTENT, HTTP_INSUFFICIENT_STORAGE, \
|
||||
is_success, is_server_error
|
||||
from swift.common.swob import HeaderKeyDict
|
||||
|
@ -1,184 +0,0 @@
|
||||
# Copyright (c) 2010-2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Methods & Attributes for shared 'on-disk' data layouts."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import errno
|
||||
|
||||
from hashlib import md5
|
||||
from random import shuffle
|
||||
from ConfigParser import ConfigParser, NoSectionError, NoOptionError
|
||||
|
||||
from swift import gettext_ as _
|
||||
from swift.common.utils import listdir, quote
|
||||
|
||||
# Used by hash_path to offer a bit more security when generating hashes for
|
||||
# paths. It simply appends this value to all paths; guessing the hash a path
|
||||
# will end up with would also require knowing this suffix.
|
||||
_hash_conf = ConfigParser()
|
||||
HASH_PATH_SUFFIX = ''
|
||||
HASH_PATH_PREFIX = ''
|
||||
if _hash_conf.read('/etc/swift/swift.conf'):
|
||||
try:
|
||||
HASH_PATH_SUFFIX = _hash_conf.get('swift-hash',
|
||||
'swift_hash_path_suffix')
|
||||
except (NoSectionError, NoOptionError):
|
||||
pass
|
||||
try:
|
||||
HASH_PATH_PREFIX = _hash_conf.get('swift-hash',
|
||||
'swift_hash_path_prefix')
|
||||
except (NoSectionError, NoOptionError):
|
||||
pass
|
||||
|
||||
|
||||
def validate_configuration():
|
||||
if not HASH_PATH_SUFFIX and not HASH_PATH_PREFIX:
|
||||
sys.exit("Error: [swift-hash]: both swift_hash_path_suffix "
|
||||
"and swift_hash_path_prefix are missing "
|
||||
"from /etc/swift/swift.conf")
|
||||
|
||||
|
||||
def hash_path(account, container=None, object=None, raw_digest=False):
|
||||
"""
|
||||
Get the canonical hash for an account/container/object
|
||||
|
||||
:param account: Account
|
||||
:param container: Container
|
||||
:param object: Object
|
||||
:param raw_digest: If True, return the raw version rather than a hex digest
|
||||
:returns: hash string
|
||||
"""
|
||||
if object and not container:
|
||||
raise ValueError('container is required if object is provided')
|
||||
paths = [account]
|
||||
if container:
|
||||
paths.append(container)
|
||||
if object:
|
||||
paths.append(object)
|
||||
if raw_digest:
|
||||
return md5(HASH_PATH_PREFIX + '/' + '/'.join(paths)
|
||||
+ HASH_PATH_SUFFIX).digest()
|
||||
else:
|
||||
return md5(HASH_PATH_PREFIX + '/' + '/'.join(paths)
|
||||
+ HASH_PATH_SUFFIX).hexdigest()
|
||||
|
||||
|
||||
def normalize_timestamp(timestamp):
|
||||
"""
|
||||
Format a timestamp (string or numeric) into a standardized
|
||||
xxxxxxxxxx.xxxxx (10.5) format.
|
||||
|
||||
Note that timestamps using values greater than or equal to November 20th,
|
||||
2286 at 17:46 UTC will use 11 digits to represent the number of
|
||||
seconds.
|
||||
|
||||
:param timestamp: unix timestamp
|
||||
:returns: normalized timestamp as a string
|
||||
"""
|
||||
return "%016.05f" % (float(timestamp))
|
||||
|
||||
|
||||
def validate_device_partition(device, partition):
|
||||
"""
|
||||
Validate that a device and a partition are valid and won't lead to
|
||||
directory traversal when used.
|
||||
|
||||
:param device: device to validate
|
||||
:param partition: partition to validate
|
||||
:raises: ValueError if given an invalid device or partition
|
||||
"""
|
||||
invalid_device = False
|
||||
invalid_partition = False
|
||||
if not device or '/' in device or device in ['.', '..']:
|
||||
invalid_device = True
|
||||
if not partition or '/' in partition or partition in ['.', '..']:
|
||||
invalid_partition = True
|
||||
|
||||
if invalid_device:
|
||||
raise ValueError('Invalid device: %s' % quote(device or ''))
|
||||
elif invalid_partition:
|
||||
raise ValueError('Invalid partition: %s' % quote(partition or ''))
|
||||
|
||||
|
||||
def storage_directory(datadir, partition, name_hash):
|
||||
"""
|
||||
Get the storage directory
|
||||
|
||||
:param datadir: Base data directory
|
||||
:param partition: Partition
|
||||
:param name_hash: Account, container or object name hash
|
||||
:returns: Storage directory
|
||||
"""
|
||||
return os.path.join(datadir, str(partition), name_hash[-3:], name_hash)
|
||||
|
||||
|
||||
def audit_location_generator(devices, datadir, suffix='',
|
||||
mount_check=True, logger=None):
|
||||
'''
|
||||
Given a devices path and a data directory, yield (path, device,
|
||||
partition) for all files in that directory
|
||||
|
||||
:param devices: parent directory of the devices to be audited
|
||||
:param datadir: a directory located under self.devices. This should be
|
||||
one of the DATADIR constants defined in the account,
|
||||
container, and object servers.
|
||||
:param suffix: path name suffix required for all names returned
|
||||
:param mount_check: Flag to check if a mount check should be performed
|
||||
on devices
|
||||
:param logger: a logger object
|
||||
'''
|
||||
device_dir = listdir(devices)
|
||||
# randomize devices in case of process restart before sweep completed
|
||||
shuffle(device_dir)
|
||||
for device in device_dir:
|
||||
if mount_check and not \
|
||||
os.path.ismount(os.path.join(devices, device)):
|
||||
if logger:
|
||||
logger.debug(
|
||||
_('Skipping %s as it is not mounted'), device)
|
||||
continue
|
||||
datadir_path = os.path.join(devices, device, datadir)
|
||||
partitions = listdir(datadir_path)
|
||||
for partition in partitions:
|
||||
part_path = os.path.join(datadir_path, partition)
|
||||
try:
|
||||
suffixes = listdir(part_path)
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOTDIR:
|
||||
raise
|
||||
continue
|
||||
for asuffix in suffixes:
|
||||
suff_path = os.path.join(part_path, asuffix)
|
||||
try:
|
||||
hashes = listdir(suff_path)
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOTDIR:
|
||||
raise
|
||||
continue
|
||||
for hsh in hashes:
|
||||
hash_path = os.path.join(suff_path, hsh)
|
||||
try:
|
||||
files = sorted(listdir(hash_path), reverse=True)
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOTDIR:
|
||||
raise
|
||||
continue
|
||||
for fname in files:
|
||||
if suffix and not fname.endswith(suffix):
|
||||
continue
|
||||
path = os.path.join(hash_path, fname)
|
||||
yield path, device, partition
|
@ -22,8 +22,7 @@ from swob in here without creating circular imports.
|
||||
|
||||
from swift.common.constraints import FORMAT2CONTENT_TYPE
|
||||
from swift.common.swob import HTTPBadRequest, HTTPNotAcceptable
|
||||
from swift.common.ondisk import validate_device_partition
|
||||
from swift.common.utils import split_path
|
||||
from swift.common.utils import split_path, validate_device_partition
|
||||
from urllib import unquote
|
||||
|
||||
|
||||
|
@ -25,8 +25,7 @@ from io import BufferedReader
|
||||
from hashlib import md5
|
||||
from itertools import chain
|
||||
|
||||
from swift.common.utils import json
|
||||
from swift.common.ondisk import hash_path, validate_configuration
|
||||
from swift.common.utils import hash_path, validate_configuration, json
|
||||
from swift.common.ring.utils import tiers_for_dev
|
||||
|
||||
|
||||
@ -131,7 +130,7 @@ class Ring(object):
|
||||
"""
|
||||
|
||||
def __init__(self, serialized_path, reload_time=15, ring_name=None):
|
||||
# Can't use the ring unless the on-disk configuration is valid
|
||||
# can't use the ring unless HASH_PATH_SUFFIX is set
|
||||
validate_configuration()
|
||||
if ring_name:
|
||||
self.serialized_path = os.path.join(serialized_path,
|
||||
|
@ -26,12 +26,14 @@ import threading as stdlib_threading
|
||||
import time
|
||||
import uuid
|
||||
import functools
|
||||
from random import random
|
||||
from hashlib import md5
|
||||
from random import random, shuffle
|
||||
from urllib import quote as _quote
|
||||
from contextlib import contextmanager, closing
|
||||
import ctypes
|
||||
import ctypes.util
|
||||
from ConfigParser import ConfigParser, RawConfigParser
|
||||
from ConfigParser import ConfigParser, NoSectionError, NoOptionError, \
|
||||
RawConfigParser
|
||||
from optparse import OptionParser
|
||||
from Queue import Queue, Empty
|
||||
from tempfile import mkstemp, NamedTemporaryFile
|
||||
@ -78,6 +80,24 @@ _posix_fadvise = None
|
||||
# available being at or below this amount, in bytes.
|
||||
FALLOCATE_RESERVE = 0
|
||||
|
||||
# Used by hash_path to offer a bit more security when generating hashes for
|
||||
# paths. It simply appends this value to all paths; guessing the hash a path
|
||||
# will end up with would also require knowing this suffix.
|
||||
hash_conf = ConfigParser()
|
||||
HASH_PATH_SUFFIX = ''
|
||||
HASH_PATH_PREFIX = ''
|
||||
if hash_conf.read('/etc/swift/swift.conf'):
|
||||
try:
|
||||
HASH_PATH_SUFFIX = hash_conf.get('swift-hash',
|
||||
'swift_hash_path_suffix')
|
||||
except (NoSectionError, NoOptionError):
|
||||
pass
|
||||
try:
|
||||
HASH_PATH_PREFIX = hash_conf.get('swift-hash',
|
||||
'swift_hash_path_prefix')
|
||||
except (NoSectionError, NoOptionError):
|
||||
pass
|
||||
|
||||
|
||||
def backward(f, blocksize=4096):
|
||||
"""
|
||||
@ -144,6 +164,13 @@ def noop_libc_function(*args):
|
||||
return 0
|
||||
|
||||
|
||||
def validate_configuration():
|
||||
if not HASH_PATH_SUFFIX and not HASH_PATH_PREFIX:
|
||||
sys.exit("Error: [swift-hash]: both swift_hash_path_suffix "
|
||||
"and swift_hash_path_prefix are missing "
|
||||
"from /etc/swift/swift.conf")
|
||||
|
||||
|
||||
def load_libc_function(func_name, log_error=True):
|
||||
"""
|
||||
Attempt to find the function in libc, otherwise return a no-op func.
|
||||
@ -395,6 +422,21 @@ def drop_buffer_cache(fd, offset, length):
|
||||
% (fd, offset, length, ret))
|
||||
|
||||
|
||||
def normalize_timestamp(timestamp):
|
||||
"""
|
||||
Format a timestamp (string or numeric) into a standardized
|
||||
xxxxxxxxxx.xxxxx (10.5) format.
|
||||
|
||||
Note that timestamps using values greater than or equal to November 20th,
|
||||
2286 at 17:46 UTC will use 11 digits to represent the number of
|
||||
seconds.
|
||||
|
||||
:param timestamp: unix timestamp
|
||||
:returns: normalized timestamp as a string
|
||||
"""
|
||||
return "%016.05f" % (float(timestamp))
|
||||
|
||||
|
||||
def mkdirs(path):
|
||||
"""
|
||||
Ensures the path is a directory or makes it if not. Errors if the path
|
||||
@ -473,6 +515,28 @@ def split_path(path, minsegs=1, maxsegs=None, rest_with_last=False):
|
||||
return segs
|
||||
|
||||
|
||||
def validate_device_partition(device, partition):
|
||||
"""
|
||||
Validate that a device and a partition are valid and won't lead to
|
||||
directory traversal when used.
|
||||
|
||||
:param device: device to validate
|
||||
:param partition: partition to validate
|
||||
:raises: ValueError if given an invalid device or partition
|
||||
"""
|
||||
invalid_device = False
|
||||
invalid_partition = False
|
||||
if not device or '/' in device or device in ['.', '..']:
|
||||
invalid_device = True
|
||||
if not partition or '/' in partition or partition in ['.', '..']:
|
||||
invalid_partition = True
|
||||
|
||||
if invalid_device:
|
||||
raise ValueError('Invalid device: %s' % quote(device or ''))
|
||||
elif invalid_partition:
|
||||
raise ValueError('Invalid partition: %s' % quote(partition or ''))
|
||||
|
||||
|
||||
class GreenthreadSafeIterator(object):
|
||||
"""
|
||||
Wrap an iterator to ensure that only one greenthread is inside its next()
|
||||
@ -1076,6 +1140,43 @@ def whataremyips():
|
||||
return addresses
|
||||
|
||||
|
||||
def storage_directory(datadir, partition, name_hash):
|
||||
"""
|
||||
Get the storage directory
|
||||
|
||||
:param datadir: Base data directory
|
||||
:param partition: Partition
|
||||
:param name_hash: Account, container or object name hash
|
||||
:returns: Storage directory
|
||||
"""
|
||||
return os.path.join(datadir, str(partition), name_hash[-3:], name_hash)
|
||||
|
||||
|
||||
def hash_path(account, container=None, object=None, raw_digest=False):
|
||||
"""
|
||||
Get the canonical hash for an account/container/object
|
||||
|
||||
:param account: Account
|
||||
:param container: Container
|
||||
:param object: Object
|
||||
:param raw_digest: If True, return the raw version rather than a hex digest
|
||||
:returns: hash string
|
||||
"""
|
||||
if object and not container:
|
||||
raise ValueError('container is required if object is provided')
|
||||
paths = [account]
|
||||
if container:
|
||||
paths.append(container)
|
||||
if object:
|
||||
paths.append(object)
|
||||
if raw_digest:
|
||||
return md5(HASH_PATH_PREFIX + '/' + '/'.join(paths)
|
||||
+ HASH_PATH_SUFFIX).digest()
|
||||
else:
|
||||
return md5(HASH_PATH_PREFIX + '/' + '/'.join(paths)
|
||||
+ HASH_PATH_SUFFIX).hexdigest()
|
||||
|
||||
|
||||
@contextmanager
|
||||
def lock_path(directory, timeout=10):
|
||||
"""
|
||||
@ -1390,6 +1491,64 @@ def remove_file(path):
|
||||
pass
|
||||
|
||||
|
||||
def audit_location_generator(devices, datadir, suffix='',
|
||||
mount_check=True, logger=None):
|
||||
'''
|
||||
Given a devices path and a data directory, yield (path, device,
|
||||
partition) for all files in that directory
|
||||
|
||||
:param devices: parent directory of the devices to be audited
|
||||
:param datadir: a directory located under self.devices. This should be
|
||||
one of the DATADIR constants defined in the account,
|
||||
container, and object servers.
|
||||
:param suffix: path name suffix required for all names returned
|
||||
:param mount_check: Flag to check if a mount check should be performed
|
||||
on devices
|
||||
:param logger: a logger object
|
||||
'''
|
||||
device_dir = listdir(devices)
|
||||
# randomize devices in case of process restart before sweep completed
|
||||
shuffle(device_dir)
|
||||
for device in device_dir:
|
||||
if mount_check and not \
|
||||
os.path.ismount(os.path.join(devices, device)):
|
||||
if logger:
|
||||
logger.debug(
|
||||
_('Skipping %s as it is not mounted'), device)
|
||||
continue
|
||||
datadir_path = os.path.join(devices, device, datadir)
|
||||
partitions = listdir(datadir_path)
|
||||
for partition in partitions:
|
||||
part_path = os.path.join(datadir_path, partition)
|
||||
try:
|
||||
suffixes = listdir(part_path)
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOTDIR:
|
||||
raise
|
||||
continue
|
||||
for asuffix in suffixes:
|
||||
suff_path = os.path.join(part_path, asuffix)
|
||||
try:
|
||||
hashes = listdir(suff_path)
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOTDIR:
|
||||
raise
|
||||
continue
|
||||
for hsh in hashes:
|
||||
hash_path = os.path.join(suff_path, hsh)
|
||||
try:
|
||||
files = sorted(listdir(hash_path), reverse=True)
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOTDIR:
|
||||
raise
|
||||
continue
|
||||
for fname in files:
|
||||
if suffix and not fname.endswith(suffix):
|
||||
continue
|
||||
path = os.path.join(hash_path, fname)
|
||||
yield path, device, partition
|
||||
|
||||
|
||||
def ratelimit_sleep(running_time, max_rate, incr_by=1, rate_buffer=5):
|
||||
'''
|
||||
Will eventlet.sleep() for the appropriate time so that the max_rate
|
||||
|
@ -35,8 +35,7 @@ from swift.common import utils
|
||||
from swift.common.swob import Request
|
||||
from swift.common.utils import capture_stdio, disable_fallocate, \
|
||||
drop_privileges, get_logger, NullLogger, config_true_value, \
|
||||
get_hub, config_auto_int_value
|
||||
from swift.common.ondisk import validate_configuration
|
||||
validate_configuration, get_hub, config_auto_int_value
|
||||
|
||||
try:
|
||||
import multiprocessing
|
||||
|
@ -23,9 +23,8 @@ from eventlet import Timeout
|
||||
import swift.common.db
|
||||
from swift.container import server as container_server
|
||||
from swift.container.backend import ContainerBroker
|
||||
from swift.common.utils import get_logger, config_true_value, \
|
||||
dump_recon_cache, ratelimit_sleep
|
||||
from swift.common.ondisk import audit_location_generator
|
||||
from swift.common.utils import get_logger, audit_location_generator, \
|
||||
config_true_value, dump_recon_cache, ratelimit_sleep
|
||||
from swift.common.daemon import Daemon
|
||||
|
||||
|
||||
|
@ -25,8 +25,7 @@ import errno
|
||||
|
||||
import sqlite3
|
||||
|
||||
from swift.common.utils import lock_parent_directory
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import normalize_timestamp, lock_parent_directory
|
||||
from swift.common.db import DatabaseBroker, DatabaseConnectionError, \
|
||||
PENDING_CAP, PICKLE_PROTOCOL, utf8encode
|
||||
|
||||
|
@ -29,11 +29,10 @@ from swift.container.backend import ContainerBroker
|
||||
from swift.common.db import DatabaseAlreadyExists
|
||||
from swift.common.request_helpers import get_param, get_listing_content_type, \
|
||||
split_and_validate_path
|
||||
from swift.common.utils import get_logger, public, validate_sync_to, \
|
||||
from swift.common.utils import get_logger, hash_path, public, \
|
||||
normalize_timestamp, storage_directory, validate_sync_to, \
|
||||
config_true_value, json, timing_stats, replication, \
|
||||
override_bytes_from_content_type
|
||||
from swift.common.ondisk import hash_path, normalize_timestamp, \
|
||||
storage_directory
|
||||
from swift.common.constraints import CONTAINER_LISTING_LIMIT, \
|
||||
check_mount, check_float, check_utf8
|
||||
from swift.common.bufferedhttp import http_connect
|
||||
|
@ -27,9 +27,8 @@ from swiftclient import ClientException, delete_object, put_object, \
|
||||
from swift.container.backend import ContainerBroker
|
||||
from swift.common.direct_client import direct_get_object
|
||||
from swift.common.ring import Ring
|
||||
from swift.common.utils import get_logger, config_true_value, \
|
||||
validate_sync_to, whataremyips, FileLikeIter
|
||||
from swift.common.ondisk import audit_location_generator, hash_path
|
||||
from swift.common.utils import audit_location_generator, get_logger, \
|
||||
hash_path, config_true_value, validate_sync_to, whataremyips, FileLikeIter
|
||||
from swift.common.daemon import Daemon
|
||||
from swift.common.http import HTTP_UNAUTHORIZED, HTTP_NOT_FOUND
|
||||
|
||||
|
@ -21,9 +21,8 @@ from eventlet import Timeout
|
||||
|
||||
from swift.obj import diskfile
|
||||
from swift.obj import server as object_server
|
||||
from swift.common.utils import get_logger, ratelimit_sleep, \
|
||||
config_true_value, dump_recon_cache, list_from_csv, json
|
||||
from swift.common.ondisk import audit_location_generator
|
||||
from swift.common.utils import get_logger, audit_location_generator, \
|
||||
ratelimit_sleep, config_true_value, dump_recon_cache, list_from_csv, json
|
||||
from swift.common.exceptions import AuditException, DiskFileError, \
|
||||
DiskFileNotExist
|
||||
from swift.common.daemon import Daemon
|
||||
|
@ -33,10 +33,9 @@ from eventlet import Timeout
|
||||
|
||||
from swift import gettext_ as _
|
||||
from swift.common.constraints import check_mount
|
||||
from swift.common.utils import mkdirs, renamer, fallocate, fsync, fdatasync, \
|
||||
drop_buffer_cache, ThreadPool, lock_path, write_pickle
|
||||
from swift.common.ondisk import hash_path, normalize_timestamp, \
|
||||
storage_directory
|
||||
from swift.common.utils import mkdirs, normalize_timestamp, \
|
||||
storage_directory, hash_path, renamer, fallocate, fsync, \
|
||||
fdatasync, drop_buffer_cache, ThreadPool, lock_path, write_pickle
|
||||
from swift.common.exceptions import DiskFileError, DiskFileNotExist, \
|
||||
DiskFileCollision, DiskFileNoSpace, DiskFileDeviceUnavailable, \
|
||||
PathNotDir, DiskFileNotOpenError
|
||||
|
@ -27,9 +27,9 @@ from hashlib import md5
|
||||
|
||||
from eventlet import sleep, Timeout
|
||||
|
||||
from swift.common.utils import mkdirs, public, get_logger, write_pickle, \
|
||||
config_true_value, timing_stats, ThreadPool, replication
|
||||
from swift.common.ondisk import normalize_timestamp, hash_path
|
||||
from swift.common.utils import mkdirs, normalize_timestamp, public, \
|
||||
hash_path, get_logger, write_pickle, config_true_value, timing_stats, \
|
||||
ThreadPool, replication
|
||||
from swift.common.bufferedhttp import http_connect
|
||||
from swift.common.constraints import check_object_creation, check_mount, \
|
||||
check_float, check_utf8
|
||||
|
@ -37,9 +37,9 @@ from eventlet.queue import Queue, Empty, Full
|
||||
from eventlet.timeout import Timeout
|
||||
|
||||
from swift.common.wsgi import make_pre_authed_env
|
||||
from swift.common.utils import config_true_value, public, split_path, \
|
||||
list_from_csv, GreenthreadSafeIterator, quorum_size
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import normalize_timestamp, config_true_value, \
|
||||
public, split_path, list_from_csv, GreenthreadSafeIterator, \
|
||||
quorum_size
|
||||
from swift.common.bufferedhttp import http_connect
|
||||
from swift.common.exceptions import ChunkReadTimeout, ConnectionTimeout
|
||||
from swift.common.http import is_informational, is_success, is_redirection, \
|
||||
|
@ -38,10 +38,10 @@ from eventlet import sleep, GreenPile
|
||||
from eventlet.queue import Queue
|
||||
from eventlet.timeout import Timeout
|
||||
|
||||
from swift.common.utils import ContextPool, config_true_value, public, json, \
|
||||
csv_append, GreenthreadSafeIterator, quorum_size, split_path, \
|
||||
override_bytes_from_content_type, get_valid_utf8_str
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import ContextPool, normalize_timestamp, \
|
||||
config_true_value, public, json, csv_append, GreenthreadSafeIterator, \
|
||||
quorum_size, split_path, override_bytes_from_content_type, \
|
||||
get_valid_utf8_str
|
||||
from swift.common.bufferedhttp import http_connect
|
||||
from swift.common.constraints import check_metadata, check_object_creation, \
|
||||
CONTAINER_LISTING_LIMIT, MAX_FILE_SIZE
|
||||
|
@ -25,8 +25,7 @@ from sqlite3 import connect
|
||||
from swiftclient import client
|
||||
|
||||
from swift.common import direct_client
|
||||
from swift.common.ondisk import hash_path
|
||||
from swift.common.utils import readconf
|
||||
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
|
||||
|
||||
|
@ -22,8 +22,7 @@ from uuid import uuid4
|
||||
from swiftclient import client
|
||||
|
||||
from swift.common import direct_client
|
||||
from swift.common.ondisk import hash_path
|
||||
from swift.common.utils import readconf
|
||||
from swift.common.utils import hash_path, readconf
|
||||
from swift.obj.diskfile import write_metadata, read_metadata
|
||||
from test.probe.common import kill_servers, reset_environment
|
||||
|
||||
|
@ -22,7 +22,7 @@ from time import sleep, time
|
||||
from uuid import uuid4
|
||||
|
||||
from swift.account.backend import AccountBroker
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import normalize_timestamp
|
||||
|
||||
|
||||
class TestAccountBroker(unittest.TestCase):
|
||||
|
@ -25,7 +25,7 @@ from contextlib import nested
|
||||
|
||||
from swift.account import reaper
|
||||
from swift.account.server import DATADIR
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import normalize_timestamp
|
||||
from swift.common.direct_client import ClientException
|
||||
|
||||
|
||||
|
@ -25,8 +25,7 @@ import xml.dom.minidom
|
||||
|
||||
from swift.common.swob import Request
|
||||
from swift.account.server import AccountController, ACCOUNT_LISTING_LIMIT
|
||||
from swift.common.utils import replication, public
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import normalize_timestamp, replication, public
|
||||
|
||||
|
||||
class TestAccountController(unittest.TestCase):
|
||||
|
@ -18,7 +18,7 @@ import unittest
|
||||
from shutil import rmtree
|
||||
|
||||
import os
|
||||
from swift.common import ring, ondisk
|
||||
from swift.common import ring, utils
|
||||
from swift.common.utils import json
|
||||
from swift.common.swob import Request, Response
|
||||
from swift.common.middleware import list_endpoints
|
||||
@ -35,8 +35,8 @@ def start_response(*args):
|
||||
|
||||
class TestListEndpoints(unittest.TestCase):
|
||||
def setUp(self):
|
||||
ondisk.HASH_PATH_SUFFIX = 'endcap'
|
||||
ondisk.HASH_PATH_PREFIX = ''
|
||||
utils.HASH_PATH_SUFFIX = 'endcap'
|
||||
utils.HASH_PATH_PREFIX = ''
|
||||
self.testdir = os.path.join(os.path.dirname(__file__), 'ring')
|
||||
rmtree(self.testdir, ignore_errors=1)
|
||||
os.mkdir(self.testdir)
|
||||
|
@ -23,7 +23,7 @@ from gzip import GzipFile
|
||||
from shutil import rmtree
|
||||
from time import sleep, time
|
||||
|
||||
from swift.common import ring, ondisk
|
||||
from swift.common import ring, utils
|
||||
|
||||
|
||||
class TestRingData(unittest.TestCase):
|
||||
@ -99,8 +99,8 @@ class TestRingData(unittest.TestCase):
|
||||
class TestRing(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
ondisk.HASH_PATH_SUFFIX = 'endcap'
|
||||
ondisk.HASH_PATH_PREFIX = ''
|
||||
utils.HASH_PATH_SUFFIX = 'endcap'
|
||||
utils.HASH_PATH_PREFIX = ''
|
||||
self.testdir = os.path.join(os.path.dirname(__file__), 'ring')
|
||||
rmtree(self.testdir, ignore_errors=1)
|
||||
os.mkdir(self.testdir)
|
||||
@ -146,15 +146,15 @@ class TestRing(unittest.TestCase):
|
||||
self.assertEquals(self.ring.reload_time, self.intended_reload_time)
|
||||
self.assertEquals(self.ring.serialized_path, self.testgz)
|
||||
# test invalid endcap
|
||||
_orig_hash_path_suffix = ondisk.HASH_PATH_SUFFIX
|
||||
_orig_hash_path_prefix = ondisk.HASH_PATH_PREFIX
|
||||
_orig_hash_path_suffix = utils.HASH_PATH_SUFFIX
|
||||
_orig_hash_path_prefix = utils.HASH_PATH_PREFIX
|
||||
try:
|
||||
ondisk.HASH_PATH_SUFFIX = ''
|
||||
ondisk.HASH_PATH_PREFIX = ''
|
||||
utils.HASH_PATH_SUFFIX = ''
|
||||
utils.HASH_PATH_PREFIX = ''
|
||||
self.assertRaises(SystemExit, ring.Ring, self.testdir, 'whatever')
|
||||
finally:
|
||||
ondisk.HASH_PATH_SUFFIX = _orig_hash_path_suffix
|
||||
ondisk.HASH_PATH_PREFIX = _orig_hash_path_prefix
|
||||
utils.HASH_PATH_SUFFIX = _orig_hash_path_suffix
|
||||
utils.HASH_PATH_PREFIX = _orig_hash_path_prefix
|
||||
|
||||
def test_has_changed(self):
|
||||
self.assertEquals(self.ring.has_changed(), False)
|
||||
|
@ -23,7 +23,7 @@ from StringIO import StringIO
|
||||
from test.unit import tmpfile
|
||||
from mock import patch
|
||||
|
||||
from swift.common import daemon, utils, ondisk
|
||||
from swift.common import daemon, utils
|
||||
|
||||
|
||||
class MyDaemon(daemon.Daemon):
|
||||
@ -63,8 +63,8 @@ class TestDaemon(unittest.TestCase):
|
||||
class TestRunDaemon(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
ondisk.HASH_PATH_SUFFIX = 'endcap'
|
||||
ondisk.HASH_PATH_PREFIX = 'startcap'
|
||||
utils.HASH_PATH_SUFFIX = 'endcap'
|
||||
utils.HASH_PATH_PREFIX = 'startcap'
|
||||
utils.drop_privileges = lambda *args: None
|
||||
utils.capture_stdio = lambda *args: None
|
||||
|
||||
|
@ -28,7 +28,7 @@ from mock import patch
|
||||
import swift.common.db
|
||||
from swift.common.db import chexor, dict_factory, get_db_connection, \
|
||||
DatabaseBroker, DatabaseConnectionError, DatabaseAlreadyExists
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import normalize_timestamp
|
||||
from swift.common.exceptions import LockTimeout
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ import mock
|
||||
import simplejson
|
||||
|
||||
from swift.common import db_replicator
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import normalize_timestamp
|
||||
from swift.container import server as container_server
|
||||
from swift.common.exceptions import DriveNotMounted
|
||||
|
||||
|
@ -1,139 +0,0 @@
|
||||
# Copyright (c) 2010-2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Tests for swift.common.ondisk"""
|
||||
|
||||
from __future__ import with_statement
|
||||
from test.unit import temptree
|
||||
|
||||
import os
|
||||
|
||||
import unittest
|
||||
|
||||
from swift.common import ondisk
|
||||
|
||||
|
||||
class TestOndisk(unittest.TestCase):
|
||||
"""Tests for swift.common.ondisk"""
|
||||
|
||||
def setUp(self):
|
||||
ondisk.HASH_PATH_SUFFIX = 'endcap'
|
||||
ondisk.HASH_PATH_PREFIX = 'startcap'
|
||||
|
||||
def test_normalize_timestamp(self):
|
||||
# Test swift.common.ondisk.normalize_timestamp
|
||||
self.assertEquals(ondisk.normalize_timestamp('1253327593.48174'),
|
||||
"1253327593.48174")
|
||||
self.assertEquals(ondisk.normalize_timestamp(1253327593.48174),
|
||||
"1253327593.48174")
|
||||
self.assertEquals(ondisk.normalize_timestamp('1253327593.48'),
|
||||
"1253327593.48000")
|
||||
self.assertEquals(ondisk.normalize_timestamp(1253327593.48),
|
||||
"1253327593.48000")
|
||||
self.assertEquals(ondisk.normalize_timestamp('253327593.48'),
|
||||
"0253327593.48000")
|
||||
self.assertEquals(ondisk.normalize_timestamp(253327593.48),
|
||||
"0253327593.48000")
|
||||
self.assertEquals(ondisk.normalize_timestamp('1253327593'),
|
||||
"1253327593.00000")
|
||||
self.assertEquals(ondisk.normalize_timestamp(1253327593),
|
||||
"1253327593.00000")
|
||||
self.assertRaises(ValueError, ondisk.normalize_timestamp, '')
|
||||
self.assertRaises(ValueError, ondisk.normalize_timestamp, 'abc')
|
||||
|
||||
def test_validate_device_partition(self):
|
||||
# Test swift.common.ondisk.validate_device_partition
|
||||
ondisk.validate_device_partition('foo', 'bar')
|
||||
self.assertRaises(ValueError,
|
||||
ondisk.validate_device_partition, '', '')
|
||||
self.assertRaises(ValueError,
|
||||
ondisk.validate_device_partition, '', 'foo')
|
||||
self.assertRaises(ValueError,
|
||||
ondisk.validate_device_partition, 'foo', '')
|
||||
self.assertRaises(ValueError,
|
||||
ondisk.validate_device_partition, 'foo/bar', 'foo')
|
||||
self.assertRaises(ValueError,
|
||||
ondisk.validate_device_partition, 'foo', 'foo/bar')
|
||||
self.assertRaises(ValueError,
|
||||
ondisk.validate_device_partition, '.', 'foo')
|
||||
self.assertRaises(ValueError,
|
||||
ondisk.validate_device_partition, '..', 'foo')
|
||||
self.assertRaises(ValueError,
|
||||
ondisk.validate_device_partition, 'foo', '.')
|
||||
self.assertRaises(ValueError,
|
||||
ondisk.validate_device_partition, 'foo', '..')
|
||||
try:
|
||||
ondisk.validate_device_partition('o\nn e', 'foo')
|
||||
except ValueError as err:
|
||||
self.assertEquals(str(err), 'Invalid device: o%0An%20e')
|
||||
try:
|
||||
ondisk.validate_device_partition('foo', 'o\nn e')
|
||||
except ValueError as err:
|
||||
self.assertEquals(str(err), 'Invalid partition: o%0An%20e')
|
||||
|
||||
def test_storage_directory(self):
|
||||
self.assertEquals(ondisk.storage_directory('objects', '1', 'ABCDEF'),
|
||||
'objects/1/DEF/ABCDEF')
|
||||
|
||||
def test_hash_path(self):
|
||||
_prefix = ondisk.HASH_PATH_PREFIX
|
||||
ondisk.HASH_PATH_PREFIX = ''
|
||||
# Yes, these tests are deliberately very fragile. We want to make sure
|
||||
# that if someones changes the results hash_path produces, they know it
|
||||
try:
|
||||
self.assertEquals(ondisk.hash_path('a'),
|
||||
'1c84525acb02107ea475dcd3d09c2c58')
|
||||
self.assertEquals(ondisk.hash_path('a', 'c'),
|
||||
'33379ecb053aa5c9e356c68997cbb59e')
|
||||
self.assertEquals(ondisk.hash_path('a', 'c', 'o'),
|
||||
'06fbf0b514e5199dfc4e00f42eb5ea83')
|
||||
self.assertEquals(
|
||||
ondisk.hash_path('a', 'c', 'o', raw_digest=False),
|
||||
'06fbf0b514e5199dfc4e00f42eb5ea83')
|
||||
self.assertEquals(ondisk.hash_path('a', 'c', 'o', raw_digest=True),
|
||||
'\x06\xfb\xf0\xb5\x14\xe5\x19\x9d\xfcN'
|
||||
'\x00\xf4.\xb5\xea\x83')
|
||||
self.assertRaises(ValueError, ondisk.hash_path, 'a', object='o')
|
||||
ondisk.HASH_PATH_PREFIX = 'abcdef'
|
||||
self.assertEquals(
|
||||
ondisk.hash_path('a', 'c', 'o', raw_digest=False),
|
||||
'363f9b535bfb7d17a43a46a358afca0e')
|
||||
finally:
|
||||
ondisk.HASH_PATH_PREFIX = _prefix
|
||||
|
||||
|
||||
class TestAuditLocationGenerator(unittest.TestCase):
|
||||
def test_non_dir_contents(self):
|
||||
with temptree([]) as tmpdir:
|
||||
data = os.path.join(tmpdir, "drive", "data")
|
||||
os.makedirs(data)
|
||||
with open(os.path.join(data, "partition1"), "w"):
|
||||
pass
|
||||
partition = os.path.join(data, "partition2")
|
||||
os.makedirs(partition)
|
||||
with open(os.path.join(partition, "suffix1"), "w"):
|
||||
pass
|
||||
suffix = os.path.join(partition, "suffix2")
|
||||
os.makedirs(suffix)
|
||||
with open(os.path.join(suffix, "hash1"), "w"):
|
||||
pass
|
||||
locations = ondisk.audit_location_generator(
|
||||
tmpdir, "data", mount_check=False
|
||||
)
|
||||
self.assertEqual(list(locations), [])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -133,6 +133,31 @@ def reset_loggers():
|
||||
class TestUtils(unittest.TestCase):
|
||||
"""Tests for swift.common.utils """
|
||||
|
||||
def setUp(self):
|
||||
utils.HASH_PATH_SUFFIX = 'endcap'
|
||||
utils.HASH_PATH_PREFIX = 'startcap'
|
||||
|
||||
def test_normalize_timestamp(self):
|
||||
# Test swift.common.utils.normalize_timestamp
|
||||
self.assertEquals(utils.normalize_timestamp('1253327593.48174'),
|
||||
"1253327593.48174")
|
||||
self.assertEquals(utils.normalize_timestamp(1253327593.48174),
|
||||
"1253327593.48174")
|
||||
self.assertEquals(utils.normalize_timestamp('1253327593.48'),
|
||||
"1253327593.48000")
|
||||
self.assertEquals(utils.normalize_timestamp(1253327593.48),
|
||||
"1253327593.48000")
|
||||
self.assertEquals(utils.normalize_timestamp('253327593.48'),
|
||||
"0253327593.48000")
|
||||
self.assertEquals(utils.normalize_timestamp(253327593.48),
|
||||
"0253327593.48000")
|
||||
self.assertEquals(utils.normalize_timestamp('1253327593'),
|
||||
"1253327593.00000")
|
||||
self.assertEquals(utils.normalize_timestamp(1253327593),
|
||||
"1253327593.00000")
|
||||
self.assertRaises(ValueError, utils.normalize_timestamp, '')
|
||||
self.assertRaises(ValueError, utils.normalize_timestamp, 'abc')
|
||||
|
||||
def test_backwards(self):
|
||||
# Test swift.common.utils.backward
|
||||
|
||||
@ -224,6 +249,36 @@ class TestUtils(unittest.TestCase):
|
||||
except ValueError as err:
|
||||
self.assertEquals(str(err), 'Invalid path: o%0An%20e')
|
||||
|
||||
def test_validate_device_partition(self):
|
||||
# Test swift.common.utils.validate_device_partition
|
||||
utils.validate_device_partition('foo', 'bar')
|
||||
self.assertRaises(ValueError,
|
||||
utils.validate_device_partition, '', '')
|
||||
self.assertRaises(ValueError,
|
||||
utils.validate_device_partition, '', 'foo')
|
||||
self.assertRaises(ValueError,
|
||||
utils.validate_device_partition, 'foo', '')
|
||||
self.assertRaises(ValueError,
|
||||
utils.validate_device_partition, 'foo/bar', 'foo')
|
||||
self.assertRaises(ValueError,
|
||||
utils.validate_device_partition, 'foo', 'foo/bar')
|
||||
self.assertRaises(ValueError,
|
||||
utils.validate_device_partition, '.', 'foo')
|
||||
self.assertRaises(ValueError,
|
||||
utils.validate_device_partition, '..', 'foo')
|
||||
self.assertRaises(ValueError,
|
||||
utils.validate_device_partition, 'foo', '.')
|
||||
self.assertRaises(ValueError,
|
||||
utils.validate_device_partition, 'foo', '..')
|
||||
try:
|
||||
utils.validate_device_partition('o\nn e', 'foo')
|
||||
except ValueError as err:
|
||||
self.assertEquals(str(err), 'Invalid device: o%0An%20e')
|
||||
try:
|
||||
utils.validate_device_partition('foo', 'o\nn e')
|
||||
except ValueError as err:
|
||||
self.assertEquals(str(err), 'Invalid partition: o%0An%20e')
|
||||
|
||||
def test_NullLogger(self):
|
||||
# Test swift.common.utils.NullLogger
|
||||
sio = StringIO()
|
||||
@ -583,6 +638,10 @@ class TestUtils(unittest.TestCase):
|
||||
logger.logger.removeHandler(handler)
|
||||
reset_loggers()
|
||||
|
||||
def test_storage_directory(self):
|
||||
self.assertEquals(utils.storage_directory('objects', '1', 'ABCDEF'),
|
||||
'objects/1/DEF/ABCDEF')
|
||||
|
||||
def test_whataremyips(self):
|
||||
myips = utils.whataremyips()
|
||||
self.assert_(len(myips) > 1)
|
||||
@ -618,6 +677,30 @@ class TestUtils(unittest.TestCase):
|
||||
self.assertEquals(len(myips), 1)
|
||||
self.assertEquals(myips[0], test_ipv6_address)
|
||||
|
||||
def test_hash_path(self):
|
||||
_prefix = utils.HASH_PATH_PREFIX
|
||||
utils.HASH_PATH_PREFIX = ''
|
||||
# Yes, these tests are deliberately very fragile. We want to make sure
|
||||
# that if someones changes the results hash_path produces, they know it
|
||||
try:
|
||||
self.assertEquals(utils.hash_path('a'),
|
||||
'1c84525acb02107ea475dcd3d09c2c58')
|
||||
self.assertEquals(utils.hash_path('a', 'c'),
|
||||
'33379ecb053aa5c9e356c68997cbb59e')
|
||||
self.assertEquals(utils.hash_path('a', 'c', 'o'),
|
||||
'06fbf0b514e5199dfc4e00f42eb5ea83')
|
||||
self.assertEquals(utils.hash_path('a', 'c', 'o', raw_digest=False),
|
||||
'06fbf0b514e5199dfc4e00f42eb5ea83')
|
||||
self.assertEquals(utils.hash_path('a', 'c', 'o', raw_digest=True),
|
||||
'\x06\xfb\xf0\xb5\x14\xe5\x19\x9d\xfcN'
|
||||
'\x00\xf4.\xb5\xea\x83')
|
||||
self.assertRaises(ValueError, utils.hash_path, 'a', object='o')
|
||||
utils.HASH_PATH_PREFIX = 'abcdef'
|
||||
self.assertEquals(utils.hash_path('a', 'c', 'o', raw_digest=False),
|
||||
'363f9b535bfb7d17a43a46a358afca0e')
|
||||
finally:
|
||||
utils.HASH_PATH_PREFIX = _prefix
|
||||
|
||||
def test_load_libc_function(self):
|
||||
self.assert_(callable(
|
||||
utils.load_libc_function('printf')))
|
||||
@ -2338,5 +2421,26 @@ class TestThreadpool(unittest.TestCase):
|
||||
self.assertTrue(caught)
|
||||
|
||||
|
||||
class TestAuditLocationGenerator(unittest.TestCase):
|
||||
def test_non_dir_contents(self):
|
||||
with temptree([]) as tmpdir:
|
||||
data = os.path.join(tmpdir, "drive", "data")
|
||||
os.makedirs(data)
|
||||
with open(os.path.join(data, "partition1"), "w"):
|
||||
pass
|
||||
partition = os.path.join(data, "partition2")
|
||||
os.makedirs(partition)
|
||||
with open(os.path.join(partition, "suffix1"), "w"):
|
||||
pass
|
||||
suffix = os.path.join(partition, "suffix2")
|
||||
os.makedirs(suffix)
|
||||
with open(os.path.join(suffix, "hash1"), "w"):
|
||||
pass
|
||||
locations = utils.audit_location_generator(
|
||||
tmpdir, "data", mount_check=False
|
||||
)
|
||||
self.assertEqual(list(locations), [])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
@ -22,7 +22,7 @@ from time import sleep, time
|
||||
from uuid import uuid4
|
||||
|
||||
from swift.container.backend import ContainerBroker
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import normalize_timestamp
|
||||
|
||||
|
||||
class TestContainerBroker(unittest.TestCase):
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
import unittest
|
||||
from swift.container import replicator
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import normalize_timestamp
|
||||
|
||||
|
||||
class TestReplicator(unittest.TestCase):
|
||||
|
@ -29,8 +29,7 @@ import simplejson
|
||||
from swift.common.swob import Request, HeaderKeyDict
|
||||
import swift.container
|
||||
from swift.container import server as container_server
|
||||
from swift.common.utils import mkdirs, public, replication
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import normalize_timestamp, mkdirs, public, replication
|
||||
from test.unit import fake_http_connect
|
||||
|
||||
|
||||
|
@ -28,7 +28,7 @@ from swift.container import updater as container_updater
|
||||
from swift.container import server as container_server
|
||||
from swift.container.backend import ContainerBroker
|
||||
from swift.common.ring import RingData
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import normalize_timestamp
|
||||
|
||||
|
||||
class TestContainerUpdater(unittest.TestCase):
|
||||
|
@ -25,8 +25,7 @@ from test.unit import FakeLogger
|
||||
from swift.obj import auditor
|
||||
from swift.obj.diskfile import DiskFile, write_metadata, invalidate_hash
|
||||
from swift.obj.server import DATADIR
|
||||
from swift.common.utils import mkdirs
|
||||
from swift.common.ondisk import hash_path, normalize_timestamp, \
|
||||
from swift.common.utils import hash_path, mkdirs, normalize_timestamp, \
|
||||
storage_directory
|
||||
|
||||
|
||||
|
@ -36,9 +36,8 @@ from eventlet import tpool
|
||||
from test.unit import FakeLogger, mock as unit_mock
|
||||
from test.unit import _setxattr as setxattr
|
||||
from swift.obj import diskfile
|
||||
from swift.common import ondisk
|
||||
from swift.common.utils import mkdirs
|
||||
from swift.common.ondisk import hash_path, normalize_timestamp
|
||||
from swift.common import utils
|
||||
from swift.common.utils import hash_path, mkdirs, normalize_timestamp
|
||||
from swift.common import ring
|
||||
from swift.common.exceptions import DiskFileNotExist, DiskFileDeviceUnavailable
|
||||
|
||||
@ -73,8 +72,8 @@ def _create_test_ring(path):
|
||||
class TestDiskFileModuleMethods(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
ondisk.HASH_PATH_SUFFIX = 'endcap'
|
||||
ondisk.HASH_PATH_PREFIX = ''
|
||||
utils.HASH_PATH_SUFFIX = 'endcap'
|
||||
utils.HASH_PATH_PREFIX = ''
|
||||
# Setup a test ring (stolen from common/test_ring.py)
|
||||
self.testdir = tempfile.mkdtemp()
|
||||
self.devices = os.path.join(self.testdir, 'node')
|
||||
|
@ -29,9 +29,8 @@ from eventlet.green import subprocess
|
||||
from eventlet import Timeout, tpool
|
||||
|
||||
from test.unit import FakeLogger
|
||||
from swift.common.utils import mkdirs
|
||||
from swift.common import ondisk
|
||||
from swift.common.ondisk import hash_path, normalize_timestamp
|
||||
from swift.common import utils
|
||||
from swift.common.utils import hash_path, mkdirs, normalize_timestamp
|
||||
from swift.common import ring
|
||||
from swift.obj import diskfile, replicator as object_replicator
|
||||
|
||||
@ -138,8 +137,8 @@ def _create_test_ring(path):
|
||||
class TestObjectReplicator(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
ondisk.HASH_PATH_SUFFIX = 'endcap'
|
||||
ondisk.HASH_PATH_PREFIX = ''
|
||||
utils.HASH_PATH_SUFFIX = 'endcap'
|
||||
utils.HASH_PATH_PREFIX = ''
|
||||
# Setup a test ring (stolen from common/test_ring.py)
|
||||
self.testdir = tempfile.mkdtemp()
|
||||
self.devices = os.path.join(self.testdir, 'node')
|
||||
|
@ -32,10 +32,9 @@ from test.unit import FakeLogger
|
||||
from test.unit import connect_tcp, readuntil2crlfs
|
||||
from swift.obj import server as object_server
|
||||
from swift.obj import diskfile
|
||||
from swift.common.utils import mkdirs, NullLogger, public, replication
|
||||
from swift.common.ondisk import hash_path, normalize_timestamp, \
|
||||
storage_directory
|
||||
from swift.common import ondisk
|
||||
from swift.common import utils
|
||||
from swift.common.utils import hash_path, mkdirs, normalize_timestamp, \
|
||||
NullLogger, storage_directory, public, replication
|
||||
from swift.common import constraints
|
||||
from eventlet import tpool
|
||||
from swift.common.swob import Request, HeaderKeyDict
|
||||
@ -46,8 +45,8 @@ class TestObjectController(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
"""Set up for testing swift.object.server.ObjectController"""
|
||||
ondisk.HASH_PATH_SUFFIX = 'endcap'
|
||||
ondisk.HASH_PATH_PREFIX = 'startcap'
|
||||
utils.HASH_PATH_SUFFIX = 'endcap'
|
||||
utils.HASH_PATH_PREFIX = 'startcap'
|
||||
self.testdir = \
|
||||
os.path.join(mkdtemp(), 'tmp_test_object_server_ObjectController')
|
||||
mkdirs(os.path.join(self.testdir, 'sda1', 'tmp'))
|
||||
@ -1905,8 +1904,8 @@ class TestObjectController(unittest.TestCase):
|
||||
'x-trans-id': '-'})})
|
||||
|
||||
def test_async_update_saves_on_exception(self):
|
||||
_prefix = ondisk.HASH_PATH_PREFIX
|
||||
ondisk.HASH_PATH_PREFIX = ''
|
||||
_prefix = utils.HASH_PATH_PREFIX
|
||||
utils.HASH_PATH_PREFIX = ''
|
||||
|
||||
def fake_http_connect(*args):
|
||||
raise Exception('test')
|
||||
@ -1919,7 +1918,7 @@ class TestObjectController(unittest.TestCase):
|
||||
{'x-timestamp': '1', 'x-out': 'set'}, 'sda1')
|
||||
finally:
|
||||
object_server.http_connect = orig_http_connect
|
||||
ondisk.HASH_PATH_PREFIX = _prefix
|
||||
utils.HASH_PATH_PREFIX = _prefix
|
||||
self.assertEquals(
|
||||
pickle.load(open(os.path.join(
|
||||
self.testdir, 'sda1', 'async_pending', 'a83',
|
||||
@ -1929,8 +1928,8 @@ class TestObjectController(unittest.TestCase):
|
||||
'account': 'a', 'container': 'c', 'obj': 'o', 'op': 'PUT'})
|
||||
|
||||
def test_async_update_saves_on_non_2xx(self):
|
||||
_prefix = ondisk.HASH_PATH_PREFIX
|
||||
ondisk.HASH_PATH_PREFIX = ''
|
||||
_prefix = utils.HASH_PATH_PREFIX
|
||||
utils.HASH_PATH_PREFIX = ''
|
||||
|
||||
def fake_http_connect(status):
|
||||
|
||||
@ -1964,7 +1963,7 @@ class TestObjectController(unittest.TestCase):
|
||||
'op': 'PUT'})
|
||||
finally:
|
||||
object_server.http_connect = orig_http_connect
|
||||
ondisk.HASH_PATH_PREFIX = _prefix
|
||||
utils.HASH_PATH_PREFIX = _prefix
|
||||
|
||||
def test_async_update_does_not_save_on_2xx(self):
|
||||
|
||||
|
@ -27,17 +27,17 @@ from eventlet import spawn, Timeout, listen
|
||||
from swift.obj import updater as object_updater, server as object_server
|
||||
from swift.obj.server import ASYNCDIR
|
||||
from swift.common.ring import RingData
|
||||
from swift.common.utils import mkdirs, write_pickle
|
||||
from swift.common import ondisk
|
||||
from swift.common.ondisk import hash_path, normalize_timestamp
|
||||
from swift.common import utils
|
||||
from swift.common.utils import hash_path, normalize_timestamp, mkdirs, \
|
||||
write_pickle
|
||||
from test.unit import FakeLogger
|
||||
|
||||
|
||||
class TestObjectUpdater(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
ondisk.HASH_PATH_SUFFIX = 'endcap'
|
||||
ondisk.HASH_PATH_PREFIX = ''
|
||||
utils.HASH_PATH_SUFFIX = 'endcap'
|
||||
utils.HASH_PATH_PREFIX = ''
|
||||
self.testdir = os.path.join(os.path.dirname(__file__),
|
||||
'object_updater')
|
||||
rmtree(self.testdir, ignore_errors=1)
|
||||
|
@ -47,9 +47,7 @@ from swift.common.constraints import MAX_META_NAME_LENGTH, \
|
||||
MAX_META_VALUE_LENGTH, MAX_META_COUNT, MAX_META_OVERALL_SIZE, \
|
||||
MAX_FILE_SIZE, MAX_ACCOUNT_NAME_LENGTH, MAX_CONTAINER_NAME_LENGTH
|
||||
from swift.common import utils
|
||||
from swift.common.utils import mkdirs, NullLogger
|
||||
from swift.common import ondisk
|
||||
from swift.common.ondisk import normalize_timestamp
|
||||
from swift.common.utils import mkdirs, normalize_timestamp, NullLogger
|
||||
from swift.common.wsgi import monkey_patch_mimetools
|
||||
from swift.proxy.controllers.obj import SegmentedIterable
|
||||
from swift.proxy.controllers.base import get_container_memcache_key, \
|
||||
@ -75,7 +73,7 @@ def request_init(self, *args, **kwargs):
|
||||
|
||||
|
||||
def setup():
|
||||
ondisk.HASH_PATH_SUFFIX = 'endcap'
|
||||
utils.HASH_PATH_SUFFIX = 'endcap'
|
||||
global _testdir, _test_servers, _test_sockets, \
|
||||
_orig_container_listing_limit, _test_coros, _orig_SysLogHandler
|
||||
_orig_SysLogHandler = utils.SysLogHandler
|
||||
|
Loading…
Reference in New Issue
Block a user