Merge "Change the mistralclient for Mistral action pack"
This commit is contained in:
@@ -15,7 +15,7 @@
|
|||||||
import six
|
import six
|
||||||
|
|
||||||
from mistralclient.api import base
|
from mistralclient.api import base
|
||||||
|
from mistralclient import utils
|
||||||
|
|
||||||
urlparse = six.moves.urllib.parse
|
urlparse = six.moves.urllib.parse
|
||||||
|
|
||||||
@@ -30,6 +30,10 @@ class ActionManager(base.ResourceManager):
|
|||||||
def create(self, definition, scope='private'):
|
def create(self, definition, scope='private'):
|
||||||
self._ensure_not_empty(definition=definition)
|
self._ensure_not_empty(definition=definition)
|
||||||
|
|
||||||
|
# If the specified definition is actually a file, read in the
|
||||||
|
# definition file
|
||||||
|
definition = utils.get_contents_if_file(definition)
|
||||||
|
|
||||||
resp = self.client.http_client.post(
|
resp = self.client.http_client.post(
|
||||||
'/actions?scope=%s' % scope,
|
'/actions?scope=%s' % scope,
|
||||||
definition,
|
definition,
|
||||||
@@ -45,6 +49,10 @@ class ActionManager(base.ResourceManager):
|
|||||||
def update(self, definition, scope='private'):
|
def update(self, definition, scope='private'):
|
||||||
self._ensure_not_empty(definition=definition)
|
self._ensure_not_empty(definition=definition)
|
||||||
|
|
||||||
|
# If the specified definition is actually a file, read in the
|
||||||
|
# definition file
|
||||||
|
definition = utils.get_contents_if_file(definition)
|
||||||
|
|
||||||
resp = self.client.http_client.put(
|
resp = self.client.http_client.put(
|
||||||
'/actions?scope=%s' % scope,
|
'/actions?scope=%s' % scope,
|
||||||
definition,
|
definition,
|
||||||
|
@@ -17,6 +17,7 @@ import json
|
|||||||
import six
|
import six
|
||||||
|
|
||||||
from mistralclient.api import base
|
from mistralclient.api import base
|
||||||
|
from mistralclient import utils
|
||||||
|
|
||||||
|
|
||||||
class Environment(base.Resource):
|
class Environment(base.Resource):
|
||||||
@@ -39,6 +40,12 @@ class EnvironmentManager(base.ResourceManager):
|
|||||||
resource_class = Environment
|
resource_class = Environment
|
||||||
|
|
||||||
def create(self, **kwargs):
|
def create(self, **kwargs):
|
||||||
|
# Check to see if the file name or URI is being passed in. If so,
|
||||||
|
# read it's contents first.
|
||||||
|
if 'file' in kwargs:
|
||||||
|
file = kwargs['file']
|
||||||
|
kwargs = utils.load_content(utils.get_contents_if_file(file))
|
||||||
|
|
||||||
self._ensure_not_empty(name=kwargs.get('name', None),
|
self._ensure_not_empty(name=kwargs.get('name', None),
|
||||||
variables=kwargs.get('variables', None))
|
variables=kwargs.get('variables', None))
|
||||||
|
|
||||||
@@ -49,6 +56,12 @@ class EnvironmentManager(base.ResourceManager):
|
|||||||
return self._create('/environments', kwargs)
|
return self._create('/environments', kwargs)
|
||||||
|
|
||||||
def update(self, **kwargs):
|
def update(self, **kwargs):
|
||||||
|
# Check to see if the file name or URI is being passed in. If so,
|
||||||
|
# read it's contents first.
|
||||||
|
if 'file' in kwargs:
|
||||||
|
file = kwargs['file']
|
||||||
|
kwargs = utils.load_content(utils.get_contents_if_file(file))
|
||||||
|
|
||||||
name = kwargs.get('name', None)
|
name = kwargs.get('name', None)
|
||||||
self._ensure_not_empty(name=name)
|
self._ensure_not_empty(name=name)
|
||||||
|
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from mistralclient.api import base
|
from mistralclient.api import base
|
||||||
|
from mistralclient import utils
|
||||||
|
|
||||||
|
|
||||||
class Workbook(base.Resource):
|
class Workbook(base.Resource):
|
||||||
@@ -26,6 +27,10 @@ class WorkbookManager(base.ResourceManager):
|
|||||||
def create(self, definition):
|
def create(self, definition):
|
||||||
self._ensure_not_empty(definition=definition)
|
self._ensure_not_empty(definition=definition)
|
||||||
|
|
||||||
|
# If the specified definition is actually a file, read in the
|
||||||
|
# definition file
|
||||||
|
definition = utils.get_contents_if_file(definition)
|
||||||
|
|
||||||
resp = self.client.http_client.post(
|
resp = self.client.http_client.post(
|
||||||
'/workbooks',
|
'/workbooks',
|
||||||
definition,
|
definition,
|
||||||
@@ -40,6 +45,10 @@ class WorkbookManager(base.ResourceManager):
|
|||||||
def update(self, definition):
|
def update(self, definition):
|
||||||
self._ensure_not_empty(definition=definition)
|
self._ensure_not_empty(definition=definition)
|
||||||
|
|
||||||
|
# If the specified definition is actually a file, read in the
|
||||||
|
# definition file
|
||||||
|
definition = utils.get_contents_if_file(definition)
|
||||||
|
|
||||||
resp = self.client.http_client.put(
|
resp = self.client.http_client.put(
|
||||||
'/workbooks',
|
'/workbooks',
|
||||||
definition,
|
definition,
|
||||||
@@ -67,6 +76,10 @@ class WorkbookManager(base.ResourceManager):
|
|||||||
def validate(self, definition):
|
def validate(self, definition):
|
||||||
self._ensure_not_empty(definition=definition)
|
self._ensure_not_empty(definition=definition)
|
||||||
|
|
||||||
|
# If the specified definition is actually a file, read in the
|
||||||
|
# definition file
|
||||||
|
definition = utils.get_contents_if_file(definition)
|
||||||
|
|
||||||
resp = self.client.http_client.post(
|
resp = self.client.http_client.post(
|
||||||
'/workbooks/validate',
|
'/workbooks/validate',
|
||||||
definition,
|
definition,
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
import six
|
import six
|
||||||
|
|
||||||
from mistralclient.api import base
|
from mistralclient.api import base
|
||||||
|
from mistralclient import utils
|
||||||
|
|
||||||
|
|
||||||
urlparse = six.moves.urllib.parse
|
urlparse = six.moves.urllib.parse
|
||||||
@@ -31,6 +32,10 @@ class WorkflowManager(base.ResourceManager):
|
|||||||
def create(self, definition, scope='private'):
|
def create(self, definition, scope='private'):
|
||||||
self._ensure_not_empty(definition=definition)
|
self._ensure_not_empty(definition=definition)
|
||||||
|
|
||||||
|
# If the specified definition is actually a file, read in the
|
||||||
|
# definition file
|
||||||
|
definition = utils.get_contents_if_file(definition)
|
||||||
|
|
||||||
resp = self.client.http_client.post(
|
resp = self.client.http_client.post(
|
||||||
'/workflows?scope=%s' % scope,
|
'/workflows?scope=%s' % scope,
|
||||||
definition,
|
definition,
|
||||||
@@ -48,6 +53,10 @@ class WorkflowManager(base.ResourceManager):
|
|||||||
|
|
||||||
url_pre = ('/workflows/%s' % id) if id else '/workflows'
|
url_pre = ('/workflows/%s' % id) if id else '/workflows'
|
||||||
|
|
||||||
|
# If the specified definition is actually a file, read in the
|
||||||
|
# definition file
|
||||||
|
definition = utils.get_contents_if_file(definition)
|
||||||
|
|
||||||
resp = self.client.http_client.put(
|
resp = self.client.http_client.put(
|
||||||
'%s?scope=%s' % (url_pre, scope),
|
'%s?scope=%s' % (url_pre, scope),
|
||||||
definition,
|
definition,
|
||||||
@@ -99,6 +108,10 @@ class WorkflowManager(base.ResourceManager):
|
|||||||
def validate(self, definition):
|
def validate(self, definition):
|
||||||
self._ensure_not_empty(definition=definition)
|
self._ensure_not_empty(definition=definition)
|
||||||
|
|
||||||
|
# If the specified definition is actually a file, read in the
|
||||||
|
# definition file
|
||||||
|
definition = utils.get_contents_if_file(definition)
|
||||||
|
|
||||||
resp = self.client.http_client.post(
|
resp = self.client.http_client.post(
|
||||||
'/workflows/validate',
|
'/workflows/validate',
|
||||||
definition,
|
definition,
|
||||||
|
10
mistralclient/tests/unit/resources/action_v2.yaml
Normal file
10
mistralclient/tests/unit/resources/action_v2.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
---
|
||||||
|
version: 2.0
|
||||||
|
|
||||||
|
my_action:
|
||||||
|
base: std.echo
|
||||||
|
base-input:
|
||||||
|
output: 'Bye!'
|
||||||
|
output:
|
||||||
|
info: <% $.output %>
|
8
mistralclient/tests/unit/resources/env_v2.json
Normal file
8
mistralclient/tests/unit/resources/env_v2.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "env1",
|
||||||
|
"description": "Test Environment #1",
|
||||||
|
"scope": "private",
|
||||||
|
"variables": {
|
||||||
|
"server": "localhost"
|
||||||
|
}
|
||||||
|
}
|
7
mistralclient/tests/unit/resources/env_v2.yaml
Normal file
7
mistralclient/tests/unit/resources/env_v2.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
"name": "env1"
|
||||||
|
"description": "Test Environment #1"
|
||||||
|
"scope": "private"
|
||||||
|
"variables":
|
||||||
|
"server": "localhost"
|
21
mistralclient/tests/unit/resources/wb_v2.yaml
Normal file
21
mistralclient/tests/unit/resources/wb_v2.yaml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
---
|
||||||
|
version: 2.0
|
||||||
|
|
||||||
|
name: wb
|
||||||
|
|
||||||
|
workflows:
|
||||||
|
wf1:
|
||||||
|
type: direct
|
||||||
|
input:
|
||||||
|
- param1
|
||||||
|
- param2
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
task1:
|
||||||
|
action: std.http url="localhost:8989"
|
||||||
|
on-success:
|
||||||
|
- test_subsequent
|
||||||
|
|
||||||
|
test_subsequent:
|
||||||
|
action: std.http url="http://some_url" server_id=1
|
10
mistralclient/tests/unit/resources/wf_v2.yaml
Normal file
10
mistralclient/tests/unit/resources/wf_v2.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
---
|
||||||
|
version: 2.0
|
||||||
|
|
||||||
|
my_wf:
|
||||||
|
type: direct
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
task1:
|
||||||
|
action: std.echo output="hello, world"
|
@@ -11,6 +11,11 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import pkg_resources as pkg
|
||||||
|
from six.moves.urllib import parse
|
||||||
|
from six.moves.urllib import request
|
||||||
|
|
||||||
from mistralclient.api.v2 import actions
|
from mistralclient.api.v2 import actions
|
||||||
from mistralclient.tests.unit.v2 import base
|
from mistralclient.tests.unit.v2 import base
|
||||||
|
|
||||||
@@ -54,6 +59,26 @@ class TestActionsV2(base.BaseClientV2Test):
|
|||||||
headers={'content-type': 'text/plain'}
|
headers={'content-type': 'text/plain'}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_create_with_file(self):
|
||||||
|
mock = self.mock_http_post(content={'actions': [ACTION]})
|
||||||
|
|
||||||
|
# The contents of action_v2.yaml must be identical to ACTION_DEF
|
||||||
|
path = pkg.resource_filename(
|
||||||
|
'mistralclient',
|
||||||
|
'tests/unit/resources/action_v2.yaml'
|
||||||
|
)
|
||||||
|
|
||||||
|
actions = self.actions.create(path)
|
||||||
|
|
||||||
|
self.assertIsNotNone(actions)
|
||||||
|
self.assertEqual(ACTION_DEF, actions[0].definition)
|
||||||
|
|
||||||
|
mock.assert_called_once_with(
|
||||||
|
URL_TEMPLATE_SCOPE,
|
||||||
|
ACTION_DEF,
|
||||||
|
headers={'content-type': 'text/plain'}
|
||||||
|
)
|
||||||
|
|
||||||
def test_update(self):
|
def test_update(self):
|
||||||
mock = self.mock_http_put(content={'actions': [ACTION]})
|
mock = self.mock_http_put(content={'actions': [ACTION]})
|
||||||
|
|
||||||
@@ -68,6 +93,29 @@ class TestActionsV2(base.BaseClientV2Test):
|
|||||||
headers={'content-type': 'text/plain'}
|
headers={'content-type': 'text/plain'}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_update_with_file_uri(self):
|
||||||
|
mock = self.mock_http_put(content={'actions': [ACTION]})
|
||||||
|
|
||||||
|
# The contents of action_v2.yaml must be identical to ACTION_DEF
|
||||||
|
path = pkg.resource_filename(
|
||||||
|
'mistralclient',
|
||||||
|
'tests/unit/resources/action_v2.yaml'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Convert the file path to file URI
|
||||||
|
uri = parse.urljoin('file:', request.pathname2url(path))
|
||||||
|
|
||||||
|
actions = self.actions.update(uri)
|
||||||
|
|
||||||
|
self.assertIsNotNone(actions)
|
||||||
|
self.assertEqual(ACTION_DEF, actions[0].definition)
|
||||||
|
|
||||||
|
mock.assert_called_once_with(
|
||||||
|
URL_TEMPLATE_SCOPE,
|
||||||
|
ACTION_DEF,
|
||||||
|
headers={'content-type': 'text/plain'}
|
||||||
|
)
|
||||||
|
|
||||||
def test_list(self):
|
def test_list(self):
|
||||||
mock = self.mock_http_get(content={'actions': [ACTION]})
|
mock = self.mock_http_get(content={'actions': [ACTION]})
|
||||||
|
|
||||||
|
@@ -11,12 +11,17 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
from collections import OrderedDict
|
||||||
import copy
|
import copy
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
import pkg_resources as pkg
|
||||||
|
from six.moves.urllib import parse
|
||||||
|
from six.moves.urllib import request
|
||||||
|
|
||||||
from mistralclient.api.v2 import environments
|
from mistralclient.api.v2 import environments
|
||||||
from mistralclient.tests.unit.v2 import base
|
from mistralclient.tests.unit.v2 import base
|
||||||
|
from mistralclient import utils
|
||||||
|
|
||||||
|
|
||||||
ENVIRONMENT = {
|
ENVIRONMENT = {
|
||||||
@@ -33,6 +38,7 @@ URL_TEMPLATE_NAME = '/environments/%s'
|
|||||||
|
|
||||||
|
|
||||||
class TestEnvironmentsV2(base.BaseClientV2Test):
|
class TestEnvironmentsV2(base.BaseClientV2Test):
|
||||||
|
|
||||||
def test_create(self):
|
def test_create(self):
|
||||||
data = copy.deepcopy(ENVIRONMENT)
|
data = copy.deepcopy(ENVIRONMENT)
|
||||||
|
|
||||||
@@ -46,6 +52,32 @@ class TestEnvironmentsV2(base.BaseClientV2Test):
|
|||||||
|
|
||||||
mock.assert_called_once_with(URL_TEMPLATE, json.dumps(expected_data))
|
mock.assert_called_once_with(URL_TEMPLATE, json.dumps(expected_data))
|
||||||
|
|
||||||
|
def test_create_with_json_file_uri(self):
|
||||||
|
# The contents of env_v2.json must be equivalent to ENVIRONMENT
|
||||||
|
path = pkg.resource_filename(
|
||||||
|
'mistralclient',
|
||||||
|
'tests/unit/resources/env_v2.json'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Convert the file path to file URI
|
||||||
|
uri = parse.urljoin('file:', request.pathname2url(path))
|
||||||
|
data = OrderedDict(
|
||||||
|
utils.load_content(
|
||||||
|
utils.get_contents_if_file(uri)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
mock = self.mock_http_post(content=data)
|
||||||
|
file_input = {'file': uri}
|
||||||
|
env = self.environments.create(**file_input)
|
||||||
|
|
||||||
|
self.assertIsNotNone(env)
|
||||||
|
|
||||||
|
expected_data = copy.deepcopy(data)
|
||||||
|
expected_data['variables'] = json.dumps(expected_data['variables'])
|
||||||
|
|
||||||
|
mock.assert_called_once_with(URL_TEMPLATE, json.dumps(expected_data))
|
||||||
|
|
||||||
def test_update(self):
|
def test_update(self):
|
||||||
data = copy.deepcopy(ENVIRONMENT)
|
data = copy.deepcopy(ENVIRONMENT)
|
||||||
|
|
||||||
@@ -59,6 +91,29 @@ class TestEnvironmentsV2(base.BaseClientV2Test):
|
|||||||
|
|
||||||
mock.assert_called_once_with(URL_TEMPLATE, json.dumps(expected_data))
|
mock.assert_called_once_with(URL_TEMPLATE, json.dumps(expected_data))
|
||||||
|
|
||||||
|
def test_update_with_yaml_file(self):
|
||||||
|
# The contents of env_v2.json must be equivalent to ENVIRONMENT
|
||||||
|
path = pkg.resource_filename(
|
||||||
|
'mistralclient',
|
||||||
|
'tests/unit/resources/env_v2.json'
|
||||||
|
)
|
||||||
|
data = OrderedDict(
|
||||||
|
utils.load_content(
|
||||||
|
utils.get_contents_if_file(path)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
mock = self.mock_http_put(content=data)
|
||||||
|
file_input = {'file': path}
|
||||||
|
env = self.environments.update(**file_input)
|
||||||
|
|
||||||
|
self.assertIsNotNone(env)
|
||||||
|
|
||||||
|
expected_data = copy.deepcopy(data)
|
||||||
|
expected_data['variables'] = json.dumps(expected_data['variables'])
|
||||||
|
|
||||||
|
mock.assert_called_once_with(URL_TEMPLATE, json.dumps(expected_data))
|
||||||
|
|
||||||
def test_list(self):
|
def test_list(self):
|
||||||
mock = self.mock_http_get(content={'environments': [ENVIRONMENT]})
|
mock = self.mock_http_get(content={'environments': [ENVIRONMENT]})
|
||||||
|
|
||||||
|
@@ -13,6 +13,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import pkg_resources as pkg
|
||||||
|
from six.moves.urllib import parse
|
||||||
|
from six.moves.urllib import request
|
||||||
|
|
||||||
from mistralclient.api import base as api_base
|
from mistralclient.api import base as api_base
|
||||||
from mistralclient.api.v2 import workbooks
|
from mistralclient.api.v2 import workbooks
|
||||||
from mistralclient.tests.unit.v2 import base
|
from mistralclient.tests.unit.v2 import base
|
||||||
@@ -79,6 +83,29 @@ class TestWorkbooksV2(base.BaseClientV2Test):
|
|||||||
headers={'content-type': 'text/plain'}
|
headers={'content-type': 'text/plain'}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_create_with_file_uri(self):
|
||||||
|
mock = self.mock_http_post(content=WORKBOOK)
|
||||||
|
|
||||||
|
# The contents of wb_v2.yaml must be identical to WB_DEF
|
||||||
|
path = pkg.resource_filename(
|
||||||
|
'mistralclient',
|
||||||
|
'tests/unit/resources/wb_v2.yaml'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Convert the file path to file URI
|
||||||
|
uri = parse.urljoin('file:', request.pathname2url(path))
|
||||||
|
|
||||||
|
wb = self.workbooks.create(uri)
|
||||||
|
|
||||||
|
self.assertIsNotNone(wb)
|
||||||
|
self.assertEqual(WB_DEF, wb.definition)
|
||||||
|
|
||||||
|
mock.assert_called_once_with(
|
||||||
|
URL_TEMPLATE,
|
||||||
|
WB_DEF,
|
||||||
|
headers={'content-type': 'text/plain'}
|
||||||
|
)
|
||||||
|
|
||||||
def test_update(self):
|
def test_update(self):
|
||||||
mock = self.mock_http_put(content=WORKBOOK)
|
mock = self.mock_http_put(content=WORKBOOK)
|
||||||
|
|
||||||
@@ -93,6 +120,26 @@ class TestWorkbooksV2(base.BaseClientV2Test):
|
|||||||
headers={'content-type': 'text/plain'}
|
headers={'content-type': 'text/plain'}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_update_with_file(self):
|
||||||
|
mock = self.mock_http_put(content=WORKBOOK)
|
||||||
|
|
||||||
|
# The contents of wb_v2.yaml must be identical to WB_DEF
|
||||||
|
path = pkg.resource_filename(
|
||||||
|
'mistralclient',
|
||||||
|
'tests/unit/resources/wb_v2.yaml'
|
||||||
|
)
|
||||||
|
|
||||||
|
wb = self.workbooks.update(path)
|
||||||
|
|
||||||
|
self.assertIsNotNone(wb)
|
||||||
|
self.assertEqual(WB_DEF, wb.definition)
|
||||||
|
|
||||||
|
mock.assert_called_once_with(
|
||||||
|
URL_TEMPLATE,
|
||||||
|
WB_DEF,
|
||||||
|
headers={'content-type': 'text/plain'}
|
||||||
|
)
|
||||||
|
|
||||||
def test_list(self):
|
def test_list(self):
|
||||||
mock = self.mock_http_get(content={'workbooks': [WORKBOOK]})
|
mock = self.mock_http_get(content={'workbooks': [WORKBOOK]})
|
||||||
|
|
||||||
@@ -145,6 +192,28 @@ class TestWorkbooksV2(base.BaseClientV2Test):
|
|||||||
headers={'content-type': 'text/plain'}
|
headers={'content-type': 'text/plain'}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_validate_with_file(self):
|
||||||
|
mock = self.mock_http_post(status_code=200,
|
||||||
|
content={'valid': True})
|
||||||
|
|
||||||
|
# The contents of wb_v2.yaml must be identical to WB_DEF
|
||||||
|
path = pkg.resource_filename(
|
||||||
|
'mistralclient',
|
||||||
|
'tests/unit/resources/wb_v2.yaml'
|
||||||
|
)
|
||||||
|
|
||||||
|
result = self.workbooks.validate(path)
|
||||||
|
|
||||||
|
self.assertIsNotNone(result)
|
||||||
|
self.assertIn('valid', result)
|
||||||
|
self.assertTrue(result['valid'])
|
||||||
|
|
||||||
|
mock.assert_called_once_with(
|
||||||
|
URL_TEMPLATE_VALIDATE,
|
||||||
|
WB_DEF,
|
||||||
|
headers={'content-type': 'text/plain'}
|
||||||
|
)
|
||||||
|
|
||||||
def test_validate_failed(self):
|
def test_validate_failed(self):
|
||||||
mock_result = {
|
mock_result = {
|
||||||
"valid": False,
|
"valid": False,
|
||||||
|
@@ -11,6 +11,11 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import pkg_resources as pkg
|
||||||
|
from six.moves.urllib import parse
|
||||||
|
from six.moves.urllib import request
|
||||||
|
|
||||||
from mistralclient.api.v2 import workflows
|
from mistralclient.api.v2 import workflows
|
||||||
from mistralclient.tests.unit.v2 import base
|
from mistralclient.tests.unit.v2 import base
|
||||||
|
|
||||||
@@ -54,6 +59,26 @@ class TestWorkflowsV2(base.BaseClientV2Test):
|
|||||||
headers={'content-type': 'text/plain'}
|
headers={'content-type': 'text/plain'}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_create_with_file(self):
|
||||||
|
mock = self.mock_http_post(content={'workflows': [WORKFLOW]})
|
||||||
|
|
||||||
|
# The contents of wf_v2.yaml must be identical to WF_DEF
|
||||||
|
path = pkg.resource_filename(
|
||||||
|
'mistralclient',
|
||||||
|
'tests/unit/resources/wf_v2.yaml'
|
||||||
|
)
|
||||||
|
|
||||||
|
wfs = self.workflows.create(path)
|
||||||
|
|
||||||
|
self.assertIsNotNone(wfs)
|
||||||
|
self.assertEqual(WF_DEF, wfs[0].definition)
|
||||||
|
|
||||||
|
mock.assert_called_once_with(
|
||||||
|
URL_TEMPLATE_SCOPE,
|
||||||
|
WF_DEF,
|
||||||
|
headers={'content-type': 'text/plain'}
|
||||||
|
)
|
||||||
|
|
||||||
def test_update(self):
|
def test_update(self):
|
||||||
mock = self.mock_http_put(content={'workflows': [WORKFLOW]})
|
mock = self.mock_http_put(content={'workflows': [WORKFLOW]})
|
||||||
|
|
||||||
@@ -82,6 +107,29 @@ class TestWorkflowsV2(base.BaseClientV2Test):
|
|||||||
headers={'content-type': 'text/plain'}
|
headers={'content-type': 'text/plain'}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_update_with_file_uri(self):
|
||||||
|
mock = self.mock_http_put(content={'workflows': [WORKFLOW]})
|
||||||
|
|
||||||
|
# The contents of wf_v2.yaml must be identical to WF_DEF
|
||||||
|
path = pkg.resource_filename(
|
||||||
|
'mistralclient',
|
||||||
|
'tests/unit/resources/wf_v2.yaml'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Convert the file path to file URI
|
||||||
|
uri = parse.urljoin('file:', request.pathname2url(path))
|
||||||
|
|
||||||
|
wfs = self.workflows.update(uri)
|
||||||
|
|
||||||
|
self.assertIsNotNone(wfs)
|
||||||
|
self.assertEqual(WF_DEF, wfs[0].definition)
|
||||||
|
|
||||||
|
mock.assert_called_once_with(
|
||||||
|
URL_TEMPLATE_SCOPE,
|
||||||
|
WF_DEF,
|
||||||
|
headers={'content-type': 'text/plain'}
|
||||||
|
)
|
||||||
|
|
||||||
def test_list(self):
|
def test_list(self):
|
||||||
mock = self.mock_http_get(content={'workflows': [WORKFLOW]})
|
mock = self.mock_http_get(content={'workflows': [WORKFLOW]})
|
||||||
|
|
||||||
|
@@ -14,9 +14,12 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
from six.moves.urllib import parse
|
||||||
|
from six.moves.urllib import request
|
||||||
|
|
||||||
from mistralclient import exceptions
|
from mistralclient import exceptions
|
||||||
|
|
||||||
|
|
||||||
@@ -51,3 +54,28 @@ def load_content(content):
|
|||||||
def load_file(path):
|
def load_file(path):
|
||||||
with open(path, 'r') as f:
|
with open(path, 'r') as f:
|
||||||
return load_content(f.read())
|
return load_content(f.read())
|
||||||
|
|
||||||
|
|
||||||
|
def get_contents_if_file(contents_or_file_name):
|
||||||
|
"""Get the contents of a file.
|
||||||
|
|
||||||
|
If the value passed in is a file name or file URI, return the
|
||||||
|
contents. If not, or there is an error reading the file contents,
|
||||||
|
return the value passed in as the contents.
|
||||||
|
|
||||||
|
For example, a workflow definition will be returned if either the
|
||||||
|
workflow definition file name, or file URI are passed in, or the
|
||||||
|
actual workflow definition itself is passed in.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if parse.urlparse(contents_or_file_name).scheme:
|
||||||
|
definition_url = contents_or_file_name
|
||||||
|
else:
|
||||||
|
path = os.path.abspath(contents_or_file_name)
|
||||||
|
definition_url = parse.urljoin(
|
||||||
|
'file:',
|
||||||
|
request.pathname2url(path)
|
||||||
|
)
|
||||||
|
return request.urlopen(definition_url).read().decode('utf8')
|
||||||
|
except Exception:
|
||||||
|
return contents_or_file_name
|
||||||
|
@@ -7,3 +7,4 @@ python-keystoneclient!=1.8.0,!=2.1.0,>=1.6.0 # Apache-2.0
|
|||||||
python-openstackclient>=2.1.0 # Apache-2.0
|
python-openstackclient>=2.1.0 # Apache-2.0
|
||||||
PyYAML>=3.1.0 # MIT
|
PyYAML>=3.1.0 # MIT
|
||||||
requests!=2.9.0,>=2.8.1 # Apache-2.0
|
requests!=2.9.0,>=2.8.1 # Apache-2.0
|
||||||
|
six>=1.9.0 # MIT
|
||||||
|
Reference in New Issue
Block a user