Skip to content

Commit 2c6d5ad

Browse files
authored
ENG-10556 | Add OracleCloud (OCI) Object Storage provider for osfstorage (#474)
* ENG-10556 | Add OracleCloud (OCI) Object Storage provider for osfstorage * ENG-10556 | Add tests for the OracleCloud (OCI) Object Storage provider for osfstorage
1 parent ac30c4e commit 2c6d5ad

10 files changed

Lines changed: 1008 additions & 0 deletions

File tree

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ humanfriendly = "10.0"
2323
invoke = "2.2.0"
2424
multidict = ">=6.0.0"
2525
newrelic = "10.8.1"
26+
oci = "^2.149.0"
2627
oauthlib = "3.2.2"
2728
pyjwe = "1.0.0"
2829
pyjwt = "2.10.1"
@@ -91,6 +92,7 @@ googledrive = "waterbutler.providers.googledrive:GoogleDriveProvider"
9192
onedrive = "waterbutler.providers.onedrive:OneDriveProvider"
9293
googlecloud = "waterbutler.providers.googlecloud:GoogleCloudProvider"
9394
azureblobstorage = "waterbutler.providers.azureblobstorage:AzureBlobStorageProvider"
95+
oraclecloud = "waterbutler.providers.oraclecloud:OracleCloudProvider"
9496

9597
[tool.pytest.ini_options]
9698
asyncio_default_fixture_loop_scope = "function"

tests/providers/oraclecloud/__init__.py

Whitespace-only changes.

tests/providers/oraclecloud/fixtures/__init__.py

Whitespace-only changes.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import pytest
2+
3+
4+
@pytest.fixture()
5+
def mock_auth():
6+
return {"name": "Test User", "email": "test@osf.io"}
7+
8+
9+
@pytest.fixture()
10+
def mock_creds():
11+
return {
12+
"oci_user": "ocid1.user.oc1..aaaaaaaafakeuser",
13+
"oci_fingerprint": "aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66:77:88:99",
14+
"oci_tenancy": "ocid1.tenancy.oc1..aaaaaaaafaketenancy",
15+
"oci_region": "us-ashburn-1",
16+
"oci_key_content": "-----BEGIN RSA PRIVATE KEY-----\nfake\n-----END RSA PRIVATE KEY-----",
17+
}
18+
19+
20+
@pytest.fixture()
21+
def mock_settings():
22+
return {
23+
"bucket": "test-bucket",
24+
"namespace": "test-namespace",
25+
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
from unittest import mock
2+
3+
import pytest
4+
5+
from waterbutler.providers.oraclecloud.metadata import (
6+
BaseOracleCloudMetadata,
7+
OracleCloudFileMetadata,
8+
OracleCloudFolderMetadata,
9+
)
10+
11+
12+
class TestOracleCloudFileMetadata:
13+
14+
def test_file_metadata_from_dict(self):
15+
16+
raw = {
17+
"object_name": "path/to/file.txt",
18+
"content_type": "text/plain",
19+
"last_modified": "Thu, 01 Mar 2025 19:04:45 GMT",
20+
"size": 1024,
21+
"etag": "abc123def456",
22+
"extra": {
23+
"md5": "rL0Y20zC+Fzt72VPzMSk2A==",
24+
"storage_tier": "Standard",
25+
"archival_state": None,
26+
},
27+
"time_created": "2025-03-01T19:00:00+00:00",
28+
}
29+
metadata = OracleCloudFileMetadata(raw)
30+
31+
assert isinstance(metadata, BaseOracleCloudMetadata)
32+
assert metadata.provider == "oraclecloud"
33+
assert metadata.kind == "file"
34+
assert metadata.name == "file.txt"
35+
assert metadata.path == "/path/to/file.txt"
36+
assert metadata.content_type == "text/plain"
37+
assert metadata.modified == "Thu, 01 Mar 2025 19:04:45 GMT"
38+
assert metadata.size == 1024
39+
assert metadata.size_as_int == 1024
40+
assert metadata.etag == "abc123def456"
41+
assert metadata.extra["md5"] == "rL0Y20zC+Fzt72VPzMSk2A=="
42+
assert metadata.extra["storage_tier"] == "Standard"
43+
assert metadata.created_utc == "2025-03-01T19:00:00+00:00"
44+
45+
def test_file_metadata_missing_optional_fields(self):
46+
47+
raw = {
48+
"object_name": "simple.txt",
49+
"content_type": None,
50+
"last_modified": None,
51+
"size": None,
52+
"etag": None,
53+
"extra": {},
54+
}
55+
metadata = OracleCloudFileMetadata(raw)
56+
57+
assert metadata.name == "simple.txt"
58+
assert metadata.content_type is None
59+
assert metadata.modified is None
60+
assert metadata.size is None
61+
assert metadata.etag is None
62+
assert metadata.extra == {}
63+
assert metadata.created_utc is None
64+
65+
def test_file_metadata_from_head_response(self):
66+
67+
head_resp = mock.Mock()
68+
head_resp.headers = {
69+
"content-type": "application/pdf",
70+
"content-length": "2048",
71+
"last-modified": "Fri, 14 Mar 2025 12:00:00 GMT",
72+
"etag": '"deadbeef"',
73+
"opc-content-md5": "rL0Y20zC+Fzt72VPzMSk2A==",
74+
"storage-tier": "Standard",
75+
}
76+
77+
metadata = OracleCloudFileMetadata.new_from_head_response(
78+
"folder/report.pdf", head_resp
79+
)
80+
81+
assert metadata.provider == "oraclecloud"
82+
assert metadata.name == "report.pdf"
83+
assert metadata.path == "/folder/report.pdf"
84+
assert metadata.content_type == "application/pdf"
85+
assert metadata.size == 2048
86+
assert metadata.etag == "deadbeef"
87+
assert metadata.extra["md5"] == "rL0Y20zC+Fzt72VPzMSk2A=="
88+
89+
def test_file_metadata_from_object_summary(self):
90+
91+
obj_summary = mock.Mock()
92+
obj_summary.name = "data/results.csv"
93+
obj_summary.size = 4096
94+
obj_summary.etag = "etag123"
95+
obj_summary.md5 = "abc123"
96+
obj_summary.storage_tier = "InfrequentAccess"
97+
obj_summary.archival_state = None
98+
obj_summary.time_modified = mock.Mock()
99+
obj_summary.time_modified.isoformat.return_value = "2025-03-10T08:00:00+00:00"
100+
obj_summary.time_created = None
101+
102+
metadata = OracleCloudFileMetadata.new_from_oci_object_summary(obj_summary)
103+
104+
assert metadata.name == "results.csv"
105+
assert metadata.path == "/data/results.csv"
106+
assert metadata.size == 4096
107+
assert metadata.etag == "etag123"
108+
assert metadata.extra["md5"] == "abc123"
109+
assert metadata.modified == "2025-03-10T08:00:00+00:00"
110+
assert metadata.created_utc is None
111+
112+
113+
class TestOracleCloudFolderMetadata:
114+
115+
def test_folder_metadata(self):
116+
117+
raw = {"object_name": "path/to/folder/"}
118+
metadata = OracleCloudFolderMetadata(raw)
119+
120+
assert isinstance(metadata, BaseOracleCloudMetadata)
121+
assert metadata.provider == "oraclecloud"
122+
assert metadata.kind == "folder"
123+
assert metadata.name == "folder"
124+
assert metadata.path == "/path/to/folder/"
125+
126+
def test_folder_metadata_nested(self):
127+
128+
raw = {"object_name": "a/b/c/"}
129+
metadata = OracleCloudFolderMetadata(raw)
130+
131+
assert metadata.name == "c"
132+
assert metadata.path == "/a/b/c/"

0 commit comments

Comments
 (0)