天天看點

動态模型中嵌入靜态模型實踐

在之前的動态模型之動态增減【FunTester測試架構】中分享了動态的性能測試模型的實作,後面在實際工作中也是受益匪淺,有文為證動态壓測模型讓工作更輕松。

這裡再重複一下思路,就是通過異步線程接收控制台輸入資訊,然後對線程池的增減管理或者對QPS管理器的QPS進行幹預。

相對一段時間來說隻有一些簡單的功能:

  1. 設定步長
  2. 增減步長
  3. 終止測試

很長一段時間内都夠用了,但是随着測試的深入,可能需要執行更多動态用例,如果靠人力一個個輸入會比較麻煩。這個時候我又想起來了靜态模型的好處來。就是過程不需要中途幹預,可以按照預定的測試計劃執行。

那麼問題來了,如何才能将動态模型和靜态模型結合在一起呢?

經過權衡,還是将靜态的模型融入動态模型比較友善,畢竟還是先啟動再說,後續過程随意設定參數調整壓力比較友善。

思路

非常簡單,就是在異步線程中增加對指令的支援即可。經過一些考慮和實踐,決定增加兩種:一是以目标、持續時間為參數;二是以增量(減量)、持續時間為參數。

private class FunTester implements IFunController {

        boolean inputKey = true;

        /**
         * 控制
         */
        boolean autoKey = false

        @Override
        public void run() {
            while (inputKey) {
                String input = getInput();
                switch (input) {
                    case "+":
                        add();
                        break;
                    case "-":
                        reduce();
                        break;
                    case "*":
                        over();
                        break;
                    case "/":
                        autoKey = true
                        break;
                    default:
                        if (Regex.isMatch(input, "(F|f)\\d+")) QPS_STEP = changeStringToInt(input.substring(1));
                        if (Regex.isMatch(input, "(T|t)\\d+(D|d)\\d+")) {
                            def split = (input - "T" - "t").split(/(d|D)/)
                            autoTarget(split[0] as int, split[1] as int)
                        }
                        if (Regex.isMatch(input, "(A|a)-{0,1}\\d+(D|d)\\d+")) {
                            def split = (input - "A" - "a").split(/(d|D)/)
                            autoAdd(split[0] as int, split[1] as int)
                        }
                        break;
                }
            }
        }

        /**
         * 自動控制遞增功能,以目标值計算
         * @param target 目标QPS
         * @param duration 持續時間
         * @return
         */
        def autoTarget(int target, duration) {
            fun {
                for (i in 0..<duration) {
                    if (autoKey) break
                    qps += (target - qps) / duration
                    sleep(1.0)
                }
                if (!autoKey) qps = target
                autoKey = false
            }
        }

        /**
         * 自動控制遞增功能,以增加值計算
         * @param sum
         * @param duration
         * @return
         */
        def autoAdd(int sum, duration) {
            fun {
                int q = qps
                for (i in 0..<duration) {
                    if (autoKey) break
                    qps += sum / duration
                    sleep(1.0)
                }
                if (!autoKey) qps = q + sum
                autoKey = false
            }
        }

        @Override
        public void add() {
            qps += QPS_STEP
        }

        @Override
        public void reduce() {
            qps -= QPS_STEP
            if (qps < 1) over()
        }

        @Override
        public void over() {
            inputKey = false
            key = false
            logger.info("動态結束任務!");
        }

    }