OpenStack Tempest

 目录

 

1.Tempest测试框架介绍

  A.概念

  B.具体内容

  C.原理

  D.优缺点

2.Tempest的安装配置

  A.安装

  B.初始化

  C.修改配置

 

3.Tempest执行测试(命令)

  A.执行测试(命令语句,格式)

  B.执行部分用例

  C.断点单步调试

 

4.Tempest代码结构、文件目录

  A.目录结构

  B.代码结构

  C.tempest.conf结构

 

5.Tempest测试

  A.API测试用例(流程图,结果)

   

 

 

 

 

 1.Tempest测试框架介绍

  a.Tempest 是 Openstack 的测试框架。和 Openstack 类似,Tempest 由社区人员维护。Tempest 测试框架包含 Openstack基本组件(nova, keystone, glance, quantum, cinder)的测试用例,同时支持 JSON、XML 两种 REST API 格式类型的测试, 以及 CLI 测试。

   Tempest为OpenStack的功能测试、集成测试项目,它被设计为可在各种不同项目中使用。在OpenStack核心项目中的单元测试代码中经常可以看到它的身影,在一些孵化项目中也会使用Tempest去测试。它可以验证代码的正确性,已经成为OpenStack项目中不可或缺的组成部分。

 

 b.Tempest具体内容

├── api # API的测试集

├── cli # OpenStack的命令行工具测试集

├── common # 一些公共的工具类和函数

├── scenario # 对OpenStack的常用场景进行测试,包括基本的启动VM,挂载volumn和网络配置等

├── services # tempest自己实现的OpenStack API Client,自己实现是为了不让一些bug隐藏在官方实现的Client里面。

├── stress # 压力测试集,利用multiprocessing来启动多个进程来同时对OpenStack发起请求。

├── thirdparty # EC2兼容的API测试集

├── whitebox # 白盒测试集,主要是对DB操作,然后发起请求,然后比对结果

 c.tempest是通过nose驱动的,python语言编写,使用testtools和testresources等几个测试工具库

 d.Tempest流程:1.调用各个Openstack组件的API

                 2.验证API返回的结果

 

 e.Tempest的优点

  1.Tempet可以自动寻找,执行测试:自动查找当前目录下所有以(T)test开头的Python源文件,并且按此规则递归查找子目录;所有以(T)test开头的Python源文件面的所有以(T)test开头的function和class,以及继承自unittest.TestCase的class(不需要test开头)都会被执行。

  2.Tempest可以指定文件、模块、函数进行测试。

  3.Tempest可以指定类型进行测试。

  4.Tempest可扩展性强,可以方便的在tempest中添加其他测试用例,可以整合其他类型测试如压力测试、场景测试等。

 

  f.tempest缺点

   对于每一套不一样的openstack环境,都要手工修改相关的配置项tempest.conf文件。(至少要修改user ids, openstack endpoints,  images id、password等).假如你要测试openstack的全部服务,那你得配置几十项内容,得花费不少时间。显然这非常不智能、且很愚笨。

 

 

 

 

 

2.Tempest的安装配置

 A.安装 #得先pip设置代理,不然容易出错

        

  a.首先得有装有openstack环境的物理机(本例使用secureCRT连接虚拟机192.168.0.25)

  b.$source keystonerc_admin                        #使用admin登录

  c.$git clone https://github.com/openstack/tempest/      #下载源码

   ( Tempest 下载地址 https://github.com/openstack/tempest

     下载的源码在/root/tempest/tempest目录下)

 在tempest目录下

 d.$pip install tempest                      #安装tempest项目                

*如果pip install报错,比如某个Python包版本冲突或者之类的,可以先执行下

$ pip install -r tempest/requirements.txt               #安装Python依赖包,然后再执

                                                  行d步命令

 B.初始化

  e.$ tempest init hunter-tempest-01                   #初始化测试环境目录

   (此步骤相当于如下命令:

    $mkdir hunter-tempest-01 && cd my-tempest-env-01 &&tempest init   )

 

 C.修改配置

   f.初始化测试环境目录过程中,会在测试环境目录hunter-tempest-01下自动生成如下目                         录

$ etc  logs  tempest_lock

其中etc目录下生成了tempest.conf.sample示例配置文件,我们修改好这个文件并重命名为tempest.conf。

下面是修改完毕的配置文件和初始化完毕的示例配置文件的diff结果

 

root@control-1:~#diff origin-sample-conf/etc/tempest.conf.samplemy-tempest-env-01/etc/tempest.conf -u

 --- origin-sample-conf/etc/tempest.conf.sample  2015-12-23 20:07:37.703580165 +0800

 +++ my-tempest-env-01/etc/tempest.conf  2015-12-23 19:45:27.390680269 +0800

 @@ -178,19 +178,19 @@

  # authenticating requests made by tenantisolation to create users and

  # projects (string value)

  # Deprecated group/name -[identity]/admin_username

 -#admin_username =

 +admin_username = admin

 

  # Tenant name to use for an  administrative user. This is needed for

  # authenticating requests made by tenantisolation to create users and

  # projects (string value)

  # Deprecated group/name -[identity]/admin_tenant_name

 -#admin_tenant_name =

 +admin_tenant_name = admin

 

  # Password to use for an  administrative user. This is needed for

  # authenticating requests made by tenantisolation to create users and

  # projects (string value)

  # Deprecated group/name -[identity]/admin_password

 -#admin_password =

 +admin_password = admin                                   #管理员模式下的用户名密码

 

 

  # Admin domain name for authentication(Keystone V3).The same domain

  # applies to user and project (string value)

 @@ -290,18 +290,18 @@

 

  # Valid primary image reference to be used intests. This is a

  # required option (string value)

 -#image_ref =

 +image_ref =643ea9b2-f2f8-408e-ab37-309494e82832     # ubuntu-12.04-root_qwerty-ubuntu_ubuntu

 

  # Valid secondary image reference to be usedin tests. This is a

  # required option, but if only one image isavailable duplicate the

  # value of image_ref above (string value)

 -#image_ref_alt =

 +image_ref_alt =42074fa5-231c-48f2-9db1-e283a5ea5b10    #Centos

 

#这两组数据是glance服务里面的两个imageID,通过 #glance image-list命令可以取得所有的image id,如果需要可以专门上传两个imagetempest使用。

 

  # Valid primary flavor to use in tests.(string value)

 -#flavor_ref = 1

 +flavor_ref = 1                         #m1,tiny

 

  # Valid secondary flavor to be used in tests.(string value)

 -#flavor_ref_alt = 2

 +flavor_ref_alt = 2                      #m1.small

    #这两组数据是tempest创建instance测试用例使用的flavor id参数。通过 $nova flavor-list命令可以看到当前openstack环境的所有flavor,默认情况下,openstack会创建5flavor, 这里的12分别代表的是m1.tinym1.small

 

 

  # Time in seconds between build statuschecks. (integer value)

  #build_interval = 1

 @@ -320,7 +320,7 @@

  # which will be used for creating servers iftempest does not create a

  # network or a network is not specifiedelsewhere. It may be used for

  # ssh validation only if floating IPs aredisabled. (string value)

 -#fixed_network_name =

 +fixed_network_name = public           #networkname,可通过neutron net-list找到

                                

  # Catalog type of the Compute service.(string value)

  #catalog_type = compute

 @@ -590,14 +590,14 @@

  #ca_certificates_file =

 

  # Full URI of the OpenStack Identity API(Keystone), v2 (string value)

 -#uri =

 +uri=http://192.168.0.100:5000/v2.0/   #测试的后端定为100openstack服务的主机IP,也就是keystone服务所在节点的IP,默认是192.168.0.100,也就是本地地址;keystone认证API地址,包含端口和版本号

  # Full URI of the OpenStack Identity API(Keystone), v3 (string value)

  #uri_v3 =

 

  # Identity API version to be used forauthentication for API tests.

  # (string value)

 -#auth_version = v2

      +auth_version = v2            #用于API测试的versionv2

 

 

  # The identity region name to use. Also usedas the other services'

  # region name unless they are set explicitly.If no such region is

 @@ -624,12 +624,12 @@

  # Username to use for Nova API requests.(string value)

  # This option is deprecated for removal.

  # Its value may be silently ignored in thefuture.

 -#username =

 +username = demo

 

  # Tenant name to use for Nova API requests.(string value)

  # This option is deprecated for removal.

  # Its value may be silently ignored in thefuture.

 -#tenant_name =

 +tenant_name = demo

 

  # Role required to administrate keystone.(string value)

  #admin_role = admin

 @@ -637,7 +637,7 @@

  # API key to use when authenticating. (stringvalue)

  # This option is deprecated for removal.

  # Its value may be silently ignored in thefuture.

 -#password =

 +password = demo

                               #非管理员用户操作的用户名密码

  # Domain name for authentication (KeystoneV3).The same domain applies

  # to user and project (string value)

 @@ -683,10 +683,10 @@

  #trust = true

 

  # Is the v2 identity API enabled (booleanvalue)

 -#api_v2 = true

 +api_v2 = true

                                #v2 api可以激活

  # Is the v3 identity API enabled (booleanvalue)

 -#api_v3 = true

 +api_v3 = false

                                #v3 api不可以激活

  # A list of enabled identity extensions witha special entry all which

  # indicates every extension is enabled. Emptylist indicates all

 @@ -851,7 +851,7 @@

 

  # Id of the public network that providesexternal connectivity (string

  # value)

 -#public_network_id =

 +#public_network_id =             

 

  # Default floating network name. Used toallocate floating IPs when

  # neutron is enabled. (string value)

 @@ -891,7 +891,7 @@

  #

 

  # Allow the execution of IPv6 tests (booleanvalue)

 -#ipv6 = true

 +ipv6 = false

                              #ipv6不可用

  # A list of enabled network extensions with aspecial entry all which

  # indicates every extension is enabled. Emptylist indicates all

 @@ -1086,32 +1086,32 @@

  #

 

  # Whether or not cinder is expected to be available(boolean value)

 -#cinder = true

 +cinder = false

                                      #cinder不可用

  # Whether or not neutron is expected to beavailable (boolean value)

 -#neutron = false

 +neutron = true

                                     #neutron可用

  # Whether or not glance is expected to beavailable (boolean value)

 -#glance = true

 +glance = true

                                     #glance可用

  # Whether or not swift is expected to beavailable (boolean value)

 -#swift = true

 +swift = false

                                       #swift不可用

  # Whether or not nova is expected to beavailable (boolean value)

 -#nova = true

 +nova = true

                                        #nova可用

  # Whether or not Heat is expected to beavailable (boolean value)

  #heat = false

 

  # Whether or not Ceilometer is expected to beavailable (boolean

  # value)

 -#ceilometer = true

 +ceilometer = true

                                         #ceilometer可用

  # Whether or not Aodh is expected to beavailable (boolean value)

  #aodh = false

 

  # Whether or not Horizon is expected to beavailable (boolean value)

 -#horizon = true

 +horizon = true

                                   #horizon可用

  # Whether or not Sahara is expected to beavailable (boolean value)

  #sahara = false

我整理了一个tempest具体配置.word文档,里面标着红色的字体是需要修改的地方。配置完毕并将文件重命名为tempest.conf,就可以执行tempest测试了。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3.Tempest执行测试(命令)

 *执行测试需要在修改好配置文件的测试环境配置目录下进行。

A.执行全部测试用例(有几种方式可以执行tempest测试)

  a.$ testr run

  b.$ testr run --parallel       #并发测试,注意是双横杠

 (并发测试:主要指当测试多个用户并同时访问同一个应用程序、同一个模块数据记录时是否存在死锁或其他性能问题,几乎所有的性能测试都会涉及并发测试。)

 

  c.$ testr help run               #查看testr的帮助文档查看更多参数

  d.$ nosetests -v tempest        #效果和tests run一样

 

执行完毕后会有类似如图的效果:

(对此结果的解读:测试了651个文件总共用时3447.950s,整个测试结果是失败的,其中skip(跳过)了18个,errors(脚本的错误)有272个,faliures(测试失败)81次)

 

*测试结果

--Tempest中的测试结果有4种:测试错误(Error)、测试失败(Failure)、跳过(Skip)、成功(success)

-- 测试错误:可以简单理解成测试代码执行时候报错了,比如:测试代码中print a,而a没有进行变量声明。跟setUp类似,如果代码在这个阶段出错,也都会认为是测试错误(Error)。

-- 测试失败:可以简单理解成测试代码执行正常,但没有得到预期的测试结果,比如:测试代码中调用功能代码add(1, 2),但返回结果不是3。

-- 跳过:也可以理解为测试忽略(Ignore),比如:某个测试只想在Windows下才运行,这样在Linux下就会被跳过,也就是忽略。

-- 成功:TestCase执行成功。

error也可能是配置环境有问题,产生skip可能是被测试的服务有bug

 

 

 

 

 

 

 

 

B.执行部分用例

  e.可以按照目录+文件++方法的方式执行某个特定用例,比如$ testrrun tempest.api.compute.servers.test_servers_negative.ServerNegativeTestJSON.test_reboot_non_existent_server

 

  f.也可以执行某个文件中的所有用例,比如:

   $testr runtempest.api.compute.servers.test_servers_negative

 

  g.或者一个类的所有用例:

   $ testr runtempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON

 

  h.还可以用python -m testtools.run来执行部分用例,比如:$  python -m testtools.runtempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_reboot_non_existent_server   (同样可以用python -m testtools.run来执行某个文件或某个类的全部用例,用法与testr run相同)

 

 

 

 

   i. nosetests 命令来执行部分用例也是一样的用法,不过要加上-s参数,

比如:

$nosetests   -sv  testtools.run\ tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_reboot_non_existent_server

 

C.断点单步调试

 如果某个用例执行出错,需要加入断点单步调试,可以用pdb调试库来完成调试工作,建议用ipdb库来调试,这个库更智能易用,它的缺点是不是Python系统库,需要手工安装才能使用。

$pip install ipdb       #ipdb库的安装

如果要加入断点单步调试,需要使用python-m testtools.run方法来执行被调试的用例,否则可能导致断点无法进入,也就没办法进行单步调试

tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_reboot_non_existent_server用例为例进行说明,这里使用的是ipdb,pdb也是类似:

  149    @test.attr(type=['negative'])

  150    @test.idempotent_id('d4c023a0-9c55-4747-9dd5-413b820143c7')

  151     deftest_reboot_non_existent_server(self):

  152         importipdb;ipdb.set_trace()       #此处加入了断点

  153         # Reboot a non existent server

  154         nonexistent_server =data_utils.rand_uuid()

  155        self.assertRaises(lib_exc.NotFound, self.client.reboot_server,

  156                          nonexistent_server, type='SOFT')

 

 

4..Tempest目录、代码结构及测试

  A.目录结构

  

 

 

 

1)api:API的测试集。

2)cli:OpenStack的命令行工具测试集。

3)common:一些公共的工具类和函数。

4)scenario:对OpenStack的常用场景进行测试,包括基本的启动虚拟机、挂载volume和网络配置等。

5)services:Tempest实现的OpenStack API Client,主要是避免官方Client中含有Bug。

6)stress:压力测试集,利用多进程(multiprocessing)同时对OpenStack发起请求进行测试。

7)thirdparty:EC2等第三方兼容API测试集。

8)whitebox:白盒测试集。

 

 

 

 

 

 

 

 

 

 

 

 

B.代码结构

   

 

 

 

 

C.Tempest.conf文件

  Tempest里有一个很重要的文件,就是我们修改过配置的tempest.conf文件,在tempest.conf文件中分为以下session,这些session需要和测试的Openstack环境匹配

 

[identity]      – 这个 session 主要包括user/tenant 相关的权限认证测试

[compute]     – 这个 session 主要包括 OS ComputeAPI/CLI 相关测试

[whitebox]     – 这个 session 主要包括查看 Nova 数据库状态,ssh 到虚机中查看其状态等   

[image]        – 这个 session 主要包括 OS 镜像 API/CLI 相关测试

[network]      – 这个 session 主要包括 OS 网络 API/CLI 相关测试

[volume]       – 这个 session 主要包括 OS Cinder 存储 API/CLI 相关测试

[object-storage] – 这个 session 主要包括 OS Swift 对象存储 API/CLI 相关测试

 

 

D.Tempest README.rst

 tempest主要包括:API测试,命令行测试,复杂场景测试,压力测试,第三方API测试。

 每一项都对应tempest中的一个目录,每个目录中包含不同类型的测试。

#/root/tempest/README.rst中记录着每个目录的作用,以及良好的测试实例及测试规则

 

 

5.Tempest测试

 A.API测试用例

  tempest.api是openstack api测试用例集

 现以tempest.api.compute.flavors.test_flavors.FlavorsV2TestJSON.test_list_flavors为例:

各类间的继承和调用:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

FlavorV2TestJSO.test_list_flavors继承自BaseV2ComputeTest。Clients是负责管理包括FlavorsClient在内的所有的openstackclients的,同时调用TempestConfig来读取配置文件tempest.conf。FlavorsClient继承自RestClient,封装了访问openstackapi的接口。FlavorsV2TestJSON通过FlavorsClient来实现对openstackapi的访问。

 

源码:

 

classFlavorsV2TestJSON(base.BaseV2ComputeTest):  #父类

    _min_disk = 'minDisk'

    _min_ram = 'minRam'

 

    @classmethod

    def setup_clients(cls):

        super(FlavorsV2TestJSON,cls).setup_clients()

        cls.client = cls.flavors_client

 

    @test.attr(type='smoke')

   @test.idempotent_id('e36c0eaa-dff5-4082-ad1f-3f9a80aa3f59')

    deftest_list_flavors(self):                   #子类

        # List of all flavors should containthe expected flavor

        flavors =self.client.list_flavors()['flavors']

        flavor =self.client.show_flavor(self.flavor_ref)['flavor']

        flavor_min_detail = {'id':flavor['id'], 'links': flavor['links'],

                             'name':flavor['name']}

        self.assertIn(flavor_min_detail,flavors)

 

   @test.idempotent_id('6e85fde4-b3cd-4137-ab72-ed5f418e8c24')

    def test_list_flavors_with_detail(self):

        # Detailed list of all flavors shouldcontain the expected flavor

        flavors = self.client.list_flavors(detail=True)['flavors']

        flavor =self.client.show_flavor(self.flavor_ref)['flavor']

        self.assertIn(flavor, flavors)

 

 

 

 

 

 (测试结果)

 

 

 

 

 

 

你可能感兴趣的:(openstack)