Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Added
``url_hosts_blacklist`` and ``url_hosts_whitelist`` runner attribute. (new feature)
#4757
* Add ``user`` parameter to ``re_run`` method of st2client. #4785
* Add ``get_entrypoint()`` method to ``ActionResourceManager`` attribute of st2client. #4791

Changed
~~~~~~~
Expand Down
3 changes: 2 additions & 1 deletion st2client/st2client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from st2client.models.core import ResourceManager
from st2client.models.core import ActionAliasResourceManager
from st2client.models.core import ActionAliasExecutionManager
from st2client.models.core import ActionResourceManager
from st2client.models.core import ExecutionResourceManager
from st2client.models.core import InquiryResourceManager
from st2client.models.core import TriggerInstanceResourceManager
Expand Down Expand Up @@ -118,7 +119,7 @@ def __init__(self, base_url=None, auth_url=None, api_url=None, stream_url=None,
models.Token, self.endpoints['auth'], cacert=self.cacert, debug=self.debug)
self.managers['RunnerType'] = ResourceManager(
models.RunnerType, self.endpoints['api'], cacert=self.cacert, debug=self.debug)
self.managers['Action'] = ResourceManager(
self.managers['Action'] = ActionResourceManager(
models.Action, self.endpoints['api'], cacert=self.cacert, debug=self.debug)
self.managers['ActionAlias'] = ActionAliasResourceManager(
models.ActionAlias, self.endpoints['api'], cacert=self.cacert, debug=self.debug)
Expand Down
1 change: 1 addition & 0 deletions st2client/st2client/models/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class RunnerType(core.Resource):
class Action(core.Resource):
_plural = 'Actions'
_repr_attributes = ['name', 'pack', 'enabled', 'runner_type']
_url_path = 'actions'


class Execution(core.Resource):
Expand Down
12 changes: 12 additions & 0 deletions st2client/st2client/models/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,18 @@ def match_and_execute(self, instance, **kwargs):
return instance


class ActionResourceManager(ResourceManager):
@add_auth_token_to_kwargs_from_env
def get_entrypoint(self, ref_or_id, **kwargs):
url = '/%s/views/entry_point/%s' % (self.resource.get_url_path_name(), ref_or_id)

response = self.client.get(url, **kwargs)
if response.status_code != http_client.OK:
self.handle_error(response)

return response.text


class ExecutionResourceManager(ResourceManager):
@add_auth_token_to_kwargs_from_env
def re_run(self, execution_id, parameters=None, tasks=None, no_reset=None, user=None, delay=0,
Expand Down
104 changes: 104 additions & 0 deletions st2client/tests/unit/test_client_actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Copyright 2019 Extreme Networks, 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 __future__ import absolute_import

import json
import logging
import mock
import unittest2

from tests import base

from st2client import client
from st2client.utils import httpclient


LOG = logging.getLogger(__name__)


EXECUTION = {
"id": 12345,
"action": {
"ref": "mock.foobar"
},
"status": "failed",
"result": "non-empty"
}

ENTRYPOINT = (
"version: 1.0"

"description: A basic workflow that runs an arbitrary linux command."

"input:"
" - cmd"
" - timeout"

"tasks:"
" task1:"
" action: core.local cmd=<% ctx(cmd) %> timeout=<% ctx(timeout) %>"
" next:"
" - when: <% succeeded() %>"
" publish:"
" - stdout: <% result().stdout %>"
" - stderr: <% result().stderr %>"

"output:"
" - stdout: <% ctx(stdout) %>"
)


class TestActionResourceManager(unittest2.TestCase):

@classmethod
def setUpClass(cls):
super(TestActionResourceManager, cls).setUpClass()
cls.client = client.Client()

@mock.patch.object(
httpclient.HTTPClient, 'get',
mock.MagicMock(return_value=base.FakeResponse(json.dumps(ENTRYPOINT), 200, 'OK')))
def test_get_action_entry_point_by_ref(self):
actual_entrypoint = self.client.actions.get_entrypoint(EXECUTION['action']['ref'])
actual_entrypoint = json.loads(actual_entrypoint)

endpoint = '/actions/views/entry_point/%s' % EXECUTION['action']['ref']
httpclient.HTTPClient.get.assert_called_with(endpoint)

self.assertEqual(ENTRYPOINT, actual_entrypoint)

@mock.patch.object(
httpclient.HTTPClient, 'get',
mock.MagicMock(return_value=base.FakeResponse(json.dumps(ENTRYPOINT), 200, 'OK')))
def test_get_action_entry_point_by_id(self):
actual_entrypoint = self.client.actions.get_entrypoint(EXECUTION['id'])
actual_entrypoint = json.loads(actual_entrypoint)

endpoint = '/actions/views/entry_point/%s' % EXECUTION['id']
httpclient.HTTPClient.get.assert_called_with(endpoint)

self.assertEqual(ENTRYPOINT, actual_entrypoint)

@mock.patch.object(
httpclient.HTTPClient, 'get',
mock.MagicMock(return_value=base.FakeResponse(
json.dumps({}), 404, '404 Client Error: Not Found'
)))
def test_get_non_existent_action_entry_point(self):
with self.assertRaisesRegexp(Exception, '404 Client Error: Not Found'):
self.client.actions.get_entrypoint('nonexistentpack.nonexistentaction')

endpoint = '/actions/views/entry_point/%s' % 'nonexistentpack.nonexistentaction'
httpclient.HTTPClient.get.assert_called_with(endpoint)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a unit tests where the status code from the API call is not OK/200.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushed a commit for this, but not sure if I implemented it correctly, please let me know if I should take a different approach.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use assertRaisesRegexp and check that the error message is actually Not Found returned in the FakeResponse? Search for assertRaisesRegexp in st2 and you will see plenty of examples.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m4dcoder sorry for the delay, I've pushed a commit to use that method. Please let me know if it's not correct.