Chromium Code Reviews| Index: appengine/chrome_infra_packages/cipd/test/api_test.py |
| diff --git a/appengine/chrome_infra_packages/cipd/test/api_test.py b/appengine/chrome_infra_packages/cipd/test/api_test.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f7962ef41a5a3995a243bf30dcfc253b0538b15f |
| --- /dev/null |
| +++ b/appengine/chrome_infra_packages/cipd/test/api_test.py |
| @@ -0,0 +1,268 @@ |
| +# Copyright 2014 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +import datetime |
| + |
| +from testing_utils import testing |
| + |
| +from components import auth |
| +from components import auth_testing |
| +from components import utils |
| + |
| +from cipd import api |
| +from cipd import impl |
| + |
| + |
| +class TestSerialization(testing.AppengineTestCase): |
| + def test_metadata_from_entity(self): |
| + ent = impl.PackageInstanceMetadata( |
| + date='Jan 1 2014', |
| + hostname='hostname', |
| + user='user', |
| + registered_by=auth.Identity.from_bytes('user:abc@example.com'), |
| + registered_ts=datetime.datetime(2014, 1, 1)) |
| + msg = api.metadata_from_entity(ent) |
| + self.assertEqual('Jan 1 2014', msg.date) |
| + self.assertEqual('hostname', msg.hostname) |
| + self.assertEqual('user', msg.user) |
| + self.assertEqual('user:abc@example.com', msg.registered_by) |
| + self.assertEqual(1388534400000000, msg.registered_ts) |
| + |
| + def test_metadata_to_entity(self): |
| + msg = api.InstanceMetadata( |
| + date='Jan 1 2014', |
| + hostname='hostname', |
| + user='user', |
| + registered_by='user:abc@example.com', |
| + registered_ts=1388534400000000) |
| + ent = api.metadata_to_entity(msg) |
| + # Ignores registered_* fields, they are output only. |
| + expected = { |
| + 'date': 'Jan 1 2014', |
| + 'hostname': 'hostname', |
| + 'user': 'user', |
| + 'registered_by': None, |
| + 'registered_ts': None, |
| + } |
| + self.assertEqual(expected, ent.to_dict()) |
| + |
| + def test_signature_from_entity(self): |
| + ent = impl.PackageInstanceSignature( |
| + hash_algo='SHA1', |
| + digest='\x00\x01\x02\x03\x04\x05', |
| + signature_algo='sig algo', |
| + signature_key='sig key', |
| + signature='signature \x00\x01\x02\x03\x04\x05', |
| + added_by=auth.Identity.from_bytes('user:abc@example.com'), |
| + added_ts=datetime.datetime(2014, 1, 1)) |
| + msg = api.signature_from_entity(ent) |
| + self.assertEqual('SHA1', msg.hash_algo) |
| + self.assertEqual('\x00\x01\x02\x03\x04\x05', msg.digest) |
| + self.assertEqual('sig algo', msg.signature_algo) |
| + self.assertEqual('sig key', msg.signature_key) |
| + self.assertEqual('signature \x00\x01\x02\x03\x04\x05', msg.signature) |
| + self.assertEqual('user:abc@example.com', msg.added_by) |
| + self.assertEqual(1388534400000000, msg.added_ts) |
| + |
| + def test_signature_to_entity(self): |
| + msg = api.Signature( |
| + hash_algo='SHA1', |
| + digest='\x00\x01\x02\x03\x04\x05', |
| + signature_algo='sig algo', |
| + signature_key='sig key', |
| + signature='signature \x00\x01\x02\x03\x04\x05', |
| + added_by='user:abc@example.com', |
| + added_ts=1388534400000000) |
| + ent = api.signature_to_entity(msg) |
| + # Ignores added_* fields, they are output only. |
| + expected = { |
| + 'hash_algo': 'SHA1', |
| + 'digest': '\x00\x01\x02\x03\x04\x05', |
| + 'signature_algo': 'sig algo', |
| + 'signature_key': 'sig key', |
| + 'signature': 'signature \x00\x01\x02\x03\x04\x05', |
| + 'added_by': None, |
| + 'added_ts': None, |
| + } |
| + self.assertEqual(expected, ent.to_dict()) |
| + |
| + |
| +class PackageRepositoryApiTest(testing.EndpointsTestCase): |
| + """Tests for API layer ONLY.""" |
| + |
| + api_service_cls = api.PackageRepositoryApi |
| + |
| + fake_metadata = { |
| + 'date': 'Jan 1 2014', |
| + 'hostname': 'hostname', |
| + 'user': 'user', |
| + } |
| + |
| + def setUp(self): |
| + super(PackageRepositoryApiTest, self).setUp() |
| + auth_testing.mock_get_current_identity(self) |
| + auth_testing.mock_is_admin(self) |
| + self.repo_service = MockedRepoService() |
| + def mocked_get_repo_service(): |
| + return self.repo_service |
| + self.mock(impl, 'get_repo_service', mocked_get_repo_service) |
|
nodir
2014/12/30 22:54:01
lambda: self.repo_service
would fit
Vadim Sh.
2014/12/31 01:27:36
Done.
|
| + |
| + def test_register_new_package_flow(self): |
| + self.mock(utils, 'utcnow', lambda: datetime.datetime(2014, 1, 1)) |
| + request = { |
| + 'package_name': 'good/name', |
| + 'instance_id': 'a'*40, |
| + 'metadata': self.fake_metadata, |
| + 'signatures': [ |
| + { |
| + 'hash_algo': 'SHA1', |
| + 'digest': 'AAECAwQ=', |
| + 'signature_algo': 'sig algo', |
| + 'signature_key': 'sig key 1', |
| + 'signature': 'c2lnbmF0dXJlIAABAgME', |
| + }, |
| + { |
| + 'hash_algo': 'SHA1', |
| + 'digest': 'AAECAwQ=', |
| + 'signature_algo': 'sig algo', |
| + 'signature_key': 'sig key 2', |
| + 'signature': 'c2lnbmF0dXJlIAABAgME', |
| + }, |
| + ], |
| + } |
| + |
| + # Package is not uploaded yet. Should ask to upload. |
| + resp = self.call_api('register_package', request) |
| + self.assertEqual(200, resp.status_code) |
| + self.assertEqual({ |
| + 'status': 'UPLOAD_FIRST', |
| + 'upload_session_id': 'upload_session_id', |
| + 'upload_url': 'http://upload_url', |
| + }, resp.json_body) |
| + |
| + # Pretend it is upload now. |
| + self.repo_service.uploaded.add('a'*40) |
| + |
| + # Should register the package. |
| + resp = self.call_api('register_package', request) |
| + self.assertEqual(200, resp.status_code) |
| + self.assertEqual({ |
| + 'status': 'REGISTERED', |
| + 'metadata': { |
| + 'date': 'Jan 1 2014', |
| + 'hostname': 'hostname', |
| + 'user': 'user', |
| + 'registered_by': 'user:mocked@example.com', |
| + 'registered_ts': '1388534400000000', |
| + }, |
| + }, resp.json_body) |
| + |
| + # Check that it is indeed there. |
| + pkg = self.repo_service.get_instance('good/name', 'a'*40) |
| + self.assertTrue(pkg) |
| + expected = { |
| + 'metadata': { |
| + 'date': 'Jan 1 2014', |
| + 'hostname': 'hostname', |
| + 'user': 'user', |
| + 'registered_by': auth.Identity(kind='user', name='mocked@example.com'), |
| + 'registered_ts': datetime.datetime(2014, 1, 1, 0, 0), |
| + }, |
| + 'signature_ids': ['SHA1:sig algo:sig key 1', 'SHA1:sig algo:sig key 2'], |
| + 'signatures': [ |
| + { |
| + 'added_by': auth.Identity(kind='user', name='mocked@example.com'), |
| + 'added_ts': datetime.datetime(2014, 1, 1, 0, 0), |
| + 'digest': '\x00\x01\x02\x03\x04', |
| + 'hash_algo': 'SHA1', |
| + 'signature': 'signature \x00\x01\x02\x03\x04', |
| + 'signature_algo': 'sig algo', |
| + 'signature_key': 'sig key 1', |
| + }, |
| + { |
| + 'added_by': auth.Identity(kind='user', name='mocked@example.com'), |
| + 'added_ts': datetime.datetime(2014, 1, 1, 0, 0), |
| + 'digest': '\x00\x01\x02\x03\x04', |
| + 'hash_algo': 'SHA1', |
| + 'signature': 'signature \x00\x01\x02\x03\x04', |
| + 'signature_algo': 'sig algo', |
| + 'signature_key': 'sig key 2', |
| + }, |
| + ], |
| + } |
| + self.assertEqual(expected, pkg.to_dict()) |
| + |
| + # Attempt to register it again, with additional signature. |
| + request['signatures'].append({ |
| + 'hash_algo': 'SHA1', |
| + 'digest': 'AAECAwQ=', |
| + 'signature_algo': 'sig algo', |
| + 'signature_key': 'sig key 3', |
| + 'signature': 'c2lnbmF0dXJlIAABAgME', |
| + }) |
| + resp = self.call_api('register_package', request) |
| + self.assertEqual(200, resp.status_code) |
| + self.assertEqual({ |
| + 'status': 'ALREADY_REGISTERED', |
| + 'metadata': { |
| + 'date': 'Jan 1 2014', |
| + 'hostname': 'hostname', |
| + 'user': 'user', |
| + 'registered_by': 'user:mocked@example.com', |
| + 'registered_ts': '1388534400000000', |
| + }, |
| + }, resp.json_body) |
| + |
| + # The signature is added to the list. |
| + pkg = self.repo_service.get_instance('good/name', 'a'*40) |
| + self.assertTrue(pkg) |
| + self.assertEqual(3, len(pkg.signatures)) |
| + |
| + def test_register_package_bad_name(self): |
| + with self.call_should_fail(400): |
| + self.call_api('register_package', { |
| + 'package_name': 'bad name', |
| + 'instance_id': 'a'*40, |
| + 'metadata': self.fake_metadata, |
| + }) |
| + |
| + def test_register_package_bad_instance_id(self): |
| + with self.call_should_fail(400): |
| + self.call_api('register_package', { |
| + 'package_name': 'good/name', |
| + 'instance_id': 'bad instance id', |
| + 'metadata': self.fake_metadata, |
| + }) |
| + |
| + def test_register_package_no_access(self): |
| + self.mock(api.acl, 'can_register_package', lambda *_: False) |
| + with self.call_should_fail(403): |
| + self.call_api('register_package', { |
| + 'package_name': 'good/name', |
| + 'instance_id': 'a'*40, |
| + 'metadata': self.fake_metadata, |
| + }) |
| + |
| + def test_register_package_no_service(self): |
| + self.repo_service = None |
| + with self.call_should_fail(500): |
| + self.call_api('register_package', { |
| + 'package_name': 'good/name', |
| + 'instance_id': 'a'*40, |
| + 'metadata': self.fake_metadata, |
| + }) |
| + |
| + |
| +class MockedRepoService(impl.RepoService): |
| + """Almost like a real one, except CAS part is stubbed.""" |
| + |
| + def __init__(self): |
| + super(MockedRepoService, self).__init__(None) |
| + self.uploaded = set() |
| + |
| + def is_data_uploaded(self, package_name, instance_id): |
| + return instance_id in self.uploaded |
| + |
| + def create_upload_session(self, package_name, instance_id, caller): |
| + return 'http://upload_url', 'upload_session_id' |