import awxkit

Co-authored-by: Christopher Wang <cwang@ansible.com>
Co-authored-by: Jake McDermott <jmcdermott@ansible.com>
Co-authored-by: Jim Ladd <jladd@redhat.com>
Co-authored-by: Elijah DeLee <kdelee@redhat.com>
Co-authored-by: Alan Rominger <arominge@redhat.com>
Co-authored-by: Yanis Guenane <yanis@guenane.org>
This commit is contained in:
Ryan Petrello
2019-08-08 22:12:31 -04:00
parent 9b836abf1f
commit 9616cc6f78
101 changed files with 10479 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
from io import StringIO
import pytest
from requests.exceptions import ConnectionError
from awxkit.cli import run, CLI
class MockedCLI(CLI):
def fetch_version_root(self):
pass
@property
def v2(self):
return MockedCLI()
@property
def json(self):
return {
'users': None
}
@pytest.mark.parametrize('help_param', ['-h', '--help'])
def test_help(capfd, help_param):
with pytest.raises(SystemExit):
run(['awx {}'.format(help_param)])
out, err = capfd.readouterr()
assert "usage:" in out
for snippet in (
'--conf.host https://example.awx.org]',
'-v, --verbose'
):
assert snippet in out
def test_connection_error(capfd):
cli = CLI()
cli.parse_args(['awx'])
with pytest.raises(ConnectionError):
cli.connect()
@pytest.mark.parametrize('resource', ['', 'invalid'])
def test_list_resources(capfd, resource):
# if a valid resource isn't specified, print --help
cli = MockedCLI()
cli.parse_args(['awx {}'.format(resource)])
cli.connect()
cli.parse_resource()
out, err = capfd.readouterr()
assert "usage:" in out
for snippet in (
'--conf.host https://example.awx.org]',
'-v, --verbose'
):
assert snippet in out

View File

@@ -0,0 +1,65 @@
import pytest
from requests.exceptions import ConnectionError
from awxkit.cli import CLI
from awxkit import config
def test_host_from_environment():
cli = CLI()
cli.parse_args(
['awx'],
env={'TOWER_HOST': 'https://xyz.local'}
)
with pytest.raises(ConnectionError):
cli.connect()
assert config.base_url == 'https://xyz.local'
def test_host_from_argv():
cli = CLI()
cli.parse_args(['awx', '--conf.host', 'https://xyz.local'])
with pytest.raises(ConnectionError):
cli.connect()
assert config.base_url == 'https://xyz.local'
def test_username_and_password_from_environment():
cli = CLI()
cli.parse_args(
['awx'],
env={
'TOWER_USERNAME': 'mary',
'TOWER_PASSWORD': 'secret'
}
)
with pytest.raises(ConnectionError):
cli.connect()
assert config.credentials.default.username == 'mary'
assert config.credentials.default.password == 'secret'
def test_username_and_password_argv():
cli = CLI()
cli.parse_args([
'awx', '--conf.username', 'mary', '--conf.password', 'secret'
])
with pytest.raises(ConnectionError):
cli.connect()
assert config.credentials.default.username == 'mary'
assert config.credentials.default.password == 'secret'
def test_config_precedence():
cli = CLI()
cli.parse_args(
[
'awx', '--conf.username', 'mary', '--conf.password', 'secret'
],
env={
'TOWER_USERNAME': 'IGNORE',
'TOWER_PASSWORD': 'IGNORE'
}
)
with pytest.raises(ConnectionError):
cli.connect()
assert config.credentials.default.username == 'mary'
assert config.credentials.default.password == 'secret'

View File

@@ -0,0 +1,46 @@
import json
import yaml
from awxkit.api.pages import Page
from awxkit.api.pages.users import Users, User
from awxkit.cli.format import format_response
def test_json_empty_list():
page = Page.from_json({
'results': []
})
formatted = format_response(page)
assert json.loads(formatted) == {'results': []}
def test_yaml_empty_list():
page = Page.from_json({
'results': []
})
formatted = format_response(page, fmt='yaml')
assert yaml.safe_load(formatted) == {'results': []}
def test_json_list():
users = {
'results': [
{'username': 'betty'},
{'username': 'tom'},
{'username': 'anne'},
]
}
page = Users.from_json(users)
formatted = format_response(page)
assert json.loads(formatted) == users
def test_yaml_list():
users = {
'results': [
{'username': 'betty'},
{'username': 'tom'},
{'username': 'anne'},
]
}
page = Users.from_json(users)
formatted = format_response(page, fmt='yaml')
assert yaml.safe_load(formatted) == users

View File

@@ -0,0 +1,229 @@
import argparse
import json
import unittest
from io import StringIO
import pytest
from requests import Response
from awxkit.api.pages import Page
from awxkit.cli.options import ResourceOptionsParser
class OptionsPage(Page):
def options(self):
return self
def endswith(self, v):
return self.endpoint.endswith(v)
def __getitem__(self, k):
return {
'GET': {},
'POST': {},
'PUT': {},
}
class TestOptions(unittest.TestCase):
def setUp(self):
_parser = argparse.ArgumentParser()
self.parser = _parser.add_subparsers(help='action')
def test_list(self):
page = OptionsPage.from_json({
'actions': {
'GET': {},
'POST': {},
}
})
ResourceOptionsParser(page, 'users', self.parser)
assert 'list' in self.parser.choices
def test_list_filtering(self):
page = OptionsPage.from_json({
'actions': {
'GET': {},
'POST': {
'first_name': {'type': 'string'}
},
}
})
options = ResourceOptionsParser(page, 'users', self.parser)
options.build_query_arguments('list', 'POST')
assert 'list' in self.parser.choices
out = StringIO()
self.parser.choices['list'].print_help(out)
assert '--first_name TEXT' in out.getvalue()
def test_list_not_filterable(self):
page = OptionsPage.from_json({
'actions': {
'GET': {},
'POST': {
'middle_name': {'type': 'string', 'filterable': False}
},
}
})
options = ResourceOptionsParser(page, 'users', self.parser)
options.build_query_arguments('list', 'POST')
assert 'list' in self.parser.choices
out = StringIO()
self.parser.choices['list'].print_help(out)
assert '--middle_name' not in out.getvalue()
def test_creation_optional_argument(self):
page = OptionsPage.from_json({
'actions': {
'POST': {
'first_name': {
'type': 'string',
'help_text': 'Please specify your first name',
}
},
}
})
options = ResourceOptionsParser(page, 'users', self.parser)
options.build_query_arguments('create', 'POST')
assert 'create' in self.parser.choices
out = StringIO()
self.parser.choices['create'].print_help(out)
assert '--first_name TEXT Please specify your first name' in out.getvalue()
def test_creation_required_argument(self):
page = OptionsPage.from_json({
'actions': {
'POST': {
'username': {
'type': 'string',
'help_text': 'Please specify a username',
'required': True
}
},
}
})
options = ResourceOptionsParser(page, self.parser)
options.build_query_arguments('create', 'POST')
assert 'create' in self.parser.choices
out = StringIO()
self.parser.choices['create'].print_help(out)
assert '--username TEXT [REQUIRED] Please specify a username' in out.getvalue()
def test_creation_required_argument(self):
page = OptionsPage.from_json({
'actions': {
'POST': {
'username': {
'type': 'string',
'help_text': 'Please specify a username',
'required': True
}
},
}
})
options = ResourceOptionsParser(page, 'users', self.parser)
options.build_query_arguments('create', 'POST')
assert 'create' in self.parser.choices
out = StringIO()
self.parser.choices['create'].print_help(out)
assert '--username TEXT [REQUIRED] Please specify a username' in out.getvalue()
def test_integer_argument(self):
page = OptionsPage.from_json({
'actions': {
'POST': {
'limit': {'type': 'integer'}
},
}
})
options = ResourceOptionsParser(page, 'job_templates', self.parser)
options.build_query_arguments('create', 'POST')
assert 'create' in self.parser.choices
out = StringIO()
self.parser.choices['create'].print_help(out)
assert '--limit INTEGER' in out.getvalue()
def test_boolean_argument(self):
page = OptionsPage.from_json({
'actions': {
'POST': {
'diff_mode': {'type': 'boolean'}
},
}
})
options = ResourceOptionsParser(page, 'users', self.parser)
options.build_query_arguments('create', 'POST')
assert 'create' in self.parser.choices
out = StringIO()
self.parser.choices['create'].print_help(out)
assert '--diff_mode BOOLEAN' in out.getvalue()
def test_choices(self):
page = OptionsPage.from_json({
'actions': {
'POST': {
'verbosity': {
'type': 'integer',
'choices': [
(0, '0 (Normal)'),
(1, '1 (Verbose)'),
(2, '2 (More Verbose)'),
(3, '3 (Debug)'),
(4, '4 (Connection Debug)'),
(5, '5 (WinRM Debug)'),
]
}
},
}
})
options = ResourceOptionsParser(page, 'users', self.parser)
options.build_query_arguments('create', 'POST')
assert 'create' in self.parser.choices
out = StringIO()
self.parser.choices['create'].print_help(out)
assert '--verbosity {0,1,2,3,4,5}' in out.getvalue()
def test_actions_with_primary_key(self):
for method in ('get', 'modify', 'delete'):
page = OptionsPage.from_json({
'actions': {'GET': {}, 'POST': {}}
})
ResourceOptionsParser(page, 'users', self.parser)
assert method in self.parser.choices
out = StringIO()
self.parser.choices[method].print_help(out)
assert 'positional arguments:\n id' in out.getvalue()
class TestSettingsOptions(unittest.TestCase):
def setUp(self):
_parser = argparse.ArgumentParser()
self.parser = _parser.add_subparsers(help='action')
def test_list(self):
page = OptionsPage.from_json({
'actions': {
'GET': {},
'POST': {},
'PUT': {},
}
})
page.endpoint = '/settings/all/'
ResourceOptionsParser(page, 'settings', self.parser)
assert 'list' in self.parser.choices
assert 'modify' in self.parser.choices
out = StringIO()
self.parser.choices['modify'].print_help(out)
assert 'modify [-h] key value' in out.getvalue()