2013-09-20 01:00:54 +08:00
|
|
|
# Copyright (c) 2011 OpenStack Foundation
|
2011-10-26 21:42:24 +00:00
|
|
|
#
|
|
|
|
# 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.
|
|
|
|
|
2013-04-15 22:12:23 +00:00
|
|
|
import urllib
|
2011-10-26 21:42:24 +00:00
|
|
|
from time import time
|
|
|
|
from unittest import main, TestCase
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
from test.unit import FakeLogger
|
2013-05-01 21:11:25 +00:00
|
|
|
from copy import deepcopy
|
2011-10-26 21:42:24 +00:00
|
|
|
|
2013-04-15 22:12:23 +00:00
|
|
|
import mock
|
|
|
|
|
2012-05-04 18:07:22 +00:00
|
|
|
from swift.common import internal_client
|
2011-10-26 21:42:24 +00:00
|
|
|
from swift.obj import expirer
|
|
|
|
|
|
|
|
|
|
|
|
def not_random():
|
|
|
|
return 0.5
|
|
|
|
|
|
|
|
|
|
|
|
last_not_sleep = 0
|
|
|
|
|
|
|
|
|
|
|
|
def not_sleep(seconds):
|
|
|
|
global last_not_sleep
|
|
|
|
last_not_sleep = seconds
|
|
|
|
|
|
|
|
|
|
|
|
class TestObjectExpirer(TestCase):
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
maxDiff = None
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
def setUp(self):
|
2012-05-04 18:07:22 +00:00
|
|
|
global not_sleep
|
2011-10-26 21:42:24 +00:00
|
|
|
|
2012-05-04 18:07:22 +00:00
|
|
|
self.old_loadapp = internal_client.loadapp
|
|
|
|
self.old_sleep = internal_client.sleep
|
|
|
|
|
|
|
|
internal_client.loadapp = lambda x: None
|
|
|
|
internal_client.sleep = not_sleep
|
|
|
|
|
|
|
|
def teardown(self):
|
|
|
|
internal_client.sleep = self.old_sleep
|
|
|
|
internal_client.loadapp = self.loadapp
|
2011-10-26 21:42:24 +00:00
|
|
|
|
2013-05-01 21:11:25 +00:00
|
|
|
def test_get_process_values_from_kwargs(self):
|
|
|
|
x = expirer.ObjectExpirer({})
|
|
|
|
vals = {
|
|
|
|
'processes': 5,
|
|
|
|
'process': 1,
|
|
|
|
}
|
|
|
|
self.assertEqual((5, 1), x.get_process_values(vals))
|
|
|
|
|
|
|
|
def test_get_process_values_from_config(self):
|
|
|
|
vals = {
|
|
|
|
'processes': 5,
|
|
|
|
'process': 1,
|
|
|
|
}
|
|
|
|
x = expirer.ObjectExpirer(vals)
|
|
|
|
self.assertEqual((5, 1), x.get_process_values({}))
|
|
|
|
|
|
|
|
def test_get_process_values_negative_process(self):
|
|
|
|
vals = {
|
|
|
|
'processes': 5,
|
|
|
|
'process': -1,
|
|
|
|
}
|
|
|
|
# from config
|
|
|
|
x = expirer.ObjectExpirer(vals)
|
|
|
|
self.assertRaises(ValueError, x.get_process_values, {})
|
|
|
|
# from kwargs
|
|
|
|
x = expirer.ObjectExpirer({})
|
|
|
|
self.assertRaises(ValueError, x.get_process_values, vals)
|
|
|
|
|
|
|
|
def test_get_process_values_negative_processes(self):
|
|
|
|
vals = {
|
|
|
|
'processes': -5,
|
|
|
|
'process': 1,
|
|
|
|
}
|
|
|
|
# from config
|
|
|
|
x = expirer.ObjectExpirer(vals)
|
|
|
|
self.assertRaises(ValueError, x.get_process_values, {})
|
|
|
|
# from kwargs
|
|
|
|
x = expirer.ObjectExpirer({})
|
|
|
|
self.assertRaises(ValueError, x.get_process_values, vals)
|
|
|
|
|
|
|
|
def test_get_process_values_process_greater_than_processes(self):
|
|
|
|
vals = {
|
|
|
|
'processes': 5,
|
|
|
|
'process': 7,
|
|
|
|
}
|
|
|
|
# from config
|
|
|
|
x = expirer.ObjectExpirer(vals)
|
|
|
|
self.assertRaises(ValueError, x.get_process_values, {})
|
|
|
|
# from kwargs
|
|
|
|
x = expirer.ObjectExpirer({})
|
|
|
|
self.assertRaises(ValueError, x.get_process_values, vals)
|
|
|
|
|
|
|
|
def test_init_concurrency_too_small(self):
|
|
|
|
conf = {
|
|
|
|
'concurrency': 0,
|
|
|
|
}
|
|
|
|
self.assertRaises(ValueError, expirer.ObjectExpirer, conf)
|
|
|
|
conf = {
|
|
|
|
'concurrency': -1,
|
|
|
|
}
|
|
|
|
self.assertRaises(ValueError, expirer.ObjectExpirer, conf)
|
|
|
|
|
|
|
|
def test_process_based_concurrency(self):
|
2013-08-31 23:42:43 -04:00
|
|
|
|
2013-05-01 21:11:25 +00:00
|
|
|
class ObjectExpirer(expirer.ObjectExpirer):
|
2013-08-31 23:42:43 -04:00
|
|
|
|
2013-05-01 21:11:25 +00:00
|
|
|
def __init__(self, conf):
|
|
|
|
super(ObjectExpirer, self).__init__(conf)
|
|
|
|
self.processes = 3
|
|
|
|
self.deleted_objects = {}
|
|
|
|
|
|
|
|
def delete_object(self, actual_obj, timestamp, container, obj):
|
2013-08-31 22:36:58 -04:00
|
|
|
if container not in self.deleted_objects:
|
2013-05-01 21:11:25 +00:00
|
|
|
self.deleted_objects[container] = set()
|
|
|
|
self.deleted_objects[container].add(obj)
|
|
|
|
|
|
|
|
class InternalClient(object):
|
2013-08-31 23:42:43 -04:00
|
|
|
|
2013-05-01 21:11:25 +00:00
|
|
|
def __init__(self, containers):
|
|
|
|
self.containers = containers
|
|
|
|
|
|
|
|
def get_account_info(self, *a, **kw):
|
|
|
|
return len(self.containers.keys()), \
|
|
|
|
sum([len(self.containers[x]) for x in self.containers])
|
|
|
|
|
|
|
|
def iter_containers(self, *a, **kw):
|
|
|
|
return [{'name': x} for x in self.containers.keys()]
|
|
|
|
|
|
|
|
def iter_objects(self, account, container):
|
|
|
|
return [{'name': x} for x in self.containers[container]]
|
|
|
|
|
|
|
|
def delete_container(*a, **kw):
|
|
|
|
pass
|
|
|
|
|
|
|
|
containers = {
|
|
|
|
0: set('1-one 2-two 3-three'.split()),
|
|
|
|
1: set('2-two 3-three 4-four'.split()),
|
|
|
|
2: set('5-five 6-six'.split()),
|
|
|
|
3: set('7-seven'.split()),
|
|
|
|
}
|
|
|
|
x = ObjectExpirer({})
|
|
|
|
x.swift = InternalClient(containers)
|
|
|
|
|
|
|
|
deleted_objects = {}
|
2013-12-10 16:16:44 -08:00
|
|
|
for i in xrange(3):
|
2013-05-01 21:11:25 +00:00
|
|
|
x.process = i
|
|
|
|
x.run_once()
|
|
|
|
self.assertNotEqual(deleted_objects, x.deleted_objects)
|
|
|
|
deleted_objects = deepcopy(x.deleted_objects)
|
|
|
|
self.assertEqual(containers, deleted_objects)
|
|
|
|
|
|
|
|
def test_delete_object(self):
|
|
|
|
class InternalClient(object):
|
|
|
|
def __init__(self, test, account, container, obj):
|
|
|
|
self.test = test
|
|
|
|
self.account = account
|
|
|
|
self.container = container
|
|
|
|
self.obj = obj
|
|
|
|
self.delete_object_called = False
|
|
|
|
|
|
|
|
def delete_object(self, account, container, obj):
|
|
|
|
self.test.assertEqual(self.account, account)
|
|
|
|
self.test.assertEqual(self.container, container)
|
|
|
|
self.test.assertEqual(self.obj, obj)
|
|
|
|
self.delete_object_called = True
|
|
|
|
|
|
|
|
class DeleteActualObject(object):
|
|
|
|
def __init__(self, test, actual_obj, timestamp):
|
|
|
|
self.test = test
|
|
|
|
self.actual_obj = actual_obj
|
|
|
|
self.timestamp = timestamp
|
|
|
|
self.called = False
|
|
|
|
|
|
|
|
def __call__(self, actual_obj, timestamp):
|
|
|
|
self.test.assertEqual(self.actual_obj, actual_obj)
|
|
|
|
self.test.assertEqual(self.timestamp, timestamp)
|
|
|
|
self.called = True
|
|
|
|
|
|
|
|
container = 'container'
|
|
|
|
obj = 'obj'
|
|
|
|
actual_obj = 'actual_obj'
|
|
|
|
timestamp = 'timestamp'
|
|
|
|
|
|
|
|
x = expirer.ObjectExpirer({})
|
|
|
|
x.logger = FakeLogger()
|
|
|
|
x.swift = \
|
|
|
|
InternalClient(self, x.expiring_objects_account, container, obj)
|
|
|
|
x.delete_actual_object = \
|
|
|
|
DeleteActualObject(self, actual_obj, timestamp)
|
|
|
|
|
|
|
|
x.delete_object(actual_obj, timestamp, container, obj)
|
|
|
|
self.assertTrue(x.swift.delete_object_called)
|
|
|
|
self.assertTrue(x.delete_actual_object.called)
|
|
|
|
|
2011-10-26 21:42:24 +00:00
|
|
|
def test_report(self):
|
|
|
|
x = expirer.ObjectExpirer({})
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
x.logger = FakeLogger()
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
x.report()
|
2013-05-01 21:11:25 +00:00
|
|
|
self.assertEqual(x.logger.log_dict['info'], [])
|
2011-10-26 21:42:24 +00:00
|
|
|
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
x.logger._clear()
|
2011-10-26 21:42:24 +00:00
|
|
|
x.report(final=True)
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
self.assertTrue('completed' in x.logger.log_dict['info'][-1][0][0],
|
|
|
|
x.logger.log_dict['info'])
|
|
|
|
self.assertTrue('so far' not in x.logger.log_dict['info'][-1][0][0],
|
|
|
|
x.logger.log_dict['info'])
|
2011-10-26 21:42:24 +00:00
|
|
|
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
x.logger._clear()
|
2011-10-26 21:42:24 +00:00
|
|
|
x.report_last_time = time() - x.report_interval
|
|
|
|
x.report()
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
self.assertTrue('completed' not in x.logger.log_dict['info'][-1][0][0],
|
|
|
|
x.logger.log_dict['info'])
|
|
|
|
self.assertTrue('so far' in x.logger.log_dict['info'][-1][0][0],
|
|
|
|
x.logger.log_dict['info'])
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
def test_run_once_nothing_to_do(self):
|
|
|
|
x = expirer.ObjectExpirer({})
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
x.logger = FakeLogger()
|
2012-05-04 18:07:22 +00:00
|
|
|
x.swift = 'throw error because a string does not have needed methods'
|
2011-10-26 21:42:24 +00:00
|
|
|
x.run_once()
|
2013-05-01 21:11:25 +00:00
|
|
|
self.assertEqual(x.logger.log_dict['exception'],
|
2013-08-31 23:42:43 -04:00
|
|
|
[(("Unhandled exception",), {},
|
|
|
|
"'str' object has no attribute "
|
|
|
|
"'get_account_info'")])
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
def test_run_once_calls_report(self):
|
2012-05-04 18:07:22 +00:00
|
|
|
class InternalClient(object):
|
|
|
|
def get_account_info(*a, **kw):
|
|
|
|
return 1, 2
|
|
|
|
|
|
|
|
def iter_containers(*a, **kw):
|
|
|
|
return []
|
|
|
|
|
2011-10-26 21:42:24 +00:00
|
|
|
x = expirer.ObjectExpirer({})
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
x.logger = FakeLogger()
|
2012-05-04 18:07:22 +00:00
|
|
|
x.swift = InternalClient()
|
2011-10-26 21:42:24 +00:00
|
|
|
x.run_once()
|
2013-05-01 21:11:25 +00:00
|
|
|
self.assertEqual(
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
x.logger.log_dict['info'],
|
|
|
|
[(('Pass beginning; 1 possible containers; '
|
|
|
|
'2 possible objects',), {}),
|
|
|
|
(('Pass completed in 0s; 0 objects expired',), {})])
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
def test_container_timestamp_break(self):
|
2012-05-04 18:07:22 +00:00
|
|
|
class InternalClient(object):
|
|
|
|
def __init__(self, containers):
|
|
|
|
self.containers = containers
|
2011-10-26 21:42:24 +00:00
|
|
|
|
2012-05-04 18:07:22 +00:00
|
|
|
def get_account_info(*a, **kw):
|
|
|
|
return 1, 2
|
|
|
|
|
|
|
|
def iter_containers(self, *a, **kw):
|
|
|
|
return self.containers
|
|
|
|
|
|
|
|
def iter_objects(*a, **kw):
|
|
|
|
raise Exception('This should not have been called')
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
x = expirer.ObjectExpirer({})
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
x.logger = FakeLogger()
|
2012-05-04 18:07:22 +00:00
|
|
|
x.swift = InternalClient([{'name': str(int(time() + 86400))}])
|
2011-10-26 21:42:24 +00:00
|
|
|
x.run_once()
|
2012-05-14 18:01:48 -05:00
|
|
|
for exccall in x.logger.log_dict['exception']:
|
|
|
|
self.assertTrue(
|
|
|
|
'This should not have been called' not in exccall[0][0])
|
2013-05-01 21:11:25 +00:00
|
|
|
self.assertEqual(
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
x.logger.log_dict['info'],
|
|
|
|
[(('Pass beginning; 1 possible containers; '
|
|
|
|
'2 possible objects',), {}),
|
|
|
|
(('Pass completed in 0s; 0 objects expired',), {})])
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
# Reverse test to be sure it still would blow up the way expected.
|
|
|
|
x = expirer.ObjectExpirer({})
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
x.logger = FakeLogger()
|
2012-05-04 18:07:22 +00:00
|
|
|
x.swift = InternalClient([{'name': str(int(time() - 86400))}])
|
2011-10-26 21:42:24 +00:00
|
|
|
x.run_once()
|
2013-08-31 23:42:43 -04:00
|
|
|
self.assertEqual(
|
|
|
|
x.logger.log_dict['exception'],
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
[(('Unhandled exception',), {},
|
|
|
|
str(Exception('This should not have been called')))])
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
def test_object_timestamp_break(self):
|
2012-05-04 18:07:22 +00:00
|
|
|
class InternalClient(object):
|
|
|
|
def __init__(self, containers, objects):
|
|
|
|
self.containers = containers
|
|
|
|
self.objects = objects
|
|
|
|
|
|
|
|
def get_account_info(*a, **kw):
|
|
|
|
return 1, 2
|
|
|
|
|
|
|
|
def iter_containers(self, *a, **kw):
|
|
|
|
return self.containers
|
2011-10-26 21:42:24 +00:00
|
|
|
|
2012-05-04 18:07:22 +00:00
|
|
|
def delete_container(*a, **kw):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def iter_objects(self, *a, **kw):
|
|
|
|
return self.objects
|
|
|
|
|
|
|
|
def should_not_be_called(*a, **kw):
|
2011-10-26 21:42:24 +00:00
|
|
|
raise Exception('This should not have been called')
|
|
|
|
|
|
|
|
x = expirer.ObjectExpirer({})
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
x.logger = FakeLogger()
|
2013-08-31 23:42:43 -04:00
|
|
|
x.swift = InternalClient(
|
|
|
|
[{'name': str(int(time() - 86400))}],
|
2012-05-04 18:07:22 +00:00
|
|
|
[{'name': '%d-actual-obj' % int(time() + 86400)}])
|
2011-10-26 21:42:24 +00:00
|
|
|
x.run_once()
|
2012-05-14 18:01:48 -05:00
|
|
|
for exccall in x.logger.log_dict['exception']:
|
|
|
|
self.assertTrue(
|
|
|
|
'This should not have been called' not in exccall[0][0])
|
2013-08-31 23:42:43 -04:00
|
|
|
self.assertEqual(
|
|
|
|
x.logger.log_dict['info'],
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
[(('Pass beginning; 1 possible containers; '
|
|
|
|
'2 possible objects',), {}),
|
|
|
|
(('Pass completed in 0s; 0 objects expired',), {})])
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
# Reverse test to be sure it still would blow up the way expected.
|
|
|
|
x = expirer.ObjectExpirer({})
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
x.logger = FakeLogger()
|
2011-10-26 21:42:24 +00:00
|
|
|
ts = int(time() - 86400)
|
2013-08-31 23:42:43 -04:00
|
|
|
x.swift = InternalClient(
|
|
|
|
[{'name': str(int(time() - 86400))}],
|
2012-05-04 18:07:22 +00:00
|
|
|
[{'name': '%d-actual-obj' % ts}])
|
|
|
|
x.delete_actual_object = should_not_be_called
|
2011-10-26 21:42:24 +00:00
|
|
|
x.run_once()
|
2012-05-14 18:01:48 -05:00
|
|
|
excswhiledeleting = []
|
|
|
|
for exccall in x.logger.log_dict['exception']:
|
|
|
|
if exccall[0][0].startswith('Exception while deleting '):
|
|
|
|
excswhiledeleting.append(exccall[0][0])
|
2013-08-31 23:42:43 -04:00
|
|
|
self.assertEqual(
|
|
|
|
excswhiledeleting,
|
2012-05-14 18:01:48 -05:00
|
|
|
['Exception while deleting object %d %d-actual-obj '
|
|
|
|
'This should not have been called' % (ts, ts)])
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
def test_failed_delete_keeps_entry(self):
|
2012-05-04 18:07:22 +00:00
|
|
|
class InternalClient(object):
|
|
|
|
def __init__(self, containers, objects):
|
|
|
|
self.containers = containers
|
|
|
|
self.objects = objects
|
|
|
|
|
|
|
|
def get_account_info(*a, **kw):
|
|
|
|
return 1, 2
|
|
|
|
|
|
|
|
def iter_containers(self, *a, **kw):
|
|
|
|
return self.containers
|
|
|
|
|
|
|
|
def delete_container(*a, **kw):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def delete_object(*a, **kw):
|
|
|
|
raise Exception('This should not have been called')
|
|
|
|
|
|
|
|
def iter_objects(self, *a, **kw):
|
|
|
|
return self.objects
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
def deliberately_blow_up(actual_obj, timestamp):
|
|
|
|
raise Exception('failed to delete actual object')
|
|
|
|
|
|
|
|
def should_not_get_called(container, obj):
|
|
|
|
raise Exception('This should not have been called')
|
|
|
|
|
|
|
|
x = expirer.ObjectExpirer({})
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
x.logger = FakeLogger()
|
2011-10-26 21:42:24 +00:00
|
|
|
x.iter_containers = lambda: [str(int(time() - 86400))]
|
|
|
|
ts = int(time() - 86400)
|
|
|
|
x.delete_actual_object = deliberately_blow_up
|
2013-08-31 23:42:43 -04:00
|
|
|
x.swift = InternalClient(
|
|
|
|
[{'name': str(int(time() - 86400))}],
|
2012-05-04 18:07:22 +00:00
|
|
|
[{'name': '%d-actual-obj' % ts}])
|
2011-10-26 21:42:24 +00:00
|
|
|
x.run_once()
|
2012-05-14 18:01:48 -05:00
|
|
|
excswhiledeleting = []
|
|
|
|
for exccall in x.logger.log_dict['exception']:
|
|
|
|
if exccall[0][0].startswith('Exception while deleting '):
|
|
|
|
excswhiledeleting.append(exccall[0][0])
|
2013-08-31 23:42:43 -04:00
|
|
|
self.assertEqual(
|
|
|
|
excswhiledeleting,
|
2012-05-14 18:01:48 -05:00
|
|
|
['Exception while deleting object %d %d-actual-obj '
|
|
|
|
'failed to delete actual object' % (ts, ts)])
|
2013-08-31 23:42:43 -04:00
|
|
|
self.assertEqual(
|
|
|
|
x.logger.log_dict['info'],
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
[(('Pass beginning; 1 possible containers; '
|
|
|
|
'2 possible objects',), {}),
|
|
|
|
(('Pass completed in 0s; 0 objects expired',), {})])
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
# Reverse test to be sure it still would blow up the way expected.
|
|
|
|
x = expirer.ObjectExpirer({})
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
x.logger = FakeLogger()
|
2011-10-26 21:42:24 +00:00
|
|
|
ts = int(time() - 86400)
|
|
|
|
x.delete_actual_object = lambda o, t: None
|
2013-08-31 23:42:43 -04:00
|
|
|
x.swift = InternalClient(
|
|
|
|
[{'name': str(int(time() - 86400))}],
|
2012-05-04 18:07:22 +00:00
|
|
|
[{'name': '%d-actual-obj' % ts}])
|
2011-10-26 21:42:24 +00:00
|
|
|
x.run_once()
|
2012-05-14 18:01:48 -05:00
|
|
|
excswhiledeleting = []
|
|
|
|
for exccall in x.logger.log_dict['exception']:
|
|
|
|
if exccall[0][0].startswith('Exception while deleting '):
|
|
|
|
excswhiledeleting.append(exccall[0][0])
|
2013-08-31 23:42:43 -04:00
|
|
|
self.assertEqual(
|
|
|
|
excswhiledeleting,
|
2012-05-14 18:01:48 -05:00
|
|
|
['Exception while deleting object %d %d-actual-obj This should '
|
|
|
|
'not have been called' % (ts, ts)])
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
def test_success_gets_counted(self):
|
2012-05-04 18:07:22 +00:00
|
|
|
class InternalClient(object):
|
|
|
|
def __init__(self, containers, objects):
|
|
|
|
self.containers = containers
|
|
|
|
self.objects = objects
|
|
|
|
|
|
|
|
def get_account_info(*a, **kw):
|
|
|
|
return 1, 2
|
|
|
|
|
|
|
|
def iter_containers(self, *a, **kw):
|
|
|
|
return self.containers
|
|
|
|
|
|
|
|
def delete_container(*a, **kw):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def delete_object(*a, **kw):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def iter_objects(self, *a, **kw):
|
|
|
|
return self.objects
|
|
|
|
|
2011-10-26 21:42:24 +00:00
|
|
|
x = expirer.ObjectExpirer({})
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
x.logger = FakeLogger()
|
2011-10-26 21:42:24 +00:00
|
|
|
x.delete_actual_object = lambda o, t: None
|
2013-05-01 21:11:25 +00:00
|
|
|
self.assertEqual(x.report_objects, 0)
|
2013-08-31 23:42:43 -04:00
|
|
|
x.swift = InternalClient(
|
|
|
|
[{'name': str(int(time() - 86400))}],
|
2012-05-04 18:07:22 +00:00
|
|
|
[{'name': '%d-actual-obj' % int(time() - 86400)}])
|
2011-10-26 21:42:24 +00:00
|
|
|
x.run_once()
|
2013-05-01 21:11:25 +00:00
|
|
|
self.assertEqual(x.report_objects, 1)
|
2013-08-31 23:42:43 -04:00
|
|
|
self.assertEqual(
|
|
|
|
x.logger.log_dict['info'],
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
[(('Pass beginning; 1 possible containers; '
|
|
|
|
'2 possible objects',), {}),
|
|
|
|
(('Pass completed in 0s; 1 objects expired',), {})])
|
2011-10-26 21:42:24 +00:00
|
|
|
|
2012-11-07 21:49:26 +00:00
|
|
|
def test_delete_actual_object_does_not_get_unicode(self):
|
|
|
|
class InternalClient(object):
|
|
|
|
def __init__(self, containers, objects):
|
|
|
|
self.containers = containers
|
|
|
|
self.objects = objects
|
|
|
|
|
|
|
|
def get_account_info(*a, **kw):
|
|
|
|
return 1, 2
|
|
|
|
|
|
|
|
def iter_containers(self, *a, **kw):
|
|
|
|
return self.containers
|
|
|
|
|
|
|
|
def delete_container(*a, **kw):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def delete_object(*a, **kw):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def iter_objects(self, *a, **kw):
|
|
|
|
return self.objects
|
|
|
|
|
|
|
|
got_unicode = [False]
|
|
|
|
|
|
|
|
def delete_actual_object_test_for_unicode(actual_obj, timestamp):
|
|
|
|
if isinstance(actual_obj, unicode):
|
|
|
|
got_unicode[0] = True
|
|
|
|
|
|
|
|
x = expirer.ObjectExpirer({})
|
|
|
|
x.logger = FakeLogger()
|
|
|
|
x.delete_actual_object = delete_actual_object_test_for_unicode
|
2013-05-01 21:11:25 +00:00
|
|
|
self.assertEqual(x.report_objects, 0)
|
2013-08-31 23:42:43 -04:00
|
|
|
x.swift = InternalClient(
|
|
|
|
[{'name': str(int(time() - 86400))}],
|
2012-11-07 21:49:26 +00:00
|
|
|
[{'name': u'%d-actual-obj' % int(time() - 86400)}])
|
|
|
|
x.run_once()
|
2013-05-01 21:11:25 +00:00
|
|
|
self.assertEqual(x.report_objects, 1)
|
2013-08-31 23:42:43 -04:00
|
|
|
self.assertEqual(
|
|
|
|
x.logger.log_dict['info'],
|
2012-11-07 21:49:26 +00:00
|
|
|
[(('Pass beginning; 1 possible containers; '
|
|
|
|
'2 possible objects',), {}),
|
|
|
|
(('Pass completed in 0s; 1 objects expired',), {})])
|
|
|
|
self.assertFalse(got_unicode[0])
|
|
|
|
|
2011-10-26 21:42:24 +00:00
|
|
|
def test_failed_delete_continues_on(self):
|
2012-05-04 18:07:22 +00:00
|
|
|
class InternalClient(object):
|
|
|
|
def __init__(self, containers, objects):
|
|
|
|
self.containers = containers
|
|
|
|
self.objects = objects
|
|
|
|
|
|
|
|
def get_account_info(*a, **kw):
|
|
|
|
return 1, 2
|
|
|
|
|
|
|
|
def iter_containers(self, *a, **kw):
|
|
|
|
return self.containers
|
|
|
|
|
|
|
|
def delete_container(*a, **kw):
|
|
|
|
raise Exception('failed to delete container')
|
|
|
|
|
|
|
|
def delete_object(*a, **kw):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def iter_objects(self, *a, **kw):
|
|
|
|
return self.objects
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
def fail_delete_actual_object(actual_obj, timestamp):
|
|
|
|
raise Exception('failed to delete actual object')
|
|
|
|
|
|
|
|
x = expirer.ObjectExpirer({})
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
x.logger = FakeLogger()
|
2012-05-04 18:07:22 +00:00
|
|
|
|
2011-10-26 21:42:24 +00:00
|
|
|
cts = int(time() - 86400)
|
|
|
|
ots = int(time() - 86400)
|
2012-05-04 18:07:22 +00:00
|
|
|
|
|
|
|
containers = [
|
|
|
|
{'name': str(cts)},
|
|
|
|
{'name': str(cts + 1)},
|
|
|
|
]
|
|
|
|
|
|
|
|
objects = [
|
|
|
|
{'name': '%d-actual-obj' % ots},
|
|
|
|
{'name': '%d-next-obj' % ots}
|
|
|
|
]
|
|
|
|
|
|
|
|
x.swift = InternalClient(containers, objects)
|
2011-10-26 21:42:24 +00:00
|
|
|
x.delete_actual_object = fail_delete_actual_object
|
|
|
|
x.run_once()
|
2012-05-14 18:01:48 -05:00
|
|
|
excswhiledeleting = []
|
|
|
|
for exccall in x.logger.log_dict['exception']:
|
|
|
|
if exccall[0][0].startswith('Exception while deleting '):
|
|
|
|
excswhiledeleting.append(exccall[0][0])
|
2013-05-01 21:11:25 +00:00
|
|
|
self.assertEqual(sorted(excswhiledeleting), sorted([
|
2012-05-14 18:01:48 -05:00
|
|
|
'Exception while deleting object %d %d-actual-obj failed to '
|
|
|
|
'delete actual object' % (cts, ots),
|
|
|
|
'Exception while deleting object %d %d-next-obj failed to '
|
|
|
|
'delete actual object' % (cts, ots),
|
|
|
|
'Exception while deleting object %d %d-actual-obj failed to '
|
|
|
|
'delete actual object' % (cts + 1, ots),
|
|
|
|
'Exception while deleting object %d %d-next-obj failed to '
|
|
|
|
'delete actual object' % (cts + 1, ots),
|
|
|
|
'Exception while deleting container %d failed to delete '
|
2013-05-01 21:11:25 +00:00
|
|
|
'container' % (cts,),
|
|
|
|
'Exception while deleting container %d failed to delete '
|
|
|
|
'container' % (cts + 1,)]))
|
2013-08-31 23:42:43 -04:00
|
|
|
self.assertEqual(
|
|
|
|
x.logger.log_dict['info'],
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
[(('Pass beginning; 1 possible containers; '
|
|
|
|
'2 possible objects',), {}),
|
|
|
|
(('Pass completed in 0s; 0 objects expired',), {})])
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
def test_run_forever_initial_sleep_random(self):
|
|
|
|
global last_not_sleep
|
|
|
|
|
|
|
|
def raise_system_exit():
|
|
|
|
raise SystemExit('test_run_forever')
|
|
|
|
|
|
|
|
interval = 1234
|
|
|
|
x = expirer.ObjectExpirer({'__file__': 'unit_test',
|
|
|
|
'interval': interval})
|
|
|
|
orig_random = expirer.random
|
|
|
|
orig_sleep = expirer.sleep
|
|
|
|
try:
|
|
|
|
expirer.random = not_random
|
|
|
|
expirer.sleep = not_sleep
|
|
|
|
x.run_once = raise_system_exit
|
|
|
|
x.run_forever()
|
2013-08-28 21:16:08 +02:00
|
|
|
except SystemExit as err:
|
2013-03-26 20:42:26 +00:00
|
|
|
pass
|
2011-10-26 21:42:24 +00:00
|
|
|
finally:
|
|
|
|
expirer.random = orig_random
|
|
|
|
expirer.sleep = orig_sleep
|
2013-05-01 21:11:25 +00:00
|
|
|
self.assertEqual(str(err), 'test_run_forever')
|
|
|
|
self.assertEqual(last_not_sleep, 0.5 * interval)
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
def test_run_forever_catches_usual_exceptions(self):
|
|
|
|
raises = [0]
|
|
|
|
|
|
|
|
def raise_exceptions():
|
|
|
|
raises[0] += 1
|
|
|
|
if raises[0] < 2:
|
|
|
|
raise Exception('exception %d' % raises[0])
|
|
|
|
raise SystemExit('exiting exception %d' % raises[0])
|
|
|
|
|
|
|
|
x = expirer.ObjectExpirer({})
|
Adding StatsD logging to Swift.
Documentation, including a list of metrics reported and their semantics,
is in the Admin Guide in a new section, "Reporting Metrics to StatsD".
An optional "metric prefix" may be configured which will be prepended to
every metric name sent to StatsD.
Here is the rationale for doing a deep integration like this versus only
sending metrics to StatsD in middleware. It's the only way to report
some internal activities of Swift in a real-time manner. So to have one
way of reporting to StatsD and one place/style of configuration, even
some things (like, say, timing of PUT requests into the proxy-server)
which could be logged via middleware are consistently logged the same
way (deep integration via the logger delegate methods).
When log_statsd_host is configured, get_logger() injects a
swift.common.utils.StatsdClient object into the logger as
logger.statsd_client. Then a set of delegate methods on LogAdapter
either pass through to the StatsdClient object or become no-ops. This
allows StatsD logging to look like:
self.logger.increment('some.metric.here')
and do the right thing in all cases and with no messy conditional logic.
I wanted to use the pystatsd module for the StatsD client, but the
version on PyPi is lagging the git repo (and is missing both the prefix
functionality and timing_since() method). So I wrote my
swift.common.utils.StatsdClient. The interface is the same as
pystatsd.Client, but the code was written from scratch. It's pretty
simple, and the tests I added cover it. This also frees Swift from an
optional dependency on the pystatsd module, making this feature easier
to enable.
There's test coverage for the new code and all existing tests continue
to pass.
Refactored out _one_audit_pass() method in swift/account/auditor.py and
swift/container/auditor.py.
Fixed some misc. PEP8 violations.
Misc test cleanups and refactorings (particularly the way "fake logging"
is handled).
Change-Id: Ie968a9ae8771f59ee7591e2ae11999c44bfe33b2
2012-04-01 16:47:08 -07:00
|
|
|
x.logger = FakeLogger()
|
2011-10-26 21:42:24 +00:00
|
|
|
orig_sleep = expirer.sleep
|
|
|
|
try:
|
|
|
|
expirer.sleep = not_sleep
|
|
|
|
x.run_once = raise_exceptions
|
|
|
|
x.run_forever()
|
2013-08-28 21:16:08 +02:00
|
|
|
except SystemExit as err:
|
2013-03-26 20:42:26 +00:00
|
|
|
pass
|
2011-10-26 21:42:24 +00:00
|
|
|
finally:
|
|
|
|
expirer.sleep = orig_sleep
|
2013-05-01 21:11:25 +00:00
|
|
|
self.assertEqual(str(err), 'exiting exception 2')
|
|
|
|
self.assertEqual(x.logger.log_dict['exception'],
|
2013-08-31 23:42:43 -04:00
|
|
|
[(('Unhandled exception',), {},
|
|
|
|
'exception 1')])
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
def test_delete_actual_object(self):
|
|
|
|
got_env = [None]
|
|
|
|
|
|
|
|
def fake_app(env, start_response):
|
|
|
|
got_env[0] = env
|
|
|
|
start_response('204 No Content', [('Content-Length', '0')])
|
|
|
|
return []
|
|
|
|
|
2012-05-04 18:07:22 +00:00
|
|
|
internal_client.loadapp = lambda x: fake_app
|
|
|
|
|
2011-10-26 21:42:24 +00:00
|
|
|
x = expirer.ObjectExpirer({})
|
|
|
|
ts = '1234'
|
|
|
|
x.delete_actual_object('/path/to/object', ts)
|
2013-05-01 21:11:25 +00:00
|
|
|
self.assertEqual(got_env[0]['HTTP_X_IF_DELETE_AT'], ts)
|
2011-10-26 21:42:24 +00:00
|
|
|
|
2012-11-07 21:49:26 +00:00
|
|
|
def test_delete_actual_object_nourlquoting(self):
|
|
|
|
# delete_actual_object should not do its own url quoting because
|
|
|
|
# internal client's make_request handles that.
|
|
|
|
got_env = [None]
|
|
|
|
|
|
|
|
def fake_app(env, start_response):
|
|
|
|
got_env[0] = env
|
|
|
|
start_response('204 No Content', [('Content-Length', '0')])
|
|
|
|
return []
|
|
|
|
|
|
|
|
internal_client.loadapp = lambda x: fake_app
|
|
|
|
|
|
|
|
x = expirer.ObjectExpirer({})
|
|
|
|
ts = '1234'
|
|
|
|
x.delete_actual_object('/path/to/object name', ts)
|
2013-05-01 21:11:25 +00:00
|
|
|
self.assertEqual(got_env[0]['HTTP_X_IF_DELETE_AT'], ts)
|
|
|
|
self.assertEqual(got_env[0]['PATH_INFO'], '/v1/path/to/object name')
|
2012-11-07 21:49:26 +00:00
|
|
|
|
2011-10-26 21:42:24 +00:00
|
|
|
def test_delete_actual_object_handles_404(self):
|
|
|
|
|
|
|
|
def fake_app(env, start_response):
|
|
|
|
start_response('404 Not Found', [('Content-Length', '0')])
|
|
|
|
return []
|
|
|
|
|
2012-05-04 18:07:22 +00:00
|
|
|
internal_client.loadapp = lambda x: fake_app
|
|
|
|
|
2011-10-26 21:42:24 +00:00
|
|
|
x = expirer.ObjectExpirer({})
|
|
|
|
x.delete_actual_object('/path/to/object', '1234')
|
|
|
|
|
|
|
|
def test_delete_actual_object_handles_412(self):
|
|
|
|
|
|
|
|
def fake_app(env, start_response):
|
|
|
|
start_response('412 Precondition Failed',
|
|
|
|
[('Content-Length', '0')])
|
|
|
|
return []
|
|
|
|
|
2012-05-04 18:07:22 +00:00
|
|
|
internal_client.loadapp = lambda x: fake_app
|
|
|
|
|
2011-10-26 21:42:24 +00:00
|
|
|
x = expirer.ObjectExpirer({})
|
|
|
|
x.delete_actual_object('/path/to/object', '1234')
|
|
|
|
|
|
|
|
def test_delete_actual_object_does_not_handle_odd_stuff(self):
|
|
|
|
|
|
|
|
def fake_app(env, start_response):
|
2013-08-31 23:42:43 -04:00
|
|
|
start_response(
|
|
|
|
'503 Internal Server Error',
|
2012-05-04 18:07:22 +00:00
|
|
|
[('Content-Length', '0')])
|
2011-10-26 21:42:24 +00:00
|
|
|
return []
|
|
|
|
|
2012-05-04 18:07:22 +00:00
|
|
|
internal_client.loadapp = lambda x: fake_app
|
2011-10-26 21:42:24 +00:00
|
|
|
|
|
|
|
x = expirer.ObjectExpirer({})
|
|
|
|
exc = None
|
|
|
|
try:
|
2012-05-04 18:07:22 +00:00
|
|
|
x.delete_actual_object('/path/to/object', '1234')
|
2013-08-28 21:16:08 +02:00
|
|
|
except Exception as err:
|
2011-10-26 21:42:24 +00:00
|
|
|
exc = err
|
|
|
|
finally:
|
2012-05-04 18:07:22 +00:00
|
|
|
pass
|
2013-05-01 21:11:25 +00:00
|
|
|
self.assertEqual(503, exc.resp.status_int)
|
2011-10-26 21:42:24 +00:00
|
|
|
|
2013-04-15 22:12:23 +00:00
|
|
|
def test_delete_actual_object_quotes(self):
|
|
|
|
name = 'this name should get quoted'
|
|
|
|
timestamp = '1366063156.863045'
|
|
|
|
x = expirer.ObjectExpirer({})
|
|
|
|
x.swift.make_request = mock.MagicMock()
|
|
|
|
x.delete_actual_object(name, timestamp)
|
|
|
|
x.swift.make_request.assert_called_once()
|
2013-05-01 21:11:25 +00:00
|
|
|
self.assertEqual(x.swift.make_request.call_args[0][1],
|
2013-08-31 23:42:43 -04:00
|
|
|
'/v1/' + urllib.quote(name))
|
2013-04-15 22:12:23 +00:00
|
|
|
|
|
|
|
|
2011-10-26 21:42:24 +00:00
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|