diff --git a/requirements.txt b/requirements.txt index e0d7513..882f0b8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ nose -coverage \ No newline at end of file +coverage +mock \ No newline at end of file diff --git a/scripts/curl_client.py b/scripts/curl_client.py new file mode 100644 index 0000000..ebff8fe --- /dev/null +++ b/scripts/curl_client.py @@ -0,0 +1,90 @@ +import json +from shell import Shell + + +class CurlClient: + username = '' + password = '' + server = '' + port = '' + proto = '' + cmd = Shell() + + def set_username(self, username): + self.username = username + + def set_password(self, password): + self.password = password + + # Set HTTP protocol (http or https) + def set_proto(self, proto): + if proto == 'http' or proto == 'https': + self.proto = proto + else: + raise ValueError('Protocol must be http or https') + + def set_server(self, server): + self.server = server + + # A number between 0 and 65535 + def set_port(self, port): + if not type(port) is int: + raise ValueError('Server port was not of type: int') + if port > 0 and port <= 65535: + self.port = port + else: + raise ValueError('Server port must be between 0 and 65535. Value was ' + str(port)) + + + # Make a request via cURL + # Must pass an HTTP verb GET|PUT|POST|DELETE + # The request to the server (possibly something like /api/v1/resource...) + # A list of query parameters + # ['param1=value1', 'param2=value2'] + + def make_request(self, verb, request, query=''): + + if not (verb == 'GET' or verb == 'POST' or verb == 'PUT' or verb == 'DELETE'): + raise ValueError('HTTP Verb must be one of GET|PUT|POST|DELETE') + + query = '&'.join(query) + url = ''.join([self.proto, '://', self.server, ':', str(self.port), request]) + url = url + '?' + url = url + query + + + credentials = ':'.join([self.username, self.password]) + credentials = '-u ' + credentials + + method = '-X ' + verb + + call = ' '.join(['curl', credentials, method, url]) + output = self.cmd.run(call) + return output + + + def __init__(self, username='', password='', proto='http', server='127.0.0.1', port=8080): + self.set_username(username) + self.set_password(password) + self.set_server(server) + self.set_port(port) + self.set_proto(proto) + + + + + + + + + + + + + + + + + + + diff --git a/scripts/shell.py b/scripts/shell.py index 9f57940..10411a3 100644 --- a/scripts/shell.py +++ b/scripts/shell.py @@ -26,7 +26,7 @@ def run(self, command, args=''): if len(self.cwd) > 0: process = subprocess.Popen(command, shell=True, cwd=path, stdout=subprocess.PIPE, stdin=subprocess.PIPE) else: - process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE) + process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) output = process.communicate() return output diff --git a/tests/test_curlclient.py b/tests/test_curlclient.py new file mode 100644 index 0000000..1c86065 --- /dev/null +++ b/tests/test_curlclient.py @@ -0,0 +1,101 @@ +import unittest +import mock +from mock import MagicMock, Mock +#from unittest.mock import MagicMock +from env import scripts +from scripts.curl_client import CurlClient + +res1 = ['\'key1\':value1', ''] +res2 = ['\'key2\':value2', ''] +res3 = ['\'key3\':value3', ''] +resErr = ['', '\'msg\':\'err\''] + +def mocked_request(*args, **kwargs): + if args[0] == 'curl -u admin:admin -X GET http://demo-server:9090/api/v1/test?': + return res1 + elif args[0] == 'curl -u admin:admin -X GET http://demo-server:9090/api/v1/bad?': + return res2 + else: + return res3 + return resErr + +class TestCurlClient(unittest.TestCase): + + @mock.patch('scripts.shell.Shell.run', side_effect=mocked_request) + def test_basic_command(self, mock_get): + un = 'admin' + pw = 'admin' + pt = 9090 + serv = 'demo-server' + prtc = 'http' + client = CurlClient(username=un, password=pw, port=pt, server=serv, proto=prtc) + assert client.username == un + assert client.password == pw + assert client.port == pt + assert client.server == serv + assert client.proto == prtc + output = client.make_request('GET', '/api/v1/test') + assert output == res1 + output = client.make_request('GET', '/api/v1/bad') + assert output == res2 + output = client.make_request('GET', '') + assert output == res3 + + + def test_bad_port(self): + ports = [-1, 0, 65536] + for pt in ports: + try: + client = CurlClient(port=pt) + self.fail('Cannot set port to ' + str(port)) + except ValueError: + pass + + def test_bad_proto(self): + protos = ['http', 'https'] + + for prtc in protos: + try: + client = CurlClient(proto=prtc) + except ValueError: + self.fail('Cannot set protocol to ' +proto) + + bad_protos = ['htp', 'thrift', 'odbc'] + for prtc in bad_protos: + try: + client = CurlClient(proto=prtc) + self.fail('Cannot set protocol to ' +proto) + except ValueError: + pass + +# @mock.patch('scripts.shell.Shell.run', side_effect=mocked_request) + def test_http_verbs(self): + client = CurlClient() + + verbs = ['GET', 'PUT', 'POST', 'DELETE'] + bad_verbs = ['BAD', 'IAMBAD', 'IAMSUPERBAD'] + + for v in verbs: + try: + client.make_request(v, '/') + except: + self.fail('Should not throw error on verb: ' + v) + + for v in bad_verbs: + try: + client.make_request(v, '/') + self.fail('Should throw error on verb: ' + v) + except: + pass + + + + + + + + + + + + \ No newline at end of file