You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by je...@apache.org on 2011/01/04 15:35:34 UTC
svn commit: r1055059 - in /incubator/libcloud/trunk: libcloud/drivers/ec2.py
test/test_ec2.py
Author: jerry
Date: Tue Jan 4 14:35:34 2011
New Revision: 1055059
URL: http://svn.apache.org/viewvc?rev=1055059&view=rev
Log:
Tests for EC2 Idempotent launches; LIBCLOUD-69
Submitted By: David LaBissoniere
Modified:
incubator/libcloud/trunk/libcloud/drivers/ec2.py
incubator/libcloud/trunk/test/test_ec2.py
Modified: incubator/libcloud/trunk/libcloud/drivers/ec2.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/drivers/ec2.py?rev=1055059&r1=1055058&r2=1055059&view=diff
==============================================================================
--- incubator/libcloud/trunk/libcloud/drivers/ec2.py (original)
+++ incubator/libcloud/trunk/libcloud/drivers/ec2.py Tue Jan 4 14:35:34 2011
@@ -17,7 +17,7 @@
Amazon EC2 driver
"""
from libcloud.providers import Provider
-from libcloud.types import NodeState, InvalidCredsError, MalformedResponseError
+from libcloud.types import NodeState, InvalidCredsError, MalformedResponseError, LibcloudError
from libcloud.base import Node, Response, ConnectionUserAndKey
from libcloud.base import NodeDriver, NodeSize, NodeImage, NodeLocation
import base64
@@ -198,6 +198,8 @@ class EC2Response(Response):
raise InvalidCredsError(err_list[-1])
if code.text == "OptInRequired":
raise InvalidCredsError(err_list[-1])
+ if code.text == "IdempotentParameterMismatch":
+ raise IdempotentParamError(err_list[-1])
return "\n".join(err_list)
class EC2Connection(ConnectionUserAndKey):
@@ -654,6 +656,12 @@ class EC2NodeDriver(NodeDriver):
res = self.connection.request(self.path, params=params).object
return self._get_terminate_boolean(res)
+class IdempotentParamError(LibcloudError):
+ """
+ Request used the same client token as a previous, but non-identical request.
+ """
+ def __str__(self):
+ return repr(self.value)
class EC2EUConnection(EC2Connection):
"""
Modified: incubator/libcloud/trunk/test/test_ec2.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/test/test_ec2.py?rev=1055059&r1=1055058&r2=1055059&view=diff
==============================================================================
--- incubator/libcloud/trunk/test/test_ec2.py (original)
+++ incubator/libcloud/trunk/test/test_ec2.py Tue Jan 4 14:35:34 2011
@@ -15,7 +15,7 @@
import sys
import unittest
-from libcloud.drivers.ec2 import EC2NodeDriver, EC2APSENodeDriver
+from libcloud.drivers.ec2 import EC2NodeDriver, EC2APSENodeDriver, IdempotentParamError
from libcloud.base import Node, NodeImage, NodeSize
from test import MockHttp, TestCaseMixin
@@ -30,6 +30,7 @@ class EC2Tests(unittest.TestCase, TestCa
def setUp(self):
EC2NodeDriver.connectionCls.conn_classes = (None, EC2MockHttp)
EC2MockHttp.use_param = 'Action'
+ EC2MockHttp.type = None
self.driver = EC2NodeDriver(EC2_ACCESS_ID, EC2_SECRET)
def test_create_node(self):
@@ -40,7 +41,36 @@ class EC2Tests(unittest.TestCase, TestCa
node = self.driver.create_node(name='foo', image=image, size=size)
self.assertEqual(node.id, 'i-2ba64342')
- # TODO: add tests for create_node for ex_clienttoken
+ def test_create_node_idempotent(self):
+ EC2MockHttp.type = 'idempotent'
+ image = NodeImage(id='ami-be3adfd7',
+ name='ec2-public-images/fedora-8-i386-base-v1.04.manifest.xml',
+ driver=self.driver)
+ size = NodeSize('m1.small', 'Small Instance', None, None, None, None, driver=self.driver)
+ token = 'testclienttoken'
+ node = self.driver.create_node(name='foo', image=image, size=size,
+ ex_clienttoken=token)
+ self.assertEqual(node.id, 'i-2ba64342')
+ self.assertEqual(node.extra['clienttoken'], token)
+
+ # from: http://docs.amazonwebservices.com/AWSEC2/latest/DeveloperGuide/index.html?Run_Instance_Idempotency.html
+
+ # If you repeat the request with the same client token, but change
+ # another request parameter, Amazon EC2 returns an
+ # IdempotentParameterMismatch error.
+
+ # In our case, changing the parameter doesn't actually matter since we
+ # are forcing the error response fixture.
+ EC2MockHttp.type = 'idempotent_mismatch'
+
+ idem_error = None
+ try:
+ self.driver.create_node(name='foo', image=image, size=size,
+ ex_mincount='2', ex_maxcount='2', # different count
+ ex_clienttoken=token)
+ except IdempotentParamError, e:
+ idem_error = e
+ self.assertTrue(idem_error is not None)
def test_list_nodes(self):
node = self.driver.list_nodes()[0]
@@ -115,6 +145,14 @@ class EC2MockHttp(MockHttp):
body = self.fixtures.load('run_instances.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ def _idempotent_RunInstances(self, method, url, body, headers):
+ body = self.fixtures.load('run_instances_idem.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _idempotent_mismatch_RunInstances(self, method, url, body, headers):
+ body = self.fixtures.load('run_instances_idem_mismatch.xml')
+ return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.BAD_REQUEST])
+
def _TerminateInstances(self, method, url, body, headers):
body = self.fixtures.load('terminate_instances.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
@@ -123,6 +161,7 @@ class EC2APSETests(EC2Tests):
def setUp(self):
EC2APSENodeDriver.connectionCls.conn_classes = (None, EC2MockHttp)
EC2MockHttp.use_param = 'Action'
+ EC2MockHttp.type = None
self.driver = EC2APSENodeDriver(EC2_ACCESS_ID, EC2_SECRET)
if __name__ == '__main__':