diff options
Diffstat (limited to 'testapi/testapi-client')
8 files changed, 298 insertions, 58 deletions
diff --git a/testapi/testapi-client/testapiclient/cli/pods.py b/testapi/testapi-client/testapiclient/cli/pods.py index df63737..a7706f6 100644 --- a/testapi/testapi-client/testapiclient/cli/pods.py +++ b/testapi/testapi-client/testapiclient/cli/pods.py @@ -3,6 +3,7 @@ import json from testapiclient.client import pods from testapiclient.utils import command from testapiclient.utils import urlparse +from testapiclient.models import pods as pm def pods_url(): @@ -61,8 +62,10 @@ class PodCreate(command.ShowOne): parser.add_argument('pod', type=json.loads, help='Pod create request format :\n' - '\'{"role": "", "name": "", "details": "", ' - '"mode": ""}\',\n role should be either ' + '\'{}\''.format(json.dumps( + pm.PodCreateRequest().__dict__ + )) + + '\n role should be either ' '"community-ci" or "production-ci", and ' 'mode should be either "metal" or "virtual.') return parser diff --git a/testapi/testapi-client/testapiclient/cli/scenarios.py b/testapi/testapi-client/testapiclient/cli/scenarios.py index 507705a..197ee0c 100644 --- a/testapi/testapi-client/testapiclient/cli/scenarios.py +++ b/testapi/testapi-client/testapiclient/cli/scenarios.py @@ -2,6 +2,7 @@ import json from testapiclient.utils import command from testapiclient.utils import urlparse +from testapiclient.models import scenario def scenarios_url(): @@ -64,22 +65,37 @@ class ScenarioCreate(command.ShowOne): parser.add_argument('scenario', type=json.loads, help='Scenario create request format :\n' - '\'{ "installers": [], "name": ""}\',\n' - 'Intaller create request format :\n' - '\'{"installer": "","versions": []}\',\n' - 'Version create request format :\n' - '\'{"owner": "","version": "",' - '"projects": []}\',\n' - 'Project create request format :\n' - '\'{"project": "","customs": [],' - '"scores": [],' - '"trust_indicators": []}\',\n' - 'Custom create request format :\n' + '\'{}\''.format(json.dumps( + scenario.ScenarioCreateRequest( + ).__dict__ + )) + + '\n Intaller create request format :\n' + '\'{}\''.format(json.dumps( + scenario.ScenarioInstallerCreateRequest( + ).__dict__ + )) + + '\n Version create request format :\n' + '\'{}\''.format(json.dumps( + scenario.ScenarioVersionCreateRequest( + ).__dict__ + )) + + '\n Project create request format :\n' + '\'{}\''.format(json.dumps( + scenario.ScenarioProjectCreateRequest( + ).__dict__ + )) + + '\n Custom create request format :\n' '\'["asf","saf"]\',\n' - 'Score create request format :\n' - '\'{"date": "", "score": ""}\',\n' - 'Trust Indicators create request format :\n' - '\'{"date": "", "status": ""}\'') + '\n Score create request format :\n' + '\'{}\''.format(json.dumps( + scenario.ScenarioScoreCreateRequest( + ).__dict__ + )) + + '\nTrustIndicator create request format:\n' + '\'{}\''.format(json.dumps( + scenario.ScenarioTICreateRequest( + ).__dict__ + ))) return parser def take_action(self, parsed_args): @@ -110,23 +126,38 @@ class ScenarioPut(command.ShowOne): help='Update scenario by name') parser.add_argument('scenario', type=json.loads, - help='Scenario create request format :\n' - '\'{ "installers": [], "name": ""}\',\n' - 'Intaller create request format :\n' - '\'{"installer": "","versions": []}\',\n' - 'Version create request format :\n' - '\'{"owner": "","version": "",' - '"projects": []}\',\n' - 'Project create request format :\n' - '\'{"project": "","customs": [],' - '"scores": [],' - '"trust_indicators": []}\',\n' - 'Custom create request format :\n' + help='Scenario create request format :\n' + + '\'{}\''.format(json.dumps( + scenario.ScenarioCreateRequest( + ).__dict__ + )) + + '\n Intaller create request format :\n' + '\'{}\''.format(json.dumps( + scenario.ScenarioInstallerCreateRequest( + ).__dict__ + )) + + '\n Version create request format :\n' + '\'{}\''.format(json.dumps( + scenario.ScenarioVersionCreateRequest( + ).__dict__ + )) + + '\n Project create request format :\n' + '\'{}\''.format(json.dumps( + scenario.ScenarioProjectCreateRequest( + ).__dict__ + )) + + '\n Custom create request format :\n' '\'["asf","saf"]\',\n' - 'Score create request format :\n' - '\'{"date": "", "score": ""}\',\n' - 'Trust Indicators create request format :\n' - '\'{"date": "", "status": ""}\'') + '\n Score create request format :\n' + '\'{}\''.format(json.dumps( + scenario.ScenarioScoreCreateRequest( + ).__dict__ + )) + + '\nTrustIndicator create request format:\n' + '\'{}\''.format(json.dumps( + scenario.ScenarioTICreateRequest( + ).__dict__ + ))) return parser def take_action(self, parsed_args): @@ -145,7 +176,10 @@ class InstallerCreate(command.Command): parser.add_argument('installer', type=json.loads, help='Intaller create request format :\n' - '\'[{"installer": "","versions": []}]\',\n') + '\'{}\''.format(json.dumps( + scenario.ScenarioInstallerCreateRequest( + ).__dict__ + ))) return parser def take_action(self, parsed_args): @@ -186,7 +220,10 @@ class InstallerPut(command.Command): parser.add_argument('installer', type=json.loads, help='Intaller create request format :\n' - '\'[{"installer": "","versions": []}]\',\n') + '\'{}\''.format(json.dumps( + scenario.ScenarioInstallerCreateRequest( + ).__dict__ + ))) return parser def take_action(self, parsed_args): @@ -209,10 +246,10 @@ class VersionCreate(command.Command): parser.add_argument('version', type=json.loads, help='version create request format :\n' - '\'[{"owner":(string),' - '"version": (string),' - '"projects": (array[ScenarioProject])' - '}]\',\n') + '\'{}\''.format(json.dumps( + scenario.ScenarioVersionCreateRequest( + ).__dict__ + ))) return parser def take_action(self, parsed_args): @@ -261,10 +298,10 @@ class VersionPut(command.Command): parser.add_argument('version', type=json.loads, help='version update request format :\n' - '\'[{"owner":(string),' - '"version": (string),' - '"projects": (array[ScenarioProject])' - '}]\',\n') + '\'{}\''.format(json.dumps( + scenario.ScenarioVersionCreateRequest( + ).__dict__ + ))) return parser def take_action(self, parsed_args): @@ -320,10 +357,10 @@ class ProjectCreate(command.Command): parser.add_argument('project', type=json.loads, help='Project create request format :\n' - '\'[{ "project" (string),' - '"scores": (array[ScenarioScore]),' - '"trust_indicators": (array[ScenarioTI]),' - '"customs": (array[string]) }]\',\n') + '\'{}\''.format(json.dumps( + scenario.ScenarioProjectCreateRequest( + ).__dict__ + ))) return parser def take_action(self, parsed_args): @@ -378,10 +415,10 @@ class ProjectPut(command.Command): parser.add_argument('project', type=json.loads, help='Project update request format :\n' - '\'[{ "project" (string),' - '"scores": (array[ScenarioScore]),' - '"trust_indicators": (array[ScenarioTI]),' - '"customs": (array[string]) }]\',\n') + '\'{}\''.format(json.dumps( + scenario.ScenarioProjectCreateRequest( + ).__dict__ + ))) return parser def take_action(self, parsed_args): @@ -511,8 +548,10 @@ class TrustIndicatorCreate(command.Command): parser.add_argument('trust_indicator', type=json.loads, help='trust indicator create request format :\n' - '\'{ "date": (string, optional),' - '"status": (string, optional) }\',\n') + '\'{}\''.format(json.dumps( + scenario.ScenarioTICreateRequest( + ).__dict__ + ))) return parser def take_action(self, parsed_args): @@ -547,8 +586,10 @@ class ScoreCreate(command.Command): parser.add_argument('score', type=json.loads, help='score create request format :\n' - '\'{ "date": (string, optional),' - '"score" : (string, optional) }\',\n') + '\'{}\''.format(json.dumps( + scenario.ScenarioScoreCreateRequest( + ).__dict__ + ))) return parser def take_action(self, parsed_args): diff --git a/testapi/testapi-client/testapiclient/client/pods.py b/testapi/testapi-client/testapiclient/client/pods.py index 4254da7..d08114f 100644 --- a/testapi/testapi-client/testapiclient/client/pods.py +++ b/testapi/testapi-client/testapiclient/client/pods.py @@ -1,4 +1,7 @@ +import json + from testapiclient.client import base +from testapiclient.utils import urlparse class PodsClient(base.Client): @@ -9,3 +12,20 @@ class PodsClient(base.Client): def create(self, pod_req): return self.clientmanager.post(self.url, pod_req) + + def get(self, **queries): + if queries: + return json.dumps( + self.clientmanager.get( + urlparse.query_join(self.url, **queries))['pods']) + else: + return json.dumps( + self.clientmanager.get(self.url)['pods']) + + def get_one(self, name): + return json.dumps(self.clientmanager.get( + urlparse.path_join(self.url, name))) + + def delete(self, name): + return self.clientmanager.delete( + urlparse.path_join(self.url, name)) diff --git a/testapi/testapi-client/testapiclient/models/pods.py b/testapi/testapi-client/testapiclient/models/pods.py index 27ea311..4fa42e7 100644 --- a/testapi/testapi-client/testapiclient/models/pods.py +++ b/testapi/testapi-client/testapiclient/models/pods.py @@ -1,5 +1,5 @@ class PodCreateRequest(object): - def __init__(self, name='', mode='', details='', role=""): + def __init__(self, name='', mode='', details='', role=''): self.name = name self.mode = mode self.details = details diff --git a/testapi/testapi-client/testapiclient/models/scenario.py b/testapi/testapi-client/testapiclient/models/scenario.py new file mode 100644 index 0000000..f4f0f40 --- /dev/null +++ b/testapi/testapi-client/testapiclient/models/scenario.py @@ -0,0 +1,37 @@ +class ScenarioCreateRequest: + def __init__(self, name='', installers=[]): + self.name = name + self.installers = installers + + +class ScenarioInstallerCreateRequest: + def __init__(self, installer='', versions=[]): + self.installer = installer + self.versions = versions + + +class ScenarioVersionCreateRequest: + def __init__(self, version='', owner='', projects=[]): + self.version = version + self.owner = owner + self.projects = projects + + +class ScenarioProjectCreateRequest: + def __init__(self, project='', scores=[], trust_indicators=[], customs=[]): + self.project = project + self.scores = scores + self.trust_indicators = trust_indicators + self.customs = customs + + +class ScenarioScoreCreateRequest: + def __init__(self, score='', date=''): + self.score = score + self.date = date + + +class ScenarioTICreateRequest: + def __init__(self, status='', date=''): + self.status = status + self.date = date diff --git a/testapi/testapi-client/testapiclient/tests/unit/test_app.py b/testapi/testapi-client/testapiclient/tests/unit/test_app.py new file mode 100644 index 0000000..c20b27f --- /dev/null +++ b/testapi/testapi-client/testapiclient/tests/unit/test_app.py @@ -0,0 +1,50 @@ +import urllib + +from mock import mock + +from testapiclient import main +from testapiclient.tests.unit import utils +from testapiclient.tests.unit import fakes + + +class MainTest(utils.TestCommand): + def setUp(self): + super(MainTest, self).setUp() + self.app = main.TestAPIClient() + self.cas_sever = '{}{}{}'.format( + self.env_variables['testapi_cas_auth_url'], + urllib.quote(self.env_variables['testapi_url']), + self.env_variables['testapi_cas_signin_return']) + self.headers = { + 'Content-type': 'application/json', + 'Accept': 'text/plain'} + + def test_auth_success(self): + self.post_mock.return_value = fakes.FakeResponse( + data={'text': "success"}) + self.app.run( + ['-u', 'user', '-p', 'pass', 'pod', 'create', + '{"name": "asfad"}']) + self.post_mock.assert_called_with( + 'http://localhost:8000/api/v1/pods', + data='{"name": "asfad"}', + headers=self.headers) + + def test_auth_failure(self): + self.post_mock.return_value = fakes.FakeResponse( + data={'text': "login"}) + self.app.run( + ['-u', 'user', '-p', 'pass', 'pod', 'create', + '{"name": "asfad"}']) + self.post_mock.assert_called_once_with( + self.cas_sever, + {'pass': 'pass', 'name': 'user', 'form_id': 'user_login'} + ) + + def test_auth_not_called(self): + self.auth_post = mock.patch( + 'testapiclient.utils.clientmanager.ClientManager.auth').start() + self.app.run(['pod', 'get']) + self.auth_post.assert_not_called() + self.get_mock.assert_called_once_with( + 'http://localhost:8000/api/v1/pods', headers=self.headers) diff --git a/testapi/testapi-client/testapiclient/tests/unit/test_pod_client.py b/testapi/testapi-client/testapiclient/tests/unit/test_pod_client.py new file mode 100644 index 0000000..1df5660 --- /dev/null +++ b/testapi/testapi-client/testapiclient/tests/unit/test_pod_client.py @@ -0,0 +1,89 @@ +import json + +from six.moves.urllib import parse +import testtools + +from testapiclient.client import pods +from testapiclient.tests.unit import fakes +from testapiclient.tests.unit import utils +from testapiclient.utils import clientmanager + + +class PodClientTest(utils.TestCommand): + def setUp(self): + super(PodClientTest, self).setUp() + self.base_url = parse.urljoin(self.api_url, 'pods') + self.pod_json = { + 'role': 'community-ci', + 'name': 'test_pod', + 'details': '', + 'mode': 'metal' + } + self.pod_client = pods.PodsClient() + self.pod_string = json.dumps(self.pod_json) + + +class PodClientGetTest(PodClientTest): + + def setUp(self): + super(PodClientGetTest, self).setUp() + self.pods_rsp = {'pods': [self.pod_json]} + + def test_get(self): + self.get_mock.return_value = fakes.FakeResponse(data=self.pods_rsp) + self.pod_client.get() + self.get_mock.assert_called_once_with( + self.base_url, + headers=clientmanager.ClientManager.headers) + + def test_get_search(self): + self.get_mock.return_value = fakes.FakeResponse(data=self.pods_rsp) + self.pod_client.get(name='pod1') + self.get_mock.assert_called_once_with( + self.base_url + '?name=pod1', + headers=clientmanager.ClientManager.headers) + + def test_get_one(self): + self.get_mock.return_value = fakes.FakeResponse(data=self.pod_json) + self.pod_client.get_one('def') + self.get_mock.assert_called_once_with( + self.base_url + '/def', + headers=clientmanager.ClientManager.headers) + + +class PodClientCreateTest(PodClientTest): + + def setUp(self): + super(PodClientCreateTest, self).setUp() + self.succ_rsp = { + 'href': '{}/{}'.format(self.base_url, self.pod_json.get('name')) + } + + def test_create_success(self): + self.post_mock.return_value = fakes.FakeResponse(data=self.succ_rsp) + self.pod_client.create(self.pod_json) + self.post_mock.assert_called_once() + + def test_create_failure(self): + with testtools.ExpectedException(Exception, 'Create failed: Error'): + self.post_mock.return_value = utils.FAKE_FAILURE + self.pod_client.create(self.pod_json) + + +class PodClientDeleteTest(PodClientTest): + + def setUp(self): + super(PodClientDeleteTest, self).setUp() + + def test_delete_success(self): + self.delete_mock.return_value = fakes.FakeResponse() + self.pod_client.delete('def') + self.delete_mock.assert_called_once_with( + self.base_url + '/def', + data=None, + headers=clientmanager.ClientManager.headers) + + def test_delete_failure(self): + with testtools.ExpectedException(Exception, 'Delete failed: Error'): + self.delete_mock.return_value = utils.FAKE_FAILURE + self.pod_client.delete('def') diff --git a/testapi/testapi-client/testapiclient/tests/unit/utils.py b/testapi/testapi-client/testapiclient/tests/unit/utils.py index 21f98c4..c59aadd 100644 --- a/testapi/testapi-client/testapiclient/tests/unit/utils.py +++ b/testapi/testapi-client/testapiclient/tests/unit/utils.py @@ -19,7 +19,7 @@ class TestCommand(testtools.TestCase): def setUp(self): super(TestCommand, self).setUp() - env_variables = { + self.env_variables = { 'testapi_url': 'http://localhost:8000/api/v1', 'testapi_cas_auth_url': ( @@ -29,7 +29,7 @@ class TestCommand(testtools.TestCase): 'testapi_cas_signin_return': '/auth/signin_return' } self.config_mock = mock.patch.dict( - 'os.environ', env_variables).start() + 'os.environ', self.env_variables).start() self.fake_stdout = fakes.FakeStdout() self.fake_log = fakes.FakeLog() self.app = fakes.FakeApp(self.fake_stdout, self.fake_log) |