JMeter5.1核心类PreCompiler代码分析

2021-12-03 16:57:01 浏览数 (1)

概述

PreCompiler类继承HashTreeTraverser类,重写addNode方法来解析jmx文件中引用的变量和内置函数。

针对本地部署还是分布式部署方式分别被StandardJMeterEngine类和ClientJMeterEngine类调用。

源码分析

构造函数

针对本地部署,被StandardJMeterEngine类调用

代码语言:txt复制
    public PreCompiler() {
        replacer = new ValueReplacer();
        isClientSide = false;  // 本地部署为false
    }

针对分布式部署,被ClientJMeterEngine类调用

代码语言:txt复制
    public PreCompiler(boolean remote) {
        replacer = new ValueReplacer();
        isClientSide = remote;  // 分布式部署为true
    }

主要变量

代码语言:txt复制
    // 参数和内置函数替换的操作类
    private final ValueReplacer replacer;

    private final boolean isClientSide;

    // 分布式部署用到的变量
    private JMeterVariables clientSideVariables;

主要方法

addNode

重写addNode方法,解析jmx文件中引用的变量和内置函数,并存储到JMeterContext线程类中。

代码语言:txt复制
    public void addNode(Object node, HashTree subTree) {
        // 分布式部署
        if(isClientSide) {
            // 判断需要参数替换的元素节点类型
            if(node instanceof ResultCollector || node instanceof Backend) {
                try {
                     // 进行参数替换
                    replacer.replaceValues((TestElement) node);
                } catch (InvalidVariableException e) {
                    log.error("invalid variables in node {}", ((TestElement)node).getName(), e);
                }
            }

            if (node instanceof TestPlan) {
                this.clientSideVariables = createVars((TestPlan)node);
            }

            if (node instanceof Arguments) {
                // Don't store User Defined Variables in the context for client side
                Map<String, String> args = createArgumentsMap((Arguments) node);
                clientSideVariables.putAll(args);
            }

        } else {  // 本地部署
            if(node instanceof TestElement) {
                try {
                    // 进行参数替换
                    replacer.replaceValues((TestElement) node);
                } catch (InvalidVariableException e) {
                    log.error("invalid variables in node {}", ((TestElement)node).getName(), e);
                }
            }
            
            //将testplan中的参数存入JMeterVariables
            if (node instanceof TestPlan) {
                JMeterVariables vars = createVars((TestPlan)node);
                JMeterContextService.getContext().setVariables(vars);
            }
            
            //将Arguments中的参数存入JMeterVariables
            if (node instanceof Arguments) {
                Map<String, String> args = createArgumentsMap((Arguments) node);
                JMeterContextService.getContext().getVariables().putAll(args);
            }
        }
    }

createVars

获取testPlan中自定义的变量

代码语言:txt复制
    private JMeterVariables createVars(TestPlan testPlan) {
        // 设置RunningVersion为true
        testPlan.prepareForPreCompile(); //A hack to make user-defined variables in the testplan element more dynamic
        // 获取testPlan中定义的变量
        Map<String, String> args = testPlan.getUserDefinedVariables();
        // 将变量存入ValueReplacer类
        replacer.setUserDefinedVariables(args);
        JMeterVariables vars = new JMeterVariables();
        vars.putAll(args);
        return vars;
    }

createArgumentsMap

获取用户自定义变量,jmx文件中testclass名为Arguments的类

代码语言:txt复制
    private Map<String, String> createArgumentsMap(Arguments arguments) {
        // 设置RunningVersion为true
        arguments.setRunningVersion(true);
        // 获取用户自定义变量列表
        Map<String, String> args = arguments.getArgumentsAsMap();
        // 将变量存入ValueReplacer类
        replacer.addVariables(args);
        return args;
    }

getClientSideVariables

获取分布式部署用到的变量

代码语言:txt复制
    public JMeterVariables getClientSideVariables() {
        return clientSideVariables;
    }

0 人点赞