Updated DB_Helper by adding firebase methods.
This commit is contained in:
parent
485cc3bbba
commit
c82121d036
1810 changed files with 537281 additions and 1 deletions
22
venv/Lib/site-packages/gcloud/resource_manager/__init__.py
Normal file
22
venv/Lib/site-packages/gcloud/resource_manager/__init__.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Copyright 2015 Google Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Google Cloud Resource Manager API wrapper."""
|
||||
|
||||
from gcloud.resource_manager.client import Client
|
||||
from gcloud.resource_manager.connection import Connection
|
||||
from gcloud.resource_manager.project import Project
|
||||
|
||||
|
||||
SCOPE = Connection.SCOPE
|
185
venv/Lib/site-packages/gcloud/resource_manager/client.py
Normal file
185
venv/Lib/site-packages/gcloud/resource_manager/client.py
Normal file
|
@ -0,0 +1,185 @@
|
|||
# Copyright 2015 Google Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""A Client for interacting with the Resource Manager API."""
|
||||
|
||||
|
||||
from gcloud.client import Client as BaseClient
|
||||
from gcloud.iterator import Iterator
|
||||
from gcloud.resource_manager.connection import Connection
|
||||
from gcloud.resource_manager.project import Project
|
||||
|
||||
|
||||
class Client(BaseClient):
|
||||
"""Client to bundle configuration needed for API requests.
|
||||
|
||||
See
|
||||
https://cloud.google.com/resource-manager/reference/rest/
|
||||
for more information on this API.
|
||||
|
||||
Automatically get credentials::
|
||||
|
||||
>>> from gcloud import resource_manager
|
||||
>>> client = resource_manager.Client()
|
||||
|
||||
:type credentials: :class:`oauth2client.client.OAuth2Credentials` or
|
||||
:class:`NoneType`
|
||||
:param credentials: The OAuth2 Credentials to use for the connection
|
||||
owned by this client. If not passed (and if no ``http``
|
||||
object is passed), falls back to the default inferred
|
||||
from the environment.
|
||||
|
||||
:type http: :class:`httplib2.Http` or class that defines ``request()``.
|
||||
:param http: An optional HTTP object to make requests. If not passed, an
|
||||
``http`` object is created that is bound to the
|
||||
``credentials`` for the current object.
|
||||
"""
|
||||
|
||||
_connection_class = Connection
|
||||
|
||||
def new_project(self, project_id, name=None, labels=None):
|
||||
"""Creates a :class:`.Project` bound to the current client.
|
||||
|
||||
Use :meth:`Project.reload() \
|
||||
<gcloud.resource_manager.project.Project.reload>` to retrieve
|
||||
project metadata after creating a :class:`.Project` instance.
|
||||
|
||||
.. note:
|
||||
|
||||
This does not make an API call.
|
||||
|
||||
:type project_id: str
|
||||
:param project_id: The ID for this project.
|
||||
|
||||
:type name: string
|
||||
:param name: The display name of the project.
|
||||
|
||||
:type labels: dict
|
||||
:param labels: A list of labels associated with the project.
|
||||
|
||||
:rtype: :class:`.Project`
|
||||
:returns: A new instance of a :class:`.Project` **without**
|
||||
any metadata loaded.
|
||||
"""
|
||||
return Project(project_id=project_id,
|
||||
client=self, name=name, labels=labels)
|
||||
|
||||
def fetch_project(self, project_id):
|
||||
"""Fetch an existing project and it's relevant metadata by ID.
|
||||
|
||||
.. note::
|
||||
|
||||
If the project does not exist, this will raise a
|
||||
:class:`NotFound <gcloud.exceptions.NotFound>` error.
|
||||
|
||||
:type project_id: str
|
||||
:param project_id: The ID for this project.
|
||||
|
||||
:rtype: :class:`.Project`
|
||||
:returns: A :class:`.Project` with metadata fetched from the API.
|
||||
"""
|
||||
project = self.new_project(project_id)
|
||||
project.reload()
|
||||
return project
|
||||
|
||||
def list_projects(self, filter_params=None, page_size=None):
|
||||
"""List the projects visible to this client.
|
||||
|
||||
Example::
|
||||
|
||||
>>> from gcloud import resource_manager
|
||||
>>> client = resource_manager.Client()
|
||||
>>> for project in client.list_projects():
|
||||
... print project.project_id
|
||||
|
||||
List all projects with label ``'environment'`` set to ``'prod'``
|
||||
(filtering by labels)::
|
||||
|
||||
>>> from gcloud import resource_manager
|
||||
>>> client = resource_manager.Client()
|
||||
>>> env_filter = {'labels.environment': 'prod'}
|
||||
>>> for project in client.list_projects(env_filter):
|
||||
... print project.project_id
|
||||
|
||||
See:
|
||||
https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/list
|
||||
|
||||
Complete filtering example::
|
||||
|
||||
>>> project_filter = { # Return projects with...
|
||||
... 'name': 'My Project', # name set to 'My Project'.
|
||||
... 'id': 'my-project-id', # id set to 'my-project-id'.
|
||||
... 'labels.stage': 'prod', # the label 'stage' set to 'prod'
|
||||
... 'labels.color': '*' # a label 'color' set to anything.
|
||||
... }
|
||||
>>> client.list_projects(project_filter)
|
||||
|
||||
:type filter_params: dict
|
||||
:param filter_params: (Optional) A dictionary of filter options where
|
||||
each key is a property to filter on, and each
|
||||
value is the (case-insensitive) value to check
|
||||
(or the glob ``*`` to check for existence of the
|
||||
property). See the example above for more
|
||||
details.
|
||||
|
||||
:type page_size: int
|
||||
:param page_size: (Optional) Maximum number of projects to return in a
|
||||
single page. If not passed, defaults to a value set
|
||||
by the API.
|
||||
|
||||
:rtype: :class:`_ProjectIterator`
|
||||
:returns: A project iterator. The iterator will make multiple API
|
||||
requests if you continue iterating and there are more
|
||||
pages of results. Each item returned will be a.
|
||||
:class:`.Project`.
|
||||
"""
|
||||
extra_params = {}
|
||||
|
||||
if page_size is not None:
|
||||
extra_params['pageSize'] = page_size
|
||||
|
||||
if filter_params is not None:
|
||||
extra_params['filter'] = filter_params
|
||||
|
||||
return _ProjectIterator(self, extra_params=extra_params)
|
||||
|
||||
|
||||
class _ProjectIterator(Iterator):
|
||||
"""An iterator over a list of Project resources.
|
||||
|
||||
You shouldn't have to use this directly, but instead should use the
|
||||
helper methods on :class:`gcloud.resource_manager.client.Client`
|
||||
objects.
|
||||
|
||||
:type client: :class:`gcloud.resource_manager.client.Client`
|
||||
:param client: The client to use for making connections.
|
||||
|
||||
:type extra_params: dict
|
||||
:param extra_params: (Optional) Extra query string parameters for
|
||||
the API call.
|
||||
"""
|
||||
|
||||
def __init__(self, client, extra_params=None):
|
||||
super(_ProjectIterator, self).__init__(client=client, path='/projects',
|
||||
extra_params=extra_params)
|
||||
|
||||
def get_items_from_response(self, response):
|
||||
"""Yield :class:`.Project` items from response.
|
||||
|
||||
:type response: dict
|
||||
:param response: The JSON API response for a page of projects.
|
||||
"""
|
||||
for resource in response.get('projects', []):
|
||||
item = Project.from_api_repr(resource, client=self.client)
|
||||
yield item
|
42
venv/Lib/site-packages/gcloud/resource_manager/connection.py
Normal file
42
venv/Lib/site-packages/gcloud/resource_manager/connection.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
# Copyright 2015 Google Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Create / interact with gcloud.resource_manager connections."""
|
||||
|
||||
|
||||
from gcloud import connection as base_connection
|
||||
|
||||
|
||||
class Connection(base_connection.JSONConnection):
|
||||
"""A connection to Google Cloud Resource Manager via the JSON REST API.
|
||||
|
||||
:type credentials: :class:`oauth2client.client.OAuth2Credentials`
|
||||
:param credentials: (Optional) The OAuth2 Credentials to use for this
|
||||
connection.
|
||||
|
||||
:type http: :class:`httplib2.Http` or class that defines ``request()``.
|
||||
:param http: (Optional) HTTP object to make requests.
|
||||
"""
|
||||
|
||||
API_BASE_URL = 'https://cloudresourcemanager.googleapis.com'
|
||||
"""The base of the API call URL."""
|
||||
|
||||
API_VERSION = 'v1beta1'
|
||||
"""The version of the API, used in building the API call's URL."""
|
||||
|
||||
API_URL_TEMPLATE = '{api_base_url}/{api_version}{path}'
|
||||
"""A template for the URL of a particular API call."""
|
||||
|
||||
SCOPE = ('https://www.googleapis.com/auth/cloud-platform',)
|
||||
"""The scopes required for authenticating as a Resouce Manager consumer."""
|
266
venv/Lib/site-packages/gcloud/resource_manager/project.py
Normal file
266
venv/Lib/site-packages/gcloud/resource_manager/project.py
Normal file
|
@ -0,0 +1,266 @@
|
|||
# Copyright 2015 Google Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Utility for managing projects via the Cloud Resource Manager API."""
|
||||
|
||||
|
||||
from gcloud.exceptions import NotFound
|
||||
|
||||
|
||||
class Project(object):
|
||||
"""Projects are containers for your work on Google Cloud Platform.
|
||||
|
||||
.. note::
|
||||
|
||||
A :class:`Project` can also be created via
|
||||
:meth:`Client.new_project() \
|
||||
<gcloud.resource_manager.client.Client.new_project>`
|
||||
|
||||
To manage labels on a :class:`Project`::
|
||||
|
||||
>>> from gcloud import resource_manager
|
||||
>>> client = resource_manager.Client()
|
||||
>>> project = client.new_project('purple-spaceship-123')
|
||||
>>> project.labels = {'color': 'purple'}
|
||||
>>> project.labels['environment'] = 'production'
|
||||
>>> project.update()
|
||||
|
||||
See:
|
||||
https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects
|
||||
|
||||
:type project_id: string
|
||||
:param project_id: The globally unique ID of the project.
|
||||
|
||||
:type client: :class:`gcloud.resource_manager.client.Client`
|
||||
:param client: The Client used with this project.
|
||||
|
||||
:type name: string
|
||||
:param name: The display name of the project.
|
||||
|
||||
:type labels: dict
|
||||
:param labels: A list of labels associated with the project.
|
||||
"""
|
||||
def __init__(self, project_id, client, name=None, labels=None):
|
||||
self._client = client
|
||||
self.project_id = project_id
|
||||
self.name = name
|
||||
self.number = None
|
||||
self.labels = labels or {}
|
||||
self.status = None
|
||||
|
||||
def __repr__(self):
|
||||
return '<Project: %r (%r)>' % (self.name, self.project_id)
|
||||
|
||||
@classmethod
|
||||
def from_api_repr(cls, resource, client):
|
||||
"""Factory: construct a project given its API representation.
|
||||
|
||||
:type resource: dict
|
||||
:param resource: project resource representation returned from the API
|
||||
|
||||
:type client: :class:`gcloud.resource_manager.client.Client`
|
||||
:param client: The Client used with this project.
|
||||
|
||||
:rtype: :class:`gcloud.resource_manager.project.Project`
|
||||
"""
|
||||
project = cls(project_id=resource['projectId'], client=client)
|
||||
project.set_properties_from_api_repr(resource)
|
||||
return project
|
||||
|
||||
def set_properties_from_api_repr(self, resource):
|
||||
"""Update specific properties from its API representation."""
|
||||
self.name = resource.get('name')
|
||||
self.number = resource['projectNumber']
|
||||
self.labels = resource.get('labels', {})
|
||||
self.status = resource['lifecycleState']
|
||||
|
||||
@property
|
||||
def full_name(self):
|
||||
"""Fully-qualified name (ie, ``'projects/purple-spaceship-123'``)."""
|
||||
if not self.project_id:
|
||||
raise ValueError('Missing project ID.')
|
||||
return 'projects/%s' % (self.project_id)
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
"""URL for the project (ie, ``'/projects/purple-spaceship-123'``)."""
|
||||
return '/%s' % (self.full_name)
|
||||
|
||||
def _require_client(self, client):
|
||||
"""Check client or verify over-ride.
|
||||
|
||||
:type client: :class:`gcloud.resource_manager.client.Client` or
|
||||
``NoneType``
|
||||
:param client: the client to use. If not passed, falls back to the
|
||||
``client`` stored on the current project.
|
||||
|
||||
:rtype: :class:`gcloud.resource_manager.client.Client`
|
||||
:returns: The client passed in or the currently bound client.
|
||||
"""
|
||||
if client is None:
|
||||
client = self._client
|
||||
return client
|
||||
|
||||
def create(self, client=None):
|
||||
"""API call: create the project via a ``POST`` request.
|
||||
|
||||
See
|
||||
https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/create
|
||||
|
||||
:type client: :class:`gcloud.resource_manager.client.Client` or
|
||||
:data:`NoneType <types.NoneType>`
|
||||
:param client: the client to use. If not passed, falls back to
|
||||
the client stored on the current project.
|
||||
"""
|
||||
client = self._require_client(client)
|
||||
|
||||
data = {
|
||||
'projectId': self.project_id,
|
||||
'name': self.name,
|
||||
'labels': self.labels,
|
||||
}
|
||||
resp = client.connection.api_request(method='POST', path='/projects',
|
||||
data=data)
|
||||
self.set_properties_from_api_repr(resource=resp)
|
||||
|
||||
def reload(self, client=None):
|
||||
"""API call: reload the project via a ``GET`` request.
|
||||
|
||||
This method will reload the newest metadata for the project. If you've
|
||||
created a new :class:`Project` instance via
|
||||
:meth:`Client.new_project() \
|
||||
<gcloud.resource_manager.client.Client.new_project>`,
|
||||
this method will retrieve project metadata.
|
||||
|
||||
.. warning::
|
||||
|
||||
This will overwrite any local changes you've made and not saved
|
||||
via :meth:`update`.
|
||||
|
||||
See
|
||||
https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/get
|
||||
|
||||
:type client: :class:`gcloud.resource_manager.client.Client` or
|
||||
:data:`NoneType <types.NoneType>`
|
||||
:param client: the client to use. If not passed, falls back to
|
||||
the client stored on the current project.
|
||||
"""
|
||||
client = self._require_client(client)
|
||||
|
||||
# We assume the project exists. If it doesn't it will raise a NotFound
|
||||
# exception.
|
||||
resp = client.connection.api_request(method='GET', path=self.path)
|
||||
self.set_properties_from_api_repr(resource=resp)
|
||||
|
||||
def exists(self, client=None):
|
||||
"""API call: test the existence of a project via a ``GET`` request.
|
||||
|
||||
See
|
||||
https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/get
|
||||
|
||||
:type client: :class:`gcloud.resource_manager.client.Client` or
|
||||
:data:`NoneType <types.NoneType>`
|
||||
:param client: the client to use. If not passed, falls back to
|
||||
the client stored on the current project.
|
||||
"""
|
||||
client = self._require_client(client)
|
||||
|
||||
try:
|
||||
# Note that we have to request the entire resource as the API
|
||||
# doesn't provide a way tocheck for existence only.
|
||||
client.connection.api_request(method='GET', path=self.path)
|
||||
except NotFound:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def update(self, client=None):
|
||||
"""API call: update the project via a ``PUT`` request.
|
||||
|
||||
See
|
||||
https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/update
|
||||
|
||||
:type client: :class:`gcloud.resource_manager.client.Client` or
|
||||
:data:`NoneType <types.NoneType>`
|
||||
:param client: the client to use. If not passed, falls back to
|
||||
the client stored on the current project.
|
||||
"""
|
||||
client = self._require_client(client)
|
||||
|
||||
data = {'name': self.name, 'labels': self.labels}
|
||||
resp = client.connection.api_request(method='PUT', path=self.path,
|
||||
data=data)
|
||||
self.set_properties_from_api_repr(resp)
|
||||
|
||||
def delete(self, client=None, reload_data=False):
|
||||
"""API call: delete the project via a ``DELETE`` request.
|
||||
|
||||
See:
|
||||
https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/delete
|
||||
|
||||
This actually changes the status (``lifecycleState``) from ``ACTIVE``
|
||||
to ``DELETE_REQUESTED``.
|
||||
Later (it's not specified when), the project will move into the
|
||||
``DELETE_IN_PROGRESS`` state, which means the deleting has actually
|
||||
begun.
|
||||
|
||||
:type client: :class:`gcloud.resource_manager.client.Client` or
|
||||
:data:`NoneType <types.NoneType>`
|
||||
:param client: the client to use. If not passed, falls back to
|
||||
the client stored on the current project.
|
||||
|
||||
:type reload_data: bool
|
||||
:param reload_data: Whether to reload the project with the latest
|
||||
state. If you want to get the updated status,
|
||||
you'll want this set to :data:`True` as the DELETE
|
||||
method doesn't send back the updated project.
|
||||
Default: :data:`False`.
|
||||
"""
|
||||
client = self._require_client(client)
|
||||
client.connection.api_request(method='DELETE', path=self.path)
|
||||
|
||||
# If the reload flag is set, reload the project.
|
||||
if reload_data:
|
||||
self.reload()
|
||||
|
||||
def undelete(self, client=None, reload_data=False):
|
||||
"""API call: undelete the project via a ``POST`` request.
|
||||
|
||||
See
|
||||
https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects/undelete
|
||||
|
||||
This actually changes the project status (``lifecycleState``) from
|
||||
``DELETE_REQUESTED`` to ``ACTIVE``.
|
||||
If the project has already reached a status of ``DELETE_IN_PROGRESS``,
|
||||
this request will fail and the project cannot be restored.
|
||||
|
||||
:type client: :class:`gcloud.resource_manager.client.Client` or
|
||||
:data:`NoneType <types.NoneType>`
|
||||
:param client: the client to use. If not passed, falls back to
|
||||
the client stored on the current project.
|
||||
|
||||
:type reload_data: bool
|
||||
:param reload_data: Whether to reload the project with the latest
|
||||
state. If you want to get the updated status,
|
||||
you'll want this set to :data:`True` as the DELETE
|
||||
method doesn't send back the updated project.
|
||||
Default: :data:`False`.
|
||||
"""
|
||||
client = self._require_client(client)
|
||||
client.connection.api_request(method='POST',
|
||||
path=self.path + ':undelete')
|
||||
|
||||
# If the reload flag is set, reload the project.
|
||||
if reload_data:
|
||||
self.reload()
|
296
venv/Lib/site-packages/gcloud/resource_manager/test_client.py
Normal file
296
venv/Lib/site-packages/gcloud/resource_manager/test_client.py
Normal file
|
@ -0,0 +1,296 @@
|
|||
# Copyright 2015 Google Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
import unittest2
|
||||
|
||||
|
||||
class Test__ProjectIterator(unittest2.TestCase):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from gcloud.resource_manager.client import _ProjectIterator
|
||||
return _ProjectIterator
|
||||
|
||||
def _makeOne(self, *args, **kw):
|
||||
return self._getTargetClass()(*args, **kw)
|
||||
|
||||
def test_constructor(self):
|
||||
client = object()
|
||||
iterator = self._makeOne(client)
|
||||
self.assertEqual(iterator.path, '/projects')
|
||||
self.assertEqual(iterator.page_number, 0)
|
||||
self.assertEqual(iterator.next_page_token, None)
|
||||
self.assertTrue(iterator.client is client)
|
||||
self.assertEqual(iterator.extra_params, {})
|
||||
|
||||
def test_get_items_from_response_empty(self):
|
||||
client = object()
|
||||
iterator = self._makeOne(client)
|
||||
self.assertEqual(list(iterator.get_items_from_response({})), [])
|
||||
|
||||
def test_get_items_from_response_non_empty(self):
|
||||
from gcloud.resource_manager.project import Project
|
||||
|
||||
PROJECT_ID = 'project-id'
|
||||
PROJECT_NAME = 'My Project Name'
|
||||
PROJECT_NUMBER = 12345678
|
||||
PROJECT_LABELS = {'env': 'prod'}
|
||||
PROJECT_LIFECYCLE_STATE = 'ACTIVE'
|
||||
API_RESOURCE = {
|
||||
'projectId': PROJECT_ID,
|
||||
'name': PROJECT_NAME,
|
||||
'projectNumber': PROJECT_NUMBER,
|
||||
'labels': PROJECT_LABELS,
|
||||
'lifecycleState': PROJECT_LIFECYCLE_STATE,
|
||||
}
|
||||
RESPONSE = {'projects': [API_RESOURCE]}
|
||||
|
||||
client = object()
|
||||
iterator = self._makeOne(client)
|
||||
projects = list(iterator.get_items_from_response(RESPONSE))
|
||||
|
||||
project, = projects
|
||||
self.assertTrue(isinstance(project, Project))
|
||||
self.assertEqual(project.project_id, PROJECT_ID)
|
||||
self.assertEqual(project._client, client)
|
||||
self.assertEqual(project.name, PROJECT_NAME)
|
||||
self.assertEqual(project.number, PROJECT_NUMBER)
|
||||
self.assertEqual(project.labels, PROJECT_LABELS)
|
||||
self.assertEqual(project.status, PROJECT_LIFECYCLE_STATE)
|
||||
|
||||
|
||||
class TestClient(unittest2.TestCase):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from gcloud.resource_manager.client import Client
|
||||
return Client
|
||||
|
||||
def _makeOne(self, *args, **kw):
|
||||
return self._getTargetClass()(*args, **kw)
|
||||
|
||||
def test_constructor(self):
|
||||
from gcloud.resource_manager.connection import Connection
|
||||
|
||||
http = object()
|
||||
credentials = _Credentials()
|
||||
client = self._makeOne(credentials=credentials, http=http)
|
||||
self.assertTrue(isinstance(client.connection, Connection))
|
||||
self.assertEqual(client.connection._credentials, credentials)
|
||||
self.assertEqual(client.connection._http, http)
|
||||
|
||||
def test_new_project_factory(self):
|
||||
from gcloud.resource_manager.project import Project
|
||||
|
||||
credentials = _Credentials()
|
||||
client = self._makeOne(credentials=credentials)
|
||||
project_id = 'project_id'
|
||||
name = object()
|
||||
labels = object()
|
||||
project = client.new_project(project_id, name=name, labels=labels)
|
||||
|
||||
self.assertTrue(isinstance(project, Project))
|
||||
self.assertEqual(project._client, client)
|
||||
self.assertEqual(project.project_id, project_id)
|
||||
self.assertEqual(project.name, name)
|
||||
self.assertEqual(project.labels, labels)
|
||||
|
||||
def test_fetch_project(self):
|
||||
from gcloud.resource_manager.project import Project
|
||||
|
||||
project_id = 'project-id'
|
||||
project_number = 123
|
||||
project_name = 'Project Name'
|
||||
labels = {'env': 'prod'}
|
||||
project_resource = {
|
||||
'projectId': project_id,
|
||||
'projectNumber': project_number,
|
||||
'name': project_name,
|
||||
'labels': labels,
|
||||
'lifecycleState': 'ACTIVE',
|
||||
}
|
||||
|
||||
credentials = _Credentials()
|
||||
client = self._makeOne(credentials=credentials)
|
||||
# Patch the connection with one we can easily control.
|
||||
client.connection = _Connection(project_resource)
|
||||
|
||||
project = client.fetch_project(project_id)
|
||||
self.assertTrue(isinstance(project, Project))
|
||||
self.assertEqual(project._client, client)
|
||||
self.assertEqual(project.project_id, project_id)
|
||||
self.assertEqual(project.name, project_name)
|
||||
self.assertEqual(project.labels, labels)
|
||||
|
||||
def test_list_projects_return_type(self):
|
||||
from gcloud.resource_manager.client import _ProjectIterator
|
||||
|
||||
credentials = _Credentials()
|
||||
client = self._makeOne(credentials=credentials)
|
||||
# Patch the connection with one we can easily control.
|
||||
client.connection = _Connection({})
|
||||
|
||||
results = client.list_projects()
|
||||
self.assertIsInstance(results, _ProjectIterator)
|
||||
|
||||
def test_list_projects_no_paging(self):
|
||||
credentials = _Credentials()
|
||||
client = self._makeOne(credentials=credentials)
|
||||
|
||||
PROJECT_ID = 'project-id'
|
||||
PROJECT_NUMBER = 1
|
||||
STATUS = 'ACTIVE'
|
||||
PROJECTS_RESOURCE = {
|
||||
'projects': [
|
||||
{
|
||||
'projectId': PROJECT_ID,
|
||||
'projectNumber': PROJECT_NUMBER,
|
||||
'lifecycleState': STATUS,
|
||||
},
|
||||
],
|
||||
}
|
||||
# Patch the connection with one we can easily control.
|
||||
client.connection = _Connection(PROJECTS_RESOURCE)
|
||||
# Make sure there will be no paging.
|
||||
self.assertFalse('nextPageToken' in PROJECTS_RESOURCE)
|
||||
|
||||
results = list(client.list_projects())
|
||||
|
||||
project, = results
|
||||
self.assertEqual(project.project_id, PROJECT_ID)
|
||||
self.assertEqual(project.number, PROJECT_NUMBER)
|
||||
self.assertEqual(project.status, STATUS)
|
||||
|
||||
def test_list_projects_with_paging(self):
|
||||
credentials = _Credentials()
|
||||
client = self._makeOne(credentials=credentials)
|
||||
|
||||
PROJECT_ID1 = 'project-id'
|
||||
PROJECT_NUMBER1 = 1
|
||||
STATUS = 'ACTIVE'
|
||||
TOKEN = 'next-page-token'
|
||||
FIRST_PROJECTS_RESOURCE = {
|
||||
'projects': [
|
||||
{
|
||||
'projectId': PROJECT_ID1,
|
||||
'projectNumber': PROJECT_NUMBER1,
|
||||
'lifecycleState': STATUS,
|
||||
},
|
||||
],
|
||||
'nextPageToken': TOKEN,
|
||||
}
|
||||
PROJECT_ID2 = 'project-id-2'
|
||||
PROJECT_NUMBER2 = 42
|
||||
SECOND_PROJECTS_RESOURCE = {
|
||||
'projects': [
|
||||
{
|
||||
'projectId': PROJECT_ID2,
|
||||
'projectNumber': PROJECT_NUMBER2,
|
||||
'lifecycleState': STATUS,
|
||||
},
|
||||
],
|
||||
}
|
||||
# Patch the connection with one we can easily control.
|
||||
client.connection = _Connection(FIRST_PROJECTS_RESOURCE,
|
||||
SECOND_PROJECTS_RESOURCE)
|
||||
|
||||
# Page size = 1 with two response means we'll have two requests.
|
||||
results = list(client.list_projects(page_size=1))
|
||||
|
||||
# Check that the results are as expected.
|
||||
project1, project2 = results
|
||||
self.assertEqual(project1.project_id, PROJECT_ID1)
|
||||
self.assertEqual(project1.number, PROJECT_NUMBER1)
|
||||
self.assertEqual(project1.status, STATUS)
|
||||
self.assertEqual(project2.project_id, PROJECT_ID2)
|
||||
self.assertEqual(project2.number, PROJECT_NUMBER2)
|
||||
self.assertEqual(project2.status, STATUS)
|
||||
|
||||
# Check that two requests were required since page_size=1.
|
||||
request1, request2 = client.connection._requested
|
||||
self.assertEqual(request1, {
|
||||
'path': '/projects',
|
||||
'method': 'GET',
|
||||
'query_params': {
|
||||
'pageSize': 1,
|
||||
},
|
||||
})
|
||||
self.assertEqual(request2, {
|
||||
'path': '/projects',
|
||||
'method': 'GET',
|
||||
'query_params': {
|
||||
'pageSize': 1,
|
||||
'pageToken': TOKEN,
|
||||
},
|
||||
})
|
||||
|
||||
def test_list_projects_with_filter(self):
|
||||
credentials = _Credentials()
|
||||
client = self._makeOne(credentials=credentials)
|
||||
|
||||
PROJECT_ID = 'project-id'
|
||||
PROJECT_NUMBER = 1
|
||||
STATUS = 'ACTIVE'
|
||||
PROJECTS_RESOURCE = {
|
||||
'projects': [
|
||||
{
|
||||
'projectId': PROJECT_ID,
|
||||
'projectNumber': PROJECT_NUMBER,
|
||||
'lifecycleState': STATUS,
|
||||
},
|
||||
],
|
||||
}
|
||||
# Patch the connection with one we can easily control.
|
||||
client.connection = _Connection(PROJECTS_RESOURCE)
|
||||
|
||||
FILTER_PARAMS = {'id': 'project-id'}
|
||||
results = list(client.list_projects(filter_params=FILTER_PARAMS))
|
||||
|
||||
project, = results
|
||||
self.assertEqual(project.project_id, PROJECT_ID)
|
||||
self.assertEqual(project.number, PROJECT_NUMBER)
|
||||
self.assertEqual(project.status, STATUS)
|
||||
|
||||
# Check that the filter made it in the request.
|
||||
request, = client.connection._requested
|
||||
self.assertEqual(request, {
|
||||
'path': '/projects',
|
||||
'method': 'GET',
|
||||
'query_params': {
|
||||
'filter': FILTER_PARAMS,
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
class _Credentials(object):
|
||||
|
||||
_scopes = None
|
||||
|
||||
@staticmethod
|
||||
def create_scoped_required():
|
||||
return True
|
||||
|
||||
def create_scoped(self, scope):
|
||||
self._scopes = scope
|
||||
return self
|
||||
|
||||
|
||||
class _Connection(object):
|
||||
|
||||
def __init__(self, *responses):
|
||||
self._responses = responses
|
||||
self._requested = []
|
||||
|
||||
def api_request(self, **kw):
|
||||
self._requested.append(kw)
|
||||
response, self._responses = self._responses[0], self._responses[1:]
|
||||
return response
|
|
@ -0,0 +1,46 @@
|
|||
# Copyright 2015 Google Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
import unittest2
|
||||
|
||||
|
||||
class TestConnection(unittest2.TestCase):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from gcloud.resource_manager.connection import Connection
|
||||
return Connection
|
||||
|
||||
def _makeOne(self, *args, **kw):
|
||||
return self._getTargetClass()(*args, **kw)
|
||||
|
||||
def test_build_api_url_no_extra_query_params(self):
|
||||
conn = self._makeOne()
|
||||
URI = '/'.join([
|
||||
conn.API_BASE_URL,
|
||||
conn.API_VERSION,
|
||||
'foo',
|
||||
])
|
||||
self.assertEqual(conn.build_api_url('/foo'), URI)
|
||||
|
||||
def test_build_api_url_w_extra_query_params(self):
|
||||
from six.moves.urllib.parse import parse_qsl
|
||||
from six.moves.urllib.parse import urlsplit
|
||||
conn = self._makeOne()
|
||||
uri = conn.build_api_url('/foo', {'bar': 'baz'})
|
||||
scheme, netloc, path, qs, _ = urlsplit(uri)
|
||||
self.assertEqual('%s://%s' % (scheme, netloc), conn.API_BASE_URL)
|
||||
self.assertEqual(path,
|
||||
'/'.join(['', conn.API_VERSION, 'foo']))
|
||||
parms = dict(parse_qsl(qs))
|
||||
self.assertEqual(parms['bar'], 'baz')
|
340
venv/Lib/site-packages/gcloud/resource_manager/test_project.py
Normal file
340
venv/Lib/site-packages/gcloud/resource_manager/test_project.py
Normal file
|
@ -0,0 +1,340 @@
|
|||
# Copyright 2015 Google Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
|
||||
import unittest2
|
||||
|
||||
|
||||
class TestProject(unittest2.TestCase):
|
||||
|
||||
def _getTargetClass(self):
|
||||
from gcloud.resource_manager.project import Project
|
||||
return Project
|
||||
|
||||
def _makeOne(self, *args, **kw):
|
||||
return self._getTargetClass()(*args, **kw)
|
||||
|
||||
def test_constructor_defaults(self):
|
||||
client = object()
|
||||
PROJECT_ID = 'project-id'
|
||||
project = self._makeOne(PROJECT_ID, client)
|
||||
self.assertEqual(project.project_id, PROJECT_ID)
|
||||
self.assertEqual(project._client, client)
|
||||
self.assertEqual(project.name, None)
|
||||
self.assertEqual(project.number, None)
|
||||
self.assertEqual(project.labels, {})
|
||||
self.assertEqual(project.status, None)
|
||||
|
||||
def test_constructor_explicit(self):
|
||||
client = object()
|
||||
PROJECT_ID = 'project-id'
|
||||
DISPLAY_NAME = 'name'
|
||||
LABELS = {'foo': 'bar'}
|
||||
project = self._makeOne(PROJECT_ID, client,
|
||||
name=DISPLAY_NAME, labels=LABELS)
|
||||
self.assertEqual(project.project_id, PROJECT_ID)
|
||||
self.assertEqual(project._client, client)
|
||||
self.assertEqual(project.name, DISPLAY_NAME)
|
||||
self.assertEqual(project.number, None)
|
||||
self.assertEqual(project.labels, LABELS)
|
||||
self.assertEqual(project.status, None)
|
||||
|
||||
def test_from_api_repr(self):
|
||||
client = object()
|
||||
PROJECT_ID = 'project-id'
|
||||
PROJECT_NAME = 'My Project Name'
|
||||
PROJECT_NUMBER = 12345678
|
||||
PROJECT_LABELS = {'env': 'prod'}
|
||||
PROJECT_LIFECYCLE_STATE = 'ACTIVE'
|
||||
resource = {'projectId': PROJECT_ID,
|
||||
'name': PROJECT_NAME,
|
||||
'projectNumber': PROJECT_NUMBER,
|
||||
'labels': PROJECT_LABELS,
|
||||
'lifecycleState': PROJECT_LIFECYCLE_STATE}
|
||||
project = self._getTargetClass().from_api_repr(resource, client)
|
||||
self.assertEqual(project.project_id, PROJECT_ID)
|
||||
self.assertEqual(project._client, client)
|
||||
self.assertEqual(project.name, PROJECT_NAME)
|
||||
self.assertEqual(project.number, PROJECT_NUMBER)
|
||||
self.assertEqual(project.labels, PROJECT_LABELS)
|
||||
self.assertEqual(project.status, PROJECT_LIFECYCLE_STATE)
|
||||
|
||||
def test_full_name(self):
|
||||
PROJECT_ID = 'project-id'
|
||||
project = self._makeOne(PROJECT_ID, None)
|
||||
self.assertEqual('projects/%s' % PROJECT_ID, project.full_name)
|
||||
|
||||
def test_full_name_missing_id(self):
|
||||
project = self._makeOne(None, None)
|
||||
with self.assertRaises(ValueError):
|
||||
self.assertIsNone(project.full_name)
|
||||
|
||||
def test_path(self):
|
||||
PROJECT_ID = 'project-id'
|
||||
project = self._makeOne(PROJECT_ID, None)
|
||||
self.assertEqual('/projects/%s' % PROJECT_ID, project.path)
|
||||
|
||||
def test_create(self):
|
||||
PROJECT_ID = 'project-id'
|
||||
PROJECT_NUMBER = 123
|
||||
PROJECT_RESOURCE = {
|
||||
'projectId': PROJECT_ID,
|
||||
'projectNumber': PROJECT_NUMBER,
|
||||
'name': 'Project Name',
|
||||
'labels': {},
|
||||
'lifecycleState': 'ACTIVE',
|
||||
}
|
||||
connection = _Connection(PROJECT_RESOURCE)
|
||||
client = _Client(connection=connection)
|
||||
project = self._makeOne(PROJECT_ID, client)
|
||||
self.assertEqual(project.number, None)
|
||||
project.create()
|
||||
self.assertEqual(project.number, PROJECT_NUMBER)
|
||||
request, = connection._requested
|
||||
|
||||
expected_request = {
|
||||
'method': 'POST',
|
||||
'data': {
|
||||
'projectId': PROJECT_ID,
|
||||
'labels': {},
|
||||
'name': None,
|
||||
},
|
||||
'path': '/projects',
|
||||
}
|
||||
self.assertEqual(request, expected_request)
|
||||
|
||||
def test_reload(self):
|
||||
PROJECT_ID = 'project-id'
|
||||
PROJECT_NUMBER = 123
|
||||
PROJECT_RESOURCE = {
|
||||
'projectId': PROJECT_ID,
|
||||
'projectNumber': PROJECT_NUMBER,
|
||||
'name': 'Project Name',
|
||||
'labels': {'env': 'prod'},
|
||||
'lifecycleState': 'ACTIVE',
|
||||
}
|
||||
connection = _Connection(PROJECT_RESOURCE)
|
||||
client = _Client(connection=connection)
|
||||
project = self._makeOne(PROJECT_ID, client)
|
||||
self.assertEqual(project.number, None)
|
||||
self.assertEqual(project.name, None)
|
||||
self.assertEqual(project.labels, {})
|
||||
self.assertEqual(project.status, None)
|
||||
project.reload()
|
||||
self.assertEqual(project.name, PROJECT_RESOURCE['name'])
|
||||
self.assertEqual(project.number, PROJECT_NUMBER)
|
||||
self.assertEqual(project.labels, PROJECT_RESOURCE['labels'])
|
||||
self.assertEqual(project.status, PROJECT_RESOURCE['lifecycleState'])
|
||||
|
||||
request, = connection._requested
|
||||
# NOTE: data is not in the request since a GET request.
|
||||
expected_request = {
|
||||
'method': 'GET',
|
||||
'path': project.path,
|
||||
}
|
||||
self.assertEqual(request, expected_request)
|
||||
|
||||
def test_exists(self):
|
||||
PROJECT_ID = 'project-id'
|
||||
connection = _Connection({'projectId': PROJECT_ID})
|
||||
client = _Client(connection=connection)
|
||||
project = self._makeOne(PROJECT_ID, client)
|
||||
self.assertTrue(project.exists())
|
||||
|
||||
def test_exists_with_explicitly_passed_client(self):
|
||||
PROJECT_ID = 'project-id'
|
||||
connection = _Connection({'projectId': PROJECT_ID})
|
||||
client = _Client(connection=connection)
|
||||
project = self._makeOne(PROJECT_ID, None)
|
||||
self.assertTrue(project.exists(client=client))
|
||||
|
||||
def test_exists_with_missing_client(self):
|
||||
PROJECT_ID = 'project-id'
|
||||
project = self._makeOne(PROJECT_ID, None)
|
||||
with self.assertRaises(AttributeError):
|
||||
project.exists()
|
||||
|
||||
def test_exists_not_found(self):
|
||||
PROJECT_ID = 'project-id'
|
||||
connection = _Connection()
|
||||
client = _Client(connection=connection)
|
||||
project = self._makeOne(PROJECT_ID, client)
|
||||
self.assertFalse(project.exists())
|
||||
|
||||
def test_update(self):
|
||||
PROJECT_ID = 'project-id'
|
||||
PROJECT_NUMBER = 123
|
||||
PROJECT_NAME = 'Project Name'
|
||||
LABELS = {'env': 'prod'}
|
||||
PROJECT_RESOURCE = {
|
||||
'projectId': PROJECT_ID,
|
||||
'projectNumber': PROJECT_NUMBER,
|
||||
'name': PROJECT_NAME,
|
||||
'labels': LABELS,
|
||||
'lifecycleState': 'ACTIVE',
|
||||
}
|
||||
connection = _Connection(PROJECT_RESOURCE)
|
||||
client = _Client(connection=connection)
|
||||
project = self._makeOne(PROJECT_ID, client)
|
||||
project.name = PROJECT_NAME
|
||||
project.labels = LABELS
|
||||
project.update()
|
||||
|
||||
request, = connection._requested
|
||||
expected_request = {
|
||||
'method': 'PUT',
|
||||
'data': {
|
||||
'name': PROJECT_NAME,
|
||||
'labels': LABELS,
|
||||
},
|
||||
'path': project.path,
|
||||
}
|
||||
self.assertEqual(request, expected_request)
|
||||
|
||||
def test_delete_without_reload_data(self):
|
||||
PROJECT_ID = 'project-id'
|
||||
PROJECT_NUMBER = 123
|
||||
PROJECT_RESOURCE = {
|
||||
'projectId': PROJECT_ID,
|
||||
'projectNumber': PROJECT_NUMBER,
|
||||
'name': 'Project Name',
|
||||
'labels': {'env': 'prod'},
|
||||
'lifecycleState': 'ACTIVE',
|
||||
}
|
||||
connection = _Connection(PROJECT_RESOURCE)
|
||||
client = _Client(connection=connection)
|
||||
project = self._makeOne(PROJECT_ID, client)
|
||||
project.delete(reload_data=False)
|
||||
|
||||
request, = connection._requested
|
||||
# NOTE: data is not in the request since a DELETE request.
|
||||
expected_request = {
|
||||
'method': 'DELETE',
|
||||
'path': project.path,
|
||||
}
|
||||
self.assertEqual(request, expected_request)
|
||||
|
||||
def test_delete_with_reload_data(self):
|
||||
PROJECT_ID = 'project-id'
|
||||
PROJECT_NUMBER = 123
|
||||
PROJECT_RESOURCE = {
|
||||
'projectId': PROJECT_ID,
|
||||
'projectNumber': PROJECT_NUMBER,
|
||||
'name': 'Project Name',
|
||||
'labels': {'env': 'prod'},
|
||||
'lifecycleState': 'ACTIVE',
|
||||
}
|
||||
DELETING_PROJECT = PROJECT_RESOURCE.copy()
|
||||
DELETING_PROJECT['lifecycleState'] = NEW_STATE = 'DELETE_REQUESTED'
|
||||
|
||||
connection = _Connection(PROJECT_RESOURCE, DELETING_PROJECT)
|
||||
client = _Client(connection=connection)
|
||||
project = self._makeOne(PROJECT_ID, client)
|
||||
project.delete(reload_data=True)
|
||||
self.assertEqual(project.status, NEW_STATE)
|
||||
|
||||
delete_request, get_request = connection._requested
|
||||
# NOTE: data is not in the request since a DELETE request.
|
||||
expected_delete_request = {
|
||||
'method': 'DELETE',
|
||||
'path': project.path,
|
||||
}
|
||||
self.assertEqual(delete_request, expected_delete_request)
|
||||
|
||||
# NOTE: data is not in the request since a GET request.
|
||||
expected_get_request = {
|
||||
'method': 'GET',
|
||||
'path': project.path,
|
||||
}
|
||||
self.assertEqual(get_request, expected_get_request)
|
||||
|
||||
def test_undelete_without_reload_data(self):
|
||||
PROJECT_ID = 'project-id'
|
||||
PROJECT_NUMBER = 123
|
||||
PROJECT_RESOURCE = {
|
||||
'projectId': PROJECT_ID,
|
||||
'projectNumber': PROJECT_NUMBER,
|
||||
'name': 'Project Name',
|
||||
'labels': {'env': 'prod'},
|
||||
'lifecycleState': 'DELETE_REQUESTED',
|
||||
}
|
||||
connection = _Connection(PROJECT_RESOURCE)
|
||||
client = _Client(connection=connection)
|
||||
project = self._makeOne(PROJECT_ID, client)
|
||||
project.undelete(reload_data=False)
|
||||
|
||||
request, = connection._requested
|
||||
# NOTE: data is not in the request, undelete doesn't need it.
|
||||
expected_request = {
|
||||
'method': 'POST',
|
||||
'path': project.path + ':undelete',
|
||||
}
|
||||
self.assertEqual(request, expected_request)
|
||||
|
||||
def test_undelete_with_reload_data(self):
|
||||
PROJECT_ID = 'project-id'
|
||||
PROJECT_NUMBER = 123
|
||||
PROJECT_RESOURCE = {
|
||||
'projectId': PROJECT_ID,
|
||||
'projectNumber': PROJECT_NUMBER,
|
||||
'name': 'Project Name',
|
||||
'labels': {'env': 'prod'},
|
||||
'lifecycleState': 'DELETE_REQUESTED',
|
||||
}
|
||||
UNDELETED_PROJECT = PROJECT_RESOURCE.copy()
|
||||
UNDELETED_PROJECT['lifecycleState'] = NEW_STATE = 'ACTIVE'
|
||||
|
||||
connection = _Connection(PROJECT_RESOURCE, UNDELETED_PROJECT)
|
||||
client = _Client(connection=connection)
|
||||
project = self._makeOne(PROJECT_ID, client)
|
||||
project.undelete(reload_data=True)
|
||||
self.assertEqual(project.status, NEW_STATE)
|
||||
|
||||
undelete_request, get_request = connection._requested
|
||||
# NOTE: data is not in the request, undelete doesn't need it.
|
||||
expected_undelete_request = {
|
||||
'method': 'POST',
|
||||
'path': project.path + ':undelete',
|
||||
}
|
||||
self.assertEqual(undelete_request, expected_undelete_request)
|
||||
|
||||
# NOTE: data is not in the request since a GET request.
|
||||
expected_get_request = {
|
||||
'method': 'GET',
|
||||
'path': project.path,
|
||||
}
|
||||
self.assertEqual(get_request, expected_get_request)
|
||||
|
||||
|
||||
class _Connection(object):
|
||||
|
||||
def __init__(self, *responses):
|
||||
self._responses = responses
|
||||
self._requested = []
|
||||
|
||||
def api_request(self, **kw):
|
||||
from gcloud.exceptions import NotFound
|
||||
self._requested.append(kw)
|
||||
|
||||
try:
|
||||
response, self._responses = self._responses[0], self._responses[1:]
|
||||
except:
|
||||
raise NotFound('miss')
|
||||
else:
|
||||
return response
|
||||
|
||||
|
||||
class _Client(object):
|
||||
|
||||
def __init__(self, connection=None):
|
||||
self.connection = connection
|
Loading…
Add table
Add a link
Reference in a new issue