Merge "Add network support to the accounts providers"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 175f0d9..1010ba5 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -253,10 +253,6 @@
 # image. (string value)
 #image_alt_ssh_user = root
 
-# Password used to authenticate to an instance using the alternate
-# image. (string value)
-#image_alt_ssh_password = password
-
 # Time in seconds between build status checks. (integer value)
 #build_interval = 1
 
@@ -269,16 +265,16 @@
 #run_ssh = false
 
 # Auth method used for authenticate to the instance. Valid choices
-# are: keypair, configured, adminpass. keypair: start the servers with
-# an ssh keypair. configured: use the configured user and password.
-# adminpass: use the injected adminPass. disabled: avoid using ssh
-# when it is an option. (string value)
+# are: keypair, configured, adminpass and disabled. Keypair: start the
+# servers with a ssh keypair. Configured: use the configured user and
+# password. Adminpass: use the injected adminPass. Disabled: avoid
+# using ssh when it is an option. (string value)
 #ssh_auth_method = keypair
 
 # How to connect to the instance? fixed: using the first ip belongs
-# the fixed network floating: creating and using a floating ip (string
-# value)
-#ssh_connect_method = fixed
+# the fixed network floating: creating and using a floating ip.
+# (string value)
+#ssh_connect_method = floating
 
 # User name used to authenticate to an instance. (string value)
 #ssh_user = root
@@ -286,6 +282,14 @@
 # Timeout in seconds to wait for ping to succeed. (integer value)
 #ping_timeout = 120
 
+# The packet size for ping packets originating from remote linux hosts
+# (integer value)
+#ping_size = 56
+
+# The number of ping packets originating from remote linux hosts
+# (integer value)
+#ping_count = 1
+
 # Timeout in seconds to wait for authentication to succeed. (integer
 # value)
 #ssh_timeout = 300
@@ -301,7 +305,8 @@
 # Name of the fixed network that is visible to all test tenants. If
 # multiple networks are available for a tenant this is the network
 # which will be used for creating servers if tempest does not create a
-# network or a network is not specified elsewhere (string value)
+# network or a network is not specified elsewhere. It may be used for
+# ssh validation only if floating IPs are disabled. (string value)
 #fixed_network_name = <None>
 
 # Network used for SSH connections. Ignored if
@@ -326,10 +331,6 @@
 # Allowed values: public, admin, internal, publicURL, adminURL, internalURL
 #endpoint_type = publicURL
 
-# Path to a private key file for SSH access to remote hosts (string
-# value)
-#path_to_private_key = <None>
-
 # Expected device name when a volume is attached to an instance
 # (string value)
 #volume_device_name = vdb
@@ -746,14 +747,19 @@
 # The mask bits for tenant ipv6 subnets (integer value)
 #tenant_network_v6_mask_bits = 64
 
-# Whether tenant network connectivity should be evaluated directly
-# (boolean value)
+# Whether tenant networks can be reached directly from the test
+# client. This must be set to True when the 'fixed' ssh_connect_method
+# is selected. (boolean value)
 #tenant_networks_reachable = false
 
 # Id of the public network that provides external connectivity (string
 # value)
 #public_network_id =
 
+# Default floating network name. Used to allocate floating IPs when
+# neutron is enabled. (string value)
+#floating_network_name = <None>
+
 # Id of the public router that provides external connectivity. This
 # should only be used when Neutron's 'allow_overlapping_ips' is set to
 # 'False' in neutron.conf. usually not needed past 'Grizzly' release
@@ -1071,6 +1077,38 @@
 #too_slow_to_test = true
 
 
+[validation]
+
+#
+# From tempest.config
+#
+
+# Default IP type used for validation: -fixed: uses the first IP
+# belonging to the fixed network -floating: creates and uses a
+# floating IP (string value)
+# Allowed values: fixed, floating
+#connect_method = floating
+
+# Default authentication method to the instance. Only ssh via keypair
+# is supported for now. Additional methods will be handled in a
+# separate spec. (string value)
+# Allowed values: keypair
+#auth_method = keypair
+
+# Default IP version for ssh connections. (integer value)
+#ip_version_for_ssh = 4
+
+# Timeout in seconds to wait for ping to succeed. (integer value)
+#ping_timeout = 120
+
+# Timeout in seconds to wait for the TCP connection to be successful.
+# (integer value)
+#connect_timeout = 60
+
+# Timeout in seconds to wait for the ssh banner. (integer value)
+#ssh_timeout = 300
+
+
 [volume]
 
 #
diff --git a/tempest/api_schema/response/compute/flavors.py b/tempest/api_schema/response/compute/flavors.py
deleted file mode 100644
index 65f2c28..0000000
--- a/tempest/api_schema/response/compute/flavors.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright 2014 NEC Corporation.  All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-from tempest.api_schema.response.compute import parameter_types
-
-list_flavors = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'flavors': {
-                'type': 'array',
-                'items': {
-                    'type': 'object',
-                    'properties': {
-                        'name': {'type': 'string'},
-                        'links': parameter_types.links,
-                        'id': {'type': 'string'}
-                    },
-                    'required': ['name', 'links', 'id']
-                }
-            },
-            'flavors_links': parameter_types.links
-        },
-        # NOTE(gmann): flavors_links attribute is not necessary
-        # to be present always So it is not 'required'.
-        'required': ['flavors']
-    }
-}
-
-common_flavor_info = {
-    'type': 'object',
-    'properties': {
-        'name': {'type': 'string'},
-        'links': parameter_types.links,
-        'ram': {'type': 'integer'},
-        'vcpus': {'type': 'integer'},
-        'swap': {'type': 'integer'},
-        'disk': {'type': 'integer'},
-        'id': {'type': 'string'}
-    },
-    'required': ['name', 'links', 'ram', 'vcpus',
-                 'swap', 'disk', 'id']
-}
-
-common_flavor_list_details = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'flavors': {
-                'type': 'array',
-                'items': common_flavor_info
-            }
-        },
-        'required': ['flavors']
-    }
-}
-
-common_flavor_details = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'flavor': common_flavor_info
-        },
-        'required': ['flavor']
-    }
-}
diff --git a/tempest/api_schema/response/compute/hosts.py b/tempest/api_schema/response/compute/hosts.py
deleted file mode 100644
index 2596c27..0000000
--- a/tempest/api_schema/response/compute/hosts.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# Copyright 2014 NEC Corporation.  All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-common_start_up_body = {
-    'type': 'object',
-    'properties': {
-        'host': {'type': 'string'},
-        'power_action': {'enum': ['startup']}
-    },
-    'required': ['host', 'power_action']
-}
-
-list_hosts = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'hosts': {
-                'type': 'array',
-                'items': {
-                    'type': 'object',
-                    'properties': {
-                        'host_name': {'type': 'string'},
-                        'service': {'type': 'string'},
-                        'zone': {'type': 'string'}
-                    },
-                    'required': ['host_name', 'service', 'zone']
-                }
-            }
-        },
-        'required': ['hosts']
-    }
-}
-
-show_host_detail = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'host': {
-                'type': 'array',
-                'item': {
-                    'type': 'object',
-                    'properties': {
-                        'resource': {
-                            'type': 'object',
-                            'properties': {
-                                'cpu': {'type': 'integer'},
-                                'disk_gb': {'type': 'integer'},
-                                'host': {'type': 'string'},
-                                'memory_mb': {'type': 'integer'},
-                                'project': {'type': 'string'}
-                            },
-                            'required': ['cpu', 'disk_gb', 'host',
-                                         'memory_mb', 'project']
-                        }
-                    },
-                    'required': ['resource']
-                }
-            }
-        },
-        'required': ['host']
-    }
-}
-
-update_host_common = {
-    'type': 'object',
-    'properties': {
-        'host': {'type': 'string'},
-        'maintenance_mode': {'enum': ['on_maintenance', 'off_maintenance']},
-        'status': {'enum': ['enabled', 'disabled']}
-    },
-    'required': ['host', 'maintenance_mode', 'status']
-}
diff --git a/tempest/api_schema/response/compute/keypairs.py b/tempest/api_schema/response/compute/keypairs.py
deleted file mode 100644
index 2ae410c..0000000
--- a/tempest/api_schema/response/compute/keypairs.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright 2014 NEC Corporation.  All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-list_keypairs = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'keypairs': {
-                'type': 'array',
-                'items': {
-                    'type': 'object',
-                    'properties': {
-                        'keypair': {
-                            'type': 'object',
-                            'properties': {
-                                'public_key': {'type': 'string'},
-                                'name': {'type': 'string'},
-                                'fingerprint': {'type': 'string'}
-                            },
-                            'required': ['public_key', 'name', 'fingerprint']
-                        }
-                    },
-                    'required': ['keypair']
-                }
-            }
-        },
-        'required': ['keypairs']
-    }
-}
-
-create_keypair = {
-    'type': 'object',
-    'properties': {
-        'keypair': {
-            'type': 'object',
-            'properties': {
-                'fingerprint': {'type': 'string'},
-                'name': {'type': 'string'},
-                'public_key': {'type': 'string'},
-                'user_id': {'type': 'string'},
-                'private_key': {'type': 'string'}
-            },
-            # When create keypair API is being called with 'Public key'
-            # (Importing keypair) then, response body does not contain
-            # 'private_key' So it is not defined as 'required'
-            'required': ['fingerprint', 'name', 'public_key', 'user_id']
-        }
-    },
-    'required': ['keypair']
-}
diff --git a/tempest/api_schema/response/compute/quotas.py b/tempest/api_schema/response/compute/quotas.py
deleted file mode 100644
index 863104c..0000000
--- a/tempest/api_schema/response/compute/quotas.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2014 NEC Corporation.  All rights reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-common_quota_set = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'quota_set': {
-                'type': 'object',
-                'properties': {
-                    'instances': {'type': 'integer'},
-                    'cores': {'type': 'integer'},
-                    'ram': {'type': 'integer'},
-                    'floating_ips': {'type': 'integer'},
-                    'fixed_ips': {'type': 'integer'},
-                    'metadata_items': {'type': 'integer'},
-                    'key_pairs': {'type': 'integer'},
-                    'security_groups': {'type': 'integer'},
-                    'security_group_rules': {'type': 'integer'},
-                    'server_group_members': {'type': 'integer'},
-                    'server_groups': {'type': 'integer'},
-                },
-                # NOTE: server_group_members and server_groups are represented
-                # when enabling quota_server_group extension. So they should
-                # not be required.
-                'required': ['instances', 'cores', 'ram',
-                             'floating_ips', 'fixed_ips',
-                             'metadata_items', 'key_pairs',
-                             'security_groups', 'security_group_rules']
-            }
-        },
-        'required': ['quota_set']
-    }
-}
diff --git a/tempest/api_schema/response/compute/v2_1/flavors.py b/tempest/api_schema/response/compute/v2_1/flavors.py
index 76c4cee..725d17a 100644
--- a/tempest/api_schema/response/compute/v2_1/flavors.py
+++ b/tempest/api_schema/response/compute/v2_1/flavors.py
@@ -12,52 +12,86 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import copy
-
-from tempest.api_schema.response.compute import flavors
 from tempest.api_schema.response.compute import parameter_types
 
-list_flavors_details = copy.deepcopy(flavors.common_flavor_list_details)
+list_flavors = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'flavors': {
+                'type': 'array',
+                'items': {
+                    'type': 'object',
+                    'properties': {
+                        'name': {'type': 'string'},
+                        'links': parameter_types.links,
+                        'id': {'type': 'string'}
+                    },
+                    'required': ['name', 'links', 'id']
+                }
+            },
+            'flavors_links': parameter_types.links
+        },
+        # NOTE(gmann): flavors_links attribute is not necessary
+        # to be present always So it is not 'required'.
+        'required': ['flavors']
+    }
+}
 
-# 'swap' attributes comes as integer value but if it is empty it comes as "".
-# So defining type of as string and integer.
-list_flavors_details['response_body']['properties']['flavors']['items'][
-    'properties']['swap'] = {'type': ['string', 'integer']}
+common_flavor_info = {
+    'type': 'object',
+    'properties': {
+        'name': {'type': 'string'},
+        'links': parameter_types.links,
+        'ram': {'type': 'integer'},
+        'vcpus': {'type': 'integer'},
+        # 'swap' attributes comes as integer value but if it is empty
+        # it comes as "". So defining type of as string and integer.
+        'swap': {'type': ['integer', 'string']},
+        'disk': {'type': 'integer'},
+        'id': {'type': 'string'},
+        'OS-FLV-DISABLED:disabled': {'type': 'boolean'},
+        'os-flavor-access:is_public': {'type': 'boolean'},
+        'rxtx_factor': {'type': 'number'},
+        'OS-FLV-EXT-DATA:ephemeral': {'type': 'integer'}
+    },
+    # 'OS-FLV-DISABLED', 'os-flavor-access', 'rxtx_factor' and
+    # 'OS-FLV-EXT-DATA' are API extensions. So they are not 'required'.
+    'required': ['name', 'links', 'ram', 'vcpus', 'swap', 'disk', 'id']
+}
 
-# Defining 'flavors_links' attributes for V2 flavor schema
-list_flavors_details['response_body'][
-    'properties'].update({'flavors_links': parameter_types.links})
-# NOTE(gmann): flavors_links attribute is not necessary to be
-# present always So it is not 'required'.
-
-# Defining extra attributes for V2 flavor schema
-list_flavors_details['response_body']['properties']['flavors']['items'][
-    'properties'].update({'OS-FLV-DISABLED:disabled': {'type': 'boolean'},
-                          'os-flavor-access:is_public': {'type': 'boolean'},
-                          'rxtx_factor': {'type': 'number'},
-                          'OS-FLV-EXT-DATA:ephemeral': {'type': 'integer'}})
-# 'OS-FLV-DISABLED', 'os-flavor-access', 'rxtx_factor' and 'OS-FLV-EXT-DATA'
-# are API extensions. So they are not 'required'.
+list_flavors_details = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'flavors': {
+                'type': 'array',
+                'items': common_flavor_info
+            },
+            # NOTE(gmann): flavors_links attribute is not necessary
+            # to be present always So it is not 'required'.
+            'flavors_links': parameter_types.links
+        },
+        'required': ['flavors']
+    }
+}
 
 unset_flavor_extra_specs = {
     'status_code': [200]
 }
 
-create_get_flavor_details = copy.deepcopy(flavors.common_flavor_details)
-
-# 'swap' attributes comes as integer value but if it is empty it comes as "".
-# So defining type of as string and integer.
-create_get_flavor_details['response_body']['properties']['flavor'][
-    'properties']['swap'] = {'type': ['string', 'integer']}
-
-# Defining extra attributes for V2 flavor schema
-create_get_flavor_details['response_body']['properties']['flavor'][
-    'properties'].update({'OS-FLV-DISABLED:disabled': {'type': 'boolean'},
-                          'os-flavor-access:is_public': {'type': 'boolean'},
-                          'rxtx_factor': {'type': 'number'},
-                          'OS-FLV-EXT-DATA:ephemeral': {'type': 'integer'}})
-# 'OS-FLV-DISABLED', 'os-flavor-access', 'rxtx_factor' and 'OS-FLV-EXT-DATA'
-# are API extensions. So they are not 'required'.
+create_get_flavor_details = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'flavor': common_flavor_info
+        },
+        'required': ['flavor']
+    }
+}
 
 delete_flavor = {
     'status_code': [202]
diff --git a/tempest/api_schema/response/compute/v2_1/hosts.py b/tempest/api_schema/response/compute/v2_1/hosts.py
index 0944792..72d5a07 100644
--- a/tempest/api_schema/response/compute/v2_1/hosts.py
+++ b/tempest/api_schema/response/compute/v2_1/hosts.py
@@ -14,12 +14,70 @@
 
 import copy
 
-from tempest.api_schema.response.compute import hosts
 
+list_hosts = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'hosts': {
+                'type': 'array',
+                'items': {
+                    'type': 'object',
+                    'properties': {
+                        'host_name': {'type': 'string'},
+                        'service': {'type': 'string'},
+                        'zone': {'type': 'string'}
+                    },
+                    'required': ['host_name', 'service', 'zone']
+                }
+            }
+        },
+        'required': ['hosts']
+    }
+}
+
+get_host_detail = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'host': {
+                'type': 'array',
+                'item': {
+                    'type': 'object',
+                    'properties': {
+                        'resource': {
+                            'type': 'object',
+                            'properties': {
+                                'cpu': {'type': 'integer'},
+                                'disk_gb': {'type': 'integer'},
+                                'host': {'type': 'string'},
+                                'memory_mb': {'type': 'integer'},
+                                'project': {'type': 'string'}
+                            },
+                            'required': ['cpu', 'disk_gb', 'host',
+                                         'memory_mb', 'project']
+                        }
+                    },
+                    'required': ['resource']
+                }
+            }
+        },
+        'required': ['host']
+    }
+}
 
 startup_host = {
     'status_code': [200],
-    'response_body': hosts.common_start_up_body
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'host': {'type': 'string'},
+            'power_action': {'enum': ['startup']}
+        },
+        'required': ['host', 'power_action']
+    }
 }
 
 # The 'power_action' attribute of 'shutdown_host' API is 'shutdown'
@@ -38,5 +96,14 @@
 
 update_host = {
     'status_code': [200],
-    'response_body': hosts.update_host_common
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'host': {'type': 'string'},
+            'maintenance_mode': {'enum': ['on_maintenance',
+                                          'off_maintenance']},
+            'status': {'enum': ['enabled', 'disabled']}
+        },
+        'required': ['host', 'maintenance_mode', 'status']
+    }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/keypairs.py b/tempest/api_schema/response/compute/v2_1/keypairs.py
index ec26fa0..ceae6cf 100644
--- a/tempest/api_schema/response/compute/v2_1/keypairs.py
+++ b/tempest/api_schema/response/compute/v2_1/keypairs.py
@@ -12,8 +12,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api_schema.response.compute import keypairs
-
 get_keypair = {
     'status_code': [200],
     'response_body': {
@@ -47,9 +45,56 @@
 
 create_keypair = {
     'status_code': [200],
-    'response_body': keypairs.create_keypair
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'keypair': {
+                'type': 'object',
+                'properties': {
+                    'fingerprint': {'type': 'string'},
+                    'name': {'type': 'string'},
+                    'public_key': {'type': 'string'},
+                    'user_id': {'type': 'string'},
+                    'private_key': {'type': 'string'}
+                },
+                # When create keypair API is being called with 'Public key'
+                # (Importing keypair) then, response body does not contain
+                # 'private_key' So it is not defined as 'required'
+                'required': ['fingerprint', 'name', 'public_key', 'user_id']
+            }
+        },
+        'required': ['keypair']
+    }
 }
 
 delete_keypair = {
     'status_code': [202],
 }
+
+list_keypairs = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'keypairs': {
+                'type': 'array',
+                'items': {
+                    'type': 'object',
+                    'properties': {
+                        'keypair': {
+                            'type': 'object',
+                            'properties': {
+                                'public_key': {'type': 'string'},
+                                'name': {'type': 'string'},
+                                'fingerprint': {'type': 'string'}
+                            },
+                            'required': ['public_key', 'name', 'fingerprint']
+                        }
+                    },
+                    'required': ['keypair']
+                }
+            }
+        },
+        'required': ['keypairs']
+    }
+}
diff --git a/tempest/api_schema/response/compute/v2_1/quota_classes.py b/tempest/api_schema/response/compute/v2_1/quota_classes.py
index a7374df..a0cdaf5 100644
--- a/tempest/api_schema/response/compute/v2_1/quota_classes.py
+++ b/tempest/api_schema/response/compute/v2_1/quota_classes.py
@@ -20,12 +20,12 @@
 # NOTE(mriedem): os-quota-class-sets responses are the same as os-quota-sets
 # except for the key in the response body is quota_class_set instead of
 # quota_set, so update this copy of the schema from os-quota-sets.
-quota_set = copy.deepcopy(quotas.quota_set)
-quota_set['response_body']['properties']['quota_class_set'] = (
-    quota_set['response_body']['properties'].pop('quota_set'))
-quota_set['response_body']['required'] = ['quota_class_set']
+get_quota_class_set = copy.deepcopy(quotas.get_quota_set)
+get_quota_class_set['response_body']['properties']['quota_class_set'] = (
+    get_quota_class_set['response_body']['properties'].pop('quota_set'))
+get_quota_class_set['response_body']['required'] = ['quota_class_set']
 
-quota_set_update = copy.deepcopy(quotas.quota_set_update)
-quota_set_update['response_body']['properties']['quota_class_set'] = (
-    quota_set_update['response_body']['properties'].pop('quota_set'))
-quota_set_update['response_body']['required'] = ['quota_class_set']
+update_quota_class_set = copy.deepcopy(quotas.update_quota_set)
+update_quota_class_set['response_body']['properties']['quota_class_set'] = (
+    update_quota_class_set['response_body']['properties'].pop('quota_set'))
+update_quota_class_set['response_body']['required'] = ['quota_class_set']
diff --git a/tempest/api_schema/response/compute/v2_1/quotas.py b/tempest/api_schema/response/compute/v2_1/quotas.py
index 630b227..9141f7e 100644
--- a/tempest/api_schema/response/compute/v2_1/quotas.py
+++ b/tempest/api_schema/response/compute/v2_1/quotas.py
@@ -14,34 +14,49 @@
 
 import copy
 
-from tempest.api_schema.response.compute import quotas
+update_quota_set = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'quota_set': {
+                'type': 'object',
+                'properties': {
+                    'instances': {'type': 'integer'},
+                    'cores': {'type': 'integer'},
+                    'ram': {'type': 'integer'},
+                    'floating_ips': {'type': 'integer'},
+                    'fixed_ips': {'type': 'integer'},
+                    'metadata_items': {'type': 'integer'},
+                    'key_pairs': {'type': 'integer'},
+                    'security_groups': {'type': 'integer'},
+                    'security_group_rules': {'type': 'integer'},
+                    'server_group_members': {'type': 'integer'},
+                    'server_groups': {'type': 'integer'},
+                    'injected_files': {'type': 'integer'},
+                    'injected_file_content_bytes': {'type': 'integer'},
+                    'injected_file_path_bytes': {'type': 'integer'}
+                },
+                # NOTE: server_group_members and server_groups are represented
+                # when enabling quota_server_group extension. So they should
+                # not be required.
+                'required': ['instances', 'cores', 'ram',
+                             'floating_ips', 'fixed_ips',
+                             'metadata_items', 'key_pairs',
+                             'security_groups', 'security_group_rules',
+                             'injected_files', 'injected_file_content_bytes',
+                             'injected_file_path_bytes']
+            }
+        },
+        'required': ['quota_set']
+    }
+}
 
-quota_set = copy.deepcopy(quotas.common_quota_set)
-quota_set['response_body']['properties']['quota_set']['properties'][
+get_quota_set = copy.deepcopy(update_quota_set)
+get_quota_set['response_body']['properties']['quota_set']['properties'][
     'id'] = {'type': 'string'}
-quota_set['response_body']['properties']['quota_set']['properties'][
-    'injected_files'] = {'type': 'integer'}
-quota_set['response_body']['properties']['quota_set']['properties'][
-    'injected_file_content_bytes'] = {'type': 'integer'}
-quota_set['response_body']['properties']['quota_set']['properties'][
-    'injected_file_path_bytes'] = {'type': 'integer'}
-quota_set['response_body']['properties']['quota_set']['required'].extend([
-    'id',
-    'injected_files',
-    'injected_file_content_bytes',
-    'injected_file_path_bytes'])
-
-quota_set_update = copy.deepcopy(quotas.common_quota_set)
-quota_set_update['response_body']['properties']['quota_set']['properties'][
-    'injected_files'] = {'type': 'integer'}
-quota_set_update['response_body']['properties']['quota_set']['properties'][
-    'injected_file_content_bytes'] = {'type': 'integer'}
-quota_set_update['response_body']['properties']['quota_set']['properties'][
-    'injected_file_path_bytes'] = {'type': 'integer'}
-quota_set_update['response_body']['properties']['quota_set'][
-    'required'].extend(['injected_files',
-                        'injected_file_content_bytes',
-                        'injected_file_path_bytes'])
+get_quota_set['response_body']['properties']['quota_set']['required'].extend([
+    'id'])
 
 delete_quota = {
     'status_code': [202]
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index fec3bd4..f84771f 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -77,7 +77,8 @@
     - name: javelin_cirros
       owner: javelin
       file: cirros-0.3.2-x86_64-blank.img
-      format: ami
+      disk_format: ami
+      container_format: ami
       aki: cirros-0.3.2-x86_64-vmlinuz
       ari: cirros-0.3.2-x86_64-initrd
 
@@ -629,6 +630,15 @@
     for image in images:
         client = client_for_user(image['owner'])
 
+        # DEPRECATED: 'format' was used for ami images
+        # Use 'disk_format' and 'container_format' instead
+        if 'format' in image:
+            LOG.warning("Deprecated: 'format' is deprecated for images "
+                        "description. Please use 'disk_format' and 'container_"
+                        "format' instead.")
+            image['disk_format'] = image['format']
+            image['container_format'] = image['format']
+
         # only upload a new image if the name isn't there
         if _get_image_by_name(client, image['name']):
             LOG.info("Image '%s' already exists" % image['name'])
@@ -636,7 +646,7 @@
 
         # special handling for 3 part image
         extras = {}
-        if image['format'] == 'ami':
+        if image['disk_format'] == 'ami':
             name, fname = _resolve_image(image, 'aki')
             aki = client.images.create_image(
                 'javelin_' + name, 'aki', 'aki')
@@ -651,7 +661,8 @@
 
         _, fname = _resolve_image(image, 'file')
         body = client.images.create_image(
-            image['name'], image['format'], image['format'], **extras)
+            image['name'], image['container_format'],
+            image['disk_format'], **extras)
         image_id = body.get('id')
         client.images.store_image(image_id, open(fname, 'r'))
 
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 3c71e07..b61f286 100755
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -24,6 +24,7 @@
 from six import moves
 
 from tempest import clients
+from tempest.common import credentials
 from tempest import config
 
 
@@ -254,7 +255,11 @@
     }
     # Get catalog list for endpoints to use for validation
     _token, auth_data = os.auth_provider.get_auth()
-    for entry in auth_data['serviceCatalog']:
+    if os.auth_version == 'v2':
+        catalog_key = 'serviceCatalog'
+    else:
+        catalog_key = 'catalog'
+    for entry in auth_data[catalog_key]:
         services.append(entry['type'])
     # Pull all catalog types from config file and compare against endpoint list
     for cfgname in dir(CONF._config):
@@ -329,7 +334,8 @@
         CONF_PARSER = moves.configparser.SafeConfigParser()
         CONF_PARSER.optionxform = str
         CONF_PARSER.readfp(conf_file)
-    os = clients.Manager()
+    icreds = credentials.get_isolated_credentials('verify_tempest_config')
+    os = clients.Manager(icreds.get_primary_creds())
     services = check_service_availability(os, update)
     results = {}
     for service in ['nova', 'cinder', 'neutron', 'swift']:
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index b19faef..29fb493 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -87,10 +87,11 @@
         cmd = 'sudo sh -c "echo \\"%s\\" >/dev/console"' % message
         return self.exec_command(cmd)
 
-    def ping_host(self, host):
+    def ping_host(self, host, count=CONF.compute.ping_count,
+                  size=CONF.compute.ping_size):
         addr = netaddr.IPAddress(host)
         cmd = 'ping6' if addr.version == 6 else 'ping'
-        cmd += ' -c1 -w1 {0}'.format(host)
+        cmd += ' -c{0} -w{0} -s{1} {2}'.format(count, size, host)
         return self.exec_command(cmd)
 
     def get_mac_address(self):
diff --git a/tempest/config.py b/tempest/config.py
index 3725f58..6b8113e 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -187,10 +187,6 @@
                default="root",
                help="User name used to authenticate to an instance using "
                     "the alternate image."),
-    cfg.StrOpt('image_alt_ssh_password',
-               default="password",
-               help="Password used to authenticate to an instance using "
-                    "the alternate image."),
     cfg.IntOpt('build_interval',
                default=1,
                help="Time in seconds between build status checks."),
@@ -205,16 +201,17 @@
     cfg.StrOpt('ssh_auth_method',
                default='keypair',
                help="Auth method used for authenticate to the instance. "
-                    "Valid choices are: keypair, configured, adminpass. "
-                    "keypair: start the servers with an ssh keypair. "
-                    "configured: use the configured user and password. "
-                    "adminpass: use the injected adminPass. "
-                    "disabled: avoid using ssh when it is an option."),
+                    "Valid choices are: keypair, configured, adminpass "
+                    "and disabled. "
+                    "Keypair: start the servers with a ssh keypair. "
+                    "Configured: use the configured user and password. "
+                    "Adminpass: use the injected adminPass. "
+                    "Disabled: avoid using ssh when it is an option."),
     cfg.StrOpt('ssh_connect_method',
-               default='fixed',
+               default='floating',
                help="How to connect to the instance? "
                     "fixed: using the first ip belongs the fixed network "
-                    "floating: creating and using a floating ip"),
+                    "floating: creating and using a floating ip."),
     cfg.StrOpt('ssh_user',
                default='root',
                help="User name used to authenticate to an instance."),
@@ -222,6 +219,14 @@
                default=120,
                help="Timeout in seconds to wait for ping to "
                     "succeed."),
+    cfg.IntOpt('ping_size',
+               default=56,
+               help="The packet size for ping packets originating "
+                    "from remote linux hosts"),
+    cfg.IntOpt('ping_count',
+               default=1,
+               help="The number of ping packets originating from remote "
+                    "linux hosts"),
     cfg.IntOpt('ssh_timeout',
                default=300,
                help="Timeout in seconds to wait for authentication to "
@@ -239,7 +244,8 @@
                     "tenants. If multiple networks are available for a tenant"
                     " this is the network which will be used for creating "
                     "servers if tempest does not create a network or a "
-                    "network is not specified elsewhere"),
+                    "network is not specified elsewhere. It may be used for "
+                    "ssh validation only if floating IPs are disabled."),
     cfg.StrOpt('network_for_ssh',
                default='public',
                help="Network used for SSH connections. Ignored if "
@@ -264,9 +270,6 @@
                choices=['public', 'admin', 'internal',
                         'publicURL', 'adminURL', 'internalURL'],
                help="The endpoint type to use for the compute service."),
-    cfg.StrOpt('path_to_private_key',
-               help="Path to a private key file for SSH access to remote "
-                    "hosts"),
     cfg.StrOpt('volume_device_name',
                default='vdb',
                help="Expected device name when a volume is attached to "
@@ -449,12 +452,16 @@
                help="The mask bits for tenant ipv6 subnets"),
     cfg.BoolOpt('tenant_networks_reachable',
                 default=False,
-                help="Whether tenant network connectivity should be "
-                     "evaluated directly"),
+                help="Whether tenant networks can be reached directly from "
+                     "the test client. This must be set to True when the "
+                     "'fixed' ssh_connect_method is selected."),
     cfg.StrOpt('public_network_id',
                default="",
                help="Id of the public network that provides external "
                     "connectivity"),
+    cfg.StrOpt('floating_network_name',
+               help="Default floating network name. Used to allocate floating "
+                    "IPs when neutron is enabled."),
     cfg.StrOpt('public_router_id',
                default="",
                help="Id of the public router that provides external "
@@ -536,6 +543,37 @@
                help='The maximum grace period for a claim'),
 ]
 
+validation_group = cfg.OptGroup(name='validation',
+                                title='SSH Validation options')
+
+ValidationGroup = [
+    cfg.StrOpt('connect_method',
+               default='floating',
+               choices=['fixed', 'floating'],
+               help='Default IP type used for validation: '
+                    '-fixed: uses the first IP belonging to the fixed network '
+                    '-floating: creates and uses a floating IP'),
+    cfg.StrOpt('auth_method',
+               default='keypair',
+               choices=['keypair'],
+               help='Default authentication method to the instance. '
+                    'Only ssh via keypair is supported for now. '
+                    'Additional methods will be handled in a separate spec.'),
+    cfg.IntOpt('ip_version_for_ssh',
+               default=4,
+               help='Default IP version for ssh connections.'),
+    cfg.IntOpt('ping_timeout',
+               default=120,
+               help='Timeout in seconds to wait for ping to succeed.'),
+    cfg.IntOpt('connect_timeout',
+               default=60,
+               help='Timeout in seconds to wait for the TCP connection to be '
+                    'successful.'),
+    cfg.IntOpt('ssh_timeout',
+               default=300,
+               help='Timeout in seconds to wait for the ssh banner.'),
+]
+
 volume_group = cfg.OptGroup(name='volume',
                             title='Block Storage Options')
 
@@ -1088,6 +1126,7 @@
     (network_group, NetworkGroup),
     (network_feature_group, NetworkFeaturesGroup),
     (messaging_group, MessagingGroup),
+    (validation_group, ValidationGroup),
     (volume_group, VolumeGroup),
     (volume_feature_group, VolumeFeaturesGroup),
     (object_storage_group, ObjectStoreGroup),
@@ -1148,6 +1187,7 @@
         self.image_feature_enabled = _CONF['image-feature-enabled']
         self.network = _CONF.network
         self.network_feature_enabled = _CONF['network-feature-enabled']
+        self.validation = _CONF.validation
         self.volume = _CONF.volume
         self.volume_feature_enabled = _CONF['volume-feature-enabled']
         self.object_storage = _CONF['object-storage']
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 65d516f..d2c41f0 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -309,8 +309,13 @@
         if isinstance(server_or_ip, six.string_types):
             ip = server_or_ip
         else:
-            addr = server_or_ip['addresses'][CONF.compute.network_for_ssh][0]
-            ip = addr['addr']
+            addrs = server_or_ip['addresses'][CONF.compute.network_for_ssh]
+            try:
+                ip = (addr['addr'] for addr in addrs if
+                      netaddr.valid_ipv4(addr['addr'])).next()
+            except StopIteration:
+                raise lib_exc.NotFound("No IPv4 addresses to use for SSH to "
+                                       "remote server.")
 
         if username is None:
             username = CONF.scenario.ssh_user
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 8353048..2c4522d 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -318,11 +318,15 @@
             LOG.info(msg)
             return
 
-        subnet = self._list_subnets(
-            network_id=CONF.network.public_network_id)
-        self.assertEqual(1, len(subnet), "Found %d subnets" % len(subnet))
+        # We ping the external IP from the instance using its floating IP
+        # which is always IPv4, so we must only test connectivity to
+        # external IPv4 IPs if the external network is dualstack.
+        v4_subnets = [s for s in self._list_subnets(
+            network_id=CONF.network.public_network_id) if s['ip_version'] == 4]
+        self.assertEqual(1, len(v4_subnets),
+                         "Found %d IPv4 subnets" % len(v4_subnets))
 
-        external_ips = [subnet[0]['gateway_ip']]
+        external_ips = [v4_subnets[0]['gateway_ip']]
         self._check_server_connectivity(self.floating_ip_tuple.floating_ip,
                                         external_ips)
 
diff --git a/tempest/services/compute/json/flavors_client.py b/tempest/services/compute/json/flavors_client.py
index 25b1869..2de43cf 100644
--- a/tempest/services/compute/json/flavors_client.py
+++ b/tempest/services/compute/json/flavors_client.py
@@ -16,11 +16,10 @@
 import json
 import urllib
 
-from tempest.api_schema.response.compute import flavors as common_schema
 from tempest.api_schema.response.compute import flavors_access as schema_access
 from tempest.api_schema.response.compute import flavors_extra_specs \
     as schema_extra_specs
-from tempest.api_schema.response.compute.v2_1 import flavors as v2schema
+from tempest.api_schema.response.compute.v2_1 import flavors as schema
 from tempest.common import service_client
 
 
@@ -33,7 +32,7 @@
 
         resp, body = self.get(url)
         body = json.loads(body)
-        self.validate_response(common_schema.list_flavors, resp, body)
+        self.validate_response(schema.list_flavors, resp, body)
         return service_client.ResponseBodyList(resp, body['flavors'])
 
     def list_flavors_with_detail(self, params=None):
@@ -43,13 +42,13 @@
 
         resp, body = self.get(url)
         body = json.loads(body)
-        self.validate_response(v2schema.list_flavors_details, resp, body)
+        self.validate_response(schema.list_flavors_details, resp, body)
         return service_client.ResponseBodyList(resp, body['flavors'])
 
     def get_flavor_details(self, flavor_id):
         resp, body = self.get("flavors/%s" % str(flavor_id))
         body = json.loads(body)
-        self.validate_response(v2schema.create_get_flavor_details, resp, body)
+        self.validate_response(schema.create_get_flavor_details, resp, body)
         return service_client.ResponseBody(resp, body['flavor'])
 
     def create_flavor(self, name, ram, vcpus, disk, flavor_id, **kwargs):
@@ -73,13 +72,13 @@
         resp, body = self.post('flavors', post_body)
 
         body = json.loads(body)
-        self.validate_response(v2schema.create_get_flavor_details, resp, body)
+        self.validate_response(schema.create_get_flavor_details, resp, body)
         return service_client.ResponseBody(resp, body['flavor'])
 
     def delete_flavor(self, flavor_id):
         """Deletes the given flavor."""
         resp, body = self.delete("flavors/{0}".format(flavor_id))
-        self.validate_response(v2schema.delete_flavor, resp, body)
+        self.validate_response(schema.delete_flavor, resp, body)
         return service_client.ResponseBody(resp, body)
 
     def is_resource_deleted(self, id):
@@ -137,7 +136,7 @@
         """Unsets extra Specs from the mentioned flavor."""
         resp, body = self.delete('flavors/%s/os-extra_specs/%s' %
                                  (str(flavor_id), key))
-        self.validate_response(v2schema.unset_flavor_extra_specs, resp, body)
+        self.validate_response(schema.unset_flavor_extra_specs, resp, body)
         return service_client.ResponseBody(resp, body)
 
     def list_flavor_access(self, flavor_id):
diff --git a/tempest/services/compute/json/hosts_client.py b/tempest/services/compute/json/hosts_client.py
index de925a9..088e695 100644
--- a/tempest/services/compute/json/hosts_client.py
+++ b/tempest/services/compute/json/hosts_client.py
@@ -15,8 +15,7 @@
 import json
 import urllib
 
-from tempest.api_schema.response.compute import hosts as schema
-from tempest.api_schema.response.compute.v2_1 import hosts as v2_schema
+from tempest.api_schema.response.compute.v2_1 import hosts as schema
 from tempest.common import service_client
 
 
@@ -39,7 +38,7 @@
 
         resp, body = self.get("os-hosts/%s" % str(hostname))
         body = json.loads(body)
-        self.validate_response(schema.show_host_detail, resp, body)
+        self.validate_response(schema.get_host_detail, resp, body)
         return service_client.ResponseBodyList(resp, body['host'])
 
     def update_host(self, hostname, **kwargs):
@@ -54,7 +53,7 @@
 
         resp, body = self.put("os-hosts/%s" % str(hostname), request_body)
         body = json.loads(body)
-        self.validate_response(v2_schema.update_host, resp, body)
+        self.validate_response(schema.update_host, resp, body)
         return service_client.ResponseBody(resp, body)
 
     def startup_host(self, hostname):
@@ -62,7 +61,7 @@
 
         resp, body = self.get("os-hosts/%s/startup" % str(hostname))
         body = json.loads(body)
-        self.validate_response(v2_schema.startup_host, resp, body)
+        self.validate_response(schema.startup_host, resp, body)
         return service_client.ResponseBody(resp, body['host'])
 
     def shutdown_host(self, hostname):
@@ -70,7 +69,7 @@
 
         resp, body = self.get("os-hosts/%s/shutdown" % str(hostname))
         body = json.loads(body)
-        self.validate_response(v2_schema.shutdown_host, resp, body)
+        self.validate_response(schema.shutdown_host, resp, body)
         return service_client.ResponseBody(resp, body['host'])
 
     def reboot_host(self, hostname):
@@ -78,5 +77,5 @@
 
         resp, body = self.get("os-hosts/%s/reboot" % str(hostname))
         body = json.loads(body)
-        self.validate_response(v2_schema.reboot_host, resp, body)
+        self.validate_response(schema.reboot_host, resp, body)
         return service_client.ResponseBody(resp, body['host'])
diff --git a/tempest/services/compute/json/keypairs_client.py b/tempest/services/compute/json/keypairs_client.py
index 722aefa..7fe335b 100644
--- a/tempest/services/compute/json/keypairs_client.py
+++ b/tempest/services/compute/json/keypairs_client.py
@@ -15,7 +15,6 @@
 
 import json
 
-from tempest.api_schema.response.compute import keypairs as common_schema
 from tempest.api_schema.response.compute.v2_1 import keypairs as schema
 from tempest.common import service_client
 
@@ -30,7 +29,7 @@
         # servers, etc. A bug?
         # For now we shall adhere to the spec, but the spec for keypairs
         # is yet to be found
-        self.validate_response(common_schema.list_keypairs, resp, body)
+        self.validate_response(schema.list_keypairs, resp, body)
         return service_client.ResponseBodyList(resp, body['keypairs'])
 
     def get_keypair(self, key_name):
diff --git a/tempest/services/compute/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
index 89f4acd..6e38c47 100644
--- a/tempest/services/compute/json/quotas_client.py
+++ b/tempest/services/compute/json/quotas_client.py
@@ -31,7 +31,7 @@
             url += '?user_id=%s' % str(user_id)
         resp, body = self.get(url)
         body = json.loads(body)
-        self.validate_response(schema.quota_set, resp, body)
+        self.validate_response(schema.get_quota_set, resp, body)
         return service_client.ResponseBody(resp, body['quota_set'])
 
     def get_default_quota_set(self, tenant_id):
@@ -40,7 +40,7 @@
         url = 'os-quota-sets/%s/defaults' % str(tenant_id)
         resp, body = self.get(url)
         body = json.loads(body)
-        self.validate_response(schema.quota_set, resp, body)
+        self.validate_response(schema.get_quota_set, resp, body)
         return service_client.ResponseBody(resp, body['quota_set'])
 
     def update_quota_set(self, tenant_id, user_id=None,
@@ -105,7 +105,7 @@
                                   post_body)
 
         body = json.loads(body)
-        self.validate_response(schema.quota_set_update, resp, body)
+        self.validate_response(schema.update_quota_set, resp, body)
         return service_client.ResponseBody(resp, body['quota_set'])
 
     def delete_quota_set(self, tenant_id):
@@ -123,7 +123,7 @@
         url = 'os-quota-class-sets/%s' % str(quota_class_id)
         resp, body = self.get(url)
         body = json.loads(body)
-        self.validate_response(classes_schema.quota_set, resp, body)
+        self.validate_response(classes_schema.get_quota_class_set, resp, body)
         return service_client.ResponseBody(resp, body['quota_class_set'])
 
     def update_quota_class_set(self, quota_class_id, **kwargs):
@@ -136,5 +136,6 @@
                               post_body)
 
         body = json.loads(body)
-        self.validate_response(classes_schema.quota_set_update, resp, body)
+        self.validate_response(classes_schema.update_quota_class_set,
+                               resp, body)
         return service_client.ResponseBody(resp, body['quota_class_set'])
diff --git a/tempest/tests/common/utils/linux/test_remote_client.py b/tempest/tests/common/utils/linux/test_remote_client.py
index 40b7b32..d6377e6 100644
--- a/tempest/tests/common/utils/linux/test_remote_client.py
+++ b/tempest/tests/common/utils/linux/test_remote_client.py
@@ -100,15 +100,17 @@
         self._assert_exec_called_with('cut -f1 -d. /proc/uptime')
 
     def test_ping_host(self):
-        ping_response = """PING localhost (127.0.0.1) 56(84) bytes of data.
-64 bytes from localhost (127.0.0.1): icmp_req=1 ttl=64 time=0.048 ms
+        ping_response = """PING localhost (127.0.0.1) 70(98) bytes of data.
+78 bytes from localhost (127.0.0.1): icmp_req=1 ttl=64 time=0.048 ms
+78 bytes from localhost (127.0.0.1): icmp_req=2 ttl=64 time=0.048 ms
 
 --- localhost ping statistics ---
-1 packets transmitted, 1 received, 0% packet loss, time 0ms
+2 packets transmitted, 2 received, 0% packet loss, time 0ms
 rtt min/avg/max/mdev = 0.048/0.048/0.048/0.000 ms"""
         self.ssh_mock.mock.exec_command.return_value = ping_response
-        self.assertEqual(self.conn.ping_host('127.0.0.1'), ping_response)
-        self._assert_exec_called_with('ping -c1 -w1 127.0.0.1')
+        self.assertEqual(self.conn.ping_host('127.0.0.1', count=2, size=70),
+                         ping_response)
+        self._assert_exec_called_with('ping -c2 -w2 -s70 127.0.0.1')
 
     def test_get_mac_address(self):
         macs = """0a:0b:0c:0d:0e:0f