Repository URL to install this package:
Version:
0.1.1-1 ▾
|
odigos-demo-inventory
/
opt
/
odigos-demo-inventory
/
site-packages
/
dulwich
/
contrib
/
test_swift.py
|
---|
# test_swift.py -- Unittests for the Swift backend.
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
#
# Author: Fabien Boucher <fabien.boucher@enovance.com>
#
# Dulwich is dual-licensed under the Apache License, Version 2.0 and the GNU
# General Public License as public by the Free Software Foundation; version 2.0
# or (at your option) any later version. You can redistribute it and/or
# modify it under the terms of either of these two licenses.
#
# 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.
#
# You should have received a copy of the licenses; if not, see
# <http://www.gnu.org/licenses/> for a copy of the GNU General Public License
# and <http://www.apache.org/licenses/LICENSE-2.0> for a copy of the Apache
# License, Version 2.0.
#
"""Tests for dulwich.contrib.swift."""
import json
import posixpath
from io import BytesIO, StringIO
from time import time
from unittest import skipIf
from dulwich.tests import TestCase
from ..objects import Blob, Commit, Tag, Tree, parse_timezone
from ..tests.test_object_store import ObjectStoreTests
missing_libs = []
try:
import gevent # noqa: F401
except ModuleNotFoundError:
missing_libs.append("gevent")
try:
import geventhttpclient # noqa: F401
except ModuleNotFoundError:
missing_libs.append("geventhttpclient")
try:
from unittest.mock import patch
except ModuleNotFoundError:
missing_libs.append("mock")
skipmsg = "Required libraries are not installed (%r)" % missing_libs
if not missing_libs:
from dulwich.contrib import swift
config_file = """[swift]
auth_url = http://127.0.0.1:8080/auth/%(version_str)s
auth_ver = %(version_int)s
username = test;tester
password = testing
region_name = %(region_name)s
endpoint_type = %(endpoint_type)s
concurrency = %(concurrency)s
chunk_length = %(chunk_length)s
cache_length = %(cache_length)s
http_pool_length = %(http_pool_length)s
http_timeout = %(http_timeout)s
"""
def_config_file = {
"version_str": "v1.0",
"version_int": 1,
"concurrency": 1,
"chunk_length": 12228,
"cache_length": 1,
"region_name": "test",
"endpoint_type": "internalURL",
"http_pool_length": 1,
"http_timeout": 1,
}
def create_swift_connector(store={}):
return lambda root, conf: FakeSwiftConnector(root, conf=conf, store=store)
class Response:
def __init__(self, headers={}, status=200, content=None) -> None:
self.headers = headers
self.status_code = status
self.content = content
def __getitem__(self, key):
return self.headers[key]
def items(self):
return self.headers.items()
def read(self):
return self.content
def fake_auth_request_v1(*args, **kwargs):
ret = Response(
{
"X-Storage-Url": "http://127.0.0.1:8080/v1.0/AUTH_fakeuser",
"X-Auth-Token": "12" * 10,
},
200,
)
return ret
def fake_auth_request_v1_error(*args, **kwargs):
ret = Response({}, 401)
return ret
def fake_auth_request_v2(*args, **kwargs):
s_url = "http://127.0.0.1:8080/v1.0/AUTH_fakeuser"
resp = {
"access": {
"token": {"id": "12" * 10},
"serviceCatalog": [
{
"type": "object-store",
"endpoints": [
{
"region": "test",
"internalURL": s_url,
},
],
},
],
}
}
ret = Response(status=200, content=json.dumps(resp))
return ret
def create_commit(data, marker=b"Default", blob=None):
if not blob:
blob = Blob.from_string(b"The blob content " + marker)
tree = Tree()
tree.add(b"thefile_" + marker, 0o100644, blob.id)
cmt = Commit()
if data:
assert isinstance(data[-1], Commit)
cmt.parents = [data[-1].id]
cmt.tree = tree.id
author = b"John Doe " + marker + b" <john@doe.net>"
cmt.author = cmt.committer = author
tz = parse_timezone(b"-0200")[0]
cmt.commit_time = cmt.author_time = int(time())
cmt.commit_timezone = cmt.author_timezone = tz
cmt.encoding = b"UTF-8"
cmt.message = b"The commit message " + marker
tag = Tag()
tag.tagger = b"john@doe.net"
tag.message = b"Annotated tag"
tag.tag_timezone = parse_timezone(b"-0200")[0]
tag.tag_time = cmt.author_time
tag.object = (Commit, cmt.id)
tag.name = b"v_" + marker + b"_0.1"
return blob, tree, tag, cmt
def create_commits(length=1, marker=b"Default"):
data = []
for i in range(length):
_marker = (f"{marker}_{i}").encode()
blob, tree, tag, cmt = create_commit(data, _marker)
data.extend([blob, tree, tag, cmt])
return data
@skipIf(missing_libs, skipmsg)
class FakeSwiftConnector:
def __init__(self, root, conf, store=None) -> None:
if store:
self.store = store
else:
self.store = {}
self.conf = conf
self.root = root
self.concurrency = 1
self.chunk_length = 12228
self.cache_length = 1
def put_object(self, name, content):
name = posixpath.join(self.root, name)
if hasattr(content, "seek"):
content.seek(0)
content = content.read()
self.store[name] = content
def get_object(self, name, range=None):
name = posixpath.join(self.root, name)
if not range:
try:
return BytesIO(self.store[name])
except KeyError:
return None
else:
l, r = range.split("-")
try:
if not l:
r = -int(r)
return self.store[name][r:]
else:
return self.store[name][int(l) : int(r)]
except KeyError:
return None
def get_container_objects(self):
return [{"name": k.replace(self.root + "/", "")} for k in self.store]
def create_root(self):
if self.root in self.store.keys():
pass
else:
self.store[self.root] = ""
def get_object_stat(self, name):
name = posixpath.join(self.root, name)
if name not in self.store:
return None
return {"content-length": len(self.store[name])}
@skipIf(missing_libs, skipmsg)
class TestSwiftRepo(TestCase):
def setUp(self):
super().setUp()
self.conf = swift.load_conf(file=StringIO(config_file % def_config_file))
def test_init(self):
store = {"fakerepo/objects/pack": ""}
with patch(
"dulwich.contrib.swift.SwiftConnector",
new_callable=create_swift_connector,
store=store,
):
swift.SwiftRepo("fakerepo", conf=self.conf)
def test_init_no_data(self):
with patch(
"dulwich.contrib.swift.SwiftConnector",
new_callable=create_swift_connector,
):
self.assertRaises(Exception, swift.SwiftRepo, "fakerepo", self.conf)
def test_init_bad_data(self):
store = {"fakerepo/.git/objects/pack": ""}
with patch(
"dulwich.contrib.swift.SwiftConnector",
new_callable=create_swift_connector,
store=store,
):
self.assertRaises(Exception, swift.SwiftRepo, "fakerepo", self.conf)
def test_put_named_file(self):
store = {"fakerepo/objects/pack": ""}
with patch(
"dulwich.contrib.swift.SwiftConnector",
new_callable=create_swift_connector,
store=store,
):
repo = swift.SwiftRepo("fakerepo", conf=self.conf)
desc = b"Fake repo"
repo._put_named_file("description", desc)
self.assertEqual(repo.scon.store["fakerepo/description"], desc)
def test_init_bare(self):
fsc = FakeSwiftConnector("fakeroot", conf=self.conf)
with patch(
"dulwich.contrib.swift.SwiftConnector",
new_callable=create_swift_connector,
store=fsc.store,
):
swift.SwiftRepo.init_bare(fsc, conf=self.conf)
self.assertIn("fakeroot/objects/pack", fsc.store)
self.assertIn("fakeroot/info/refs", fsc.store)
self.assertIn("fakeroot/description", fsc.store)
@skipIf(missing_libs, skipmsg)
class TestSwiftInfoRefsContainer(TestCase):
def setUp(self):
super().setUp()
content = (
b"22effb216e3a82f97da599b8885a6cadb488b4c5\trefs/heads/master\n"
b"cca703b0e1399008b53a1a236d6b4584737649e4\trefs/heads/dev"
)
self.store = {"fakerepo/info/refs": content}
self.conf = swift.load_conf(file=StringIO(config_file % def_config_file))
self.fsc = FakeSwiftConnector("fakerepo", conf=self.conf)
self.object_store = {}
def test_init(self):
"""info/refs does not exists."""
irc = swift.SwiftInfoRefsContainer(self.fsc, self.object_store)
self.assertEqual(len(irc._refs), 0)
self.fsc.store = self.store
irc = swift.SwiftInfoRefsContainer(self.fsc, self.object_store)
self.assertIn(b"refs/heads/dev", irc.allkeys())
self.assertIn(b"refs/heads/master", irc.allkeys())
def test_set_if_equals(self):
self.fsc.store = self.store
irc = swift.SwiftInfoRefsContainer(self.fsc, self.object_store)
irc.set_if_equals(
b"refs/heads/dev",
b"cca703b0e1399008b53a1a236d6b4584737649e4",
b"1" * 40,
)
self.assertEqual(irc[b"refs/heads/dev"], b"1" * 40)
def test_remove_if_equals(self):
self.fsc.store = self.store
irc = swift.SwiftInfoRefsContainer(self.fsc, self.object_store)
irc.remove_if_equals(
b"refs/heads/dev", b"cca703b0e1399008b53a1a236d6b4584737649e4"
)
self.assertNotIn(b"refs/heads/dev", irc.allkeys())
@skipIf(missing_libs, skipmsg)
class TestSwiftConnector(TestCase):
def setUp(self):
super().setUp()
self.conf = swift.load_conf(file=StringIO(config_file % def_config_file))
with patch("geventhttpclient.HTTPClient.request", fake_auth_request_v1):
self.conn = swift.SwiftConnector("fakerepo", conf=self.conf)
def test_init_connector(self):
self.assertEqual(self.conn.auth_ver, "1")
self.assertEqual(self.conn.auth_url, "http://127.0.0.1:8080/auth/v1.0")
self.assertEqual(self.conn.user, "test:tester")
self.assertEqual(self.conn.password, "testing")
self.assertEqual(self.conn.root, "fakerepo")
self.assertEqual(
self.conn.storage_url, "http://127.0.0.1:8080/v1.0/AUTH_fakeuser"
)
self.assertEqual(self.conn.token, "12" * 10)
self.assertEqual(self.conn.http_timeout, 1)
self.assertEqual(self.conn.http_pool_length, 1)
self.assertEqual(self.conn.concurrency, 1)
self.conf.set("swift", "auth_ver", "2")
self.conf.set("swift", "auth_url", "http://127.0.0.1:8080/auth/v2.0")
with patch("geventhttpclient.HTTPClient.request", fake_auth_request_v2):
conn = swift.SwiftConnector("fakerepo", conf=self.conf)
self.assertEqual(conn.user, "tester")
self.assertEqual(conn.tenant, "test")
self.conf.set("swift", "auth_ver", "1")
self.conf.set("swift", "auth_url", "http://127.0.0.1:8080/auth/v1.0")
with patch("geventhttpclient.HTTPClient.request", fake_auth_request_v1_error):
self.assertRaises(
swift.SwiftException,
lambda: swift.SwiftConnector("fakerepo", conf=self.conf),
)
def test_root_exists(self):
with patch("geventhttpclient.HTTPClient.request", lambda *args: Response()):
self.assertEqual(self.conn.test_root_exists(), True)
def test_root_not_exists(self):
with patch(
"geventhttpclient.HTTPClient.request",
lambda *args: Response(status=404),
):
self.assertEqual(self.conn.test_root_exists(), None)
def test_create_root(self):
with patch(
"dulwich.contrib.swift.SwiftConnector.test_root_exists",
lambda *args: None,
):
with patch("geventhttpclient.HTTPClient.request", lambda *args: Response()):
self.assertEqual(self.conn.create_root(), None)
def test_create_root_fails(self):
with patch(
"dulwich.contrib.swift.SwiftConnector.test_root_exists",
lambda *args: None,
):
with patch(
"geventhttpclient.HTTPClient.request",
lambda *args: Response(status=404),
):
self.assertRaises(swift.SwiftException, self.conn.create_root)
def test_get_container_objects(self):
with patch(
"geventhttpclient.HTTPClient.request",
lambda *args: Response(content=json.dumps(({"name": "a"}, {"name": "b"}))),
):
self.assertEqual(len(self.conn.get_container_objects()), 2)
def test_get_container_objects_fails(self):
with patch(
"geventhttpclient.HTTPClient.request",
lambda *args: Response(status=404),
):
self.assertEqual(self.conn.get_container_objects(), None)
def test_get_object_stat(self):
with patch(
"geventhttpclient.HTTPClient.request",
lambda *args: Response(headers={"content-length": "10"}),
):
self.assertEqual(self.conn.get_object_stat("a")["content-length"], "10")
def test_get_object_stat_fails(self):
with patch(
"geventhttpclient.HTTPClient.request",
lambda *args: Response(status=404),
):
self.assertEqual(self.conn.get_object_stat("a"), None)
def test_put_object(self):
with patch(
"geventhttpclient.HTTPClient.request",
lambda *args, **kwargs: Response(),
):
self.assertEqual(self.conn.put_object("a", BytesIO(b"content")), None)
def test_put_object_fails(self):
with patch(
"geventhttpclient.HTTPClient.request",
lambda *args, **kwargs: Response(status=400),
):
self.assertRaises(
swift.SwiftException,
lambda: self.conn.put_object("a", BytesIO(b"content")),
)
def test_get_object(self):
with patch(
"geventhttpclient.HTTPClient.request",
lambda *args, **kwargs: Response(content=b"content"),
):
self.assertEqual(self.conn.get_object("a").read(), b"content")
with patch(
"geventhttpclient.HTTPClient.request",
lambda *args, **kwargs: Response(content=b"content"),
):
self.assertEqual(self.conn.get_object("a", range="0-6"), b"content")
def test_get_object_fails(self):
with patch(
"geventhttpclient.HTTPClient.request",
lambda *args, **kwargs: Response(status=404),
):
self.assertEqual(self.conn.get_object("a"), None)
def test_del_object(self):
with patch("geventhttpclient.HTTPClient.request", lambda *args: Response()):
self.assertEqual(self.conn.del_object("a"), None)
def test_del_root(self):
with patch(
"dulwich.contrib.swift.SwiftConnector.del_object",
lambda *args: None,
):
with patch(
"dulwich.contrib.swift.SwiftConnector." "get_container_objects",
lambda *args: ({"name": "a"}, {"name": "b"}),
):
with patch(
"geventhttpclient.HTTPClient.request",
lambda *args: Response(),
):
self.assertEqual(self.conn.del_root(), None)
@skipIf(missing_libs, skipmsg)
class SwiftObjectStoreTests(ObjectStoreTests, TestCase):
def setUp(self):
TestCase.setUp(self)
conf = swift.load_conf(file=StringIO(config_file % def_config_file))
fsc = FakeSwiftConnector("fakerepo", conf=conf)
self.store = swift.SwiftObjectStore(fsc)