http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/describe_disks.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ecs/describe_disks.xml 
b/libcloud/test/compute/fixtures/ecs/describe_disks.xml
new file mode 100644
index 0000000..87e1846
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/describe_disks.xml
@@ -0,0 +1,62 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeDisksResponse>
+    <Disks>
+        <Disk>
+           <DiskChargeType>PostPaid</DiskChargeType>
+            <DeleteAutoSnapshot>true</DeleteAutoSnapshot>
+            <DeleteWithInstance>false</DeleteWithInstance>
+            <EnableAutoSnapshot>false</EnableAutoSnapshot>
+            <Category>cloud</Category>
+            <Description></Description>
+            <DiskName></DiskName>
+            <Size>5</Size>
+            <Type>data</Type>
+            <InstanceId></InstanceId>
+            <CreationTime>2014-07-23T02:44:07Z</CreationTime>
+            <ImageId></ImageId>
+            <ZoneId>cn-qingdao-b</ZoneId>
+            <AttachedTime>2014-07-23T07:47:35Z</AttachedTime>
+            <DetachedTime>2014-07-23T08:28:48Z</DetachedTime>
+            <Device></Device>
+            <OperationLocks></OperationLocks>
+            <Portable>true</Portable>
+            <ProductCode></ProductCode>
+            <RegionId>cn-qingdao</RegionId>
+            <DiskId>d-28m5zbua0</DiskId>
+            <SourceSnapshotId></SourceSnapshotId>
+            <Status>Available</Status>
+           <Tags />
+        </Disk>
+        <Disk>
+           <DiskChargeType>PostPaid</DiskChargeType>
+            <DeleteAutoSnapshot>true</DeleteAutoSnapshot>
+            <DeleteWithInstance>true</DeleteWithInstance>
+            <EnableAutoSnapshot>true</EnableAutoSnapshot>
+            <Category>cloud</Category>
+            <Description>Description</Description>
+            <DiskName>ubuntu1404sys</DiskName>
+            <Size>5</Size>
+            <Type>system</Type>
+            <InstanceId>i-28whl2nj2</InstanceId>
+            <CreationTime>2014-07-23T02:44:06Z</CreationTime>
+            <ImageId>ubuntu1404_64_20G_aliaegis_20150325.vhd</ImageId>
+            <ZoneId>cn-qingdao-b</ZoneId>
+            <AttachedTime>2016-01-04T15:02:17Z</AttachedTime>
+            <DetachedTime></DetachedTime>
+           <Device>/dev/xvda</Device>
+            <OperationLocks></OperationLocks>
+            <Portable>false</Portable>
+            <ProductCode></ProductCode>
+            <RegionId>cn-qingdao</RegionId>
+            <DiskId>d-28zfrmo13</DiskId>
+            <SourceSnapshotId></SourceSnapshotId>
+            <Status>In_use</Status>
+           <OperationLocks />
+           <ExpiredTime>2999-09-08T16:00Z</ExpiredTime>
+        </Disk>
+    </Disks>
+    <PageNumber>1</PageNumber>
+    <PageSize>10</PageSize>
+    <TotalCount>2</TotalCount>
+    <RequestId>ED5CF6DD-71CA-462C-9C94-A61A78A01479</RequestId>
+</DescribeDisksResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/describe_images.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ecs/describe_images.xml 
b/libcloud/test/compute/fixtures/ecs/describe_images.xml
new file mode 100644
index 0000000..80b1a31
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/describe_images.xml
@@ -0,0 +1,41 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeImagesResponse>
+       <PageNumber>1</PageNumber>
+       <TotalCount>1</TotalCount>
+       <PageSize>10</PageSize>
+       <RegionId>cn-qingdao</RegionId>
+       <RequestId>FAD4D9B9-D75F-4A9E-BC13-991C0F06F50F</RequestId>
+       <Images>
+               <Image>
+                       
<ImageId>freebsd1001_64_20G_aliaegis_20150527.vhd</ImageId>
+                       
<Description>freebsd1001_64_20G_aliaegis_20150527.vhd</Description>
+                       <ProductCode></ProductCode>
+                       <OSType>linux</OSType>
+                       <Architecture>x86_64</Architecture>
+                       <OSName>FreeBSD  10.1 64位</OSName>
+                       <DiskDeviceMappings>
+                               <DiskDeviceMapping>
+                                       <ImportOSSObject></ImportOSSObject>
+                                       <Format></Format>
+                                       <Device>/dev/xvda</Device>
+                                       <SnapshotId></SnapshotId>
+                                       <ImportOSSBucket></ImportOSSBucket>
+                                       <Size>20</Size>
+                               </DiskDeviceMapping>
+                       </DiskDeviceMappings>
+                       <ImageOwnerAlias>system</ImageOwnerAlias>
+                       <Progress>100%</Progress>
+                       <Usage>instance</Usage>
+                       <CreationTime>2015-06-19T07:25:42Z</CreationTime>
+                       <Tags />
+                       <ImageVersion>1.0.0</ImageVersion>
+                       <Status>Available</Status>
+                       
<ImageName>freebsd1001_64_20G_aliaegis_20150527.vhd</ImageName>
+                       <IsSelfShared></IsSelfShared>
+                       <IsCopied>false</IsCopied>
+                       <IsSubscribed>false</IsSubscribed>
+                       <Platform>Freebsd</Platform>
+                       <Size>20</Size>
+               </Image>
+       </Images>
+</DescribeImagesResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/describe_instance_types.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ecs/describe_instance_types.xml 
b/libcloud/test/compute/fixtures/ecs/describe_instance_types.xml
new file mode 100644
index 0000000..6009564
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/describe_instance_types.xml
@@ -0,0 +1,18 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeInstanceTypesResponse>
+    <RequestId>1651FBB6-4FBF-49FF-A9F5-DF5D696C7EC6</RequestId>
+    <InstanceTypes>
+        <InstanceType>
+            <InstanceTypeId>ecs.t1.xsmall</InstanceTypeId>
+            <CpuCoreCount>1</CpuCoreCount>
+            <MemorySize>0.5</MemorySize>
+            <InstanceTypeFamily>ecs.t1</InstanceTypeFamily>
+        </InstanceType>
+        <InstanceType>
+            <InstanceTypeId>ecs.s2.small</InstanceTypeId>
+            <CpuCoreCount>2</CpuCoreCount>
+            <MemorySize>1.0</MemorySize>
+            <InstanceTypeFamily>ecs.s2</InstanceTypeFamily>
+        </InstanceType>
+    </InstanceTypes>
+</DescribeInstanceTypesResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/describe_instances.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ecs/describe_instances.xml 
b/libcloud/test/compute/fixtures/ecs/describe_instances.xml
new file mode 100644
index 0000000..f1c7713
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/describe_instances.xml
@@ -0,0 +1,56 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeInstancesResponse>
+       <PageNumber>1</PageNumber>
+       <TotalCount>1</TotalCount>
+       <PageSize>10</PageSize>
+       <RequestId>CA75EE06-D5F7-433C-870B-5042EED6C1DC</RequestId>
+       <Instances>
+               <Instance>
+                       
<ImageId>ubuntu1404_64_20G_aliaegis_20150325.vhd</ImageId>
+                       <InnerIpAddress>
+                               <IpAddress>10.163.197.74</IpAddress>
+                       </InnerIpAddress>
+                       <InstanceTypeFamily>ecs.t1</InstanceTypeFamily>
+                       <VlanId></VlanId>
+                       <InstanceId>i-28n7dkvov</InstanceId>
+                       <EipAddress>
+                               <IpAddress></IpAddress>
+                               <AllocationId></AllocationId>
+                               <InternetChargeType></InternetChargeType>
+                       </EipAddress>
+                       <InternetMaxBandwidthIn>-1</InternetMaxBandwidthIn>
+                       <ZoneId>cn-qingdao-b</ZoneId>
+                       <InternetChargeType>PayByTraffic</InternetChargeType>
+                       
<SerialNumber>ca0122d9-374d-4fce-9fc0-71f7c3eaf1c3</SerialNumber>
+                       <IoOptimized>false</IoOptimized>
+                       <Memory>1024</Memory>
+                       <Cpu>1</Cpu>
+                       <VpcAttributes>
+                               <NatIpAddress></NatIpAddress>
+                               <PrivateIpAddress />
+                               <VSwitchId></VSwitchId>
+                               <VpcId></VpcId>
+                       </VpcAttributes>
+                       <InternetMaxBandwidthOut>1</InternetMaxBandwidthOut>
+                       <DeviceAvailable>true</DeviceAvailable>
+                       <SecurityGroupIds>
+                               <SecurityGroupId>sg-28ou0f3xa</SecurityGroupId>
+                       </SecurityGroupIds>
+                       <InstanceName>iZ28n7dkvovZ</InstanceName>
+                       <Description></Description>
+                       <InstanceNetworkType>classic</InstanceNetworkType>
+                       <PublicIpAddress>
+                               <IpAddress>114.215.124.73</IpAddress>
+                       </PublicIpAddress>
+                       <HostName>iZ28n7dkvovZ</HostName>
+                       <InstanceType>ecs.t1.small</InstanceType>
+                       <CreationTime>2015-12-27T07:35Z</CreationTime>
+                       <Status>Starting</Status>
+                       <ClusterId></ClusterId>
+                       <RegionId>cn-qingdao</RegionId>
+                       <OperationLocks />
+                       <InstanceChargeType>PostPaid</InstanceChargeType>
+                       <ExpiredTime>2999-09-08T16:00Z</ExpiredTime>
+               </Instance>
+       </Instances>
+</DescribeInstancesResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/describe_regions.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ecs/describe_regions.xml 
b/libcloud/test/compute/fixtures/ecs/describe_regions.xml
new file mode 100644
index 0000000..91fef57
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/describe_regions.xml
@@ -0,0 +1,42 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeRegionsResponse>
+       <RequestId>FD28A957-20B2-447E-8A5A-952F50C4EDF0</RequestId>
+       <Regions>
+               <Region>
+                       <RegionId>ap-southeast-1</RegionId>
+                       <LocalName>亚太(新加坡)</LocalName>
+               </Region>
+               <Region>
+                       <RegionId>cn-shenzhen</RegionId>
+                       <LocalName>深圳</LocalName>
+               </Region>
+               <Region>
+                       <RegionId>cn-qingdao</RegionId>
+                       <LocalName>青岛</LocalName>
+               </Region>
+               <Region>
+                       <RegionId>cn-beijing</RegionId>
+                       <LocalName>北京</LocalName>
+               </Region>
+               <Region>
+                       <RegionId>cn-shanghai</RegionId>
+                       <LocalName>上海</LocalName>
+               </Region>
+               <Region>
+                       <RegionId>us-east-1</RegionId>
+                       <LocalName>美东弗吉尼亚</LocalName>
+               </Region>
+               <Region>
+                       <RegionId>cn-hongkong</RegionId>
+                       <LocalName>香港</LocalName>
+               </Region>
+               <Region>
+                       <RegionId>cn-hangzhou</RegionId>
+                       <LocalName>杭州</LocalName>
+               </Region>
+               <Region>
+                       <RegionId>us-west-1</RegionId>
+                       <LocalName>美国硅谷</LocalName>
+               </Region>
+       </Regions>
+</DescribeRegionsResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/describe_security_groups.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ecs/describe_security_groups.xml 
b/libcloud/test/compute/fixtures/ecs/describe_security_groups.xml
new file mode 100644
index 0000000..24be5c3
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/describe_security_groups.xml
@@ -0,0 +1,18 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeSecurityGroupsResponse>
+       <PageNumber>1</PageNumber>
+       <TotalCount>1</TotalCount>
+       <PageSize>10</PageSize>
+       <RegionId>cn-qingdao</RegionId>
+       <RequestId>7F154B0C-2594-416D-B546-75021185A6DA</RequestId>
+       <SecurityGroups>
+               <SecurityGroup>
+                       <CreationTime>2015-06-26T08:35:30Z</CreationTime>
+                       <Tags />
+                       <SecurityGroupId>sg-28ou0f3xa</SecurityGroupId>
+                       <SecurityGroupName>sg-28ou0f3xa</SecurityGroupName>
+                       <Description>System created security 
group.</Description>
+                       <VpcId></VpcId>
+               </SecurityGroup>
+       </SecurityGroups>
+</DescribeSecurityGroupsResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/describe_snapshots.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ecs/describe_snapshots.xml 
b/libcloud/test/compute/fixtures/ecs/describe_snapshots.xml
new file mode 100644
index 0000000..d30afb4
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/describe_snapshots.xml
@@ -0,0 +1,25 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeSnapshotsResponse>
+       <PageNumber>1</PageNumber>
+       <TotalCount>1</TotalCount>
+       <PageSize>10</PageSize>
+       <RequestId>09CAE6FF-B864-4104-BBF4-FE1EF08066A6</RequestId>
+       <Snapshots>
+               <Snapshot>
+                       <CreationTime>2016-01-05T11:12:42Z</CreationTime>
+                       <Tags />
+                       <Status>progressing</Status>
+                       <Description>
+                       </Description>
+                       <ProductCode>
+                       </ProductCode>
+                       <SnapshotName>sys-snapshot-20160108</SnapshotName>
+                       <SourceDiskType>system</SourceDiskType>
+                       <SourceDiskId>d-28x069z28</SourceDiskId>
+                       <SnapshotId>s-28n9lltbf</SnapshotId>
+                       <SourceDiskSize>20</SourceDiskSize>
+                       <Progress>0%</Progress>
+                       <Usage>none</Usage>
+               </Snapshot>
+       </Snapshots>
+</DescribeSnapshotsResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/describe_zones.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ecs/describe_zones.xml 
b/libcloud/test/compute/fixtures/ecs/describe_zones.xml
new file mode 100644
index 0000000..a434836
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/describe_zones.xml
@@ -0,0 +1,42 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeZonesResponse>
+       <RequestId>CE75D5FB-C343-47DB-882D-E0709D95D61E</RequestId>
+       <Zones>
+               <Zone>
+                       <AvailableResourceCreation>
+                               <ResourceTypes>IoOptimized</ResourceTypes>
+                               <ResourceTypes>Instance</ResourceTypes>
+                               <ResourceTypes>Disk</ResourceTypes>
+                       </AvailableResourceCreation>
+                       <AvailableInstanceTypes>
+                               <InstanceTypes>ecs.m2.medium</InstanceTypes>
+                               <InstanceTypes>ecs.m1.medium</InstanceTypes>
+                               <InstanceTypes>ecs.s2.xlarge</InstanceTypes>
+                               <InstanceTypes>ecs.t1.xsmall</InstanceTypes>
+                               <InstanceTypes>ecs.s2.large</InstanceTypes>
+                               <InstanceTypes>ecs.s2.2xlarge</InstanceTypes>
+                               <InstanceTypes>ecs.s3.medium</InstanceTypes>
+                               <InstanceTypes>ecs.m1.xlarge</InstanceTypes>
+                               <InstanceTypes>ecs.s1.small</InstanceTypes>
+                               <InstanceTypes>ecs.s1.large</InstanceTypes>
+                               <InstanceTypes>ecs.c2.xlarge</InstanceTypes>
+                               <InstanceTypes>ecs.c2.large</InstanceTypes>
+                               <InstanceTypes>ecs.s3.large</InstanceTypes>
+                               <InstanceTypes>ecs.c1.small</InstanceTypes>
+                               <InstanceTypes>ecs.m2.xlarge</InstanceTypes>
+                               <InstanceTypes>ecs.c2.medium</InstanceTypes>
+                               <InstanceTypes>ecs.t1.small</InstanceTypes>
+                               <InstanceTypes>ecs.c1.large</InstanceTypes>
+                               <InstanceTypes>ecs.s2.small</InstanceTypes>
+                               <InstanceTypes>ecs.s1.medium</InstanceTypes>
+                       </AvailableInstanceTypes>
+                       <ZoneId>cn-qingdao-b</ZoneId>
+                       <LocalName>青岛可用区B</LocalName>
+                       <AvailableDiskCategories>
+                               <DiskCategories>cloud_ssd</DiskCategories>
+                               <DiskCategories>ephemeral</DiskCategories>
+                               <DiskCategories>cloud</DiskCategories>
+                       </AvailableDiskCategories>
+               </Zone>
+       </Zones>
+</DescribeZonesResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/destroy_node_describe_instances.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/compute/fixtures/ecs/destroy_node_describe_instances.xml 
b/libcloud/test/compute/fixtures/ecs/destroy_node_describe_instances.xml
new file mode 100644
index 0000000..329bb79
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/destroy_node_describe_instances.xml
@@ -0,0 +1,56 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeInstancesResponse>
+       <PageNumber>1</PageNumber>
+       <TotalCount>1</TotalCount>
+       <PageSize>10</PageSize>
+       <RequestId>CA75EE06-D5F7-433C-870B-5042EED6C1DC</RequestId>
+       <Instances>
+               <Instance>
+                       
<ImageId>ubuntu1404_64_20G_aliaegis_20150325.vhd</ImageId>
+                       <InnerIpAddress>
+                               <IpAddress>10.163.197.74</IpAddress>
+                       </InnerIpAddress>
+                       <InstanceTypeFamily>ecs.t1</InstanceTypeFamily>
+                       <VlanId></VlanId>
+                       <InstanceId>i-28n7dkvov</InstanceId>
+                       <EipAddress>
+                               <IpAddress></IpAddress>
+                               <AllocationId></AllocationId>
+                               <InternetChargeType></InternetChargeType>
+                       </EipAddress>
+                       <InternetMaxBandwidthIn>-1</InternetMaxBandwidthIn>
+                       <ZoneId>cn-qingdao-b</ZoneId>
+                       <InternetChargeType>PayByTraffic</InternetChargeType>
+                       
<SerialNumber>ca0122d9-374d-4fce-9fc0-71f7c3eaf1c3</SerialNumber>
+                       <IoOptimized>false</IoOptimized>
+                       <Memory>1024</Memory>
+                       <Cpu>1</Cpu>
+                       <VpcAttributes>
+                               <NatIpAddress></NatIpAddress>
+                               <PrivateIpAddress />
+                               <VSwitchId></VSwitchId>
+                               <VpcId></VpcId>
+                       </VpcAttributes>
+                       <InternetMaxBandwidthOut>1</InternetMaxBandwidthOut>
+                       <DeviceAvailable>true</DeviceAvailable>
+                       <SecurityGroupIds>
+                               <SecurityGroupId>sg-28ou0f3xa</SecurityGroupId>
+                       </SecurityGroupIds>
+                       <InstanceName>iZ28n7dkvovZ</InstanceName>
+                       <Description></Description>
+                       <InstanceNetworkType>classic</InstanceNetworkType>
+                       <PublicIpAddress>
+                               <IpAddress>114.215.124.73</IpAddress>
+                       </PublicIpAddress>
+                       <HostName>iZ28n7dkvovZ</HostName>
+                       <InstanceType>ecs.t1.small</InstanceType>
+                       <CreationTime>2015-12-27T07:35Z</CreationTime>
+                       <Status>Stopped</Status>
+                       <ClusterId></ClusterId>
+                       <RegionId>cn-qingdao</RegionId>
+                       <OperationLocks />
+                       <InstanceChargeType>PostPaid</InstanceChargeType>
+                       <ExpiredTime>2999-09-08T16:00Z</ExpiredTime>
+               </Instance>
+       </Instances>
+</DescribeInstancesResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/destroy_volume_describe_disks.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/compute/fixtures/ecs/destroy_volume_describe_disks.xml 
b/libcloud/test/compute/fixtures/ecs/destroy_volume_describe_disks.xml
new file mode 100644
index 0000000..5b045e6
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/destroy_volume_describe_disks.xml
@@ -0,0 +1,36 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeDisksResponse>
+    <Disks>
+        <Disk>
+           <DiskChargeType>PostPaid</DiskChargeType>
+            <DeleteAutoSnapshot>true</DeleteAutoSnapshot>
+            <DeleteWithInstance>true</DeleteWithInstance>
+            <EnableAutoSnapshot>true</EnableAutoSnapshot>
+            <Category>cloud</Category>
+            <Description>Description</Description>
+            <DiskName>ubuntu1404sys</DiskName>
+            <Size>5</Size>
+            <Type>system</Type>
+            <InstanceId>i-28whl2nj2</InstanceId>
+            <CreationTime>2014-07-23T02:44:06Z</CreationTime>
+            <ImageId>ubuntu1404_64_20G_aliaegis_20150325.vhd</ImageId>
+            <ZoneId>cn-qingdao-b</ZoneId>
+            <AttachedTime>2016-01-04T15:02:17Z</AttachedTime>
+            <DetachedTime></DetachedTime>
+           <Device>/dev/xvda</Device>
+            <OperationLocks></OperationLocks>
+            <Portable>false</Portable>
+            <ProductCode></ProductCode>
+            <RegionId>cn-qingdao</RegionId>
+            <DiskId>d-28zfrmo13</DiskId>
+            <SourceSnapshotId></SourceSnapshotId>
+            <Status>Available</Status>
+           <OperationLocks />
+           <ExpiredTime>2999-09-08T16:00Z</ExpiredTime>
+        </Disk>
+    </Disks>
+    <PageNumber>1</PageNumber>
+    <PageSize>10</PageSize>
+    <TotalCount>1</TotalCount>
+    <RequestId>ED5CF6DD-71CA-462C-9C94-A61A78A01479</RequestId>
+</DescribeDisksResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/detach_disk.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ecs/detach_disk.xml 
b/libcloud/test/compute/fixtures/ecs/detach_disk.xml
new file mode 100644
index 0000000..cc2d357
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/detach_disk.xml
@@ -0,0 +1,4 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DetachDiskResponse>
+       <RequestId>DA38B11A-9D6D-420B-942F-95D68606C4FC</RequestId>
+</DetachDiskResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/detach_volume_describe_disks.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/compute/fixtures/ecs/detach_volume_describe_disks.xml 
b/libcloud/test/compute/fixtures/ecs/detach_volume_describe_disks.xml
new file mode 100644
index 0000000..d25c9a1
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/detach_volume_describe_disks.xml
@@ -0,0 +1,36 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeDisksResponse>
+    <Disks>
+        <Disk>
+           <DiskChargeType>PostPaid</DiskChargeType>
+            <DeleteAutoSnapshot>true</DeleteAutoSnapshot>
+            <DeleteWithInstance>true</DeleteWithInstance>
+            <EnableAutoSnapshot>true</EnableAutoSnapshot>
+            <Category>cloud</Category>
+            <Description>Description</Description>
+            <DiskName>ubuntu1404sys</DiskName>
+            <Size>5</Size>
+            <Type>system</Type>
+            <InstanceId>i-28whl2nj2</InstanceId>
+            <CreationTime>2014-07-23T02:44:06Z</CreationTime>
+            <ImageId>ubuntu1404_64_20G_aliaegis_20150325.vhd</ImageId>
+            <ZoneId>cn-qingdao-b</ZoneId>
+            <AttachedTime>2016-01-04T15:02:17Z</AttachedTime>
+            <DetachedTime></DetachedTime>
+           <Device>/dev/xvda</Device>
+            <OperationLocks></OperationLocks>
+            <Portable>false</Portable>
+            <ProductCode></ProductCode>
+            <RegionId>cn-qingdao</RegionId>
+            <DiskId>d-28zfrmo13</DiskId>
+            <SourceSnapshotId></SourceSnapshotId>
+            <Status>In_use</Status>
+           <OperationLocks />
+           <ExpiredTime>2999-09-08T16:00Z</ExpiredTime>
+        </Disk>
+    </Disks>
+    <PageNumber>1</PageNumber>
+    <PageSize>10</PageSize>
+    <TotalCount>1</TotalCount>
+    <RequestId>ED5CF6DD-71CA-462C-9C94-A61A78A01479</RequestId>
+</DescribeDisksResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/get_image_describe_images.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ecs/get_image_describe_images.xml 
b/libcloud/test/compute/fixtures/ecs/get_image_describe_images.xml
new file mode 100644
index 0000000..e1b0d65
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/get_image_describe_images.xml
@@ -0,0 +1,10 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeImagesResponse>
+       <PageNumber>0</PageNumber>
+       <TotalCount>0</TotalCount>
+       <PageSize>10</PageSize>
+       <RegionId>cn-qingdao</RegionId>
+       <RequestId>FAD4D9B9-D75F-4A9E-BC13-991C0F06F50F</RequestId>
+       <Images>
+       </Images>
+</DescribeImagesResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/pages_describe_images.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ecs/pages_describe_images.xml 
b/libcloud/test/compute/fixtures/ecs/pages_describe_images.xml
new file mode 100644
index 0000000..76e8877
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/pages_describe_images.xml
@@ -0,0 +1,41 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeImagesResponse>
+       <PageNumber>1</PageNumber>
+       <TotalCount>2</TotalCount>
+       <PageSize>1</PageSize>
+       <RegionId>cn-qingdao</RegionId>
+       <RequestId>FAD4D9B9-D75F-4A9E-BC13-991C0F06F50F</RequestId>
+       <Images>
+               <Image>
+                       
<ImageId>freebsd1001_64_20G_aliaegis_20150527.vhd</ImageId>
+                       
<Description>freebsd1001_64_20G_aliaegis_20150527.vhd</Description>
+                       <ProductCode></ProductCode>
+                       <OSType>linux</OSType>
+                       <Architecture>x86_64</Architecture>
+                       <OSName>FreeBSD  10.1 64位</OSName>
+                       <DiskDeviceMappings>
+                               <DiskDeviceMapping>
+                                       <ImportOSSObject></ImportOSSObject>
+                                       <Format></Format>
+                                       <Device>/dev/xvda</Device>
+                                       <SnapshotId></SnapshotId>
+                                       <ImportOSSBucket></ImportOSSBucket>
+                                       <Size>20</Size>
+                               </DiskDeviceMapping>
+                       </DiskDeviceMappings>
+                       <ImageOwnerAlias>system</ImageOwnerAlias>
+                       <Progress>100%</Progress>
+                       <Usage>instance</Usage>
+                       <CreationTime>2015-06-19T07:25:42Z</CreationTime>
+                       <Tags />
+                       <ImageVersion>1.0.0</ImageVersion>
+                       <Status>Available</Status>
+                       
<ImageName>freebsd1001_64_20G_aliaegis_20150527.vhd</ImageName>
+                       <IsSelfShared></IsSelfShared>
+                       <IsCopied>false</IsCopied>
+                       <IsSubscribed>false</IsSubscribed>
+                       <Platform>Freebsd</Platform>
+                       <Size>20</Size>
+               </Image>
+       </Images>
+</DescribeImagesResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/pages_describe_images_page2.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ecs/pages_describe_images_page2.xml 
b/libcloud/test/compute/fixtures/ecs/pages_describe_images_page2.xml
new file mode 100644
index 0000000..615e152
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/pages_describe_images_page2.xml
@@ -0,0 +1,41 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeImagesResponse>
+       <PageNumber>2</PageNumber>
+       <TotalCount>2</TotalCount>
+       <PageSize>1</PageSize>
+       <RegionId>cn-qingdao</RegionId>
+       <RequestId>FAD4D9B9-D75F-4A9E-BC13-991C0F06F50F</RequestId>
+       <Images>
+               <Image>
+                       
<ImageId>freebsd1001_64_20G_aliaegis_20150527.vhd</ImageId>
+                       
<Description>freebsd1001_64_20G_aliaegis_20150527.vhd</Description>
+                       <ProductCode></ProductCode>
+                       <OSType>linux</OSType>
+                       <Architecture>x86_64</Architecture>
+                       <OSName>FreeBSD  10.1 64位</OSName>
+                       <DiskDeviceMappings>
+                               <DiskDeviceMapping>
+                                       <ImportOSSObject></ImportOSSObject>
+                                       <Format></Format>
+                                       <Device>/dev/xvda</Device>
+                                       <SnapshotId></SnapshotId>
+                                       <ImportOSSBucket></ImportOSSBucket>
+                                       <Size>20</Size>
+                               </DiskDeviceMapping>
+                       </DiskDeviceMappings>
+                       <ImageOwnerAlias>system</ImageOwnerAlias>
+                       <Progress>100%</Progress>
+                       <Usage>instance</Usage>
+                       <CreationTime>2015-06-19T07:25:42Z</CreationTime>
+                       <Tags />
+                       <ImageVersion>1.0.0</ImageVersion>
+                       <Status>Available</Status>
+                       
<ImageName>freebsd1001_64_20G_aliaegis_20150527.vhd</ImageName>
+                       <IsSelfShared></IsSelfShared>
+                       <IsCopied>false</IsCopied>
+                       <IsSubscribed>false</IsSubscribed>
+                       <Platform>Freebsd</Platform>
+                       <Size>20</Size>
+               </Image>
+       </Images>
+</DescribeImagesResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/reboot_instance.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ecs/reboot_instance.xml 
b/libcloud/test/compute/fixtures/ecs/reboot_instance.xml
new file mode 100644
index 0000000..5fc39aa
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/reboot_instance.xml
@@ -0,0 +1,4 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<RebootInstanceResponse>
+       <RequestId>DA38B11A-9D6D-420B-942F-95D68606C4FC</RequestId>
+</RebootInstanceResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/reboot_node_describe_instances.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/compute/fixtures/ecs/reboot_node_describe_instances.xml 
b/libcloud/test/compute/fixtures/ecs/reboot_node_describe_instances.xml
new file mode 100644
index 0000000..24eae7e
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/reboot_node_describe_instances.xml
@@ -0,0 +1,56 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeInstancesResponse>
+       <PageNumber>1</PageNumber>
+       <TotalCount>1</TotalCount>
+       <PageSize>10</PageSize>
+       <RequestId>CA75EE06-D5F7-433C-870B-5042EED6C1DC</RequestId>
+       <Instances>
+               <Instance>
+                       
<ImageId>ubuntu1404_64_20G_aliaegis_20150325.vhd</ImageId>
+                       <InnerIpAddress>
+                               <IpAddress>10.163.197.74</IpAddress>
+                       </InnerIpAddress>
+                       <InstanceTypeFamily>ecs.t1</InstanceTypeFamily>
+                       <VlanId></VlanId>
+                       <InstanceId>i-28n7dkvov</InstanceId>
+                       <EipAddress>
+                               <IpAddress></IpAddress>
+                               <AllocationId></AllocationId>
+                               <InternetChargeType></InternetChargeType>
+                       </EipAddress>
+                       <InternetMaxBandwidthIn>-1</InternetMaxBandwidthIn>
+                       <ZoneId>cn-qingdao-b</ZoneId>
+                       <InternetChargeType>PayByTraffic</InternetChargeType>
+                       
<SerialNumber>ca0122d9-374d-4fce-9fc0-71f7c3eaf1c3</SerialNumber>
+                       <IoOptimized>false</IoOptimized>
+                       <Memory>1024</Memory>
+                       <Cpu>1</Cpu>
+                       <VpcAttributes>
+                               <NatIpAddress></NatIpAddress>
+                               <PrivateIpAddress />
+                               <VSwitchId></VSwitchId>
+                               <VpcId></VpcId>
+                       </VpcAttributes>
+                       <InternetMaxBandwidthOut>1</InternetMaxBandwidthOut>
+                       <DeviceAvailable>true</DeviceAvailable>
+                       <SecurityGroupIds>
+                               <SecurityGroupId>sg-28ou0f3xa</SecurityGroupId>
+                       </SecurityGroupIds>
+                       <InstanceName>iZ28n7dkvovZ</InstanceName>
+                       <Description></Description>
+                       <InstanceNetworkType>classic</InstanceNetworkType>
+                       <PublicIpAddress>
+                               <IpAddress>114.215.124.73</IpAddress>
+                       </PublicIpAddress>
+                       <HostName>iZ28n7dkvovZ</HostName>
+                       <InstanceType>ecs.t1.small</InstanceType>
+                       <CreationTime>2015-12-27T07:35Z</CreationTime>
+                       <Status>Running</Status>
+                       <ClusterId></ClusterId>
+                       <RegionId>cn-qingdao</RegionId>
+                       <OperationLocks />
+                       <InstanceChargeType>PostPaid</InstanceChargeType>
+                       <ExpiredTime>2999-09-08T16:00Z</ExpiredTime>
+               </Instance>
+       </Instances>
+</DescribeInstancesResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/start_instance.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ecs/start_instance.xml 
b/libcloud/test/compute/fixtures/ecs/start_instance.xml
new file mode 100644
index 0000000..f7e87e0
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/start_instance.xml
@@ -0,0 +1,4 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<StartInstanceResponse>
+       <RequestId>DA38B11A-9D6D-420B-942F-95D68606C4FC</RequestId>
+</StartInstanceResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/stop_instance.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ecs/stop_instance.xml 
b/libcloud/test/compute/fixtures/ecs/stop_instance.xml
new file mode 100644
index 0000000..156b113
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/stop_instance.xml
@@ -0,0 +1,4 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<StopInstanceResponse>
+       <RequestId>DA38B11A-9D6D-420B-942F-95D68606C4FC</RequestId>
+</StopInstanceResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/fixtures/ecs/stop_node_describe_instances.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/compute/fixtures/ecs/stop_node_describe_instances.xml 
b/libcloud/test/compute/fixtures/ecs/stop_node_describe_instances.xml
new file mode 100644
index 0000000..329bb79
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ecs/stop_node_describe_instances.xml
@@ -0,0 +1,56 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeInstancesResponse>
+       <PageNumber>1</PageNumber>
+       <TotalCount>1</TotalCount>
+       <PageSize>10</PageSize>
+       <RequestId>CA75EE06-D5F7-433C-870B-5042EED6C1DC</RequestId>
+       <Instances>
+               <Instance>
+                       
<ImageId>ubuntu1404_64_20G_aliaegis_20150325.vhd</ImageId>
+                       <InnerIpAddress>
+                               <IpAddress>10.163.197.74</IpAddress>
+                       </InnerIpAddress>
+                       <InstanceTypeFamily>ecs.t1</InstanceTypeFamily>
+                       <VlanId></VlanId>
+                       <InstanceId>i-28n7dkvov</InstanceId>
+                       <EipAddress>
+                               <IpAddress></IpAddress>
+                               <AllocationId></AllocationId>
+                               <InternetChargeType></InternetChargeType>
+                       </EipAddress>
+                       <InternetMaxBandwidthIn>-1</InternetMaxBandwidthIn>
+                       <ZoneId>cn-qingdao-b</ZoneId>
+                       <InternetChargeType>PayByTraffic</InternetChargeType>
+                       
<SerialNumber>ca0122d9-374d-4fce-9fc0-71f7c3eaf1c3</SerialNumber>
+                       <IoOptimized>false</IoOptimized>
+                       <Memory>1024</Memory>
+                       <Cpu>1</Cpu>
+                       <VpcAttributes>
+                               <NatIpAddress></NatIpAddress>
+                               <PrivateIpAddress />
+                               <VSwitchId></VSwitchId>
+                               <VpcId></VpcId>
+                       </VpcAttributes>
+                       <InternetMaxBandwidthOut>1</InternetMaxBandwidthOut>
+                       <DeviceAvailable>true</DeviceAvailable>
+                       <SecurityGroupIds>
+                               <SecurityGroupId>sg-28ou0f3xa</SecurityGroupId>
+                       </SecurityGroupIds>
+                       <InstanceName>iZ28n7dkvovZ</InstanceName>
+                       <Description></Description>
+                       <InstanceNetworkType>classic</InstanceNetworkType>
+                       <PublicIpAddress>
+                               <IpAddress>114.215.124.73</IpAddress>
+                       </PublicIpAddress>
+                       <HostName>iZ28n7dkvovZ</HostName>
+                       <InstanceType>ecs.t1.small</InstanceType>
+                       <CreationTime>2015-12-27T07:35Z</CreationTime>
+                       <Status>Stopped</Status>
+                       <ClusterId></ClusterId>
+                       <RegionId>cn-qingdao</RegionId>
+                       <OperationLocks />
+                       <InstanceChargeType>PostPaid</InstanceChargeType>
+                       <ExpiredTime>2999-09-08T16:00Z</ExpiredTime>
+               </Instance>
+       </Instances>
+</DescribeInstancesResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/compute/test_ecs.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_ecs.py 
b/libcloud/test/compute/test_ecs.py
new file mode 100644
index 0000000..96e482e
--- /dev/null
+++ b/libcloud/test/compute/test_ecs.py
@@ -0,0 +1,912 @@
+# -*- coding: utf-8 -*-
+# 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 __future__ import unicode_literals
+
+import sys
+import unittest
+
+from libcloud.common.types import LibcloudError
+from libcloud.compute.base import Node, NodeAuthPassword, NodeImage, \
+    NodeLocation, NodeSize, StorageVolume, VolumeSnapshot
+from libcloud.compute.drivers.ecs import ECSDriver
+from libcloud.compute.types import NodeState, StorageVolumeState
+from libcloud.test import MockHttpTestCase, LibcloudTestCase
+from libcloud.test.file_fixtures import ComputeFileFixtures
+from libcloud.test.secrets import ECS_PARAMS
+from libcloud.utils.py3 import httplib
+
+
+class ECSDriverTestCase(LibcloudTestCase):
+    region = 'cn-qingdao'
+    zone = 'cn-qingdao-b'
+    image_id = 'ubuntu1404_64_20G_aliaegis_20150325.vhd'
+
+    def setUp(self):
+        ECSMockHttp.test = self
+        ECSDriver.connectionCls.conn_classes = (ECSMockHttp, ECSMockHttp)
+        ECSMockHttp.use_param = 'Action'
+        ECSMockHttp.type = None
+
+        self.driver = ECSDriver(*ECS_PARAMS, region=self.region)
+        self.fake_size = NodeSize('ecs.t1.small', 'ecs t1 small',
+                                  None, None, None, None,
+                                  self.driver)
+        self.fake_image = NodeImage(self.image_id, name='ubuntu 14.04 64bit',
+                                    driver=self.driver)
+        self.fake_node = Node(id='fake-node1', name='fake-node',
+                              state=NodeState.RUNNING,
+                              public_ips=None,
+                              private_ips=None,
+                              driver=self.driver)
+        self.fake_volume = StorageVolume(id='fake-volume1', name='fake-volume',
+                                         size=self.fake_size,
+                                         driver=self.driver)
+        self.fake_snapshot = VolumeSnapshot(id='fake-snapshot1',
+                                            driver=self.driver)
+        self.fake_location = NodeLocation(id=self.region, name=self.region,
+                                          country=None, driver=self.driver)
+
+    def test_list_nodes(self):
+        nodes = self.driver.list_nodes()
+        self.assertIsNotNone(nodes)
+        self.assertEqual(1, len(nodes))
+        node = nodes[0]
+        self.assertEqual('iZ28n7dkvovZ', node.name)
+        self.assertEqual('i-28n7dkvov', node.id)
+        self.assertEqual(NodeState.PENDING, node.state)
+        self.assertEqual(1, len(node.public_ips))
+        self.assertEqual('114.215.124.73', node.public_ips[0])
+        self.assertEqual(1, len(node.private_ips))
+        self.assertEqual('10.163.197.74', node.private_ips[0])
+        expected_extra = {
+            'image_id': 'ubuntu1404_64_20G_aliaegis_20150325.vhd',
+            'description': '',
+            'instance_type_family': 'ecs.t1',
+            'zone_id': 'cn-qingdao-b',
+            'internet_charge_type': 'PayByTraffic',
+            'serial_number': 'ca0122d9-374d-4fce-9fc0-71f7c3eaf1c3',
+            'io_optimized': 'false',
+            'device_available': 'true',
+            'instance_network_type': 'classic',
+            'hostname': 'iZ28n7dkvovZ',
+            'instance_type': 'ecs.t1.small',
+            'creation_time': '2015-12-27T07:35Z',
+            'instance_charge_type': 'PostPaid',
+            'expired_time': '2999-09-08T16:00Z'
+        }
+        self._validate_extras(expected_extra, node.extra)
+        vpc = {
+            'vpc_id': '',
+            'vswitch_id': '',
+            'private_ip_address': None,
+            'nat_ip_address': ''
+        }
+        self._validate_extras(vpc, node.extra['vpc_attributes'])
+        eip_address = {
+            'allocation_id': '',
+            'ip_address': '',
+            'internet_charge_type': '',
+            'bandwidth': None
+        }
+        self._validate_extras(eip_address, node.extra['eip_address'])
+        self.assertIsNone(node.extra['operation_locks']['lock_reason'])
+
+    def test_list_nodes_with_ex_node_ids(self):
+        ECSMockHttp.type = 'list_nodes_ex_node_ids'
+        nodes = self.driver.list_nodes(ex_node_ids=['i-28n7dkvov',
+                                                    'not-existed-id'])
+        self.assertIsNotNone(nodes)
+
+    def test_list_nodes_with_ex_filters(self):
+        ECSMockHttp.type = 'list_nodes_ex_filters'
+        nodes = self.driver.list_nodes(ex_filters={'ZoneId': self.zone})
+        self.assertIsNotNone(nodes)
+
+    def _validate_extras(self, expected, actual):
+        self.assertIsNotNone(actual)
+        for key, value in iter(expected.items()):
+            self.assertTrue(key in actual)
+            self.assertEqual(value, actual[key], ('extra %(key)s not equal, '
+                                                  'expected: "%(expected)s", '
+                                                  'actual: "%(actual)s"' %
+                                                  {'key': key,
+                                                   'expected': value,
+                                                   'actual': actual[key]}))
+
+    def test_create_node(self):
+        ECSMockHttp.type = 'create_node'
+        name = 'test_create_node'
+        node = self.driver.create_node(name=name, image=self.fake_image,
+                                       size=self.fake_size,
+                                       ex_security_group_id='sg-28ou0f3xa',
+                                       ex_description='description',
+                                       ex_internet_charge_type='PayByTraffic',
+                                       ex_internet_max_bandwidth_out=1,
+                                       ex_internet_max_bandwidth_in=200,
+                                       ex_hostname='hostname',
+                                       auth=NodeAuthPassword('password'),
+                                       ex_io_optimized=True,
+                                       ex_system_disk={'category': 'cloud',
+                                                       'disk_name': 'root',
+                                                       'description': 'sys'},
+                                       ex_vswitch_id='vswitch-id1',
+                                       ex_private_ip_address='1.1.1.2',
+                                       ex_client_token='client_token')
+        self.assertIsNotNone(node)
+
+    def test_create_node_with_data_disk(self):
+        ECSMockHttp.type = 'create_node_with_data'
+        self.name = 'test_create_node'
+        self.data_disk = {
+            'size': 5,
+            'category': self.driver.disk_categories.CLOUD,
+            'disk_name': 'data1',
+            'description': 'description',
+            'device': '/dev/xvdb',
+            'delete_with_instance': True}
+        node = self.driver.create_node(name=self.name, image=self.fake_image,
+                                       size=self.fake_size,
+                                       ex_security_group_id='sg-28ou0f3xa',
+                                       ex_data_disk=self.data_disk)
+        self.assertIsNotNone(node)
+
+    def test_list_sizes(self):
+        sizes = self.driver.list_sizes()
+        self.assertEqual(2, len(sizes))
+        size = sizes[0]
+        self.assertEqual('ecs.t1.xsmall', size.id)
+        self.assertEqual('ecs.t1.xsmall', size.name)
+        self.assertEqual(0.5, size.ram)
+        self.assertEqual(1, size.extra['cpu_core_count'])
+        self.assertEqual('ecs.t1', size.extra['instance_type_family'])
+        size = sizes[1]
+        self.assertEqual('ecs.s2.small', size.id)
+        self.assertEqual('ecs.s2.small', size.name)
+        self.assertEqual(1.0, size.ram)
+        self.assertEqual(2, size.extra['cpu_core_count'])
+        self.assertEqual('ecs.s2', size.extra['instance_type_family'])
+
+    def test_list_locations(self):
+        locations = self.driver.list_locations()
+        self.assertEqual(9, len(locations))
+        location = locations[0]
+        self.assertEqual('ap-southeast-1', location.id)
+        self.assertEqual('亚太(新加坡)', location.name)
+        self.assertIsNone(location.country)
+
+    def test_create_node_without_sg_id_exception(self):
+        name = 'test_create_node_without_sg_id_exception'
+        self.assertRaises(AttributeError, self.driver.create_node,
+                          name=name, image=self.fake_image,
+                          size=self.fake_size)
+
+    def test_creat_node_paybytraffic_exception(self):
+        name = 'test_create_node_paybytraffic_exception'
+        self.assertRaises(AttributeError, self.driver.create_node,
+                          name=name, image=self.fake_image,
+                          size=self.fake_size,
+                          ex_security_group_id='sg-id1',
+                          ex_internet_charge_type='PayByTraffic')
+
+    def test_create_node_ex_system_disk_exception(self):
+        name = 'test_creat_node_ex_system_disk_exception'
+        self.assertRaises(AttributeError, self.driver.create_node,
+                          name=name, image=self.fake_image,
+                          size=self.fake_size,
+                          ex_security_group_id='sg-id1',
+                          ex_system_disk=None)
+
+    def test_create_node_ex_private_ip_address_exception(self):
+        name = 'test_create_node_ex_private_ip_address_exception'
+        self.assertRaises(AttributeError, self.driver.create_node,
+                          name=name, image=self.fake_image,
+                          size=self.fake_size,
+                          ex_security_group_id='sg-id1',
+                          ex_private_ip_address='1.1.1.2')
+
+    def test_reboot_node(self):
+        ECSMockHttp.type = 'reboot_node'
+        result = self.driver.reboot_node(self.fake_node)
+        self.assertTrue(result)
+
+    def test_reboot_node_with_ex_force_stop(self):
+        ECSMockHttp.type = 'reboot_node_force_stop'
+        result = self.driver.reboot_node(self.fake_node, ex_force_stop=True)
+        self.assertTrue(result)
+
+    def test_destroy_node(self):
+        ECSMockHttp.type = 'destroy_node'
+        result = self.driver.destroy_node(self.fake_node)
+        self.assertTrue(result)
+
+    def test_ex_start_node(self):
+        ECSMockHttp.type = 'start_node'
+        result = self.driver.ex_start_node(self.fake_node)
+        self.assertTrue(result)
+
+    def test_ex_stop_node(self):
+        ECSMockHttp.type = 'stop_node'
+        result = self.driver.ex_stop_node(self.fake_node)
+        self.assertTrue(result)
+
+    def test_stop_node_with_ex_force_stop(self):
+        ECSMockHttp.type = 'stop_node_force_stop'
+        result = self.driver.ex_stop_node(self.fake_node, ex_force_stop=True)
+        self.assertTrue(result)
+
+    def test_list_volumes(self):
+        volumes = self.driver.list_volumes()
+        self.assertEqual(2, len(volumes))
+        volume = volumes[0]
+        self.assertEqual('d-28m5zbua0', volume.id)
+        self.assertEqual('', volume.name)
+        self.assertEqual(5, volume.size)
+        self.assertEqual(StorageVolumeState.AVAILABLE, volume.state)
+        expected_extras = {
+            'region_id': 'cn-qingdao',
+            'zone_id': 'cn-qingdao-b',
+            'description': '',
+            'type': 'data',
+            'category': 'cloud',
+            'image_id': '',
+            'source_snapshot_id': '',
+            'product_code': '',
+            'portable': True,
+            'instance_id': '',
+            'device': '',
+            'delete_with_instance': False,
+            'enable_auto_snapshot': False,
+            'creation_time': '2014-07-23T02:44:07Z',
+            'attached_time': '2014-07-23T07:47:35Z',
+            'detached_time': '2014-07-23T08:28:48Z',
+            'disk_charge_type': 'PostPaid',
+            'operation_locks': {'lock_reason': None}
+        }
+        self._validate_extras(expected_extras, volume.extra)
+        volume = volumes[1]
+        self.assertEqual('d-28zfrmo13', volume.id)
+        self.assertEqual('ubuntu1404sys', volume.name)
+        self.assertEqual(5, volume.size)
+        self.assertEqual(StorageVolumeState.INUSE, volume.state)
+        expected_extras = {
+            'region_id': 'cn-qingdao',
+            'zone_id': 'cn-qingdao-b',
+            'description': 'Description',
+            'type': 'system',
+            'category': 'cloud',
+            'image_id': 'ubuntu1404_64_20G_aliaegis_20150325.vhd',
+            'source_snapshot_id': '',
+            'product_code': '',
+            'portable': False,
+            'instance_id': 'i-28whl2nj2',
+            'device': '/dev/xvda',
+            'delete_with_instance': True,
+            'enable_auto_snapshot': True,
+            'creation_time': '2014-07-23T02:44:06Z',
+            'attached_time': '2016-01-04T15:02:17Z',
+            'detached_time': '',
+            'disk_charge_type': 'PostPaid',
+            'operation_locks': {'lock_reason': None}
+        }
+        self._validate_extras(expected_extras, volume.extra)
+
+    def test_list_volumes_with_ex_volume_ids(self):
+        ECSMockHttp.type = 'list_volumes_ex_volume_ids'
+        volumes = self.driver.list_volumes(ex_volume_ids=['i-28n7dkvov',
+                                                          'not-existed-id'])
+        self.assertIsNotNone(volumes)
+
+    def test_list_volumes_with_ex_filters(self):
+        ECSMockHttp.type = 'list_volumes_ex_filters'
+        ex_filters = {'InstanceId': self.fake_node.id}
+        volumes = self.driver.list_volumes(ex_filters=ex_filters)
+        self.assertIsNotNone(volumes)
+
+    def test_list_volume_snapshots(self):
+        snapshots = self.driver.list_volume_snapshots(self.fake_volume)
+        self.assertEqual(1, len(snapshots))
+
+    def test_list_volume_snapshots_with_ex_snapshot_ids(self):
+        ECSMockHttp.type = 'list_volume_snapshots_ex_snapshot_ids'
+        ex_snapshot_ids = ['fake-snapshot1']
+        self.driver.list_volume_snapshots(self.fake_volume,
+                                          ex_snapshot_ids=ex_snapshot_ids)
+
+    def test_list_volume_snapshots_with_ex_filters(self):
+        ECSMockHttp.type = 'list_volume_snapshots_ex_filters'
+        ex_filters = {'InstanceId': self.fake_node.id}
+        self.driver.list_volume_snapshots(self.fake_volume,
+                                          ex_filters=ex_filters)
+
+    def test_create_volume(self):
+        ECSMockHttp.type = 'create_volume'
+        self.volume_size = 1
+        self.volume_name = 'fake-volume-name'
+        self.description = 'fake-description'
+        self.disk_category = 'system'
+        self.client_token = 'client_token'
+        volume = self.driver.create_volume(self.volume_size, self.volume_name,
+                                           snapshot=self.fake_snapshot,
+                                           ex_zone_id=self.zone,
+                                           ex_description=self.description,
+                                           ex_disk_category=self.disk_category,
+                                           ex_client_token=self.client_token)
+        self.assertIsNotNone(volume)
+
+    def test_create_volume_without_ex_zone_id_exception(self):
+        self.assertRaises(AttributeError,
+                          self.driver.create_volume,
+                          1, 'fake-volume-name')
+
+    def test_create_volume_snapshot(self):
+        ECSMockHttp.type = 'create_volume_snapshot'
+        self.snapshot_name = 'fake-snapshot1'
+        self.description = 'fake-description'
+        self.client_token = 'client-token'
+        snapshot = self.driver.create_volume_snapshot(
+            self.fake_volume, name=self.snapshot_name,
+            ex_description=self.description,
+            ex_client_token=self.client_token)
+        self.assertIsNotNone(snapshot)
+
+    def test_attach_volume(self):
+        self.device = '/dev/sdb'
+        self.delete_with_instance = True
+        attached = self.driver.attach_volume(
+            self.fake_node, self.fake_volume, device=self.device,
+            ex_delete_with_instance=self.delete_with_instance)
+        self.assertTrue(attached)
+
+    def test_detach_volume(self):
+        self.instance_id = 'fake-node1'
+        result = self.driver.detach_volume(self.fake_volume,
+                                           ex_instance_id=self.instance_id)
+        self.assertTrue(result)
+
+    def test_detach_volume_query_instance_id(self):
+        ECSMockHttp.type = 'detach_volume'
+        result = self.driver.detach_volume(self.fake_volume)
+        self.assertTrue(result)
+
+    def test_detach_volume_query_instance_id_exception(self):
+        self.assertRaises(AttributeError, self.driver.detach_volume,
+                          self.fake_volume)
+
+    def test_destroy_volume(self):
+        ECSMockHttp.type = 'destroy_volume'
+        result = self.driver.destroy_volume(self.fake_volume)
+        self.assertTrue(result)
+
+    def test_destroy_volume_query_volumes_exception(self):
+        self.assertRaises(LibcloudError, self.driver.destroy_volume,
+                          self.fake_volume)
+
+    def test_destroy_volume_state_exception(self):
+        ECSMockHttp.type = 'destroy_volume_state'
+        self.assertRaises(LibcloudError, self.driver.destroy_volume,
+                          self.fake_volume)
+
+    def test_destroy_volume_snapshot(self):
+        result = self.driver.destroy_volume_snapshot(self.fake_snapshot)
+        self.assertTrue(result)
+
+    def test_destroy_volume_snapshot_exception(self):
+        self.assertRaises(AttributeError, self.driver.destroy_volume_snapshot,
+                          self.fake_volume)
+
+    def test_list_images(self):
+        images = self.driver.list_images(self.fake_location)
+        self.assertEqual(1, len(images))
+        image = images[0]
+        self.assertEqual('freebsd1001_64_20G_aliaegis_20150527.vhd', image.id)
+        self.assertEqual('freebsd1001_64_20G_aliaegis_20150527.vhd',
+                         image.name)
+        expected_extra = {
+            'image_version': '1.0.0',
+            'os_type': 'linux',
+            'platform': 'Freebsd',
+            'architecture': 'x86_64',
+            'description': 'freebsd1001_64_20G_aliaegis_20150527.vhd',
+            'size': 20,
+            'image_owner_alias': 'system',
+            'os_name': 'FreeBSD  10.1 64位',
+            'product_code': '',
+            'is_subscribed': False,
+            'progress': '100%',
+            'creation_time': '2015-06-19T07:25:42Z',
+            'usage': 'instance',
+            'is_copied': False
+        }
+        self._validate_extras(expected_extra, image.extra)
+        expected_dev_mappings = {
+            'snapshot_id': '',
+            'size': 20,
+            'device': '/dev/xvda',
+            'format': '',
+            'import_oss_bucket': '',
+            'import_oss_object': ''
+        }
+        self._validate_extras(expected_dev_mappings,
+                              image.extra['disk_device_mappings'])
+
+    def test_list_images_with_ex_image_ids(self):
+        ECSMockHttp.type = 'list_images_ex_image_ids'
+        self.driver.list_images(location=self.fake_location,
+                                ex_image_ids=[self.fake_image.id,
+                                              'not-existed'])
+
+    def test_list_images_with_ex_image_ids_type_exception(self):
+        self.assertRaises(AttributeError, self.driver.list_images,
+                          location=self.fake_location,
+                          ex_image_ids={'image_ids': 'id1,id2'})
+
+    def test_list_images_with_ex_filters(self):
+        ECSMockHttp.type = 'list_images_ex_filters'
+        ex_filters = {'Status': 'Available'}
+        self.driver.list_images(location=self.fake_location,
+                                ex_filters=ex_filters)
+
+    def test_list_images_multiple_pages(self):
+        ECSMockHttp.type = 'list_images_pages'
+        images = self.driver.list_images()
+        self.assertEqual(2, len(images))
+
+    def test_create_image(self):
+        self.image_name = 'fake-image1'
+        self.description = 'description'
+        self.image_version = '1.0.0'
+        self.client_token = 'client_token'
+        image = self.driver.create_image(None, self.image_name,
+                                         self.description,
+                                         ex_snapshot_id=self.fake_snapshot.id,
+                                         ex_image_version=self.image_version,
+                                         ex_client_token=self.client_token)
+        self.assertIsNotNone(image)
+
+    def test_creaet_image_exception(self):
+        self.assertRaises(AttributeError, self.driver.create_image,
+                          None, None)
+
+    def test_delete_image(self):
+        result = self.driver.delete_image(self.fake_image)
+        self.assertTrue(result)
+
+    def test_get_image(self):
+        ECSMockHttp.type = 'get_image'
+        image = self.driver.get_image(self.fake_image.id)
+        self.assertIsNotNone(image)
+
+    def test_get_image_not_found_exception(self):
+        ECSMockHttp.type = 'get_image_not_found'
+        self.assertRaises(LibcloudError, self.driver.get_image,
+                          self.fake_image.id)
+
+    def test_copy_image(self):
+        self.image_name = 'copied-image1'
+        self.description = 'description'
+        self.dest_region = 'cn-hangzhou'
+        self.client_token = 'client-token'
+        image = self.driver.copy_image(
+            self.region, self.fake_image,
+            self.image_name,
+            description=self.description,
+            ex_destination_region_id=self.dest_region,
+            ex_client_token=self.client_token)
+        self.assertIsNotNone(image)
+
+    def test_copy_image_in_the_same_region(self):
+        ECSMockHttp.type = 'copy_image_same_region'
+        image = self.driver.copy_image(self.region, self.fake_image, None)
+        self.assertIsNotNone(image)
+
+    def test_ex_list_security_groups(self):
+        sgs = self.driver.ex_list_security_groups()
+        self.assertEqual(1, len(sgs))
+        sg = sgs[0]
+        self.assertEqual('sg-28ou0f3xa', sg.id)
+        self.assertEqual('sg-28ou0f3xa', sg.name)
+        self.assertEqual('System created security group.', sg.description)
+        self.assertEqual('', sg.vpc_id)
+        self.assertEqual('2015-06-26T08:35:30Z', sg.creation_time)
+
+    def test_ex_list_security_groups_with_ex_filters(self):
+        ECSMockHttp.type = 'list_sgs_filters'
+        self.vpc_id = 'vpc1'
+        ex_filters = {'VpcId': self.vpc_id}
+        sgs = self.driver.ex_list_security_groups(ex_filters=ex_filters)
+        self.assertEqual(1, len(sgs))
+
+    def test_ex_list_zones(self):
+        zones = self.driver.ex_list_zones()
+        self.assertEqual(1, len(zones))
+        zone = zones[0]
+        self.assertEqual('cn-qingdao-b', zone.id)
+        self.assertEqual('青岛可用区B', zone.name)
+        self.assertEqual(self.driver, zone.driver)
+        self.assertIsNotNone(zone.available_resource_types)
+        self.assertEqual('IoOptimized', zone.available_resource_types[0])
+        self.assertIsNotNone(zone.available_instance_types)
+        self.assertEqual('ecs.m2.medium', zone.available_instance_types[0])
+        self.assertIsNotNone(zone.available_disk_categories)
+        self.assertEqual('cloud_ssd', zone.available_disk_categories[0])
+
+
+class ECSMockHttp(MockHttpTestCase):
+    fixtures = ComputeFileFixtures('ecs')
+
+    def _DescribeInstances(self, method, url, body, headers):
+        resp_body = self.fixtures.load('describe_instances.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _list_nodes_ex_node_ids_DescribeInstances(self, method, url, body,
+                                                  headers):
+        params = {'InstanceIds': '["i-28n7dkvov", "not-existed-id"]'}
+        self.assertUrlContainsQueryParams(url, params)
+        return self._DescribeInstances(method, url, body, headers)
+
+    def _list_nodes_ex_filters_DescribeInstances(self, method, url, body,
+                                                 headers):
+        params = {'ZoneId': self.test.zone}
+        self.assertUrlContainsQueryParams(url, params)
+        return self._DescribeInstances(method, url, body, headers)
+
+    def _DescribeInstanceTypes(self, method, url, body, headers):
+        resp_body = self.fixtures.load('describe_instance_types.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _DescribeRegions(self, method, url, body, headers):
+        resp_body = self.fixtures.load('describe_regions.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _create_node_CreateInstance(self, method, url, body, headers):
+        params = {'SecurityGroupId': 'sg-28ou0f3xa',
+                  'Description': 'description',
+                  'InternetChargeType': 'PayByTraffic',
+                  'InternetMaxBandwidthOut': '1',
+                  'InternetMaxBandwidthIn': '200',
+                  'HostName': 'hostname',
+                  'Password': 'password',
+                  'IoOptimized': 'true',
+                  'SystemDisk.Category': 'cloud',
+                  'SystemDisk.DiskName': 'root',
+                  'SystemDisk.Description': 'sys',
+                  'VSwitchId': 'vswitch-id1',
+                  'PrivateIpAddress': '1.1.1.2',
+                  'ClientToken': 'client_token'}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('create_instance.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _create_node_DescribeInstances(self, method, url, body, headers):
+        resp_body = self.fixtures.load('create_node_describe_instances.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _create_node_StartInstance(self, method, url, body, headers):
+        resp_body = self.fixtures.load('start_instance.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _create_node_with_data_CreateInstance(self, method, url, body,
+                                              headers):
+        params = {'SecurityGroupId': 'sg-28ou0f3xa',
+                  'DataDisk.1.Size': '5',
+                  'DataDisk.1.Category': 'cloud',
+                  'DataDisk.1.DiskName': 'data1',
+                  'DataDisk.1.Description': 'description',
+                  'DataDisk.1.Device': '/dev/xvdb',
+                  'DataDisk.1.DeleteWithInstance': 'true'}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('create_instance.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _create_node_with_data_DescribeInstances(self, method, url, body,
+                                                 headers):
+        resp_body = self.fixtures.load('create_node_describe_instances.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _create_node_with_data_StartInstance(self, method, url, body,
+                                             headers):
+        resp_body = self.fixtures.load('start_instance.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _reboot_node_RebootInstance(self, method, url, body, headers):
+        node_id = self.test.fake_node.id
+        self.assertUrlContainsQueryParams(url, {'InstanceId': node_id,
+                                                'ForceStop': 'false'})
+        resp_body = self.fixtures.load('reboot_instance.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _reboot_node_DescribeInstances(self, method, url, body, headers):
+        resp_body = self.fixtures.load('reboot_node_describe_instances.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _reboot_node_force_stop_RebootInstance(self, method, url, body,
+                                               headers):
+        node_id = self.test.fake_node.id
+        self.assertUrlContainsQueryParams(url, {'InstanceId': node_id,
+                                                'ForceStop': 'true'})
+        resp_body = self.fixtures.load('reboot_instance.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _reboot_node_force_stop_DescribeInstances(self, method, url, body,
+                                                  headers):
+        resp_body = self.fixtures.load('reboot_node_describe_instances.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _destroy_node_DescribeInstances(self, method, url, body, headers):
+        resp_body = self.fixtures.load('destroy_node_describe_instances.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _destroy_node_DeleteInstance(self, method, url, body, headers):
+        node_id = self.test.fake_node.id
+        self.assertUrlContainsQueryParams(url, {'InstanceId': node_id})
+        resp_body = self.fixtures.load('delete_instance.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _start_node_StartInstance(self, method, url, body, headers):
+        node_id = self.test.fake_node.id
+        self.assertUrlContainsQueryParams(url, {'InstanceId': node_id})
+        resp_body = self.fixtures.load('start_instance.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _start_node_DescribeInstances(self, method, url, body, headers):
+        resp_body = self.fixtures.load('reboot_node_describe_instances.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _stop_node_StopInstance(self, method, url, body, headers):
+        node_id = self.test.fake_node.id
+        self.assertUrlContainsQueryParams(url, {'InstanceId': node_id,
+                                                'ForceStop': 'false'})
+        resp_body = self.fixtures.load('stop_instance.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _stop_node_DescribeInstances(self, method, url, body, headers):
+        resp_body = self.fixtures.load('stop_node_describe_instances.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _stop_node_force_stop_StopInstance(self, method, url, body, headers):
+        node_id = self.test.fake_node.id
+        self.assertUrlContainsQueryParams(url, {'InstanceId': node_id,
+                                                'ForceStop': 'true'})
+        resp_body = self.fixtures.load('stop_instance.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _stop_node_force_stop_DescribeInstances(self, method, url, body,
+                                                headers):
+        resp_body = self.fixtures.load('stop_node_describe_instances.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _DescribeDisks(self, method, url, body, headers):
+        resp_body = self.fixtures.load('describe_disks.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _list_volumes_ex_volume_ids_DescribeDisks(self, method, url, body,
+                                                  headers):
+        region = self.test.region
+        params = {'DiskIds': '["i-28n7dkvov", "not-existed-id"]',
+                  'RegionId': region}
+        self.assertUrlContainsQueryParams(url, params)
+        return self._DescribeInstances(method, url, body, headers)
+
+    def _list_volumes_ex_filters_DescribeDisks(self, method, url, body,
+                                               headers):
+        params = {'InstanceId': self.test.fake_node.id}
+        self.assertUrlContainsQueryParams(url, params)
+        return self._DescribeDisks(method, url, body, headers)
+
+    def _DescribeSnapshots(self, method, url, body, headers):
+        region = self.test.region
+        volume_id = self.test.fake_volume.id
+        params = {'RegionId': region,
+                  'DiskId': volume_id}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('describe_snapshots.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _list_volume_snapshots_ex_snapshot_ids_DescribeSnapshots(
+            self, method, url, body, headers):
+        params = {'RegionId': self.test.region,
+                  'SnapshotIds': '["fake-snapshot1"]'}
+        self.assertUrlContainsQueryParams(url, params)
+        return self._DescribeSnapshots(method, url, body, headers)
+
+    def _list_volume_snapshots_ex_filters_DescribeSnapshots(self, method, url, 
body,
+                                                            headers):
+        params = {'InstanceId': self.test.fake_node.id}
+        self.assertUrlContainsQueryParams(url, params)
+        return self._DescribeSnapshots(method, url, body, headers)
+
+    def _create_volume_CreateDisk(self, method, url, body, headers):
+        params = {'RegionId': self.test.region,
+                  'DiskName': self.test.volume_name,
+                  'Size': str(self.test.volume_size),
+                  'ZoneId': self.test.zone,
+                  'SnapshotId': self.test.fake_snapshot.id,
+                  'Description': self.test.description,
+                  'DiskCategory': self.test.disk_category,
+                  'ClientToken': self.test.client_token}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('create_disk.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _create_volume_DescribeDisks(self, method, url, body, headers):
+        resp_body = self.fixtures.load('create_volume_describe_disks.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _create_volume_snapshot_CreateSnapshot(self, method, url, body,
+                                               headers):
+        params = {'DiskId': self.test.fake_volume.id,
+                  'SnapshotName': self.test.snapshot_name,
+                  'Description': self.test.description,
+                  'ClientToken': self.test.client_token}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('create_snapshot.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _create_volume_snapshot_DescribeSnapshots(self, method, url, body,
+                                                  headers):
+        resp_body = self.fixtures.load('describe_snapshots.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _AttachDisk(self, method, url, body, headers):
+        delete_with_instance = str(self.test.delete_with_instance).lower()
+        params = {'InstanceId': self.test.fake_node.id,
+                  'DiskId': self.test.fake_volume.id,
+                  'Device': self.test.device,
+                  'DeleteWithInstance': delete_with_instance}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('attach_disk.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _DetachDisk(self, method, url, body, headers):
+        params = {'DiskId': self.test.fake_volume.id,
+                  'InstanceId': self.test.instance_id}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('detach_disk.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _detach_volume_DescribeDisks(self, method, url, body, headers):
+        params = {'DiskIds': '["' + self.test.fake_volume.id + '"]'}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('detach_volume_describe_disks.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _detach_volume_DetachDisk(self, method, url, body, headers):
+        params = {'DiskId': self.test.fake_volume.id,
+                  'InstanceId': 'i-28whl2nj2'}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('detach_disk.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _destroy_volume_DescribeDisks(self, method, url, body, headers):
+        params = {'DiskIds': '["' + self.test.fake_volume.id + '"]'}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('destroy_volume_describe_disks.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _destroy_volume_DeleteDisk(self, method, url, body, headers):
+        params = {'DiskId': self.test.fake_volume.id}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('delete_disk.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _destroy_volume_state_DescribeDisks(self, method, url, body, headers):
+        return self._detach_volume_DescribeDisks(method, url, body, headers)
+
+    def _DeleteSnapshot(self, method, url, body, header):
+        params = {'SnapshotId': self.test.fake_snapshot.id}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('delete_snapshot.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _DescribeImages(self, method, url, body, headers):
+        params = {'RegionId': self.test.fake_location.id}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('describe_images.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _list_images_pages_DescribeImages(self, method, url, body, headers):
+        if 'PageNumber=2' in url:
+            resp_body = self.fixtures.load('pages_describe_images_page2.xml')
+        else:
+            resp_body = self.fixtures.load('pages_describe_images.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _list_images_ex_image_ids_DescribeImages(self, method, url, body,
+                                                 headers):
+        params = {'ImageId': self.test.fake_image.id + ',not-existed'}
+        self.assertUrlContainsQueryParams(url, params)
+        return self._DescribeImages(method, url, body, headers)
+
+    def _list_images_ex_filters_DescribeImages(self, method, url, body,
+                                               headers):
+        params = {'Status': 'Available'}
+        self.assertUrlContainsQueryParams(url, params)
+        return self._DescribeImages(method, url, body, headers)
+
+    def _CreateImage(self, method, url, body, headers):
+        params = {'RegionId': self.test.region,
+                  'ImageName': self.test.image_name,
+                  'Description': self.test.description,
+                  'SnapshotId': self.test.fake_snapshot.id,
+                  'ImageVersion': self.test.image_version,
+                  'ClientToken': self.test.client_token}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('create_image.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _DeleteImage(self, method, url, body, headers):
+        params = {'RegionId': self.test.region,
+                  'ImageId': self.test.fake_image.id}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('delete_image.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _get_image_DescribeImages(self, method, url, body, headers):
+        params = {'RegionId': self.test.region,
+                  'ImageId': self.test.fake_image.id}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('describe_images.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _get_image_not_found_DescribeImages(self, method, url, body, headers):
+        params = {'RegionId': self.test.region,
+                  'ImageId': self.test.fake_image.id}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('get_image_describe_images.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _CopyImage(self, method, url, body, headers):
+        params = {'RegionId': self.test.region,
+                  'ImageId': self.test.fake_image.id,
+                  'DestinationRegionId': self.test.dest_region,
+                  'DestinationImageName': self.test.image_name,
+                  'DestinationDescription': self.test.description,
+                  'ClientToken': self.test.client_token}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('copy_image.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _copy_image_same_region_CopyImage(self, method, url, body, headers):
+        params = {'RegionId': self.test.region,
+                  'ImageId': self.test.fake_image.id,
+                  'DestinationRegionId': self.test.region}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('copy_image.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _copy_image_same_region_DescribeImages(self, method, url, body,
+                                               headers):
+        return self._DescribeImages(method, url, body, headers)
+
+    def _DescribeSecurityGroups(self, method, url, body, headers):
+        params = {'RegionId': self.test.region}
+        self.assertUrlContainsQueryParams(url, params)
+        resp_body = self.fixtures.load('describe_security_groups.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+    def _list_sgs_filters_DescribeSecurityGroups(self, method, url, body,
+                                                 headers):
+        params = {'VpcId': self.test.vpc_id}
+        self.assertUrlContainsQueryParams(url, params)
+        return self._DescribeSecurityGroups(method, url, body, headers)
+
+    def _DescribeZones(self, method, url, body, headers):
+        resp_body = self.fixtures.load('describe_zones.xml')
+        return (httplib.OK, resp_body, {}, httplib.responses[httplib.OK])
+
+
+if __name__ == '__main__':
+    sys.exit(unittest.main())

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/loadbalancer/fixtures/slb/add_backend_servers.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/slb/add_backend_servers.xml 
b/libcloud/test/loadbalancer/fixtures/slb/add_backend_servers.xml
new file mode 100644
index 0000000..73d7db5
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/slb/add_backend_servers.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<AddBackendServersResponse>
+    <RequestId>365F4154-92F6-4AE4-92F8-7FF34B540710</RequestId>
+    <LoadBalancerId>139a00604ad-cn-east-hangzhou-01</LoadBalancerId>
+    <BackendServers>
+        <BackendServer>
+            <ServerId>node1</ServerId>
+            <Weight>100</Weight>
+        </BackendServer>
+    </BackendServers>
+</AddBackendServersResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/loadbalancer/fixtures/slb/create_load_balancer.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/slb/create_load_balancer.xml 
b/libcloud/test/loadbalancer/fixtures/slb/create_load_balancer.xml
new file mode 100644
index 0000000..b328027
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/slb/create_load_balancer.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CreateLoadBalancerResponse>
+    <RequestId>365F4154-92F6-4AE4-92F8-7FF34B540710</RequestId>
+    <LoadBalancerId>139a00604ad-cn-east-hangzhou-01</LoadBalancerId>
+    <Address>42.250.6.36</Address>
+    <NetworkType>classic</NetworkType>
+    <MasterZoneId>cn-hangzhou-d</MasterZoneId>
+    <SlaveZoneId>cn-hangzhou-b</SlaveZoneId>
+    <LoadBalancerName>balancer1</LoadBalancerName>
+</CreateLoadBalancerResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/loadbalancer/fixtures/slb/create_load_balancer_http_listener.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/loadbalancer/fixtures/slb/create_load_balancer_http_listener.xml
 
b/libcloud/test/loadbalancer/fixtures/slb/create_load_balancer_http_listener.xml
new file mode 100644
index 0000000..fc33ff1
--- /dev/null
+++ 
b/libcloud/test/loadbalancer/fixtures/slb/create_load_balancer_http_listener.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CreateLoadBalancerHTTPListenerResponse>
+    <RequestId>CEF72CEB-54B6-4AE8-B225-F876FF7BA984</RequestId>
+</CreateLoadBalancerHTTPListenerResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/loadbalancer/fixtures/slb/delete_load_balancer.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/slb/delete_load_balancer.xml 
b/libcloud/test/loadbalancer/fixtures/slb/delete_load_balancer.xml
new file mode 100644
index 0000000..ff01059
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/slb/delete_load_balancer.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<DeleteLoadBalancerResponse>
+       <RequestId>CEF72CEB-54B6-4AE8-B225-F876FF7BA984</RequestId>
+</DeleteLoadBalancerResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/loadbalancer/fixtures/slb/delete_server_certificate.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/loadbalancer/fixtures/slb/delete_server_certificate.xml 
b/libcloud/test/loadbalancer/fixtures/slb/delete_server_certificate.xml
new file mode 100644
index 0000000..e0351dd
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/slb/delete_server_certificate.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<DeleteServerCertificateResponse>
+      <RequestId>CEF72CEB-54B6-4AE8-B225-F876FF7BA984</RequestId>
+</DeleteServerCertificateResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/loadbalancer/fixtures/slb/describe_load_balancer_attribute.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/loadbalancer/fixtures/slb/describe_load_balancer_attribute.xml 
b/libcloud/test/loadbalancer/fixtures/slb/describe_load_balancer_attribute.xml
new file mode 100644
index 0000000..ef88068
--- /dev/null
+++ 
b/libcloud/test/loadbalancer/fixtures/slb/describe_load_balancer_attribute.xml
@@ -0,0 +1,38 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeLoadBalancerAttributeResponse>
+       <CreateTimeStamp>1452403099000</CreateTimeStamp>
+       <RegionIdAlias>cn-hangzhou</RegionIdAlias>
+       <BackendServers>
+               <BackendServer>
+                       <ServerId>i-23tshnsdq</ServerId>
+                       <Weight>100</Weight>
+               </BackendServer>
+       </BackendServers>
+       <LoadBalancerId>15229f88562-cn-hangzhou-dg-a01</LoadBalancerId>
+       <ListenerPorts>
+               <ListenerPort>80</ListenerPort>
+       </ListenerPorts>
+       <InternetChargeType>paybytraffic</InternetChargeType>
+       <SlaveZoneId>cn-hangzhou-b</SlaveZoneId>
+       <NetworkType>classic</NetworkType>
+       <MasterZoneId>cn-hangzhou-d</MasterZoneId>
+       <ListenerPortsAndProtocal>
+               <ListenerPortAndProtocal>
+                       <ListenerProtocal>http</ListenerProtocal>
+                       <ListenerPort>80</ListenerPort>
+               </ListenerPortAndProtocal>
+       </ListenerPortsAndProtocal>
+       <CreateTime>2016-01-10 13:18:19</CreateTime>
+       <Address>120.27.186.149</Address>
+       <RegionId>cn-hangzhou-dg-a01</RegionId>
+       <RequestId>D67B80CD-C359-4352-AE3C-4F286CC3782D</RequestId>
+       <AddressType>internet</AddressType>
+       <ListenerPortsAndProtocol>
+               <ListenerPortAndProtocol>
+                       <ListenerProtocol>http</ListenerProtocol>
+                       <ListenerPort>80</ListenerPort>
+               </ListenerPortAndProtocol>
+       </ListenerPortsAndProtocol>
+       <LoadBalancerStatus>active</LoadBalancerStatus>
+       <Bandwidth>1</Bandwidth>
+</DescribeLoadBalancerAttributeResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/loadbalancer/fixtures/slb/describe_load_balancers.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/loadbalancer/fixtures/slb/describe_load_balancers.xml 
b/libcloud/test/loadbalancer/fixtures/slb/describe_load_balancers.xml
new file mode 100644
index 0000000..5275086
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/slb/describe_load_balancers.xml
@@ -0,0 +1,20 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<DescribeLoadBalancersResponse>
+       <LoadBalancers>
+               <LoadBalancer>
+                       <CreateTimeStamp>1452403099000</CreateTimeStamp>
+                       <SlaveZoneId>cn-hangzhou-b</SlaveZoneId>
+                       <NetworkType>classic</NetworkType>
+                       <MasterZoneId>cn-hangzhou-d</MasterZoneId>
+                       <RegionIdAlias>cn-hangzhou</RegionIdAlias>
+                       <CreateTime>2016-01-10T13:18Z</CreateTime>
+                       <RegionId>cn-hangzhou-dg-a01</RegionId>
+                       <Address>120.27.186.149</Address>
+                       <AddressType>internet</AddressType>
+                       
<LoadBalancerId>15229f88562-cn-hangzhou-dg-a01</LoadBalancerId>
+                       <LoadBalancerName>abc</LoadBalancerName>
+                       <LoadBalancerStatus>active</LoadBalancerStatus>
+               </LoadBalancer>
+       </LoadBalancers>
+       <RequestId>A0DAF856-B181-4098-B507-6CE9E40420E8</RequestId>
+</DescribeLoadBalancersResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/loadbalancer/fixtures/slb/describe_server_certificates.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/loadbalancer/fixtures/slb/describe_server_certificates.xml 
b/libcloud/test/loadbalancer/fixtures/slb/describe_server_certificates.xml
new file mode 100644
index 0000000..b927a6d
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/slb/describe_server_certificates.xml
@@ -0,0 +1,15 @@
+<DescribeServerCertificateResponse>
+  <RequestId>365F4154-92F6-4AE4-92F8-7FF34B540710</RequestId>
+    <ServerCertificates>
+          <ServerCertificate>
+              
<ServerCertificateId>139a00604ad-cn-east-hangzhou-01</ServerCertificateId>
+              <ServerCertificateName>abe</ServerCertificateName>
+              <Fingerprint>A:B:E</Fingerprint>
+          </ServerCertificate>
+          <ServerCertificate>
+              
<ServerCertificateId>139a00604ad-cn-east-hangzhou-02</ServerCertificateId>
+              <ServerCertificateName>abf</ServerCertificateName>
+              <Fingerprint>A:B:F</Fingerprint>
+          </ServerCertificate>
+    </ServerCertificates>
+</DescribeServerCertificateResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/loadbalancer/fixtures/slb/remove_backend_servers.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/slb/remove_backend_servers.xml 
b/libcloud/test/loadbalancer/fixtures/slb/remove_backend_servers.xml
new file mode 100644
index 0000000..4201472
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/slb/remove_backend_servers.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<RemoveBackendServersResponse>
+    <RequestId>365F4154-92F6-4AE4-92F8-7FF34B540710</RequestId>
+    <LoadBalancerId>139a00604ad-cn-east-hangzhou-01</LoadBalancerId>
+    <BackendServers>
+        <BackendServer>
+            <ServerId>node1</ServerId>
+            <Weight>100</Weight>
+        </BackendServer>
+    </BackendServers>
+</RemoveBackendServersResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/loadbalancer/fixtures/slb/set_server_certificate_name.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/loadbalancer/fixtures/slb/set_server_certificate_name.xml 
b/libcloud/test/loadbalancer/fixtures/slb/set_server_certificate_name.xml
new file mode 100644
index 0000000..d03763d
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/slb/set_server_certificate_name.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<SetServerCertificateNameResponse>
+      <RequestId>CEF72CEB-54B6-4AE8-B225-F876FF7BA984</RequestId>
+</SetServerCertificateNameResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/loadbalancer/fixtures/slb/start_load_balancer_listener.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/loadbalancer/fixtures/slb/start_load_balancer_listener.xml 
b/libcloud/test/loadbalancer/fixtures/slb/start_load_balancer_listener.xml
new file mode 100644
index 0000000..b7fd414
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/slb/start_load_balancer_listener.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<SetLoadBanancerListenerStatusResponse>
+    <RequestId>CEF72CEB-54B6-4AE8-B225-F876FF7BA984</RequestId>
+</SetLoadBanancerListenerStatusResponse>

http://git-wip-us.apache.org/repos/asf/libcloud/blob/e6002e0a/libcloud/test/loadbalancer/fixtures/slb/upload_server_certificate.xml
----------------------------------------------------------------------
diff --git 
a/libcloud/test/loadbalancer/fixtures/slb/upload_server_certificate.xml 
b/libcloud/test/loadbalancer/fixtures/slb/upload_server_certificate.xml
new file mode 100644
index 0000000..711cd56
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/slb/upload_server_certificate.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<UploadServerCertificateResponse>
+  <RequestId>365F4154-92F6-4AE4-92F8-7FF34B540710</RequestId>
+  <ServerCertificateId>idkp-123-cn-test-01</ServerCertificateId>
+  <ServerCertificateName>cert1</ServerCertificateName>
+  <Fingerprint>01:DF:AB:CD</Fingerprint>
+</UploadServerCertificateResponse>

Reply via email to