10000 Add access to dictionary entries as attributes and fix some tests · codeplay/cf-python-client@a438813 · GitHub
[go: up one dir, main page]

Skip to content

Commit a438813

Browse files
author
Ben Einaudi
committed
Add access to dictionary entries as attributes and fix some tests
1 parent 4bf75f0 commit a438813

File tree

9 files changed

+132
-130
lines changed

9 10000 files changed

+132
-130
lines changed

integration/python/v2/test_applications.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ def test_list(self):
5757

5858
def test_start(self):
5959
client = build_client_from_configuration()
60-
_logger.debug('start - %s', client.application.start(client.app_guid, False))
60+
61+
_logger.debug('start - %s', client.application.start(client.app_guid, async=False))
6162

6263
def test_stop(self):
6364
client = build_client_from_configuration()
64-
_logger.debug('stop - %s', client.application.stop(client.app_guid, False))
65+
_logger.debug('stop - %s', client.application.stop(client.app_guid, async=False))
6566

integration/python/v2/test_service_plans.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
class TestServicePlan(unittest.TestCase):
1111
def test_list_instance_for_plan(self):
1212
client = build_client_from_configuration()
13-
for instance in client.service_plan.list_instance(client.plan_guid, space_guid=client.space_guid):
13+
for instance in client.service_plan.list_instances(client.plan_guid, space_guid=client.space_guid):
1414
_logger.debug('test_list_instance_for_plan - %s -%s', instance['metadata']['guid'], instance['entity']['name'])
1515

1616
def test_list_by_broker(self):

src/python/cloudfoundry_client/calls.py

Lines changed: 0 additions & 107 deletions
This file was deleted.

src/python/cloudfoundry_client/entities.py

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
_logger = logging.getLogger(__name__)
66

77

8+
class JsonObject(dict):
9+
def __init__(self, *args, **kwargs):
10+
super(JsonObject, self).__init__(*args, **kwargs)
11+
self.__dict__ = self
12+
13+
814
class InvalidStatusCode(Exception):
915
def __init__(self, status_code, body):
1016
self.status_code = status_code
@@ -26,18 +32,18 @@ def __init__(self, target_endpoint, credentials_manager, entity_uri):
2632
self.credentials_manager = credentials_manager
2733

2834
def _get_one(self, url):
29-
return EntityManager._check_response(self.credentials_manager.get(url)).json()
35+
return EntityManager._read_response(EntityManager._check_response(self.credentials_manager.get(url)))
3036

3137
def _create(self, data):
3238
response = EntityManager._check_response(self.credentials_manager.post(self.base_url, json=data))
3339
_logger.debug('POST - %s - %s', self.base_url, response.text)
34-
return response.json()
40+
return EntityManager._read_response(response)
3541

3642
def _update(self, resource_id, data):
3743
response = EntityManager._check_response(self.credentials_manager.put('%s/%s' % (self.base_url, resource_id),
3844
json=data))
3945
_logger.debug('PUT - %s/%s - %s', self.base_url, resource_id, response.text)
40-
return response.json()
46+
return EntityManager._read_response(response)
4147

4248
def _remove(self, resource_id):
4349
response = EntityManager._check_response(
@@ -54,22 +60,22 @@ def list(self, *extra_paths, **kwargs):
5460
.get(url_requested))
5561
while True:
5662
_logger.debug('GET - %s - %s', url_requested, response.text)
57-
response_json = response.json()
58-
for resource in response_json['resources']:
63+
response_json = EntityManager._read_response(response)
64+
for resource in response_json.resources:
5965
yield resource
60-
if response_json['next_url'] is None:
66+
if response_json.next_url is None:
6167
break
6268
else:
63-
url_requested = '%s%s' % (self.target_endpoint, response_json['next_url'])
69+
url_requested = '%s%s' % (self.target_endpoint, response_json.next_url)
6470
response = EntityManager._check_response(self.credentials_manager.get(url_requested))
6571

6672
def get_first(self, **kwargs):
6773
response = EntityManager._check_response(self.credentials_manager
6874
.get(EntityManager._get_url_filtered(self.base_url, **kwargs)))
6975
_logger.debug('GET - %s - %s', self.base_url, response.text)
70-
response_json = response.json()
71-
if len(response_json['resources']) > 0:
72-
return response_json['resources'][0]
76+
response_json = EntityManager._read_response(response)
77+
if len(response_json.resources) > 0:
78+
return response_json.resources[0]
7379
else:
7480
return None
7581

@@ -81,7 +87,7 @@ def get(self, entity_id, *extra_paths):
8187
requested_path = '%s/%s/%s' % (self.base_url, entity_id, '/'.join(extra_paths))
8288
response = EntityManager._check_response(self.credentials_manager.get(requested_path))
8389
_logger.debug('GET - %s - %s', requested_path, response.text)
84-
return response.json()
90+
return EntityManager._read_response(response)
8591

8692
@staticmethod
8793
def _get_url_filtered(url, **kwargs):
@@ -115,3 +121,13 @@ def _check_response(response):
115121
except Exception, _:
116122
body = response.text
117123
raise InvalidStatusCode(response.status_code, body)
124+
125+
@staticmethod
126+
def _read_response(response):
127+
def _to_attr_object(pairs):
128+
result = JsonObject()
129+
for k in pairs:
130+
result[k[0]] = k[1]
131+
return result
132+
133+
return response.json(object_pairs_hook=_to_attr_object)

src/python/cloudfoundry_client/main.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ def main():
207207
resource_id = resolve_id(arguments.id[0], lambda x: client.application.get_first(name=x), 'application', True)
208208
for entity in client.application.list(resource_id, arguments.action):
209209
name_property = application_extra_list_commands[arguments.action][1]
210-
print('%s - %s' % (entity['metadata']['guid'], entity['entity'][name_property]))
210+
print('%s - %s' % (entity.metadata.guid, entity.entity[name_property]))
211211
elif arguments.action.find('list_') == 0:
212212
domain = arguments.action[len('list_'): len(arguments.action) - 1]
213213
filter_list = dict()
@@ -218,9 +218,9 @@ def main():
218218
for entity in getattr(client, domain).list(**filter_list):
219219
name_property = commands[domain]['name']
220220
if name_property is not None:
221-
print('%s - %s' % (entity['metadata']['guid'], entity['entity'][name_property]))
221+
print('%s - %s' % (entity.metadata.guid, entity.entity[name_property]))
222222
else:
223-
print(entity['metadata']['guid'])
223+
print(entity.metadata.guid)
224224
elif arguments.action.find('get_') == 0:
225225
domain = arguments.action[len('get_'):]
226226
resource_id = resolve_id(arguments.id[0],
@@ -254,7 +254,7 @@ def main():
254254
if entity is None:
255255
raise InvalidStatusCode(httplib.NOT_FOUND, '%s with name %s' % (domain, arguments.id[0]))
256256
else:
257-
getattr(client, domain)._remove(entity['metadata']['guid'])
257+
getattr(client, domain)._remove(entity.metadata.guid)
258258
else:
259259
raise ValueError('id: %s: does not allow search by name' % domain)
260260

src/python/cloudfoundry_client/v2/applications.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import httplib
2-
import json
32
import logging
43
from time import sleep
54

@@ -72,4 +71,6 @@ def _safe_get_instances(self, application_guid):
7271
# 220001: instances error
7372
if code == 220001 or code == 170002:
7473
return {}
74+
else:
75+
_logger.error("")
7576
raise
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"code": 220001,
3+
"error_code": "CF-InstancesError",
4+
"description": "Instances error: Request failed for app: test as the app is in stopped state."
5+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
2+
{
3+
"version": "0b9e28b8-b69d-46ba-ad7e-6c83899826b2",
4+
"staging_failed_reason": null,
5+
"docker_credentials_json": {
6+
"redacted_message": "[PRIVATE DATA HIDDEN]"
7+
},
8+
"staging_failed_description": null,
9+
"instances": 1,
10+
"guid": "a5eee659-56a7-4123-91ac-ba190ddc5477",
11+
"docker_image": null,
12+
"diego": true,
13+
"console": false,
14+
"package_state": "STAGED",
15+
"state": "STOPPED",
16+
"production": false,
17+
"stack_guid": "3cb62b55-3230-45d1-a297-ace25b3e3479",
18+
"memory": 512,
19+
"package_updated_at": "2016-08-10T14:01:54Z",
20+
"staging_task_id": "c80457643d7d455c93f92151d6384c2d",
21+
"buildpack": null,
22+
"enable_ssh": true,
23+
"detected_start_command": "sh boot.sh",
24+
"disk_quota": 1024,
25+
"routes": [
26+
{
27+
"path": "",
28+
"host": "application_name",
29+
"guid": "6c7d07f9-57a1-474e-8e91-82a597550956",
30+
"port": null,
31+
"domain": {
32+
"guid": "f030f4bb-2b60-47e9-be3e-8105655c0286",
33+
"name": "some-domain"
34+
}
35+
}
36+
],
37+
"services": [],
38+
"detected_buildpack": "staticfile 1.3.8",
39+
"space_guid": "6c99652b-4795-416c-9466-64a3e4555627",
40+
"name": "application_name",
41+
"running_instances": 0,
42+
"health_check_type": "port",
43+
"command": null,
44+
"debug": null,
45+
"available_domains": [
46+
{
47+
"guid": "255b9370-3836-402c-9e1f-08b2a96dd180",
48+
"name": "some-domain",
49+
"owning_organization_guid": "d7d77408-a250-45e3-8de5-71fcf199bbab"
50+
},
51+
{
52+
"guid": "f030f4bb-2b60-47e9-be3e-8105655c0286",
53+
"name": "other-domain",
54+
"owning_organization_guid": "d7d77408-a250-45e3-8de5-71fcf199bbab"
55+
}
56+
],
57+
"environment_json": {},
58+
"ports": null,
59+
"health_check_timeout": null
60+
}

test/python/test_applications.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,17 @@ def test_get_routes(self):
7272
self.credential_manager.get.assert_called_with(self.credential_manager.get.return_value.url)
7373
self.assertEqual(cpt, 1)
7474

75+
def test_get_sumary(self):
76+
self.credential_manager.get.return_value = mock_response(
77+
'/v2/apps/app_id/summary',
78+
httplib.OK,
79+
None,
80+
'v2', 'apps', 'GET_{id}_summary_response.json')
81+
application = self.applications.get_summary('app_id')
82+
83+
self.credential_manager.get.assert_called_with(self.credential_manager.get.return_value.url)
84+
self.assertIsNotNone(application)
85+
7586
def test_get(self):
7687
self.credential_manager.get.return_value = mock_response(
7788
'/v2/apps/app_id',
@@ -88,16 +99,30 @@ def test_start(self):
8899
httplib.CREATED,
89100
None,
90101
'v2', 'apps', 'PUT_{id}_response.json')
91-
self.credential_manager.get.return_value = mock_response(
102+
mock_summary = mock_response(
103+
'/v2/apps/app_id/summary',
104+
httplib.OK,
105+
None,
106+
'v2', 'apps', 'GET_{id}_summary_response.json')
107+
mock_instances_stopped = mock_response(
108+
'/v2/apps/app_id/instances',
109+
httplib.BAD_REQUEST,
110+
None,
111+
'v2', 'apps', 'GET_{id}_instances_stopped_response.json')
112+
mock_instances_started = mock_response(
92113
'/v2/apps/app_id/instances',
93114
httplib.OK,
94115
None,
95116
'v2', 'apps', 'GET_{id}_instances_response.json')
117+
self.credential_manager.get.side_effect = [mock_summary, mock_instances_stopped, mock_instances_started]
96118

97119
application = self.applications.start('app_id')
98120
self.credential_manager.put.assert_called_with(self.credential_manager.put.return_value.url,
99121
json=dict(state='STARTED'))
100-
self.credential_manager.get.assert_called_with(self.credential_manager.get.return_value.url)
122+
self.credential_manager.get.assert_has_calls([mock.call(mock_summary.url),
123+
mock.call(mock_instances_stopped.url),
124+
mock.call(mock_instances_started.url)],
125+
any_order=False)
101126
self.assertIsNotNone(application)
102127

103128
def test_stop(self):
@@ -108,8 +133,9 @@ def test_stop(self):
108133
'v2', 'apps', 'PUT_{id}_response.json')
109134
self.credential_manager.get.return_value = mock_response(
110135
'/v2/apps/app_id/instances',
111-
httplib.BAD_REQUEST, None)
112-
136+
httplib.BAD_REQUEST,
137+
None,
138+
'v2', 'apps', 'GET_{id}_instances_stopped_response.json')
113139
application = self.applications.stop('app_id')
114140
self.credential_manager.put.assert_called_with(self.credential_manager.put.return_value.url,
115141
json=dict(state='STOPPED'))

0 commit comments

Comments
 (0)
0