Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Remove session concept #7

Merged
merged 15 commits into from

2 participants

Tomaz Muraus Gary Dusbabek
Commits on Mar 18, 2013
  1. Tomaz Muraus

    Update readme.

    Kami authored
  2. Tomaz Muraus

    Update client code.

    Kami authored
  3. Tomaz Muraus

    Update .gitignore.

    Kami authored
Commits on Mar 28, 2013
  1. Tomaz Muraus

    Update register method.

    Kami authored
  2. Tomaz Muraus

    Update test fixtures.

    Kami authored
  3. Tomaz Muraus

    Update client.

    Kami authored
  4. Tomaz Muraus

    Handle json parse errors better.

    Kami authored
  5. Tomaz Muraus

    Update test utils.

    Kami authored
  6. Tomaz Muraus

    Update client.

    Kami authored
  7. Tomaz Muraus

    Remove unused idFromUrl stuff.

    Kami authored
  8. Tomaz Muraus

    Update tests.

    Kami authored
  9. Tomaz Muraus

    pep8.

    Kami authored
  10. Tomaz Muraus

    Bump version.

    Kami authored
  11. Tomaz Muraus

    Also run tests with PyPy.

    Kami authored
  12. Tomaz Muraus

    Revert "Also run tests with PyPy."

    Kami authored
    This reverts commit 9fac31c.
This page is out of date. Refresh to see the latest.
Showing with 140 additions and 495 deletions.
  1. +2 −0  .gitignore
  2. +3 −168 README.md
  3. +1 −1  setup.py
  4. +38 −94 txServiceRegistry/client.py
  5. +2 −2 txServiceRegistry/test/fixtures/request/services-post.json
  6. +0 −6 txServiceRegistry/test/fixtures/request/sessions-post.json
  7. +18 −0 txServiceRegistry/test/fixtures/response/configuration-api-get.json
  8. +2 −4 txServiceRegistry/test/fixtures/response/events-get.json
  9. +3 −2 txServiceRegistry/test/fixtures/response/services-dfw1-db1-get.json
  10. 0  ...est/fixtures/response/{sessions-sessionId-heartbeat-post.json → services-dfw1-db1-heartbeat-post.json}
  11. +3 −2 txServiceRegistry/test/fixtures/response/services-get-limit-1-page-1.json
  12. +3 −2 txServiceRegistry/test/fixtures/response/services-get-with-marker-page-2.json
  13. +5 −3 txServiceRegistry/test/fixtures/response/services-get.json
  14. +2 −2 txServiceRegistry/test/fixtures/response/{sessions-not-found-get.json → services-not-found-get.json}
  15. 0  txServiceRegistry/test/fixtures/response/{sessions-post.json → services-post.json}
  16. +3 −2 txServiceRegistry/test/fixtures/response/services-tag-db-get.json
  17. +0 −18 txServiceRegistry/test/fixtures/response/sessions-get.json
  18. +0 −8 txServiceRegistry/test/fixtures/response/sessions-sessionId-get.json
  19. +0 −42 txServiceRegistry/test/fixtures/response/views-overview-get.json
  20. +12 −16 txServiceRegistry/test/mock_http_server.py
  21. +25 −67 txServiceRegistry/test/test_client.py
  22. +18 −56 txServiceRegistry/test/utils.py
2  .gitignore
View
@@ -2,3 +2,5 @@
*.pyc
_trial_temp
mock_api_server.log
+dist/
+txServiceRegistry.egg-info
171 README.md
View
@@ -18,175 +18,10 @@ RACKSPACE_KEY = 'api key'
client = Client(RACKSPACE_USERNAME, RACKSPACE_KEY)
+# Do something
+reactor.run()
+
def resultCallback(result):
print result
reactor.stop()
```
-
-## Sessions
-
-Create a session with a heartbeat timeout of 10:
-
-```Python
-# Optional metadata (must contain string keys and values, up to 255 chars)
-options = {'key': 'value'}
-heartbeatTimeout = 10
-
-d = client.sessions.create(heartbeatTimeout, options)
-d.addCallback(resultCallback)
-```
-
-List sessions:
-
-```Python
-d = client.sessions.list()
-d.addCallback(resultCallback)
-```
-
-Get session:
-
-```Python
-sessionId = 'seFoo'
-
-d = client.sessions.get(sessionId)
-d.addCallback(resultCallback)
-```
-
-Heartbeat a session:
-
-```Python
-sessionId = 'seFoo'
-token = 'token'
-
-d = client.sessions.heartbeat(sessionId, token)
-d.addCallback(resultCallback)
-```
-
-Update existing session:
-
-```Python
-sessionId = 'seFoo'
-payload = {'heartbeat_timeout': 15}
-
-d = client.sessions.update(sessionId, payload)
-d.addCallback(resultCallback)
-```
-
-## Events
-
-List events:
-
-```Python
-marker = 'last-seen-token'
-
-d = client.events.list(marker)
-d.addCallback(resultCallback)
-```
-
-## Services
-
-List services:
-
-```Python
-
-d = client.services.list()
-d.addCallback(resultCallback)
-```
-
-List services for a specific tag:
-
-```Python
-tag = 'tag'
-
-d = client.services.listForTag(tag)
-d.addCallback(resultCallback)
-```
-
-Get service by ID:
-
-```Python
-serviceId = 'messenger1'
-
-d = client.services.get(serviceId)
-d.addCallback(resultCallback)
-```
-
-Create a new service:
-
-```Python
-sessionId = 'sessionId'
-serviceId = 'messenger1'
-payload = {
- 'tags': ['messenger', 'stats'],
- 'metadata': {'someKey': 'someValue', 'anotherKey': 'anotherValue'}
-}
-
-d = client.services.register(sessionId, serviceId, payload)
-d.addCallback(resultCallback)
-```
-
-Update existing service:
-
-```Python
-serviceId = 'messenger1'
-payload = {
- 'tags': ['tag1', 'tag2'],
- 'metadata': {'aKey': 'aValue'}
-}
-
-d = client.services.update(serviceId, payload)
-d.addCallback(resultCallback)
-```
-
-## Configuration
-
-List configuration values:
-
-```Python
-
-d = client.configuration.list()
-d.addCallback(resultCallback)
-```
-
-Get configuration value by id:
-
-```Python
-configurationId = 'configId'
-
-d = client.configuration.get(configurationId)
-d.addCallback(resultCallback)
-```
-
-Update configuration value:
-
-```Python
-configurationId = 'configId'
-value = 'new-value'
-
-d = client.configuration.set(configurationId, value)
-d.addCallback(resultCallback)
-```
-
-Delete configuration value:
-
-```Python
-configurationId = 'configId'
-
-d = client.configuration.remove(configurationId)
-d.addCallback(resultCallback)
-```
-
-## Accounts
-
-Get account limits:
-
-```Python
-d = client.account.getLimits()
-d.addCallback(resultCallback)
-```
-
-Also, make sure to call:
-
-```Python
-reactor.run()
-```
2  setup.py
View
@@ -100,7 +100,7 @@ def run(self):
setup(
name='txServiceRegistry',
- version='0.1.3',
+ version='0.2.0',
description='A Twisted Python client for Rackspace Service Registry.',
author='Rackspace Hosting, Inc.',
author_email='sr@rackspace.com',
132 txServiceRegistry/client.py
View
@@ -47,20 +47,16 @@ class ResponseReceiver(Protocol):
as it arrives.
When the body has been completely delivered, connectionLost is called.
"""
- def __init__(self, finished, idFromUrl=None, heartbeater=None):
+ def __init__(self, finished, heartbeater=None):
"""
@param finished: Deferred to callback with result in connectionLost
@type finished: L{Deferred}
- @param idFromUrl: Optional session or service ID that was parsed out
- of the location header.
- @type idFromUrl: C{str}
@param heartbeater: Optional HeartBeater object created when a
session is created.
@type heartbeater: L{HeartBeater}
"""
self.finished = finished
self.remaining = StringIO()
- self.idFromUrl = idFromUrl
self.heartbeater = heartbeater
def dataReceived(self, receivedBytes):
@@ -79,29 +75,19 @@ def connectionLost(self, reason):
a twisted.web.http.PotentialDataLoss exception.
"""
self.remaining.reset()
- # When creating a session, the token is returned in the body, and the
- # session ID is in the location header URL. When creating a service,
- # the body is empty, and the service ID is in the location header URL.
- if self.idFromUrl:
- result = None
- if self.remaining.getvalue():
- result = json.load(self.remaining)
-
- returnTuple = (result, self.idFromUrl)
- if self.heartbeater:
- self.heartbeater.nextToken = result['token']
- returnTuple = returnTuple + (self.heartbeater,)
-
- # Return just service ID if result is None
- if result is None:
- self.finished.callback(self.idFromUrl)
- else:
- self.finished.callback(returnTuple)
+ try:
+ result = json.load(self.remaining)
+ except Exception, e:
+ self.finished.errback(e)
return
- result = json.load(self.remaining)
- self.finished.callback(result)
+ returnValue = result
+ if self.heartbeater:
+ self.heartbeater.nextToken = result['token']
+ returnValue = (result, self.heartbeater)
+
+ self.finished.callback(returnValue)
class BaseClient(object):
@@ -147,23 +133,13 @@ def cbRequest(self,
heartbeater,
retry_count)
finished = Deferred()
- idFromUrl = None
# If response has no body, callback with True
if response.code == httplib.NO_CONTENT:
finished.callback(True)
return finished
- # If response code is 201, extract service or session id
- # from the location
- if response.code == httplib.CREATED:
- locationHeader = response.headers.getRawHeaders('location')[0]
- idFromUrl = self.getIdFromUrl(locationHeader)
- if 'sessions' in locationHeader:
- heartbeater.sessionId = idFromUrl
-
response.deliverBody(ResponseReceiver(finished,
- idFromUrl,
heartbeater))
return finished
@@ -218,50 +194,6 @@ def _request(authHeaders, options, payload, heartbeater, retry_count):
return d
-class SessionsClient(BaseClient):
- def __init__(self, agent, baseUrl):
- super(SessionsClient, self).__init__(agent, baseUrl)
- self.agent = agent
- self.baseUrl = baseUrl
- self.sessionsPath = '/sessions'
-
- def list(self, marker=None, limit=None):
- path = self.sessionsPath
- options = self._get_options_object(marker, limit)
-
- return self.request('GET', path, options=options)
-
- def get(self, sessionId):
- path = '%s/%s' % (self.sessionsPath, sessionId)
-
- return self.request('GET', path)
-
- def create(self, heartbeatTimeout, payload=None):
- path = self.sessionsPath
- payload = deepcopy(payload) if payload else {}
- payload['heartbeat_timeout'] = heartbeatTimeout
- heartbeater = HeartBeater(self.agent,
- self.baseUrl,
- None,
- heartbeatTimeout)
-
- return self.request('POST',
- path,
- payload=payload,
- heartbeater=heartbeater)
-
- def heartbeat(self, sessionId, token):
- path = '%s/%s/heartbeat' % (self.sessionsPath, sessionId)
- payload = {'token': token}
-
- return self.request('POST', path, payload=payload)
-
- def update(self, sessionId, payload):
- path = '%s/%s' % (self.sessionsPath, sessionId)
-
- return self.request('PUT', path, payload=payload)
-
-
class EventsClient(BaseClient):
def __init__(self, agent, baseUrl):
super(EventsClient, self).__init__(agent, baseUrl)
@@ -294,12 +226,23 @@ def get(self, serviceId):
return self.request('GET', path)
- def create(self, sessionId, serviceId, payload=None):
+ def create(self, serviceId, heartbeatTimeout, payload=None):
payload = deepcopy(payload) if payload else {}
- payload['session_id'] = sessionId
payload['id'] = serviceId
+ payload['heartbeat_timeout'] = heartbeatTimeout
+ heartbeater = HeartBeater(self.agent,
+ self.baseUrl,
+ None,
+ heartbeatTimeout)
+
+ return self.request('POST', self.servicesPath, payload=payload,
+ heartbeater=heartbeater)
- return self.request('POST', self.servicesPath, payload=payload)
+ def heartbeat(self, serviceId, token):
+ path = '%s/%s/heartbeat' % (self.servicesPath, serviceId)
+ payload = {'token': token}
+
+ return self.request('POST', path, payload=payload)
def update(self, serviceId, payload):
path = '%s/%s' % (self.servicesPath, serviceId)
@@ -311,19 +254,19 @@ def remove(self, serviceId):
return self.request('DELETE', path)
- def register(self, sessionId, serviceId, payload=None, retryDelay=2):
+ def register(self, serviceId, heartbeatTimeout, payload=None,
+ retryDelay=2):
retryCount = MAX_HEARTBEAT_TIMEOUT / retryDelay
success = False
retryCounter = 0
registerResult = Deferred()
lastErr = None
- def doRegister(sessionId, serviceId, retryCounter, success, lastErr):
+ def doRegister(serviceId, heartbeatTimeout, retryCounter,
+ success, lastErr, result=None):
if success and (retryCounter < retryCount):
- registerResult.callback(serviceId)
-
+ registerResult.callback(result)
return registerResult
-
elif (not success) and (retryCounter == retryCount):
registerResult.errback(lastErr)
@@ -337,8 +280,9 @@ def cbCreate(result, retryCounter, success):
lastErr = result
if result['type'] == 'serviceWithThisIdExists':
retryCounter += 1
- reactor.callLater(retryDelay, doRegister, sessionId,
- serviceId, retryCounter, success,
+ reactor.callLater(retryDelay, doRegister,
+ serviceId, heartbeatTimeout,
+ retryCounter, success,
lastErr)
return registerResult
@@ -347,15 +291,16 @@ def cbCreate(result, retryCounter, success):
return registerResult
else:
- return doRegister(sessionId, serviceId, retryCounter,
- True, None)
+ return doRegister(serviceId, heartbeatTimeout,
+ retryCounter, True, None, result)
- d = self.create(sessionId, serviceId, payload)
+ d = self.create(serviceId, heartbeatTimeout, payload)
d.addCallback(cbCreate, retryCounter, success)
return d
- return doRegister(sessionId, serviceId, retryCounter, success, lastErr)
+ return doRegister(serviceId, heartbeatTimeout, retryCounter, success,
+ lastErr)
class ConfigurationClient(BaseClient):
@@ -488,7 +433,6 @@ def __init__(self, username, apiKey, region='us', baseUrl=DEFAULT_API_URL,
self.agent = KeystoneAgent(agent, authUrl, (username, apiKey))
self.baseUrl = baseUrl
- self.sessions = SessionsClient(self.agent, self.baseUrl)
self.events = EventsClient(self.agent, self.baseUrl)
self.services = ServicesClient(self.agent, self.baseUrl)
self.configuration = ConfigurationClient(self.agent, self.baseUrl)
4 txServiceRegistry/test/fixtures/request/services-post.json
View
@@ -10,5 +10,5 @@
"version": "5.5.24-0ubuntu0.12.04.1 (Ubuntu)"
},
"id": "dfw1-db1",
- "session_id": "sessionId"
-}
+ "heartbeat_timeout": 30
+}
6 txServiceRegistry/test/fixtures/request/sessions-post.json
View
@@ -1,6 +0,0 @@
-{
- "metadata": {
- "region": "dfw"
- },
- "heartbeat_timeout": 30
-}
18 txServiceRegistry/test/fixtures/response/configuration-api-get.json
View
@@ -0,0 +1,18 @@
+{
+ "values": [
+ {
+ "id": "/api/key-1",
+ "value": "test value 123456"
+ },
+ {
+ "id": "/api/key-2",
+ "value": "test value 23456"
+ }
+ ],
+ "metadata": {
+ "count": 2,
+ "limit": 100,
+ "marker": null,
+ "next_href": null
+ }
+}
6 txServiceRegistry/test/fixtures/response/events-get.json
View
@@ -1,4 +1,4 @@
-{
+
"values": [
{
"id": "6bc8d050-f86a-11e1-a89e-ca2ffe480b20",
@@ -6,7 +6,6 @@
"type": "service.join",
"payload": {
"id": "dfw1-api",
- "session_id": "sessionId",
"tags": [],
"metadata": {}
}
@@ -15,7 +14,6 @@
"type": "service.join",
"payload": {
"id": "dfw1-db1",
- "session_id": "sessionId",
"tags": [
"db",
"mysql"
@@ -43,4 +41,4 @@
"marker": null,
"next_href": null
}
-}
+}
5 txServiceRegistry/test/fixtures/response/services-dfw1-db1-get.json
View
@@ -1,6 +1,7 @@
{
"id": "dfw1-db1",
- "session_id": "sessionId",
+ "heartbeat_timeout": 30,
+ "last_seen": 1362900438,
"tags": [
"db",
"mysql"
@@ -11,4 +12,4 @@
"ip": "127.0.0.1",
"version": "5.5.24-0ubuntu0.12.04.1 (Ubuntu)"
}
-}
+}
0  ...s/response/sessions-sessionId-heartbeat-post.json → ...es/response/services-dfw1-db1-heartbeat-post.json
View
File renamed without changes
5 txServiceRegistry/test/fixtures/response/services-get-limit-1-page-1.json
View
@@ -2,7 +2,8 @@
"values": [
{
"id": "dfw1-api",
- "session_id": "seOne",
+ "heartbeat_timeout": 30,
+ "last_seen": 1362900438,
"tags": [],
"metadata": {}
}
@@ -14,4 +15,4 @@
"next_marker": "dfw1-db1",
"next_href": "https://todo.api.rackspacecloud.com/v1.0/7777/services?limit=1&marker=dfw1-db1"
}
-}
+}
5 txServiceRegistry/test/fixtures/response/services-get-with-marker-page-2.json
View
@@ -2,7 +2,8 @@
"values": [
{
"id": "dfw1-db1",
- "session_id": "seOne",
+ "heartbeat_timeout": 30,
+ "last_seen": 1362900438,
"tags": [
"db",
"mysql"
@@ -21,4 +22,4 @@
"marker": "dfw1-db1",
"next_href": null
}
-}
+}
8 txServiceRegistry/test/fixtures/response/services-get.json
View
@@ -2,13 +2,15 @@
"values": [
{
"id": "dfw1-api",
- "session_id": "sessionId",
+ "heartbeat_timeout": 30,
+ "last_seen": 1362900438,
"tags": [],
"metadata": {}
},
{
"id": "dfw1-db1",
- "session_id": "sessionId",
+ "heartbeat_timeout": 30,
+ "last_seen": 1362900438,
"tags": [
"db",
"mysql"
@@ -27,4 +29,4 @@
"marker": null,
"next_href": null
}
-}
+}
4 ...est/fixtures/response/sessions-not-found-get.json → ...est/fixtures/response/services-not-found-get.json
View
@@ -2,6 +2,6 @@
"type": "notFoundError",
"code": 404,
"message": "object does not exist",
- "details": "Object \"Session\" with key \"seNotFound\" does not exist",
+ "details": "Object \"Service\" with key \"my-service-1\" does not exist",
"txnId": ".rh-qyek.h-farscape.r-q3i5psGp.c-3.ts-1347320188220.v-0.1"
-}
+}
0  ...egistry/test/fixtures/response/sessions-post.json → ...egistry/test/fixtures/response/services-post.json
View
File renamed without changes
5 txServiceRegistry/test/fixtures/response/services-tag-db-get.json
View
@@ -2,7 +2,8 @@
"values": [
{
"id": "dfw1-db1",
- "session_id": "sessionId",
+ "heartbeat_timeout": 30,
+ "last_seen": 1362900438,
"tags": [
"db",
"mysql"
@@ -21,4 +22,4 @@
"marker": null,
"next_href": null
}
-}
+}
18 txServiceRegistry/test/fixtures/response/sessions-get.json
View
@@ -1,18 +0,0 @@
-{
- "values": [
- {
- "id": "sessionId",
- "metadata": {
- "region": "dfw"
- },
- "heartbeat_timeout": 30,
- "last_seen": null
- }
- ],
- "metadata": {
- "count": 1,
- "limit": 100,
- "marker": null,
- "next_href": null
- }
-}
8 txServiceRegistry/test/fixtures/response/sessions-sessionId-get.json
View
@@ -1,8 +0,0 @@
-{
- "id": "sessionId",
- "metadata": {
- "region": "dfw"
- },
- "heartbeat_timeout": 30,
- "last_seen": null
-}
42 txServiceRegistry/test/fixtures/response/views-overview-get.json
View
@@ -1,42 +0,0 @@
-{
- "values": [
- {
- "session": {
- "id": "seId0",
- "metadata": {
- "region": "dfw"
- },
- "heartbeat_timeout": 30,
- "last_seen": null
- },
- "services": [
- {
- "id": "dfw1-api",
- "session_id": "seId0",
- "tags": [],
- "metadata": {}
- },
- {
- "id": "dfw1-db1",
- "session_id": "seId0",
- "tags": [
- "db",
- "mysql"
- ],
- "metadata": {
- "region": "dfw",
- "port": "3306",
- "ip": "127.0.0.1",
- "version": "5.5.24-0ubuntu0.12.04.1 (Ubuntu)"
- }
- }
- ]
- }
- ],
- "metadata": {
- "count": 1,
- "limit": 100,
- "marker": null,
- "next_href": null
- }
-}
28 txServiceRegistry/test/mock_http_server.py
View
@@ -25,13 +25,13 @@
signature = None
HTTP_GET_PATHS = {
- '/sessions': {'fixture_path': 'sessions-get.json'},
- '/sessions/sessionId': {'fixture_path': 'sessions-sessionId-get.json'},
'/limits': {'fixture_path': 'limits-get.json'},
'/events': {'fixture_path': 'events-get.json'},
'/configuration': {'fixture_path': 'configuration-get.json'},
'/configuration/configId':
{'fixture_path': 'configuration-configId-get.json'},
+ '/configuration/api/':
+ {'fixture_path': 'configuration-api-get.json'},
'/services': {'fixture_path': 'services-get.json'},
'/services/dfw1-db1':
{'fixture_path': 'services-dfw1-db1-get.json'},
@@ -39,14 +39,12 @@
}
HTTP_POST_PATHS = {
- '/sessions':
- {'fixture_path': 'sessions-post.json',
- 'headers': {'Location': '127.0.0.1/v1.0/7777/sessions/sessionId'}},
- '/sessions/sessionId/heartbeat':
- {'fixture_path': 'sessions-sessionId-heartbeat-post.json',
- 'status_code': 200},
'/services':
- {'headers': {'Location': '127.0.0.1/v1.0/7777/services/dfw1-db1'}}
+ {'fixture_path': 'services-post.json',
+ 'headers': {'Location': '127.0.0.1/v1.0/7777/services/dfw1-db1'}},
+ '/services/dfw1-db1/heartbeat':
+ {'fixture_path': 'services-dfw1-db1-heartbeat-post.json',
+ 'status_code': 200}
}
usage = 'usage: %prog --port=<port> --fixtures-dir=<fixtures directory>'
@@ -55,8 +53,7 @@
help='Port to listen on', metavar='PORT')
parser.add_option("--fixtures-dir", dest='fixtures_dir',
default='fixtures/response/',
- help='The folder in which JSON response fixtures'
- ' for the tests live')
+ help='The folder in which JSON fixtures for the tests live')
(options, args) = parser.parse_args()
@@ -90,11 +87,7 @@ def do_POST(self):
return self._setup_response(HTTP_POST_PATHS, 201)
def do_PUT(self):
- if 'sessions' in self.path:
- headers = \
- {'Location': '127.0.0.1/v1.0/7777/sessions/sessionId'}
- return self._end(status_code=204, headers=headers)
- elif 'services' in self.path:
+ if 'services' in self.path:
headers = \
{'Location': '127.0.0.1/v1.0/7777/services/dfw1-db1'}
return self._end(status_code=204, headers=headers)
@@ -104,12 +97,15 @@ def do_DELETE(self):
def _end(self, status_code=200, headers=None, body=''):
print 'Sending response: status_code=%s, body=%s' % (status_code, body)
+
self.send_response(status_code)
self.send_header('Content-Type', 'application/json')
self.send_header('Content-Length', str(len(body)))
+
if headers:
for key, value in headers.iteritems():
self.send_header(key, value)
+
self.end_headers()
self.wfile.write(body)
92 txServiceRegistry/test/test_client.py
View
@@ -55,54 +55,49 @@ def limits_assert(result):
return d
- def test_create_session(self):
- def session_assert(result):
+ def test_create_service(self):
+ def service_assert(result):
response_body = {'token': TOKENS[0]}
self.assertEqual(result[0], response_body)
- self.assertEqual(result[1], 'sessionId')
- self.assertTrue(isinstance(result[2], HeartBeater))
- self.assertEqual(result[2].heartbeatInterval, 12.0)
- self.assertEqual(result[2].nextToken, TOKENS[0])
-
- d = self.client.sessions.create(15)
- d.addCallback(session_assert)
+ self.assertTrue(isinstance(result[1], HeartBeater))
+ self.assertEqual(result[1].heartbeatInterval, 12.0)
+ self.assertEqual(result[1].nextToken, TOKENS[0])
- return d
-
- def test_heartbeat_session(self):
- def heartbeat_assert(result):
- heartbeat_response = {'token': TOKENS[0]}
- self.assertEqual(result, heartbeat_response)
-
- d = self.client.sessions.heartbeat('sessionId', 'someToken')
- d.addCallback(heartbeat_assert)
+ d = self.client.services.create('dfw1-db1', 15)
+ d.addCallback(service_assert)
return d
- def test_create_service(self):
+ def test_register_service(self):
def service_assert(result):
- self.assertEqual(result, 'dfw1-db1')
+ response_body = {'token': TOKENS[0]}
+ self.assertEqual(result[0], response_body)
+ self.assertTrue(isinstance(result[1], HeartBeater))
+ self.assertEqual(result[1].heartbeatInterval, 12.0)
+ self.assertEqual(result[1].nextToken, TOKENS[0])
- d = self.client.services.create('sessionId', 'dfw1-db1')
+ d = self.client.services.register('dfw1-db1', 15)
d.addCallback(service_assert)
return d
- def test_register_service(self):
- def service_assert(result):
- self.assertEqual(result, 'dfw1-db1')
+ def test_heartbeat_service(self):
+ def heartbeat_assert(result):
+ heartbeat_response = {'token': TOKENS[0]}
+ self.assertEqual(result, heartbeat_response)
- d = self.client.services.register('sessionId', 'dfw1-db1')
- d.addCallback(service_assert)
+ d = self.client.services.heartbeat('dfw1-db1', 'someToken')
+ d.addCallback(heartbeat_assert)
return d
def test_get_service(self):
def service_assert(result):
self.assertEqual(result['id'], 'dfw1-db1')
- self.assertEqual(result['session_id'], 'sessionId')
self.assertEqual(result['tags'], ['db', 'mysql'])
self.assertEqual(result['metadata'], EXPECTED_METADATA)
+ self.assertEqual(result['heartbeat_timeout'], 30)
+ self.assertTrue('last_seen' in result)
d = self.client.services.get('dfw1-db1')
d.addCallback(service_assert)
@@ -112,11 +107,9 @@ def service_assert(result):
def test_list_services(self):
def services_assert(result):
self.assertEqual(result['values'][0]['id'], 'dfw1-api')
- self.assertEqual(result['values'][0]['session_id'], 'sessionId')
self.assertTrue('tags' in result['values'][0])
self.assertTrue('metadata' in result['values'][0])
self.assertEqual(result['values'][1]['id'], 'dfw1-db1')
- self.assertEqual(result['values'][1]['session_id'], 'sessionId')
self.assertEqual(result['values'][1]['tags'],
['db', 'mysql'])
self.assertEqual(result['values'][1]['metadata'],
@@ -131,7 +124,6 @@ def services_assert(result):
def test_listForTag(self):
def services_for_tag_assert(result):
self.assertEqual(result['values'][0]['id'], 'dfw1-db1')
- self.assertEqual(result['values'][0]['session_id'], 'sessionId')
self.assertEqual(result['values'][0]['tags'],
['db', 'mysql'])
self.assertEqual(result['values'][0]['metadata'],
@@ -143,31 +135,6 @@ def services_for_tag_assert(result):
return d
- def test_get_sessions(self):
- def sessions_assert(result):
- self.assertEqual(result['values'][0]['id'], 'sessionId')
- self.assertEqual(result['values'][0]['heartbeat_timeout'], 30)
- self.assertTrue('metadata' in result['values'][0])
- self.assertTrue('last_seen' in result['values'][0])
- self.assertTrue('metadata' in result)
-
- d = self.client.sessions.list()
- d.addCallback(sessions_assert)
-
- return d
-
- def test_get_session(self):
- def session_assert(result):
- self.assertEqual(result['id'], 'sessionId')
- self.assertEqual(result['heartbeat_timeout'], 30)
- self.assertTrue('metadata' in result)
- self.assertTrue('last_seen' in result)
-
- d = self.client.sessions.get('sessionId')
- d.addCallback(session_assert)
-
- return d
-
def test_list_configuration(self):
def configuration_assert(result):
self.assertEqual(result['values'][0]['id'], 'configId')
@@ -189,20 +156,20 @@ def configuration_assert(result):
return d
- @mock.patch("txServiceRegistry.client.BaseClient.request")
+ @mock.patch('txServiceRegistry.client.BaseClient.request')
def _marker_assertion(self, path, request):
client = getattr(self.client, path.strip('/'))
client.list(marker='someMarker')
request.assert_called_with('GET', path,
options={'marker': 'someMarker'})
- @mock.patch("txServiceRegistry.client.BaseClient.request")
+ @mock.patch('txServiceRegistry.client.BaseClient.request')
def _limit_assertion(self, path, request):
client = getattr(self.client, path.strip('/'))
client.list(limit=3)
request.assert_called_with('GET', path, options={'limit': 3})
- @mock.patch("txServiceRegistry.client.BaseClient.request")
+ @mock.patch('txServiceRegistry.client.BaseClient.request')
def _marker_and_limit_assertion(self, path, request):
client = getattr(self.client, path.strip('/'))
client.list(marker='someMarker', limit=3)
@@ -213,9 +180,6 @@ def _marker_and_limit_assertion(self, path, request):
def test_list_services_with_marker_calls_request_with_marker(self):
return self._marker_assertion('/services')
- def test_list_sessions_with_marker_calls_request_with_marker(self):
- return self._marker_assertion('/sessions')
-
def test_list_events_with_marker_calls_request_with_marker(self):
return self._marker_assertion('/events')
@@ -225,9 +189,6 @@ def test_list_configuration_with_marker_calls_request_with_marker(self):
def test_list_services_with_limit_calls_request_with_limit(self):
return self._limit_assertion('/services')
- def test_list_sessions_with_limit_calls_request_with_limit(self):
- return self._limit_assertion('/sessions')
-
def test_list_events_with_limit_calls_request_with_limit(self):
return self._limit_assertion('/events')
@@ -237,9 +198,6 @@ def test_list_configuration_with_limit_calls_request_with_limit(self):
def test_list_services_with_marker_and_limit(self):
return self._marker_and_limit_assertion('/services')
- def test_list_sessions_request_with_marker_and_limit(self):
- return self._marker_and_limit_assertion('/sessions')
-
def test_list_events_with_mark_and_limit(self):
return self._marker_and_limit_assertion('/events')
74 txServiceRegistry/test/utils.py
View
@@ -11,20 +11,25 @@
# 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.
+#
+# Taken from
+# https://github.com/Kami/python-yubico-client/blob/master/tests/utils.py
+
+from __future__ import with_statement
import os
+import sys
import subprocess
import signal
import time
import socket
import errno
import atexit
-from os.path import join as pjoin
+from os.path import join as pjoin
-# From https://github.com/Kami/python-yubico-client/blob/master/tests/utils.py
-def waitForStartUp(process, pid, address, timeout=10):
+def waitForStartUp(process, address, timeout=10):
# connect to it, with a timeout in case something went wrong
start = time.time()
while time.time() < start + timeout:
@@ -38,57 +43,18 @@ def waitForStartUp(process, pid, address, timeout=10):
# see if process is still alive
process.poll()
- if pid and process.returncode is None:
- os.kill(pid, signal.SIGKILL)
+ if process and process.returncode is None:
+ process.terminate()
raise RuntimeError("Couldn't connect to server; aborting test")
class ProcessRunner(object):
def setUp(self, *args, **kwargs):
- # clean up old.
- p = self.getPid()
- if p is not None:
- try:
- # remember, process may already be dead.
- os.kill(p, 9)
- time.sleep(0.01)
- except:
- pass
+ pass
def tearDown(self, *args, **kwargs):
- spid = self.getPid()
- if spid:
- max_wait = 1
- os.kill(spid, signal.SIGTERM)
- slept = 0
- while (slept < max_wait):
- time.sleep(0.5)
- if not self.isAlive(spid):
- if os.path.exists(self.pid_fname):
- os.unlink(self.pid_fname)
- break
- slept += 0.5
- if (slept > max_wait and self.isAlive(spid)):
- os.kill(spid, signal.SIGKILL)
- if os.path.exists(self.pid_fname):
- os.unlink(self.pid_fname)
- raise Exception('Server did not shut down correctly')
- else:
- print 'Unable to locate pid file (%s)!' % self.pid_fname
-
- def isAlive(self, pid):
- try:
- os.kill(pid, 0)
- return 1
- except OSError, err:
- return err.errno == errno.EPERM
-
- def getPid(self):
if self.process:
- return self.process.pid
- elif os.path.exists(self.pid_fname):
- return int(open(self.pid_fname, 'r').read())
- return None
+ self.process.terminate()
class MockAPIServerRunner(ProcessRunner):
@@ -99,23 +65,19 @@ def setUp(self, *args, **kwargs):
self.cwd = os.getcwd()
self.process = None
self.base_dir = pjoin(self.cwd)
- self.pid_fname = pjoin(self.cwd, 'mock_api_server.pid')
self.log_path = pjoin(self.cwd, 'mock_api_server.log')
super(MockAPIServerRunner, self).setUp(*args, **kwargs)
script = pjoin(os.path.dirname(__file__), 'mock_http_server.py')
with open(self.log_path, 'a+') as log_fp:
- port_arg = '%s --port=%s' % (script, self.port)
+ args = '%s --port=%s' % (script, str(self.port))
fixtures_dir_arg = \
'--fixtures-dir=txServiceRegistry/test/fixtures/response'
- args = '%s %s' % (port_arg, fixtures_dir_arg)
- self.process = subprocess.Popen(args,
- shell=True,
- cwd=self.base_dir,
- stdout=log_fp,
+ args = [script, '--port=%s' % (self.port), fixtures_dir_arg]
+
+ self.process = subprocess.Popen(args, shell=False,
+ cwd=self.base_dir, stdout=log_fp,
stderr=log_fp)
- waitForStartUp(self.process,
- self.getPid(),
- ('127.0.0.1', self.port), 10)
+ waitForStartUp(self.process, ('127.0.0.1', self.port), 10)
atexit.register(self.tearDown)
Something went wrong with that request. Please try again.