Skip to content

Commit

Permalink
Implement setter and getter for metadata (facebookresearch#398)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: facebookresearch#398

This will be used to upload and host checksum data for now, and could be extended to hosting other data in the future.

Differential Revision: D38516464

fbshipit-source-id: 8552d7ab8f4ac98297fca1519a0f5b2711d134a7
  • Loading branch information
Yige Zhu authored and facebook-github-bot committed Aug 10, 2022
1 parent 881bd9b commit 1330754
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 8 deletions.
23 changes: 18 additions & 5 deletions onedocker/repository/onedocker_repository_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

from typing import Optional
import json
from dataclasses import asdict
from typing import Any, Dict, Optional

from fbpcp.service.storage import StorageService
from onedocker.entity.object_metadata import PackageMetadata
Expand All @@ -16,11 +18,15 @@ def __init__(
self,
storage_svc: StorageService,
package_repository_path: str,
metadata_repository_path: str,
) -> None:
self.storage_svc = storage_svc
self.package_repo = OneDockerPackageRepository(
storage_svc, package_repository_path
)
self.metadata_repo = OneDockerPackageRepository(
storage_svc, metadata_repository_path
)

def upload(
self,
Expand All @@ -30,6 +36,8 @@ def upload(
metadata: Optional[dict] = None,
) -> None:
self.package_repo.upload(package_name, version, source)
if metadata:
self._set_metadata(package_name, version, metadata)

def download(self, package_name: str, version: str, destination: str) -> None:
self.package_repo.download(package_name, version, destination)
Expand All @@ -38,17 +46,22 @@ def _set_metadata(
self,
package_name: str,
version: str,
metadata: PackageMetadata,
metadata_dict: Dict[Any, Any],
) -> None:
# TODO: T127441856 handle storing metadata
raise NotImplementedError
metadata = PackageMetadata(**metadata_dict)
path = self.metadata_repo._build_package_path(package_name, version)
metadata_json = json.dumps(asdict(metadata))
self.storage_svc.write(path, metadata_json)

def _get_metadata(
self,
package_name: str,
version: str,
) -> PackageMetadata:
raise NotImplementedError
path = self.metadata_repo._build_package_path(package_name, version)
metadata_json = self.storage_svc.read(path)
metadata_dict = json.loads(metadata_json)
return PackageMetadata(**metadata_dict)

def archive_package(self, package_name: str, version: str) -> None:
# TODO: Archive or delete checksum file associated with the archived package if exists.
Expand Down
71 changes: 68 additions & 3 deletions onedocker/tests/repository/test_onedocker_repository_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

import json

import unittest
from dataclasses import asdict
from unittest.mock import MagicMock, patch

from onedocker.repository.onedocker_repository_service import OneDockerRepositoryService
Expand All @@ -18,14 +21,17 @@ class TestOneDockerRepositoryService(unittest.TestCase):
@patch(
"onedocker.repository.onedocker_repository_service.OneDockerPackageRepository"
)
@patch("fbpcp.service.storage_s3.S3StorageService")
@patch("onedocker.repository.onedocker_repository_service.StorageService")
def setUp(self, mockStorageService, mockPackageRepoCall) -> None:
package_repo_path = "/package_repo_path/"
metadata_repo_path = "/metadata_repo_path/"
self.package_repo = MagicMock()
mockPackageRepoCall.return_value = self.package_repo
self.metadata_repo = MagicMock()
mockPackageRepoCall.side_effect = [self.package_repo, self.metadata_repo]
self.repo_service = OneDockerRepositoryService(
mockStorageService, package_repo_path
mockStorageService, package_repo_path, metadata_repo_path
)
self.storage_svc = mockStorageService

def test_onedocker_repo_service_upload(self) -> None:
# Arrange
Expand Down Expand Up @@ -64,3 +70,62 @@ def test_onedocker_repo_service_archive(self) -> None:
self.package_repo.archive_package.assert_called_once_with(
self.TEST_PACKAGE_PATH, self.TEST_PACKAGE_VERSION
)

def test_onedocker_repo_service_set_metadata(self) -> None:
# Arrange
metadata_dict = {"checksum": "checksum_data"}
metadata_json = json.dumps(metadata_dict)
path = "test_metadata_path"
self.metadata_repo._build_package_path.return_value = path
# Act
self.repo_service._set_metadata(
self.TEST_PACKAGE_NAME, self.TEST_PACKAGE_VERSION, metadata_dict
)
# Assert
self.storage_svc.write.assert_called_once_with(path, metadata_json)

def test_onedocker_repo_service_set_metadata_fail(self) -> None:
# Arrange
metadata_dict = {"checksum": "checksum_data", "not_a_valid_field": "some_data"}
path = "test_metadata_path"
self.metadata_repo._build_package_path.return_value = path
# Act & Assert
with self.assertRaises(TypeError):
self.repo_service._set_metadata(
self.TEST_PACKAGE_NAME, self.TEST_PACKAGE_VERSION, metadata_dict
)

def test_onedocker_repo_service_get_metadata(self) -> None:
# Arrange
metadata_dict = {"checksum": "checksum_data"}
metadata_json = json.dumps(metadata_dict)
path = "test_metadata_path"
self.metadata_repo._build_package_path.return_value = path
self.storage_svc.read.return_value = metadata_json
# Act
result = self.repo_service._get_metadata(
self.TEST_PACKAGE_NAME, self.TEST_PACKAGE_VERSION
)
# Assert
self.storage_svc.read.assert_called_once_with(path)
self.assertEqual(asdict(result), metadata_dict)

@patch(
"onedocker.repository.onedocker_repository_service.OneDockerRepositoryService._set_metadata"
)
def test_onedocker_repo_service_upload_with_metadata(self, setMetadataMock) -> None:
# Arrange
source_path = "test_source_path"
metadata = {"checksum": "checksum_data"}
# Act
self.repo_service.upload(
self.TEST_PACKAGE_NAME, self.TEST_PACKAGE_VERSION, source_path, metadata
)

# Assert
setMetadataMock.assert_called_once_with(
self.TEST_PACKAGE_NAME, self.TEST_PACKAGE_VERSION, metadata
)
self.package_repo.upload.assert_called_with(
self.TEST_PACKAGE_NAME, self.TEST_PACKAGE_VERSION, source_path
)

0 comments on commit 1330754

Please sign in to comment.