ChaosTestKafkaMQ.groovy 14.2 KB
Newer Older
1 2 3 4 5 6 7
pipeline {
    options {
        timestamps()
        timeout(time: 30, unit: 'MINUTES')   // timeout on this stage
    }
    agent {
        kubernetes {
8
            label "milvus-test"
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
            defaultContainer 'main'
            yamlFile "build/ci/jenkins/pod/chaos-test.yaml"
            customWorkspace '/home/jenkins/agent/workspace'
            // idle 5 minutes to wait clean up tasks
            idleMinutes 5
        }
    }
    parameters{
        choice(
            description: 'Chaos Test Type',
            name: 'chaos_type',
            choices: ['pod-kill', 'pod-failure', 'mem-stress', 'network-latency', 'network-partition', 'io-latency']
        )
        choice(
            description: 'Chaos Test Target: \
24
            mem-stress: datanode, etcd, indexnode, minio, proxy, kafka, querynode, standalone \
25 26
            io-fault & io-latency: minio, kafka, etcd ',
            name: 'pod_name',
27
            choices: ["allstandalone", "allcluster", "standalone", "datacoord", "datanode", "indexcoord", "indexnode", "proxy", "kafka", "querycoord", "querynode", "rootcoord", "etcd", "minio"]
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
        )
        choice(
            description: 'Chaos Test Task',
            name: 'chaos_task',
            choices: ['chaos-test', 'data-consist-test']
        )
        string(
            description: 'Image Repository',
            name: 'image_repository',
            defaultValue: 'registry.milvus.io/milvus/milvus'
        )
        string(
            description: 'Image Tag',
            name: 'image_tag',
            defaultValue: 'master-latest'
        )
        string(
45 46
            description: 'Etcd Image Repository',
            name: 'etcd_image_repository',
47
            defaultValue: "milvusdb/etcd"
48 49 50 51
        )
        string(
            description: 'Etcd Image Tag',
            name: 'etcd_image_tag',
52
            defaultValue: "3.5.0-r3"
53 54
        )
        string(
55
            description: 'QueryNode Nums',
56 57
            name: 'querynode_nums',
            defaultValue: '3'
58
        )
59 60 61 62 63 64 65 66 67 68 69 70 71 72
        string(
            description: 'DataNode Nums',
            name: 'datanode_nums',
            defaultValue: '2'
        )
        string(
            description: 'IndexNode Nums',
            name: 'indexnode_nums',
            defaultValue: '1'
        )
        string(
            description: 'Proxy Nums',
            name: 'proxy_nums',
            defaultValue: '1'
73
        )
74 75 76 77 78 79
        booleanParam(
            description: 'Keep Env',
            name: 'keep_env',
            defaultValue: 'false'
        )
    }
80
    
81 82 83 84 85 86 87 88 89 90 91 92
    environment {
        ARTIFACTS = "${env.WORKSPACE}/_artifacts"
        RELEASE_NAME = "${params.pod_name}-${params.chaos_type}-${env.BUILD_ID}"
        NAMESPACE = "chaos-testing"
    }

    stages {
        stage ('Install Dependency') {
            steps {
                container('main') {
                    dir ('tests/python_client') {
                        script {
93
                        sh "pip install -r requirements.txt --trusted-host https://test.pypi.org"       
94 95 96 97 98 99 100 101 102 103
                        }
                    }
                }
            }
        }
        stage ('Modify Milvus chart values') {
            steps {
                container('main') {
                    dir ('tests/python_client/chaos') {
                        script {
104 105
                        sh """
                        yq -i '.kafka.enabled = true' standalone-values.yaml
106 107
                        yq -i '.kafka.enabled = true' cluster-values.yaml
                        yq -i '.queryNode.replicas = "${params.querynode_nums}"' cluster-values.yaml
108 109 110
                        yq -i '.dataNode.replicas = "${params.datanode_nums}"' cluster-values.yaml
                        yq -i '.indexNode.replicas = "${params.indexnode_nums}"' cluster-values.yaml
                        yq -i '.proxy.replicas = "${params.proxy_nums}"' cluster-values.yaml
111 112 113 114 115
                        yq -i '.etcd.image.repository = "${params.etcd_image_repository}"' cluster-values.yaml
                        yq -i '.etcd.image.tag = "${params.etcd_image_tag}"' cluster-values.yaml
                        yq -i '.etcd.image.repository = "${params.etcd_image_repository}"' standalone-values.yaml
                        yq -i '.etcd.image.tag = "${params.etcd_image_tag}"' standalone-values.yaml
                        """
116 117 118
                        }
                        }
                    }
119
                }
120 121 122
        }
        stage ('Deploy Milvus') {
            options {
123
              timeout(time: 15, unit: 'MINUTES')   // timeout on this stage
124 125 126 127 128 129 130
            }
            steps {
                container('main') {
                    dir ('tests/python_client/chaos/scripts') {
                        script {
                            def image_tag_modified = ""
                            if ("${params.image_tag}" == "master-latest") {
131
                                image_tag_modified = sh(returnStdout: true, script: 'bash ../../../../scripts/docker_image_find_tag.sh -n milvusdb/milvus-dev -t master-latest -f master- -F -L -q').trim()    
132 133 134 135 136 137 138 139 140 141 142 143 144 145
                            }
                            else {
                                image_tag_modified = "${params.image_tag}"
                            }
                            sh "echo ${image_tag_modified}"
                            sh "echo ${params.chaos_type}"
                            sh "helm repo add milvus https://milvus-io.github.io/milvus-helm"
                            sh "helm repo update"
                            if ("${params.pod_name}" == "standalone"){
                                sh"""
                                IMAGE_TAG="${image_tag_modified}" \
                                REPOSITORY="${params.image_repository}" \
                                RELEASE_NAME="${env.RELEASE_NAME}" \
                                bash install_milvus_standalone.sh
146 147
                                """    
                            }else{   
148 149 150 151 152 153 154 155 156
                                sh"""
                                IMAGE_TAG="${image_tag_modified}" \
                                REPOSITORY="${params.image_repository}" \
                                RELEASE_NAME="${env.RELEASE_NAME}" \
                                bash install_milvus_cluster.sh
                                """
                            }
                            sh "kubectl wait --for=condition=Ready pod -l app.kubernetes.io/instance=${env.RELEASE_NAME} -n ${env.NAMESPACE} --timeout=360s"
                            sh "kubectl wait --for=condition=Ready pod -l release=${env.RELEASE_NAME} -n ${env.NAMESPACE} --timeout=360s"
157
                            sh "kubectl get pods -o wide|grep ${env.RELEASE_NAME}"
158 159 160 161 162 163 164 165
                            }
                        }
                    }
                }
        }
        stage ('Run e2e test before chaos') {
            options {
              timeout(time: 5, unit: 'MINUTES')   // timeout on this stage
166
            }            
167 168 169 170 171
            steps {
                container('main') {
                    dir ('tests/python_client/chaos') {
                        script {
                        def host = sh(returnStdout: true, script: "kubectl get svc/${env.RELEASE_NAME}-milvus -o jsonpath=\"{.spec.clusterIP}\"").trim()
172
                        sh "pytest -s -v ../testcases/test_e2e.py --host $host --log-cli-level=INFO --capture=no"       
173 174 175 176
                        }
                    }
                }
            }
177
            
178 179 180 181 182 183 184 185 186 187 188
        }

        stage ('Run hello_milvus before chaos') {
            options {
              timeout(time: 5, unit: 'MINUTES')   // timeout on this stage
            }
            steps {
                container('main') {
                    dir ('tests/python_client/chaos') {
                        script {
                        def host = sh(returnStdout: true, script: "kubectl get svc/${env.RELEASE_NAME}-milvus -o jsonpath=\"{.spec.clusterIP}\"").trim()
189
                        sh "python3 scripts/hello_milvus.py --host $host"          
190 191 192 193
                        }
                    }
                }
            }
194
            
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
        }


        stage ('Run chaos test'){
            options {
              timeout(time: 15, unit: 'MINUTES')   // timeout on this stage
            }
            steps {
                container('main') {
                    dir ('tests/python_client/chaos') {
                        script {
                        sh"""
                        POD_NAME="${params.pod_name}" \
                        CHAOS_TYPE="${params.chaos_type}" \
                        RELEASE_NAME="${env.RELEASE_NAME}" \
                        bash scripts/modify_config.sh
                        """

                        if ("${params.chaos_task}" == "chaos-test"){
                            def host = sh(returnStdout: true, script: "kubectl get svc/${env.RELEASE_NAME}-milvus -o jsonpath=\"{.spec.clusterIP}\"").trim()
                            sh "pytest -s -v test_chaos.py --host $host --log-cli-level=INFO --capture=no || echo 'chaos test fail' "
                        }
                        if ("${params.chaos_task}" == "data-consist-test"){
                            def host = sh(returnStdout: true, script: "kubectl get svc/${env.RELEASE_NAME}-milvus -o jsonpath=\"{.spec.clusterIP}\"").trim()
219
                            sh "pytest -s -v test_chaos_data_consist.py --host $host --log-cli-level=INFO --capture=no || echo 'chaos test fail' "                           
220 221 222
                        }
                        echo "chaos test done"
                        sh "kubectl wait --for=condition=Ready pod -l app.kubernetes.io/instance=${env.RELEASE_NAME} -n ${env.NAMESPACE} --timeout=360s"
223
                        sh "kubectl wait --for=condition=Ready pod -l release=${env.RELEASE_NAME} -n ${env.NAMESPACE} --timeout=360s"                               
224 225 226 227 228
                        sh "kubectl get pods -o wide|grep ${env.RELEASE_NAME}"
                        }
                    }
                }
            }
229
            
230 231 232 233 234 235 236 237 238 239 240 241
        }
        stage ('result analysis') {
            steps {
                container('main') {
                    dir ('tests/python_client/chaos/reports') {
                        script {
                            echo "result analysis"
                            sh "cat ${env.RELEASE_NAME}.log || echo 'no log file'"
                        }
                    }
                }
            }
242
        } 
243 244 245 246

        stage ('run e2e test after chaos') {
            options {
              timeout(time: 5, unit: 'MINUTES')   // timeout on this stage
247
            }            
248 249 250 251 252
            steps {
                container('main') {
                    dir ('tests/python_client/chaos') {
                        script {
                        def host = sh(returnStdout: true, script: "kubectl get svc/${env.RELEASE_NAME}-milvus -o jsonpath=\"{.spec.clusterIP}\"").trim()
253
                        sh "pytest -s -v ../testcases/test_e2e.py --host $host --log-cli-level=INFO --capture=no"        
254 255 256 257 258
                        sh "kubectl get pods -o wide|grep ${env.RELEASE_NAME}"
                        }
                    }
                }
            }
259
            
260 261 262 263 264 265 266 267 268 269 270
        }

        stage ('Run hello_milvus after chaos') {
            options {
              timeout(time: 5, unit: 'MINUTES')   // timeout on this stage
            }
            steps {
                container('main') {
                    dir ('tests/python_client/chaos') {
                        script {
                        def host = sh(returnStdout: true, script: "kubectl get svc/${env.RELEASE_NAME}-milvus -o jsonpath=\"{.spec.clusterIP}\"").trim()
271
                        sh "python3 scripts/hello_milvus.py --host $host"        
272 273 274 275
                        sh "kubectl get pods -o wide|grep ${env.RELEASE_NAME}"
                        }
                    }
                }
276
            } 
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
        }
        stage ('Verify all collections after chaos') {
            options {
              timeout(time: 10, unit: 'MINUTES')   // timeout on this stage
            }
            steps {
                container('main') {
                    dir ('tests/python_client/chaos') {
                        script {
                        def host = sh(returnStdout: true, script: "kubectl get svc/${env.RELEASE_NAME}-milvus -o jsonpath=\"{.spec.clusterIP}\"").trim()
                        sh "python3 scripts/verify_all_collections.py --host $host"
                        sh "kubectl get pods -o wide|grep ${env.RELEASE_NAME}"
                        }
                    }
                }
292 293
            } 
        }        
294 295 296 297 298 299 300 301 302 303
    }
    post {
        always {
            echo 'upload logs'
            container('main') {
                dir ('tests/python_client/chaos') {
                    script {
                        echo "get pod status"
                        sh "kubectl get pods -o wide|grep ${env.RELEASE_NAME} || true"
                        echo "collecte logs"
304
                        sh "bash ../../scripts/export_log_k8s.sh ${env.NAMESPACE} ${env.RELEASE_NAME} k8s_log/${env.RELEASE_NAME} || true"                        
305 306 307 308 309 310 311 312 313 314
                        sh "tar -zcvf artifacts-${env.RELEASE_NAME}-pytest-logs.tar.gz /tmp/ci_logs/ --remove-files || true"
                        sh "tar -zcvf artifacts-${env.RELEASE_NAME}-server-logs.tar.gz k8s_log/ --remove-files || true"
                        archiveArtifacts artifacts: "artifacts-${env.RELEASE_NAME}-pytest-logs.tar.gz", allowEmptyArchive: true
                        archiveArtifacts artifacts: "artifacts-${env.RELEASE_NAME}-server-logs.tar.gz", allowEmptyArchive: true
                        if ("${params.keep_env}" == "false"){
                            sh "bash scripts/uninstall_milvus.sh ${env.RELEASE_NAME}"
                        }
                    }
                }
            }
315
        
316 317 318 319 320 321 322 323 324
        }
        success {
            echo 'I succeeeded!'
            container('main') {
                dir ('tests/python_client/chaos/scripts') {
                    script {
                        sh "bash uninstall_milvus.sh ${env.RELEASE_NAME} || true"
                    }
                }
325
            }  
326 327 328 329 330 331 332 333 334 335 336 337

        }
        unstable {
            echo 'I am unstable :/'
        }
        failure {
            echo 'I failed :('
        }
        changed {
            echo 'Things were different before...'
        }
    }
338
}