Implement python-mistralclient v2

* Added versioned pythonclient lib

Partially implements blueprint mistral-client-2.0

TODO:
 * Add ActionManager
 * Clarify endpoints
 * Clarify workbook upload operation
 * Add unit tests

Change-Id: Ic9488e3c819da9f647e9a3407ba0657ef87eafee
This commit is contained in:
Nikolay Mahotkin 2014-08-27 16:37:34 +04:00
parent b0d0c31361
commit 8427879b18
26 changed files with 531 additions and 128 deletions

View File

@ -14,97 +14,40 @@
import six
from mistralclient.api import httpclient
from mistralclient.api import workbooks
from mistralclient.api import executions
from mistralclient.api import tasks
from mistralclient.api import listeners
from mistralclient.api.v1 import client as client_v1
from mistralclient.api.v2 import client as client_v2
class Client(object):
def __init__(self, mistral_url=None, username=None, api_key=None,
project_name=None, auth_url=None, project_id=None,
endpoint_type='publicURL', service_type='workflow',
auth_token=None, user_id=None):
def client(mistral_url=None, username=None, api_key=None,
project_name=None, auth_url=None, project_id=None,
endpoint_type='publicURL', service_type='workflow',
auth_token=None, user_id=None):
if mistral_url and not isinstance(mistral_url, six.string_types):
raise RuntimeError('Mistral url should be string')
if auth_url:
(mistral_url, auth_token, project_id, user_id) = \
self.authenticate(mistral_url, username, api_key,
project_name, auth_url, project_id,
endpoint_type, service_type, auth_token,
user_id)
if not mistral_url:
mistral_url = "http://localhost:8989/v1"
mistral_url = "http://localhost:8989/v2"
self.http_client = httpclient.HTTPClient(mistral_url,
auth_token,
project_id,
user_id)
# Create all resource managers.
self.workbooks = workbooks.WorkbookManager(self)
self.executions = executions.ExecutionManager(self)
self.tasks = tasks.TaskManager(self)
self.listeners = listeners.ListenerManager(self)
version = determine_client_version(mistral_url)
def authenticate(self, mistral_url=None, username=None, api_key=None,
project_name=None, auth_url=None, project_id=None,
endpoint_type='publicURL', service_type='workflow',
auth_token=None, user_id=None):
if version == 1:
client_cls = client_v1.Client
else:
client_cls = client_v2.Client
if (not (project_name or project_id) or
not (isinstance(project_name, six.string_types) or
isinstance(project_id, six.string_types))):
raise RuntimeError('Either project name or project id should'
' be non-empty string')
if project_name and project_id:
raise RuntimeError('Only project name or '
'project id should be set')
if (not (username or user_id) or
not (isinstance(username, six.string_types) or
isinstance(user_id, six.string_types))):
raise RuntimeError('Either user name or user id should'
' be non-empty string')
if username and user_id:
raise RuntimeError('Only user name or user id'
' should be set')
keystone_client = _get_keystone_client(auth_url)
keystone = keystone_client.Client(
username=username,
user_id=user_id,
password=api_key,
token=auth_token,
tenant_id=project_id,
tenant_name=project_name,
auth_url=auth_url,
endpoint=auth_url)
keystone.authenticate()
token = keystone.auth_token
user_id = keystone.user_id
project_id = keystone.project_id
if not mistral_url:
catalog = keystone.service_catalog.get_endpoints(
service_type=service_type,
endpoint_type=endpoint_type
)
if service_type in catalog:
service = catalog.get(service_type)
mistral_url = service[0].get('url') if service else None
return mistral_url, token, project_id, user_id
return client_cls(mistral_url=mistral_url, username=username,
api_key=api_key, project_name=project_name,
auth_url=auth_url, project_id=project_id,
endpoint_type=endpoint_type,
service_type=service_type, auth_token=auth_token,
user_id=user_id)
def _get_keystone_client(auth_url):
if "v2.0" in auth_url:
from keystoneclient.v2_0 import client
else:
from keystoneclient.v3 import client
return client
def determine_client_version(mistral_url):
if mistral_url.find("v2") != -1:
return 2
elif mistral_url.find("v1") != -1:
return 1
raise RuntimeError("Can not determine mistral API version")

View File

View File

@ -0,0 +1,111 @@
# Copyright 2013 - Mirantis, Inc.
#
# 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 six
from mistralclient.api import httpclient
from mistralclient.api.v1 import workbooks
from mistralclient.api.v1 import executions
from mistralclient.api.v1 import tasks
from mistralclient.api.v1 import listeners
class Client(object):
def __init__(self, mistral_url=None, username=None, api_key=None,
project_name=None, auth_url=None, project_id=None,
endpoint_type='publicURL', service_type='workflow',
auth_token=None, user_id=None):
if mistral_url and not isinstance(mistral_url, six.string_types):
raise RuntimeError('Mistral url should be string')
if auth_url:
(mistral_url, auth_token, project_id, user_id) = \
self.authenticate(mistral_url, username, api_key,
project_name, auth_url, project_id,
endpoint_type, service_type, auth_token,
user_id)
if not mistral_url:
mistral_url = "http://localhost:8989/v1"
self.http_client = httpclient.HTTPClient(mistral_url,
auth_token,
project_id,
user_id)
# Create all resource managers.
self.workbooks = workbooks.WorkbookManager(self)
self.executions = executions.ExecutionManager(self)
self.tasks = tasks.TaskManager(self)
self.listeners = listeners.ListenerManager(self)
def authenticate(self, mistral_url=None, username=None, api_key=None,
project_name=None, auth_url=None, project_id=None,
endpoint_type='publicURL', service_type='workflow',
auth_token=None, user_id=None):
if (not (project_name or project_id) or
not (isinstance(project_name, six.string_types) or
isinstance(project_id, six.string_types))):
raise RuntimeError('Either project name or project id should'
' be non-empty string')
if project_name and project_id:
raise RuntimeError('Only project name or '
'project id should be set')
if (not (username or user_id) or
not (isinstance(username, six.string_types) or
isinstance(user_id, six.string_types))):
raise RuntimeError('Either user name or user id should'
' be non-empty string')
if username and user_id:
raise RuntimeError('Only user name or user id'
' should be set')
keystone_client = _get_keystone_client(auth_url)
keystone = keystone_client.Client(
username=username,
user_id=user_id,
password=api_key,
token=auth_token,
tenant_id=project_id,
tenant_name=project_name,
auth_url=auth_url,
endpoint=auth_url)
keystone.authenticate()
token = keystone.auth_token
user_id = keystone.user_id
project_id = keystone.project_id
if not mistral_url:
catalog = keystone.service_catalog.get_endpoints(
service_type=service_type,
endpoint_type=endpoint_type
)
if service_type in catalog:
service = catalog.get(service_type)
mistral_url = service[0].get('url') if service else None
return mistral_url, token, project_id, user_id
def _get_keystone_client(auth_url):
if "v2.0" in auth_url:
from keystoneclient.v2_0 import client
else:
from keystoneclient.v3 import client
return client

View File

View File

@ -0,0 +1,111 @@
# Copyright 2014 - Mirantis, Inc.
#
# 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 six
from mistralclient.api import httpclient
from mistralclient.api.v2 import workbooks
from mistralclient.api.v2 import executions
from mistralclient.api.v2 import tasks
from mistralclient.api.v2 import workflows
class Client(object):
def __init__(self, mistral_url=None, username=None, api_key=None,
project_name=None, auth_url=None, project_id=None,
endpoint_type='publicURL', service_type='workflow',
auth_token=None, user_id=None):
if mistral_url and not isinstance(mistral_url, six.string_types):
raise RuntimeError('Mistral url should be string')
if auth_url:
(mistral_url, auth_token, project_id, user_id) = \
self.authenticate(mistral_url, username, api_key,
project_name, auth_url, project_id,
endpoint_type, service_type, auth_token,
user_id)
if not mistral_url:
mistral_url = "http://localhost:8989/v2"
self.http_client = httpclient.HTTPClient(mistral_url,
auth_token,
project_id,
user_id)
# Create all resource managers.
self.workbooks = workbooks.WorkbookManager(self)
self.executions = executions.ExecutionManager(self)
self.tasks = tasks.TaskManager(self)
self.workflows = workflows.WorkflowManager(self)
def authenticate(self, mistral_url=None, username=None, api_key=None,
project_name=None, auth_url=None, project_id=None,
endpoint_type='publicURL', service_type='workflow',
auth_token=None, user_id=None):
if (not (project_name or project_id) or
not (isinstance(project_name, six.string_types) or
isinstance(project_id, six.string_types))):
raise RuntimeError('Either project name or project id should'
' be non-empty string')
if project_name and project_id:
raise RuntimeError('Only project name or '
'project id should be set')
if (not (username or user_id) or
not (isinstance(username, six.string_types) or
isinstance(user_id, six.string_types))):
raise RuntimeError('Either user name or user id should'
' be non-empty string')
if username and user_id:
raise RuntimeError('Only user name or user id'
' should be set')
keystone_client = _get_keystone_client(auth_url)
keystone = keystone_client.Client(
username=username,
user_id=user_id,
password=api_key,
token=auth_token,
tenant_id=project_id,
tenant_name=project_name,
auth_url=auth_url,
endpoint=auth_url)
keystone.authenticate()
token = keystone.auth_token
user_id = keystone.user_id
project_id = keystone.project_id
if not mistral_url:
catalog = keystone.service_catalog.get_endpoints(
service_type=service_type,
endpoint_type=endpoint_type
)
if service_type in catalog:
service = catalog.get(service_type)
mistral_url = service[0].get('url') if service else None
return mistral_url, token, project_id, user_id
def _get_keystone_client(auth_url):
if "v2.0" in auth_url:
from keystoneclient.v2_0 import client
else:
from keystoneclient.v3 import client
return client

View File

@ -0,0 +1,66 @@
# Copyright 2014 - Mirantis, Inc.
#
# 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.
from mistralclient.api import base
class Execution(base.Resource):
resource_name = 'Execution'
class ExecutionManager(base.ResourceManager):
resource_class = Execution
def create(self, workflow_name, workflow_input=None, **params):
self._ensure_not_empty(workflow_name=workflow_name)
data = {'workflow_name': workflow_name}
if workflow_input:
data.update({'workflow_input': workflow_input})
data.update(params)
return self._create('/executions', data)
def create_reverse_workflow(self, workflow_name, workflow_input,
task_name, **params):
params.update({'task_name': task_name})
return self.create(workflow_name, workflow_input, **params)
def create_direct_workflow(self, workflow_name, workflow_input, **params):
return self.create(workflow_name, workflow_input, **params)
def update(self, id, state):
self._ensure_not_empty(id=id, state=state)
data = {
'state': state
}
return self._update('/executions/%s' % id, data)
def list(self):
return self._list('/executions', response_key='executions')
def get(self, id):
self._ensure_not_empty(id=id)
return self._get('/executions/%s' % id)
def delete(self, id):
self._ensure_not_empty(id=id)
self._delete('/executions/%s' % id)

View File

@ -0,0 +1,40 @@
# Copyright 2014 - Mirantis, Inc.
#
# 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.
from mistralclient.api import base
class Task(base.Resource):
resource_name = 'Task'
class TaskManager(base.ResourceManager):
resource_class = Task
def update(self, id, state):
self._ensure_not_empty(id=id, state=state)
data = {
'state': state
}
return self._update('/tasks/%s' % id, data)
def list(self):
return self._list('/tasks', response_key='tasks')
def get(self, id):
self._ensure_not_empty(id=id)
return self._get('/tasks/%s' % id)

View File

@ -0,0 +1,64 @@
# Copyright 2014 - Mirantis, Inc.
#
# 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.
from mistralclient.api import base
class Workbook(base.Resource):
resource_name = 'Workbook'
class WorkbookManager(base.ResourceManager):
resource_class = Workbook
def create(self, name, definition=None, description=None, tags=None):
self._ensure_not_empty(name=name)
data = {
'name': name,
'description': description,
'tags': tags,
}
if definition:
data.update({'definition': definition})
return self._create('/workbooks', data)
def update(self, name, definition=None, description=None, tags=None):
self._ensure_not_empty(name=name)
data = {
'name': name,
'description': description,
'tags': tags,
}
if definition:
data.update({'definition': definition})
return self._update('/workbooks/%s' % name, data)
def list(self):
return self._list('/workbooks', response_key='workbooks')
def get(self, name):
self._ensure_not_empty(name=name)
return self._get('/workbooks/%s' % name)
def delete(self, name):
self._ensure_not_empty(name=name)
self._delete('/workbooks/%s' % name)

View File

@ -0,0 +1,62 @@
# Copyright 2014 - Mirantis, Inc.
#
# 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.
from mistralclient.api import base
class Workflow(base.Resource):
resource_name = 'Workflow'
class WorkflowManager(base.ResourceManager):
resource_class = Workflow
def create(self, name, definition, description=None, tags=None):
self._ensure_not_empty(name=name, definition=definition)
data = {
'name': name,
'definition': definition,
'description': description,
'tags': tags,
}
return self._create('/workflows', data)
def update(self, name, definition=None, description=None, tags=None):
self._ensure_not_empty(name=name)
data = {
'name': name,
'description': description,
'tags': tags,
}
if definition:
data.update({'definition': definition})
return self._update('/workflows/%s' % name, data)
def list(self):
return self._list('/workflows', response_key='workflows')
def get(self, name):
self._ensure_not_empty(name=name)
return self._get('/workflows/%s' % name)
def delete(self, name):
self._ensure_not_empty(name=name)
self._delete('/workflows/%s' % name)

View File

@ -21,7 +21,7 @@ from cliff.command import Command as BaseCommand
from cliff.lister import Lister as ListCommand
from cliff.show import ShowOne as ShowCommand
from mistralclient.api.executions import ExecutionManager
from mistralclient.api.v1.executions import ExecutionManager
LOG = logging.getLogger(__name__)

View File

@ -19,7 +19,7 @@ import logging
from cliff.lister import Lister as ListCommand
from cliff.show import ShowOne as ShowCommand
from mistralclient.api.tasks import TaskManager
from mistralclient.api.v1.tasks import TaskManager
LOG = logging.getLogger(__name__)

View File

@ -21,7 +21,7 @@ from cliff.command import Command as BaseCommand
from cliff.lister import Lister as ListCommand
from cliff.show import ShowOne as ShowCommand
from mistralclient.api.workbooks import WorkbookManager
from mistralclient.api.v1.workbooks import WorkbookManager
LOG = logging.getLogger(__name__)

View File

@ -23,7 +23,7 @@ import sys
from mistralclient.openstack.common.cliutils import env
from mistralclient.api.client import Client
from mistralclient.api import client
import mistralclient.commands.workbooks
import mistralclient.commands.executions
@ -188,15 +188,15 @@ class MistralShell(App):
return parser
def initialize_app(self, argv):
self.client = Client(mistral_url=self.options.mistral_url,
username=self.options.username,
api_key=self.options.password,
project_name=self.options.tenant_name,
auth_url=self.options.auth_url,
project_id=self.options.tenant_id,
endpoint_type='publicURL',
service_type='workflow',
auth_token=self.options.token)
self.client = client.client(mistral_url=self.options.mistral_url,
username=self.options.username,
api_key=self.options.password,
project_name=self.options.tenant_name,
auth_url=self.options.auth_url,
project_id=self.options.tenant_id,
endpoint_type='publicURL',
service_type='workflow',
auth_token=self.options.token)
def main(argv=sys.argv[1:]):

View File

@ -5,7 +5,7 @@ from tempest import clients
from tempest.common import rest_client
from mistralclient.api import base
from mistralclient.api import client as mclient
from mistralclient.api.v1 import client as mclient
class ClientAuth(rest_client.RestClient):

View File

@ -16,7 +16,7 @@ import unittest2
import mock
import json
from mistralclient.api import client
from mistralclient.api.v1 import client
class FakeResponse(object):

View File

@ -20,7 +20,7 @@ import mock
from mistralclient.tests.unit import base
from mistralclient.commands import executions
from mistralclient.api.executions import Execution
from mistralclient.api.v1.executions import Execution
EXECUTION = Execution(mock, {
'id': '123',
@ -31,7 +31,7 @@ EXECUTION = Execution(mock, {
class TestCLIExecutions(base.BaseCommandTest):
@mock.patch('mistralclient.api.executions.ExecutionManager.create')
@mock.patch('mistralclient.api.v1.executions.ExecutionManager.create')
def test_create_ctx_string(self, mock):
mock.return_value = EXECUTION
@ -40,7 +40,7 @@ class TestCLIExecutions(base.BaseCommandTest):
self.assertEqual(('123', 'some', 'else', 'RUNNING'), result[1])
@mock.patch('mistralclient.api.executions.ExecutionManager.create')
@mock.patch('mistralclient.api.v1.executions.ExecutionManager.create')
def test_create_ctx_file(self, mock):
mock.return_value = EXECUTION
path = pkg.resource_filename('mistralclient',
@ -50,7 +50,7 @@ class TestCLIExecutions(base.BaseCommandTest):
self.assertEqual(('123', 'some', 'else', 'RUNNING'), result[1])
@mock.patch('mistralclient.api.executions.ExecutionManager.update')
@mock.patch('mistralclient.api.v1.executions.ExecutionManager.update')
def test_update(self, mock):
mock.return_value = EXECUTION
@ -59,7 +59,7 @@ class TestCLIExecutions(base.BaseCommandTest):
self.assertEqual(('123', 'some', 'else', 'RUNNING'), result[1])
@mock.patch('mistralclient.api.executions.ExecutionManager.list')
@mock.patch('mistralclient.api.v1.executions.ExecutionManager.list')
def test_list(self, mock):
mock.return_value = (EXECUTION,)
@ -67,7 +67,7 @@ class TestCLIExecutions(base.BaseCommandTest):
self.assertEqual([('123', 'some', 'else', 'RUNNING')], result[1])
@mock.patch('mistralclient.api.executions.ExecutionManager.get')
@mock.patch('mistralclient.api.v1.executions.ExecutionManager.get')
def test_get(self, mock):
mock.return_value = EXECUTION
@ -75,7 +75,7 @@ class TestCLIExecutions(base.BaseCommandTest):
self.assertEqual(('123', 'some', 'else', 'RUNNING'), result[1])
@mock.patch('mistralclient.api.executions.ExecutionManager.delete')
@mock.patch('mistralclient.api.v1.executions.ExecutionManager.delete')
def test_delete(self, mock):
result = self.call(executions.Delete, app_args=['name', 'id'])

View File

@ -19,7 +19,7 @@ import mock
from mistralclient.tests.unit import base
from mistralclient.commands import tasks
from mistralclient.api.tasks import Task
from mistralclient.api.v1.tasks import Task
TASK = Task(mock, {
'id': '123',
@ -33,7 +33,7 @@ TASK = Task(mock, {
class TestCLIExecutions(base.BaseCommandTest):
@mock.patch('mistralclient.api.tasks.TaskManager.update')
@mock.patch('mistralclient.api.v1.tasks.TaskManager.update')
def test_update(self, mock):
mock.return_value = TASK
@ -44,7 +44,7 @@ class TestCLIExecutions(base.BaseCommandTest):
('123', 'some', 'thing', 'else', 'keeps', 'RUNNING', 'a, b'),
result[1])
@mock.patch('mistralclient.api.tasks.TaskManager.list')
@mock.patch('mistralclient.api.v1.tasks.TaskManager.list')
def test_list(self, mock):
mock.return_value = (TASK,)
@ -54,7 +54,7 @@ class TestCLIExecutions(base.BaseCommandTest):
[('123', 'some', 'thing', 'else', 'keeps', 'RUNNING', 'a, b')],
result[1])
@mock.patch('mistralclient.api.tasks.TaskManager.get')
@mock.patch('mistralclient.api.v1.tasks.TaskManager.get')
def test_get(self, mock):
mock.return_value = TASK

View File

@ -19,7 +19,7 @@ import mock
from mistralclient.tests.unit import base
from mistralclient.commands import workbooks
from mistralclient.api.workbooks import Workbook
from mistralclient.api.v1.workbooks import Workbook
WORKBOOK = Workbook(mock, {
'name': 'a',
@ -29,7 +29,7 @@ WORKBOOK = Workbook(mock, {
class TestCLIWorkbooks(base.BaseCommandTest):
@mock.patch('mistralclient.api.workbooks.WorkbookManager.create')
@mock.patch('mistralclient.api.v1.workbooks.WorkbookManager.create')
def test_create(self, mock):
mock.return_value = WORKBOOK
@ -37,7 +37,7 @@ class TestCLIWorkbooks(base.BaseCommandTest):
self.assertEqual(('a', 'some', 'a, b'), result[1])
@mock.patch('mistralclient.api.workbooks.WorkbookManager.update')
@mock.patch('mistralclient.api.v1.workbooks.WorkbookManager.update')
def test_update(self, mock):
mock.return_value = WORKBOOK
@ -45,7 +45,7 @@ class TestCLIWorkbooks(base.BaseCommandTest):
self.assertEqual(('a', 'some', 'a, b'), result[1])
@mock.patch('mistralclient.api.workbooks.WorkbookManager.list')
@mock.patch('mistralclient.api.v1.workbooks.WorkbookManager.list')
def test_list(self, mock):
mock.return_value = (WORKBOOK,)
@ -53,7 +53,7 @@ class TestCLIWorkbooks(base.BaseCommandTest):
self.assertEqual([('a', 'some', 'a, b')], result[1])
@mock.patch('mistralclient.api.workbooks.WorkbookManager.get')
@mock.patch('mistralclient.api.v1.workbooks.WorkbookManager.get')
def test_get(self, mock):
mock.return_value = WORKBOOK
@ -61,13 +61,13 @@ class TestCLIWorkbooks(base.BaseCommandTest):
self.assertEqual(('a', 'some', 'a, b'), result[1])
@mock.patch('mistralclient.api.workbooks.WorkbookManager.delete')
@mock.patch('mistralclient.api.v1.workbooks.WorkbookManager.delete')
def test_delete(self, mock):
self.assertIsNone(self.call(workbooks.Delete, app_args=['name']))
@mock.patch('argparse.open', create=True)
@mock.patch(
'mistralclient.api.workbooks.WorkbookManager.upload_definition'
'mistralclient.api.v1.workbooks.WorkbookManager.upload_definition'
)
def test_upload_definition(self, mock, mock_open):
mock.return_value = WORKBOOK
@ -78,7 +78,8 @@ class TestCLIWorkbooks(base.BaseCommandTest):
self.assertIsNone(result)
@mock.patch('mistralclient.api.workbooks.WorkbookManager.get_definition')
@mock.patch('mistralclient.api.v1.workbooks.'
'WorkbookManager.get_definition')
def test_get_definition(self, mock):
mock.return_value = 'sometext'

View File

@ -16,7 +16,7 @@ import unittest2
import json
from mistralclient.tests.unit import base
from mistralclient.api.executions import Execution
from mistralclient.api.v1.executions import Execution
# TODO: Later we need additional tests verifying all the errors etc.
@ -55,11 +55,14 @@ class TestExecutions(base.BaseClientTest):
EXECS[0]['context'])
self.assertIsNotNone(ex)
self.assertEqual(Execution(self.executions, EXECS[0]).__dict__,
ex.__dict__)
mock.assert_called_once_with(
URL_TEMPLATE % EXECS[0]['workbook_name'],
json.dumps(body))
self.assertDictEqual(Execution(self.executions, EXECS[0]).__dict__,
ex.__dict__)
arg_body = mock.call_args[0][1]
url = mock.call_args[0][0]
self.assertEqual(url, URL_TEMPLATE % EXECS[0]['workbook_name'])
self.assertDictEqual(json.loads(arg_body), body)
def test_create_with_empty_context(self):
mock = self.mock_http_post(content=EXECS[0])
@ -71,9 +74,11 @@ class TestExecutions(base.BaseClientTest):
self.executions.create(EXECS[0]['workbook_name'],
EXECS[0]['task'])
mock.assert_called_once_with(
URL_TEMPLATE % EXECS[0]['workbook_name'],
json.dumps(body))
arg_body = mock.call_args[0][1]
url = mock.call_args[0][0]
self.assertEqual(url, URL_TEMPLATE % EXECS[0]['workbook_name'])
self.assertDictEqual(json.loads(arg_body), body)
@unittest2.expectedFailure
def test_create_failure1(self):

View File

@ -15,7 +15,7 @@
import json
from mistralclient.tests.unit import base
from mistralclient.api.listeners import Listener
from mistralclient.api.v1.listeners import Listener
# TODO: later we need additional tests verifying all the errors etc.

View File

@ -15,7 +15,7 @@
import json
from mistralclient.tests.unit import base
from mistralclient.api.tasks import Task
from mistralclient.api.v1.tasks import Task
# TODO: later we need additional tests verifying all the errors etc.

View File

@ -15,7 +15,7 @@
import json
from mistralclient.tests.unit import base
from mistralclient.api.workbooks import Workbook
from mistralclient.api.v1.workbooks import Workbook
# TODO: later we need additional tests verifying all the errors etc.