美文网首页
jenkins-pipeline实践 - tempest

jenkins-pipeline实践 - tempest

作者: writeme | 来源:发表于2018-05-24 18:10 被阅读89次
    properties([
        buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '60', numToKeepStr: '')),
        parameters([
            string(defaultValue: '', description: 'auth url', name: 'auth_url'),
            password(defaultValue: '', description: 'admin password', name: 'password'),
            string(defaultValue: 'identity image volume network compute', description: 'services', name: 'services'),
            string(defaultValue: '', description: 'testcase label.eg: smoke', name: 'label'),
        ]),
    ])
     
     
    node('tempest') { timestamps{
        println(params)
        auth_url = params.get('auth_url')
        project_domain_name = 'Default'
        user_domain_name = 'Default'
        project_name = 'admin'
        username = 'admin'
        password = params.get('password')
     
        services = params.get('services').split()
        label = params.get('label')
     
        emailto = [
        ].join(',')
        date_s = sh(returnStdout: true, script: "date +%s").trim()
       
        tempest_version = '10'
        venv = "tempest-${tempest_version}"
        host = "${auth_url.split('://')[1].split('/')[0].split(':')[0]}"
        workspace = "${venv}-${host}"
       
        resultmap = [:]
       
        try {
            stage('prepare') {
                sh """
                    yum install epel-release -y
                    yum install python-pip -y
                    yum install python-devel -y
                    yum install gcc -y
                    yum install jq -y
                    pip install tox
                """
                dir(env.WORKSPACE) {
                    withEnv(["venv=${venv}", "tempest_version=${tempest_version}"]) { sh '''
                        virtualenv --no-site-packages ${venv}
                        source ${venv}/bin/activate
       
                        pip install tempest==${tempest_version}  # Todo: 1 install from git; 2 plugins
                        pip install python-openstackclient
                        pip install junitxml
       
                        python_lib_dir=`python -c \'from distutils.sysconfig import get_python_lib; print(get_python_lib())\'`
                        cp -fu $python_lib_dir/tempest/lib/common/rest_client.py{,.bak}
                        cp -fu $python_lib_dir/tempest/cmd/cleanup_service.py{,.bak}
                        sed -i \'/def validate_response(.*):$/ a\\        return\' $python_lib_dir/tempest/lib/common/rest_client.py
                        sed  -i \'/def _get_network_id/,/return/s/if (net\\[\'\\\'\'\\([a-z_]*\\)\'\\\'\'\\] == \\([a-z_]*\\) and net\\[\'\\\'\'name\'\\\'\'\\] == net_name):/if (net.get(\'\\\'\'\\1\'\\\'\') == \\2 and net\\[\'\\\'\'name\'\\\'\'\\] == net_name):/\' $python_lib_dir/tempest/cmd/cleanup_service.py
                    '''}
                }
            }
       
            withEnv(["PATH=${env.WORKSPACE}/${venv}/bin:${env.PATH}"]) {
                stage('init') { dir(env.WORKSPACE) {
                    sh """
                    rm -rf ${workspace}/{*,.[!.]*}
                    mkdir -p ${workspace} && cd ${workspace} && tempest init
                    mkdir -p output/${date_s}
                    """
                }}
       
                stage('config') {
                    def osc = "openstack --os-auth-url ${auth_url} --os-identity-api-version 3 --os-project-domain-name ${project_domain_name} --os-user-domain-name ${user_domain_name} --os-project-name ${project_name} --os-username ${username} --os-password ${password}"
     
                    def public_network_name = 'provider'
                    def public_network_id = sh(returnStdout: true, script: "${osc} network list -f json | jq '.[] | select(.Name==\"${public_network_name}\") | .ID' | head -n 1 | tr -d '\"'").trim()
     
                    def fixed_network_name = 'tempest_tenant_net'
                    def fixed_network_id = sh(returnStdout: true, script: "${osc} network list -f json | jq '.[] | select(.Name==\"${fixed_network_name}\") | .ID' | head -n 1 | tr -d '\"'").trim()
                    if(! fixed_network_id) {
                        sh "${osc} network create --share --enable ${fixed_network_name}"
                        fixed_network_id = sh(returnStdout: true, script:"${osc} subnet create --network ${fixed_network_name} --dns-nameserver 8.8.4.4 --gateway 172.16.1.1 --subnet-range 172.16.1.0/24 ${fixed_network_name}_subnet -f value -c id").trim()
                    }
     
                    def public_router_name = 'tempest_router'
                    def public_router_id = sh(returnStdout: true, script: "${osc} router list -f json | jq '.[] | select(.Name==\"${public_router_name}\") | .ID' | head -n 1 | tr -d '\"'").trim()
                    if(! public_router_id) {
                        public_router_id = sh(returnStdout: true, script: "${osc} router create ${public_router_name} -f value -c id").trim()
                        sh "${osc} router set --external-gateway provider ${public_router_name}"
                    }
    
                    def image_id = sh(returnStdout: true, script: "${osc} image list -f json | jq '.[] | select(.Name==\"cirros\") | .ID' | head -n 1 | tr -d '\"'").trim()
                    if(! image_id) {
                        image_id = sh(returnStdout: true, script: "${osc} image create cirros --file /opt/tempest/cirros-*.img --disk-format qcow2 --container-format bare --public -f value -c id").trim()
                    }
       
                    sh """
                    cat <<EOF | tee ${workspace}/etc/tempest.conf
    [DEFAULT]
    debug = true
    log_dir = logs
    log_file = tempest.log
    use_stderr = false
    use_syslog = false
       
    [oslo_concurrency]
    lock_path = tempest_lock
       
    [auth]
    use_dynamic_credentials = true
    default_credentials_domain_name = ${project_domain_name}
    tempest_roles = user
    admin_domain_scope = true
    admin_domain_name = ${user_domain_name}
    admin_project_name = ${project_name}
    admin_tenant_name = ${project_name}
    admin_username = ${username}
    admin_password = ${password}
       
    [identity]
    auth_version = v3
    uri_v3 = ${auth_url.split('/v')[0]}/v3
    uri = ${auth_url.split('/v')[0]}/v2.0
       
    [identity-feature-enabled]
    api_v2 = true
    security_compliance = true
       
    [network]
    public_network_id = ${public_network_id}
    floating_network_name = ${public_network_name}
    public_router_id = ${public_router_id}
      
    [network-feature-enabled]
    ipv6 = false
    ipv6_subnet_attributes = false
    api_extensions = all
    port_security = true
    floating_ips = true
       
    [compute]
    min_microversion = 2.1
    max_microversion = 2.25
    flavor_ref = 2
    flavor_ref_alt = 3
    image_ref = ${image_id}
    image_ref_alt = ${image_id}
    fixed_network_name = ${fixed_network_name}
       
    [compute-feature-enabled]
    min_microversion = 2.1
    max_microversion = 2.25
    nova_cert = false
    personality = false
    resize = false
    swap_volume = true
    vnc_console = true
       
    [volume]
    max_microversion = latest
       
    [volume-feature-enabled]
    api_v3 = false
    backup = false
    multi_backend = false
    manage_volume = true
    manage_snapshot = true
    extend_attached_volume = false
      
    [image-feature-enabled]
    api_v1 = false
    deactivate_image = true
       
    [service_available]
    cinder = true
    neutron = true
    glance = true
    swift = false
    nova = true
    heat = true
    ceilometer = false
    aodh = false
    horizon = false
    sahara = false
    ironic = false
    trove = true
       
    [validation]
    run_validation = false
    security_group = true
    security_group_rules = true
    connect_method = floating
    image_ssh_user = cirros
    image_ssh_password = gocubsgo
    network_for_ssh = public
       
    [scenario]
    img_dir = /opt/tempest/
    img_file = cirros-0.4.0-x86_64-disk.img
      
    EOF"""
                }
       
                try {stage('run') {
                    dir("${workspace}") {
                        // sh "tempest verify-config"
                        if(sh(returnStatus: true, script: "tempest cleanup --init-saved-state")){echo 'init-saved-state fail'}
                        sh """
                        stestr init
                        python_lib_dir=` python -c \'from distutils.sysconfig import get_python_lib; print(get_python_lib())\'`
                        cat <<EOF | tee .stestr.conf
    [DEFAULT]
    test_path=\${python_lib_dir}/tempest/test_discover
    top_dir=\${python_lib_dir}/tempest
    EOF
     
                        cat <<EOF | tee blacklist
    tempest\\.api\\.compute\\.images\\.test_images_oneserver\\.ImagesOneServerTestJSON\\.test_create_image_specify_multibyte_character_image_name.*
    tempest\\.api\\.compute\\.images\\.test_images_oneserver_negative\\.ImagesOneServerNegativeTestJSON\\.test_create_second_image_when_first_image_is_being_saved.*
    tempest\\.api\\.compute\\.servers\\.test_delete_server\\.DeleteServersTestJSON\\.test_delete_server_while_in_shelved_state.*
    tempest\\.api\\.compute\\.servers\\.test_delete_server\\.DeleteServersTestJSON.*
    tempest\\.api\\.compute\\.servers\\.test_servers_negative\\.ServersNegativeTestJSON\\.test_delete_server_pass_id_exceeding_length_limit.*
    tempest\\.api\\.compute\\.servers\\.test_server_actions\\.ServerActionsTestJSON\\.test_create_backup.*
    tempest\\.api\\.compute\\.servers\\.test_server_actions\\.ServerActionsTestJSON\\.test_get_console_output_server_id_in_shutoff_status.*
    tempest\\.api\\.compute\\.servers\\.test_server_actions\\.ServerActionsTestJSON\\.test_shelve_unshelve_server.*
    tempest\\.api\\.compute\\.servers\\.test_server_rescue\\.ServerRescueTestJSON.*
    tempest\\.api\\.compute\\.servers\\.test_servers_negative\\.ServersNegativeTestJSON\\.test_delete_server_pass_negative_id.*
    tempest\\.api\\.compute\\.images\\.test_images_oneserver\\.ImagesOneServerTestJSON\\.test_create_delete_image.*
    tempest\\.api\\.compute\\.images\\.test_images_oneserver_negative\\.ImagesOneServerNegativeTestJSON\\.test_delete_image_that_is_not_yet_active.*
    tempest\\.api\\.compute\\.admin\\.test_aggregates_negative\\.AggregatesAdminNegativeTestJSON\\.test_aggregate_list_as_user.*
    tempest\\.api\\.compute\\.admin\\.test_hypervisor_negative\\.HypervisorAdminNegativeTestJSON\\.test_get_hypervisor_list_details_with_non_admin_user.*
    tempest\\.api\\.compute\\.admin\\.test_hypervisor_negative\\.HypervisorAdminNegativeTestJSON\\.test_get_hypervisor_uptime_with_non_admin_user.*
    tempest\\.api\\.compute\\.admin\\.test_hypervisor_negative\\.HypervisorAdminNegativeTestJSON\\.test_search_hypervisor_with_non_admin_user.*
    tempest\\.api\\.compute\\.admin\\.test_hypervisor_negative\\.HypervisorAdminNegativeTestJSON\\.test_show_hypervisor_with_non_admin_user.*
    tempest\\.api\\.compute\\.admin\\.test_hypervisor_negative\\.HypervisorAdminNegativeTestJSON\\.test_get_hypervisor_list_with_non_admin_user.*
    tempest\\.api\\.compute\\.admin\\.test_hypervisor_negative\\.HypervisorAdminNegativeTestJSON\\.test_get_hypervisor_stats_with_non_admin_user.*
    tempest\\.api\\.compute\\.admin\\.test_hypervisor_negative\\.HypervisorAdminNegativeTestJSON\\.test_show_servers_with_non_admin_user.*
    tempest\\.api\\.compute\\.images\\.test_images\\.ImagesTestJSON\\.test_delete_saving_image.*
    tempest\\.api\\.compute\\.floating_ips\\.test_floating_ips_actions\\.FloatingIPsTestJSON.*
    tempest\\.api\\.compute\\.floating_ips\\.test_list_floating_ips\\.FloatingIPDetailsTestJSON.*
    tempest\\.api\\.compute\\.images\\.test_list_image_filters\\.ListImageFiltersTestJSON.*
    tempest\\.api\\.compute\\.flavors\\.test_flavors\\.FlavorsV2TestJSON\\.test_list_flavors.*
    tempest\\.api\\.network\\.admin\\.test_floating_ips_admin_actions\\.FloatingIPAdminTestJSON\\.test_create_list_show_floating_ip_with_tenant_id_by_admin.*
    tempest\\.api\\.network\\.admin\\.test_floating_ips_admin_actions\\.FloatingIPAdminTestJSON.*
    tempest\\.api\\.network\\.test_floating_ips\\.FloatingIPTestJSON\\.test_create_update_floatingip_with_port_multiple_ip_address.*
    tempest\\.api\\.network\\.test_floating_ips\\.FloatingIPTestJSON.*
    tempest\\.api\\.network\\.test_floating_ips_negative\\.FloatingIPNegativeTestJSON\\.test_associate_floatingip_port_ext_net_unreachable.*
    tempest\\.api\\.network\\.test_routers\\.DvrRoutersTest\\.test_convert_centralized_router.*
    tempest\\.api\\.network\\.test_routers_negative\\.DvrRoutersNegativeTest\\.test_router_create_tenant_distributed_returns_forbidden.*
    tempest\\.api\\.network\\.admin\\.test_routers_dvr\\.RoutersTestDVR\\.test_centralized_router_update_to_dvr.*
    tempest\\.api\\.network\\.test_floating_ips\\.FloatingIPTestJSON\\.test_floating_ip_update_different_router.*
    tempest\\.api\\.network\\.test_floating_ips_negative\\.FloatingIPNegativeTestJSON\\.test_create_floatingip_with_port_ext_net_unreachable.*
    tempest\\.api\\.volume\\.admin\\.test_volume_types\\.VolumeTypesV1Test\\.test_volume_crud_with_volume_type_and_extra_specs.*
    tempest\\.api\\.volume\\.admin\\.test_volume_types\\.VolumeTypesV2Test\\.test_volume_crud_with_volume_type_and_extra_specs.*
    EOF
                        """
                        def exitcode=sh(returnStatus: true, script: "stestr run --log-file ./output/${date_s}/result.log --subunit 'api\\.(${services.join("|")}).*\\[.*${label}.*\\]' --blacklist-file blacklist --concurrency 4 | tee ./output/${date_s}/subunit.out | subunit-trace")
                        _ = sh(returnStatus: true, script: "subunit2junitxml ./output/${date_s}/subunit.out -o ./output/${date_s}/result.xml")
                        _ = sh(returnStatus: true, script: "subunit2html ./output/${date_s}/subunit.out ./output/${date_s}/result.html")
                        _ = sh(returnStatus: true, script: "subunit-filter --error --failure --no-skip ./output/${date_s}/subunit.out | subunit-ls")
                        if(exitcode) {error 'FAIL'}
                    }
                }} catch(Exception ex) {resultmap['run'] = false; echo ex.toString()}
            }
        } catch(Exception ex) {
            echo ex.toString()
            resultmap['ALL'] = false
        } finally {
            stage('report') {
                sh "cp -Rfu ${workspace}/{logs,output/${date_s}} ${WORKSPACE}"
                archiveArtifacts allowEmptyArchive: true, artifacts: "${date_s}/*, logs/*"
                junit allowEmptyResults: true, healthScaleFactor: 10.0, testDataPublishers: [[$class: 'AttachmentPublisher']], testResults: "${date_s}/*.xml"
       
                if(resultmap.any {entry -> entry.value == false}) {
                    currentBuild.result = 'FAILURE'
                    echo currentBuild.result
                }
    
                if(fileExists("${date_s}/result.html")){
                    emailbody = "\${FILE, path=\"${date_s}/result.html\"}"
                }else{
                    emailbody = '${SCRIPT, template="groovy-html.template"}'
                }
    
                emailext to: emailto, replyTo: '$DEFAULT_REPLYTO', subject: "\$DEFAULT_SUBJECT - ${host}-${label?:'full'}", body: emailbody, mimeType: 'text/html', attachmentsPattern: "${date_s}/*.html", attachLog: false
            }
       
            withEnv(["PATH=${env.WORKSPACE}/${venv}/bin:${env.PATH}"]) { stage('cleanup') {
                dir("${workspace}") {
                    if(sh(returnStatus: true, script: "tempest cleanup")){echo 'cleanup fail'}
                }
                // cleanWs()
            }}
        }
        echo "END job."
    }}
    

    相关文章

      网友评论

          本文标题:jenkins-pipeline实践 - tempest

          本文链接:https://www.haomeiwen.com/subject/mwosjftx.html