add a raw method check, implement basic data testing
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/95b14af1 Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/95b14af1 Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/95b14af1 Branch: refs/heads/trunk Commit: 95b14af18be90eeeeca142a2882bef190f6f02a5 Parents: f278cca Author: Anthony Shaw <anthonys...@apache.org> Authored: Tue Jan 10 16:22:05 2017 +1100 Committer: Anthony Shaw <anthonys...@apache.org> Committed: Tue Jan 10 16:22:05 2017 +1100 ---------------------------------------------------------------------- integration/__main__.py | 22 +++++++++++++++++++++- integration/api/__main__.py | 5 ++++- integration/api/data.py | 13 ++++++++++++- integration/api/routes.py | 9 ++++++++- integration/api/util.py | 35 +++++++++++++++++++++++++++++++++++ integration/config.py | 21 +++++++++++++++++++++ integration/driver/test.py | 4 ++++ tox.ini | 9 ++++++++- 8 files changed, 113 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/95b14af1/integration/__main__.py ---------------------------------------------------------------------- diff --git a/integration/__main__.py b/integration/__main__.py index 7999ca4..9e70f7d 100644 --- a/integration/__main__.py +++ b/integration/__main__.py @@ -3,7 +3,7 @@ import sys from .driver.test import TestNodeDriver -from .api.data import NODES +from .api.data import NODES, REPORT_DATA class IntegrationTest(unittest.TestCase): def setUp(self): @@ -11,7 +11,27 @@ class IntegrationTest(unittest.TestCase): host='localhost', port=9898) def test_nodes(self): + """ + Test that you can list nodes and that the responding objects + match basic values, list (ip), and dict (extra). + """ nodes = self.instance.list_nodes() + for node in NODES: + match = [n for n in nodes if n.id == node['id']] + self.assertTrue(len(match) == 1) + match = match[0] + self.assertEqual(match.id, node['id']) + self.assertEqual(match.name, node['name']) + self.assertEqual(match.private_ips, node['private_ips']) + self.assertEqual(match.public_ips, node['public_ips']) + self.assertEqual(match.extra, node['extra']) + + def test_ex_report_data(self): + """ + Test that a raw request can correctly return the data + """ + data = self.instance.ex_report_data().body + self.assertEqual(data, REPORT_DATA) if __name__ == '__main__': sys.exit(unittest.main()) http://git-wip-us.apache.org/repos/asf/libcloud/blob/95b14af1/integration/api/__main__.py ---------------------------------------------------------------------- diff --git a/integration/api/__main__.py b/integration/api/__main__.py index 2257687..94c6e37 100644 --- a/integration/api/__main__.py +++ b/integration/api/__main__.py @@ -13,8 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +from functools import wraps + from bottle import run from .routes import * -run(host='localhost', port=9898) +if __name__ == '__main__': + run(host='localhost', port=9898) http://git-wip-us.apache.org/repos/asf/libcloud/blob/95b14af1/integration/api/data.py ---------------------------------------------------------------------- diff --git a/integration/api/data.py b/integration/api/data.py index e49d515..ece9fa4 100644 --- a/integration/api/data.py +++ b/integration/api/data.py @@ -22,5 +22,16 @@ NODES = [ 'size': 'test-size-1', 'created_at': '2017-01-09T05:25:12+00:00', 'image': 'test-image-1', + 'extra': {'test-key': 'test-value'}}, + {'id': '4567a', + 'name': 'test-2', + 'state': 'RUNNING', + 'public_ips': ['4.4.4.5', '8.8.8.8'], + 'private_ips': ['10.0.0.2', '192.168.1.1'], + 'size': 'test-size-1', + 'created_at': '2017-01-09T05:25:12+00:00', + 'image': 'test-image-1', 'extra': {'test-key': 'test-value'}} -] \ No newline at end of file +] + +REPORT_DATA = "Around the ragged rocks, the ragged rascal ran. \r\n" \ No newline at end of file http://git-wip-us.apache.org/repos/asf/libcloud/blob/95b14af1/integration/api/routes.py ---------------------------------------------------------------------- diff --git a/integration/api/routes.py b/integration/api/routes.py index 7fdc3b1..b333aec 100644 --- a/integration/api/routes.py +++ b/integration/api/routes.py @@ -17,8 +17,15 @@ import json from bottle import route, template -from .data import NODES +from .data import NODES, REPORT_DATA +from .util import secure @route('/compute/nodes', method='GET') +@secure def list_nodes(): return json.dumps(NODES) + +@route('/compute/report_data', method='GET') +@secure +def ex_report_data(): + return REPORT_DATA \ No newline at end of file http://git-wip-us.apache.org/repos/asf/libcloud/blob/95b14af1/integration/api/util.py ---------------------------------------------------------------------- diff --git a/integration/api/util.py b/integration/api/util.py new file mode 100644 index 0000000..c4478e5 --- /dev/null +++ b/integration/api/util.py @@ -0,0 +1,35 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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 bottle import run, request +import base64 +from functools import wraps + +from libcloud.utils.py3 import b + +from ..config import EXPECTED_AUTH + +def secure(f): + @wraps(f) + def secure_route(*args, **kwargs): + if 'Authorization' not in request.headers.keys(): + raise Exception('Argghhhh') + else: + auth = request.headers['Authorization'] + + if auth != EXPECTED_AUTH: + raise Exception('Bad authentication') + return f(*args, **kwargs) + return secure_route \ No newline at end of file http://git-wip-us.apache.org/repos/asf/libcloud/blob/95b14af1/integration/config.py ---------------------------------------------------------------------- diff --git a/integration/config.py b/integration/config.py new file mode 100644 index 0000000..d5e524d --- /dev/null +++ b/integration/config.py @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. + +import base64 +from libcloud.utils.py3 import b + +API_AUTH = ('apache', 'libcloud') + +EXPECTED_AUTH = 'Basic %s' % (base64.b64encode(b('%s:%s' % API_AUTH))) \ No newline at end of file http://git-wip-us.apache.org/repos/asf/libcloud/blob/95b14af1/integration/driver/test.py ---------------------------------------------------------------------- diff --git a/integration/driver/test.py b/integration/driver/test.py index b695002..a3ac1dc 100644 --- a/integration/driver/test.py +++ b/integration/driver/test.py @@ -70,3 +70,7 @@ class TestNodeDriver(NodeDriver): for node in r.object: nodes.append(Node(driver=self, **node)) return nodes + + def ex_report_data(self): + r = self.connection.request('/compute/report_data', raw=True) + return r.response.read() \ No newline at end of file http://git-wip-us.apache.org/repos/asf/libcloud/blob/95b14af1/tox.ini ---------------------------------------------------------------------- diff --git a/tox.ini b/tox.ini index 0ee0ff6..c3e4a57 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{2.6,2.7,pypy,pypy3,3.3,3.4,3.5,3.6},lint,pylint +envlist = py{2.6,2.7,pypy,pypy3,3.3,3.4,3.5,3.6},lint,pylint,integration [testenv] passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH @@ -88,6 +88,7 @@ commands = pylint -E --rcfile=./.pylintrc libcloud/common/ pylint -E --rcfile=./.pylintrc libcloud/storage/ pylint -E --rcfile=./.pylintrc libcloud/utils/ pylint -E --rcfile=./.pylintrc demos/ + pylint -E --rcfile=./.pylintrc integration/ pylint -E --rcfile=./.pylintrc contrib/ [testenv:lint] @@ -97,6 +98,12 @@ deps = -r{toxinidir}/requirements-tests.txt commands = flake8 --ignore=E402 --exclude="test" libcloud/ flake8 --ignore=E402 --max-line-length=160 libcloud/test/ flake8 --ignore=E402 demos/ + flake8 --ignore=E402 integration/ flake8 --ignore=E402,E902 docs/examples/ flake8 --ignore=E402,E902 --max-line-length=160 contrib/ python -mjson.tool libcloud/data/pricing.json + +[testenv:integration] +deps = -r{toxinidir}/integration/requirements.txt + +commands = python -m integration \ No newline at end of file