Skip to content

Commit

Permalink
Merge pull request #90 from dcos/ken/spinner
Browse files Browse the repository at this point in the history
Wait function and predicates
  • Loading branch information
kensipe authored Nov 8, 2016
2 parents 803d262 + 08fc333 commit 3b66c90
Show file tree
Hide file tree
Showing 8 changed files with 432 additions and 20 deletions.
233 changes: 232 additions & 1 deletion API.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,26 @@
* [get_marathon_tasks()](#get_marathon_tasks)
* [service_healthy()](#service_healthy)
* [wait_for_service_endpoint()](#wait_for_service_endpoint)
* [wait_for_service_endpoint_removal()](#wait_for_service_endpoint_removal)
* Spinner
* [wait_for()](#wait_for)
* [time_wait()](#time_wait)
* [elapse_time()](#elapse_time)
* Tasks
* [get_task()](#get_task)
* [get_tasks()](#get_tasks)
* [get_active_tasks()](#get_active_tasks)
* [task_completed()](#task_completed)
* [wait_for_task()](#wait_for_task)
* [wait_for_task_property()](#wait_for_task_property)
* [wait_for_task_property_value()](#wait_for_task_property_value)
* [wait_for_dns()](#wait_for_dns)
* ZooKeeper
* [delete_zk_node()](#delete_zk_node)
* Marathon
* [deployment_wait()](#deployment_wait)
* [delete_all_apps()](#delete_all_apps)
* [delete_all_apps_wait()](#delete_all_apps_wait)
* Masters
* [partition_master()](#partition_master)
* [reconnect_master()](#reconnect_master)
Expand Down Expand Up @@ -680,6 +693,105 @@ timeout_sec | how long in seconds to wait before timing out | int | `120`
wait_for_service_endpoint("marathon-user")
```

### wait_for_service_endpoint_removal()

Checks the service url returns HTTP 500 within a timeout if available it returns true on expiration it returns time to remove.

##### *parameters*

parameter | description | type | default
--------- | ----------- | ---- | -------
**service_name** | the name of the service | str
timeout_sec | how long in seconds to wait before timing out | int | `120`

##### *example usage*

```python
# will wait
wait_for_service_endpoint_removal("marathon-user")
```

### wait_for()

Waits for a function to return true or times out.

##### *parameters*

parameter | description | type | default
--------- | ----------- | ---- | -------
**predicate** | the predicate function| fn
timeout_seconds | how long in seconds to wait before timing out | int | `120`
sleep_seconds | time to sleep between multiple calls to predicate | int | `1`
ignore_exceptions | ignore exceptions thrown by predicate | bool | True
inverse_predicate | if True look for False from predicate | bool | False

##### *example usage*

```python
# simple predicate
def deployment_predicate(client=None):
...

wait_for(deployment_predicate, timeout)

# predicate with a parameter
def service_available_predicate(service_name):
...

wait_for(lambda: service_available_predicate(service_name), timeout_seconds=timeout_sec)

```

### time_wait()

Waits for a function to return true or times out. Returns the elapsed time of wait.

##### *parameters*

parameter | description | type | default
--------- | ----------- | ---- | -------
**predicate** | the predicate function| fn
timeout_seconds | how long in seconds to wait before timing out | int | `120`
sleep_seconds | time to sleep between multiple calls to predicate | int | `1`
ignore_exceptions | ignore exceptions thrown by predicate | bool | True
inverse_predicate | if True look for False from predicate | bool | False

##### *example usage*

```python
# simple predicate
def deployment_predicate(client=None):
...

time_wait(deployment_predicate, timeout)

# predicate with a parameter
def service_available_predicate(service_name):
...

time_wait(lambda: service_available_predicate(service_name), timeout_seconds=timeout_sec)

```

### elapse_time()

returns the time difference with a given precision.

##### *parameters*

parameter | description | type | default
--------- | ----------- | ---- | -------
**start** | the start time | time
end | end time, if not provided current time is used | time | None
precision | the number decimal places to maintain | int | `3`

##### *example usage*

```python
# will wait
elapse_time("marathon-user")
```

### get_task()

Get information about a task.
Expand Down Expand Up @@ -728,7 +840,6 @@ for task in tasks:
print("{} has state {}".format(task['id'], task['state']))
```


### task_completed()

Check whether a task has completed.
Expand All @@ -748,6 +859,82 @@ while not task_completed('driver-20160517222552-0072'):
time.sleep(5)
```

### wait_for_task()

Wait for a task to be reported running by Mesos. Returns the elapsed time of wait.

##### *parameters*

parameter | description | type | default
--------- | ----------- | ---- | -------
service | framework service name | str
task | task name | str
timeout_sec | timeout | int | `120`


##### *example usage*

```python
wait_for_task('marathon', 'marathon-user')
```

### wait_for_task_property()

Wait for a task to be report having a specific property. Returns the elapsed time of wait.

##### *parameters*

parameter | description | type | default
--------- | ----------- | ---- | -------
service | framework service name | str
task | task name | str
prop | property name | str
timeout_sec | timeout | int | `120`


##### *example usage*

```python
wait_for_task_property('marathon', 'chronos', 'resources')
```

### wait_for_task_property_value()

Wait for a task to be reported having a property with a specific value. Returns the elapsed time of wait.

##### *parameters*

parameter | description | type | default
--------- | ----------- | ---- | -------
service | framework service name | str
task | task name | str
prop | property name | str
value | value of property | str
timeout_sec | timeout | int | `120`


##### *example usage*

```python
wait_for_task_property_value('marathon', 'marathon-user', 'state', 'TASK_RUNNING')
```

### wait_for_dns()

Wait for a task dns. Returns the elapsed time of wait.

##### *parameters*

parameter | description | type | default
--------- | ----------- | ---- | -------
name | dns name | str
timeout_sec | timeout | int | `120`

##### *example usage*

```python
wait_for_dns('marathon-user.marathon.mesos')
```

### delete_zk_node()

Expand All @@ -766,6 +953,50 @@ node_name | the name of the node | str
delete_zk_node('universe/marathon-user')
```

### deployment_wait()

Waits for Marathon Deployment to complete or times out.

##### *parameters*

parameter | description | type | default
--------- | ----------- | ---- | -------
timeout | max time to wait for deployment | int | 120

##### *example usage*

```python
# assuming a client.add_app() or similar
deployment_wait()
```

### delete_all_apps()

Deletes all apps running on Marathon.

##### *parameters*

None.

##### *example usage*

```python
delete_all_apps()
```

### delete_all_apps_wait()

Deletes all apps running on Marathon and waits for deployment to finish.

##### *parameters*

None.

##### *example usage*

```python
delete_all_apps_wait()
```

### partition_master()

Expand Down
2 changes: 2 additions & 0 deletions shakedown/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
from shakedown.dcos.config import *
from shakedown.dcos.command import *
from shakedown.dcos.file import *
from shakedown.dcos.marathon import *
from shakedown.dcos.network import *
from shakedown.dcos.package import *
from shakedown.dcos.service import *
from shakedown.dcos.spinner import *
from shakedown.dcos.task import *
from shakedown.dcos.zookeeper import *
from shakedown.dcos.agent import *
Expand Down
21 changes: 21 additions & 0 deletions shakedown/dcos/marathon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from dcos import marathon
from shakedown.dcos.spinner import *


def deployment_predicate():
client = marathon.create_client()
return len(client.get_deployments()) == 0


def deployment_wait(timeout=120):
time_wait(deployment_predicate, timeout)


def delete_all_apps():
client = marathon.create_client()
client.remove_group("/")


def delete_all_apps_wait():
delete_all_apps()
deployment_wait()
1 change: 0 additions & 1 deletion shakedown/dcos/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,6 @@ def get_package_repos(
return cosmos.get_repos()



def add_package_repo(
repo_name,
repo_url,
Expand Down
48 changes: 30 additions & 18 deletions shakedown/dcos/service.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from dcos import (marathon, mesos)
from shakedown.dcos.spinner import *


def get_service(
Expand Down Expand Up @@ -159,6 +160,7 @@ def get_service_ips(

return ips


def service_healthy(service_name, app_id=None):
""" Check whether a named service is healthy
Expand Down Expand Up @@ -187,26 +189,36 @@ def service_healthy(service_name, app_id=None):

return False

def wait_for_service_endpoint(service,timeout_sec=120):
"""Checks the service url returns HTTP 200 within a timeout if available it returns true on expiration it returns false"""

url = dcos_service_url(service)

now = time.time()
future = now + timeout_sec
time.sleep(5)
def service_available_predicate(service_name):
url = dcos_service_url(service_name)
try:
response = http.get(url)
return response.status_code == 200
except Exception as e:
return False

while now < future:
response = None
try:
response = http.get(url)
except Exception as e:
pass

if response is None:
time.sleep(5)
now = time.time()
elif response.status_code == 200:
def service_unavailable_predicate(service_name):
url = dcos_service_url(service_name)
try:
response = http.get(url)
except DCOSHTTPException as e:
if e.response.status_code == 500:
return True
else:
return False

return False

def wait_for_service_endpoint(service_name, timeout_sec=120):
"""Checks the service url if available it returns true, on expiration
it returns false"""

return time_wait(lambda: service_available_predicate(service_name), timeout_seconds=timeout_sec)


def wait_for_service_endpoint_removal(service_name, timeout_sec=120):
"""Checks the service url if it is removed it returns true, on expiration
it returns false"""

return time_wait(lambda: service_unavailable_predicate(service_name))
Loading

0 comments on commit 3b66c90

Please sign in to comment.