]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Add a common implementation for fetching a URL
authorZane Bitter <zbitter@redhat.com>
Thu, 6 Dec 2012 18:35:05 +0000 (19:35 +0100)
committerZane Bitter <zbitter@redhat.com>
Thu, 6 Dec 2012 19:38:40 +0000 (20:38 +0100)
There are multiple implementations of fetching a template from a URL, so
add a common one where changes can be shared.

Change-Id: I9c834efa71f97360dafb741e26713e3f3c124b6f
Signed-off-by: Zane Bitter <zbitter@redhat.com>
heat/common/urlfetch.py [new file with mode: 0644]
heat/tests/test_urlfetch.py [new file with mode: 0644]

diff --git a/heat/common/urlfetch.py b/heat/common/urlfetch.py
new file mode 100644 (file)
index 0000000..db17c32
--- /dev/null
@@ -0,0 +1,45 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+#
+#    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.
+
+'''
+Utility for fetching a resource (e.g. a template) from a URL.
+'''
+
+import urllib2
+import urlparse
+
+from heat.common import exception
+
+from heat.openstack.common import log as logging
+
+logger = logging.getLogger(__name__)
+
+
+def get(url):
+    '''
+    Get the data at the specifier URL.
+
+    The URL must use the http: or https: schemes.
+    Raise an IOError if getting the data fails.
+    '''
+    logger.info(_('Fetching data from %s') % url)
+
+    components = urlparse.urlparse(url)
+
+    if components.scheme not in ('http', 'https'):
+        raise urllib2.URLError('Invalid URL scheme %s' % components.scheme)
+
+    response = urllib2.urlopen(url)
+    return response.read()
diff --git a/heat/tests/test_urlfetch.py b/heat/tests/test_urlfetch.py
new file mode 100644 (file)
index 0000000..a2d3952
--- /dev/null
@@ -0,0 +1,73 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+#
+#    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.
+
+import mox
+import nose
+from nose.plugins.attrib import attr
+import StringIO
+import unittest
+import urllib2
+
+from heat.common import urlfetch
+
+
+@attr(tag=['unit', 'urlfetch'])
+@attr(speed='fast')
+class UrlFetchTest(unittest.TestCase):
+    def setUp(self):
+        self.m = mox.Mox()
+        self.m.StubOutWithMock(urllib2, 'urlopen')
+
+    def tearDown(self):
+        self.m.UnsetStubs()
+
+    def test_file_scheme(self):
+        self.m.ReplayAll()
+        self.assertRaises(IOError, urlfetch.get, 'file:///etc/profile')
+        self.m.VerifyAll()
+
+    def test_http_scheme(self):
+        url = 'http://example.com/template'
+        data = '{ "foo": "bar" }'
+
+        urllib2.urlopen(url).AndReturn(StringIO.StringIO(data))
+        self.m.ReplayAll()
+
+        self.assertEqual(urlfetch.get(url), data)
+        self.m.VerifyAll()
+
+    def test_https_scheme(self):
+        url = 'https://example.com/template'
+        data = '{ "foo": "bar" }'
+
+        urllib2.urlopen(url).AndReturn(StringIO.StringIO(data))
+        self.m.ReplayAll()
+
+        self.assertEqual(urlfetch.get(url), data)
+        self.m.VerifyAll()
+
+    def test_http_error(self):
+        url = 'http://example.com/template'
+
+        urllib2.urlopen(url).AndRaise(urllib2.URLError('fubar'))
+        self.m.ReplayAll()
+
+        self.assertRaises(IOError, urlfetch.get, url)
+        self.m.VerifyAll()
+
+    def test_garbage(self):
+        self.m.ReplayAll()
+        self.assertRaises(IOError, urlfetch.get, 'wibble')
+        self.m.VerifyAll()