summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Smith <dansmith@redhat.com>2020-08-20 08:10:41 -0700
committerDan Smith <dansmith@redhat.com>2020-08-26 07:38:55 -0700
commit4dc622dc91cf161ebbb1f3ab3a8ffa3bcc7e1a43 (patch)
tree66df750aa737f128d5b2943b674512ffbb7125a6
parent982313615a368e5caa2e12fce781ea528483512f (diff)
downloadglance_store-4dc622dc91cf161ebbb1f3ab3a8ffa3bcc7e1a43.tar.gz
Bring FakeData utility over from glance
This brings over the small-footprint FakeData generator from glance and refactors the rbd resize tests to use it instead of a static string. Change-Id: I842578ca933294e4340ba080be488999e7910727
-rw-r--r--glance_store/tests/unit/test_rbd_store.py4
-rw-r--r--glance_store/tests/unit/test_test_utils.py38
-rw-r--r--glance_store/tests/utils.py42
3 files changed, 82 insertions, 2 deletions
diff --git a/glance_store/tests/unit/test_rbd_store.py b/glance_store/tests/unit/test_rbd_store.py
index 4f44bc2..fe6a2ac 100644
--- a/glance_store/tests/unit/test_rbd_store.py
+++ b/glance_store/tests/unit/test_rbd_store.py
@@ -24,6 +24,7 @@ from glance_store import exceptions
from glance_store import location as g_location
from glance_store.tests import base
from glance_store.tests.unit import test_store_capabilities
+from glance_store.tests import utils as test_utils
class TestException(Exception):
@@ -189,9 +190,8 @@ class TestReSize(base.StoreBaseTest,
def test_add_w_image_size_zero_less_resizes(self):
"""Assert that correct size is returned even though 0 was provided."""
- # TODO(jokke): use the FakeData iterator once it exists.
data_len = 57 * units.Mi
- data_iter = six.BytesIO(b'*' * data_len)
+ data_iter = test_utils.FakeData(data_len)
with mock.patch.object(rbd_store.rbd.Image, 'resize') as resize:
with mock.patch.object(rbd_store.rbd.Image, 'write') as write:
ret = self.store.add(
diff --git a/glance_store/tests/unit/test_test_utils.py b/glance_store/tests/unit/test_test_utils.py
new file mode 100644
index 0000000..81495a2
--- /dev/null
+++ b/glance_store/tests/unit/test_test_utils.py
@@ -0,0 +1,38 @@
+# Copyright 2020 Red Hat, Inc
+# All Rights Reserved.
+#
+# 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.
+
+from glance_store.tests import base
+from glance_store.tests import utils as test_utils
+
+
+class TestFakeData(base.StoreBaseTest):
+ def test_via_read(self):
+ fd = test_utils.FakeData(1024)
+ data = []
+ for i in range(0, 1025, 256):
+ chunk = fd.read(256)
+ data.append(chunk)
+ if not chunk:
+ break
+
+ self.assertEqual(5, len(data))
+ # Make sure we got a zero-length final read
+ self.assertEqual(b'', data[-1])
+ # Make sure we only got 1024 bytes
+ self.assertEqual(1024, len(b''.join(data)))
+
+ def test_via_iter(self):
+ data = b''.join(list(test_utils.FakeData(1024)))
+ self.assertEqual(1024, len(data))
diff --git a/glance_store/tests/utils.py b/glance_store/tests/utils.py
index 2f3a90f..5180bdd 100644
--- a/glance_store/tests/utils.py
+++ b/glance_store/tests/utils.py
@@ -16,6 +16,7 @@
import six
from six.moves import urllib
+from oslo_utils import units
import requests
@@ -73,3 +74,44 @@ def fake_response(status_code=200, headers=None, content=None, **kwargs):
r.headers = headers or {}
r.raw = FakeHTTPResponse(status_code, headers, content, kwargs)
return r
+
+
+class FakeData(object):
+ """Generate a bunch of data without storing it in memory.
+
+ This acts like a read-only file object which generates fake data
+ in chunks when read() is called or it is used as a generator. It
+ can generate an arbitrary amount of data without storing it in
+ memory.
+
+ :param length: The number of bytes to generate
+ :param chunk_size: The chunk size to return in iteration mode, or when
+ read() is called unbounded
+
+ """
+ def __init__(self, length, chunk_size=64 * units.Ki):
+ self._max = length
+ self._chunk_size = chunk_size
+ self._len = 0
+
+ def read(self, length=None):
+ if length is None:
+ length = self._chunk_size
+
+ length = min(length, self._max - self._len)
+
+ self._len += length
+ if length == 0:
+ return b''
+ else:
+ return b'0' * length
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ r = self.read()
+ if len(r) == 0:
+ raise StopIteration()
+ else:
+ return r