当前位置: 首页 > 工具软件 > Grinder > 使用案例 >

grinder脚本解析原理

袁玮
2023-12-01
先看个典型的grinder脚本
from net.grinder.script.Grinder import grinder
from net.grinder.script import Test
from net.grinder.plugin.http import HTTPRequest

test1 = Test(1, "Request resource")
request1 = test1.wrap(HTTPRequest())
class TestRunner:
    def __call__(self):
        result = request1.GET("http://www.google.com.hk)

脚本解析的入口:Test 类。

1. 解析脚本:test1 = Test(1, "Request resource")
// number=1,description="Request resource"
public class Test extends AbstractTestSemantics implements Serializable{
  public Test( int number, String description) {
    m_number = number;
    m_description = description;
//Test类在初始化的时候,向registeredTest注册该测试对象Test
    m_registeredTest = Grinder.grinder .getTestRegistry().register(this);
  }
class TestRegistryImplementation
  public RegisteredTest register(Test test) {
 //先判断instrumenter是否为空
    if ( m_instrumenter == null) {
      throw new AssertionError("Instrumenter not set");
    }
  // 创建测试业务实现对象, TestData可以包装关联被测目标对象 /方法,同时实现计时功能
    final TestData newTestData;
    //同步信息,从testMap中查询是否存在这个test,如果存在就直接返回。保证test在testMap中的唯一性。 
    synchronized ( this) {
      final TestData existing = m_testMap .get(test);
      if (existing != null) {
        return existing;
      }
      //如果不存在,new 一个TestData对象。
      newTestData = new TestData(m_threadContextLocator ,
                                 m_statisticsSetFactory,
                                 m_testStatisticsHelper,
                                 m_timeAuthority,
                                 m_instrumenter,
                                 test);
// 把test和newTestData放入testMap 中进行管理。
      m_testMap.put(test, newTestData);
      m_testStatisticsMap.put(test, newTestData.getTestStatistics());

      if (m_newTests == null) {
        m_newTests = new ArrayList<Test>();
      }

      // To avoid many minor console updates we store a collection of
      // the new tests which is periodically read and sent to the
      // console by the scheduled reporter task.
      //Collection<Test> 中新增这个test
      m_newTests.add(test);
    }
    return newTestData;
  }
2. 解析脚本:request1 = test1.wrap(HTTPRequest())
  //Test类的wrap方法,传入参数 Object对象"HTTPRequest()",返回registerTest的创建proxy方法。
  public final Object wrap(Object target) throws NotWrappableTypeException {
    return m_registeredTest.createProxy(target);
  }
TestData类,TestData实现了RegisteredTest和recorder类。
  //传入object对象,实现创建proxy。
  public Object createProxy(Object o)
    throws NotWrappableTypeException {
  //传入 test,testData,object,返回instrumenter的创建instrumentedProxy方法。 
    return m_instrumenter .createInstrumentedProxy(getTest(), this, o);
  }
class TraditionalJythonInstrumenter
//传入test,recoder,因为TestData类实现recoder类,所以这里传入testData。
 public Object createInstrumentedProxy(Test test,
                                                  Recorder recorder,
                                                  Object o)
    throws NotWrappableTypeException {
  // 返回instrumentObject。
    return instrumentObject(test, new PyDispatcher(recorder), o);
  }
// instrumentObject 是个pyobject对象了。
 private PyObject instrumentObject(Test test,
                                    PyDispatcher pyDispatcher,
                                    Object o)
    throws NotWrappableTypeException {
    //对Object o 进行判定。如果是python对象。。。。
    if (o instanceof PyObject) {
      // Jython object.
      if (o instanceof PyInstance) {
        final PyInstance pyInstance = (PyInstance)o;
        final PyClass pyClass =
          m_versionAdapter .getClassForInstance(pyInstance);
        return new InstrumentedPyInstance(
          test, pyClass, pyInstance, pyDispatcher);
      }
      else if (o instanceof PyFunction) {
        return new InstrumentedPyJavaInstanceForPyFunctions(
          test, (PyFunction)o, pyDispatcher);
      }
      else if (o instanceof PyMethod) {
        return new InstrumentedPyJavaInstanceForPyMethods(
          test, (PyMethod)o, pyDispatcher);
      }
      else if (o instanceof PyReflectedFunction) {
        return new InstrumentedPyReflectedFunction(
          test, (PyReflectedFunction)o, pyDispatcher);
      }
      else {
        // Fail, rather than guess a generic approach.
        throw new NotWrappableTypeException( "Unknown PyObject: " +
                                            o.getClass());
      }
    }
    else if (o instanceof PyProxy) {
      // Jython object that extends a Java class.
      final PyInstance pyInstance = ((PyProxy)o)._getPyInstance();
      final PyClass pyClass =
        m_versionAdapter.getClassForInstance(pyInstance);
      return new InstrumentedPyInstance(
        test, pyClass, pyInstance, pyDispatcher);
    }
    //如果O是java class<?>,实现这段逻辑。
    else if (o instanceof Class<?>) {
      return new InstrumentedPyJavaClass(test, (Class<?>)o, pyDispatcher);
    }
    else if (o != null) {
      // Java object.

      // NB Jython uses Java types for some primitives and strings.
      if (!o.getClass().isArray() &&
          !(o instanceof Number) &&
          !(o instanceof String)) {
        //如果是java 对象,返回InstrumentedPyJavaInstanceForJavaInstances
        return new InstrumentedPyJavaInstanceForJavaInstances(
          test, o, pyDispatcher);
      }
    }
    return null;
  }
class InstrumentedPyJavaInstanceForJavaInstances
//脚本: request.GET("http://www.google.com.hk/")
  public PyObject invoke( final String name, final PyObject arg1) {
    //调用
    return getInstrumentationHelper().dispatch(
      new PyDispatcher.Callable() {
        public PyObject call() {
        //invoke后,脚本变成request(GET,"http://www.google.com.hk/")
         //name=GET,arg1="http://www.google.com.hk/"
          return InstrumentedPyJavaInstanceForJavaInstances.super.invoke(
            name, arg1);
        //
        }
      }
    );
  }
//class InstrumentationHelper
//invoke后的PyDispatcher.Callable() ,传入getInstrumentationHelper().dispatch

  public PyObject dispatch(PyDispatcher.Callable callable) {
    return m_dispatcher.dispatch(callable);
  }
class PyDispatcher
  public PyObject dispatch(Callable callable) {

    try {
      //开始计时,这里涉及到grinder的数据统计。另外分析。
      //计时最小单位是一个request。
      m_recorder.start();

      boolean success = false;

      try {
        final PyObject result = callable.call();

        success = true;

        return result;
      }
      finally { 
        //计时结束。
        m_recorder.end(success);
      }
    }



 类似资料: