Skip to content

Commit

Permalink
Skeleton for metadata service (#398)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #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: 6e794182dcacd73ebcfc2ff8b1f9e5c5879ce506
  • Loading branch information
Yige Zhu authored and facebook-github-bot committed Aug 19, 2022
1 parent 3e84a68 commit 04a8f70
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 8 deletions.
24 changes: 24 additions & 0 deletions onedocker/repository/onedocker_metadata_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env python3
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# 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 Any, Dict

from fbpcp.service.storage import StorageService
from onedocker.entity.object_metadata import PackageMetadata


class OneDockerMetadataService:
def __init__(
self,
storage_svc: StorageService,
) -> None:
self.storage_svc = storage_svc

def set_metadata(self, package_path: str, metadata_dict: Dict[Any, Any]) -> None:
raise NotImplementedError

def get_metadata(self, package_path: str) -> PackageMetadata:
raise NotImplementedError
15 changes: 10 additions & 5 deletions onedocker/repository/onedocker_repository_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
# 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
from typing import Any, Dict, Optional

from fbpcp.service.storage import StorageService
from onedocker.entity.object_metadata import PackageMetadata
from onedocker.repository.onedocker_metadata_service import OneDockerMetadataService
from onedocker.repository.onedocker_package import OneDockerPackageRepository

DEFAULT_PROD_VERSION = "latest"
Expand All @@ -23,6 +24,7 @@ def __init__(
self.package_repo = OneDockerPackageRepository(
storage_svc, package_repository_path
)
self.metadata_svc = OneDockerMetadataService(storage_svc)

def upload(
self,
Expand All @@ -38,6 +40,8 @@ def upload(
f"Version {version} already exists. Please specify another version."
)
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 @@ -46,17 +50,18 @@ def _set_metadata(
self,
package_name: str,
version: str,
metadata: PackageMetadata,
metadata_dict: Dict[Any, Any],
) -> None:
# TODO: T127441856 handle storing metadata
raise NotImplementedError
path = self.package_repo._build_package_path(package_name, version)
self.metadata_svc.set_metadata(path, metadata_dict)

def _get_metadata(
self,
package_name: str,
version: str,
) -> PackageMetadata:
raise NotImplementedError
path = self.package_repo._build_package_path(package_name, version)
return self.metadata_svc.get_metadata(path)

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
23 changes: 23 additions & 0 deletions onedocker/tests/repository/test_onedocker_metadata_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env python3
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.


import unittest
from unittest.mock import patch

from onedocker.repository.onedocker_metadata_service import OneDockerMetadataService


class TestOneDockerMetadataService(unittest.TestCase):
@patch("onedocker.repository.onedocker_metadata_service.StorageService")
def setUp(self, mockStorageService):
self.metadata_svc = OneDockerMetadataService(mockStorageService)

def test_set_metadata(self):
pass

def test_get_metadata(self):
pass
59 changes: 56 additions & 3 deletions onedocker/tests/repository/test_onedocker_repository_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
# 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 unittest.mock import MagicMock, patch

Expand All @@ -18,17 +20,21 @@ class TestOneDockerRepositoryService(unittest.TestCase):
TEST_PACKAGE_NAME = TEST_PACKAGE_PATH.split("/")[-1]
TEST_PACKAGE_VERSION = "1.0"

@patch("onedocker.repository.onedocker_repository_service.OneDockerMetadataService")
@patch(
"onedocker.repository.onedocker_repository_service.OneDockerPackageRepository"
)
@patch("fbpcp.service.storage_s3.S3StorageService")
def setUp(self, mockStorageService, mockPackageRepoCall) -> None:
@patch("onedocker.repository.onedocker_repository_service.StorageService")
def setUp(self, mockStorageService, mockPackageRepo, mockMetadataService) -> None:
package_repo_path = "/package_repo_path/"
self.package_repo = MagicMock()
mockPackageRepoCall.return_value = self.package_repo
self.metadata_svc = MagicMock()
mockPackageRepo.return_value = self.package_repo
mockMetadataService.return_value = self.metadata_svc
self.repo_service = OneDockerRepositoryService(
mockStorageService, package_repo_path
)
self.storage_svc = mockStorageService

def test_onedocker_repo_service_upload(self) -> None:
# Arrange
Expand Down Expand Up @@ -85,3 +91,50 @@ def test_onedocker_repo_service_upload_to_latest(self) -> None:
self.package_repo.upload.assert_called_with(
self.TEST_PACKAGE_PATH, DEFAULT_PROD_VERSION, source_path
)

def test_onedocker_repo_service_set_metadata(self) -> None:
# Arrange
metadata_dict = {"checksum": "checksum_data", "not_a_valid_field": "some_data"}
path = "test_metadata_path"
self.package_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.metadata_svc.set_metadata.assert_called_once_with(path, 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.package_repo._build_package_path.return_value = path
self.storage_svc.read.return_value = metadata_json
# Act
self.repo_service._get_metadata(
self.TEST_PACKAGE_NAME, self.TEST_PACKAGE_VERSION
)
# Assert
self.metadata_svc.get_metadata.assert_called_once_with(path)
# TODO: add result validation after implementing get_metadata

@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 04a8f70

Please sign in to comment.