记录阿里巴巴QA架构组成长点滴。2008年关键词为效率,技术,影响力!QA/测试架构师定义:开发和设计测试框架测试库;纵横全局的考虑产品的功能,设计复杂的测试系统;负责研发某一项特定的测试技术;为公司考虑如何提高测试效率。领导公司测试技术的发展和测试策略上的方向,关注整个公司的测试部门的问题,前瞻性的考虑未来的版本的测试策略和技术。测试架构师计划/设计测试平台,关注着产品的测试过程,提供咨询服务,影响到公司内的测试机构测试社区,以及开发机构等,对产品各个方面施加深远而正确的影响,最终提高整体软件质量。

发布新日志

  • 阿里巴巴集团部分技术BLOG

    2008-12-07 17:31:05

      阿里人才济济,越来越多的技术专家在infoq上露面,也有很多的BLOG 生根发芽:)

    数据库与数据仓库

    http://rdc.taobao.com/blog/dw/

    http://rdc.taobao.com/blog/dba/

     http://www.dbanotes.net

    http://blue-prince.spaces.live.com/

    http://WWW.ALIDBA.NET/

    http://www.orawh.com/

    (biti_rainy)  http://space.itpub.net/3505/

     http://www.hellodba.net/

    http://www.jianzhaoyang.com/

     

    http://xujt82.spaces.live.com/

    http://www.ningoo.net/

    http://hutuworm.blogspot.com/

    前端研发

    http://ued.taobao.com/blog/

    http://www.aliued.cn/

    http://ued.alipay.com/

    http://www.alisoftued.com/

    http://ued.koubei.com/

    JAVA研发

    http://rdc.taobao.com/blog/arch/

    http://www.blogjava.net/BlueDavy/archive/2008/11.html


     http://blog.csdn.net/yzhz/category/24108.aspx

    http://blog.csdn.net/cenwenchu79

                  http://www.blogjava.net/cenwenchu/

    http://davyyew.blogbus.com

     http://www.esbzone.net/

     http://amoeba.meidusa.com/wordpress/?p=14

    http://www.alinotes.cn/

    http://www.blogkid.cn/

    安全

    http://blog.csdn.net/kj021320

    http://blog.ph4nt0m.org/

    Linux C

    QA

     http://fafeng.blogbus.com/

    http://rdc.taobao.com/blog/qa/

    http://nmtcolin.itpub.net/category/5135/31300

  • 软件需求分析使用的工具描述

    2008-11-24 20:03:16

    转载请保留:本文出自qaarchitech的51Testing软件测试博客:http://www.51testing.com/?170805

    1)原型设计模型工具交互原型设计软件 Axure RP Pro 5

    Axure RP 能帮助网站需求设计者,快捷而简便的创建 基于目录组织的原型文档、功能说明、交互界面以及带注释的wireframe网页,并可自动生成用于演示的网页文件和word文档,以提供演示与开发。
    Axure RP 的特点是:快速创建带注释的wireframe文件,并可根据所设置的时间周期,软件自动保存文档,确保文件安全。在不写任何一条html与javascrīpt语句的情况下,通过创建的文档以及相关条件和注释,一键生成html prototype演示。根据设计稿,一键生成一致而专业的word版本的原型设计文档。

    2)StarUML工具

    可绘制9款UML图:用例图、类图、序列图、状态图、活动图、通信图、模块图、部署图以及复合结构图等。
    完全免费:StarUML是一套开放源码的软件,不仅免费自由下载,连代码都免费开放。
    多种格式影像文件:可导出JPG、JPEG、BMP、EMF和WMF等格式的影像文件。
    语法检验:StarUML遵守UML的语法规则,不支持违反语法的动作。
    正反向工程:StarUML可以依据类图的内容生成Java、C++、C#代码,也能够读取Java、C++、C#代码反向生成类图。

    转载请保留:本文出自qaarchitech的51Testing软件测试博客:http://www.51testing.com/?170805

    3)Visio 工具

    Microsoft visio 可以建立流程图、组织图、时间表、营销图和其它更多图表,把特定的图表加入文件,让商业沟通变得更加清晰,令演示更加有趣。

    4)FreeMind 工具 思维导图软件

    Freemind是一实用的开源思维导图/心智(MindMap)软件.它可用来作为管理项目(包括子任务的管理,子任务的状态,时间记录,资源链接管理),笔记或知识库,文章写作或者头脑风暴,结构化的存储小型数据库,绘制思维导图,整理软件流程思路。
  • Spirng ibatis web 简单示例

    2008-11-24 19:20:13

    1)
    创建web工程
    spring-test工程文件
    2)
    需要jar包支持
    Spring-web.jar
    Spring-webmvc.jar
    Spring.jar
    Commons-io.jar
    Log4j.jar
    Commons-dbcp.jar
    Commons-lang.jar
    Commons-pool.jar
    Ibatis.jar
    Mysql-connector-java.jar
    3)
    创建配置文件

    文件名 web-inf
    描述
    web.xml
    Spring 配置加入

    <context-param>


    加载
    /WEB-INF/applicationContext.xml


    <servlet>
    接收mvc分发

    org.springframework.web.servlet.DispatcherServlet
    <param-value> /WEB-INF/roadrantz-servlet.xml


    <servlet-mapping> 对应的结尾名


    <url-pattern>*.do</url-pattern>


    监听器
    加载spring上下文
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>


    applicationContent.xml

    加载属性文件
    <
    bean id="propertyConfigurer"

    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">


    加载数据源文件
    <
    bean id="dataSource"
    class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">


    关联ibatis
    class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">


    <property name="dataSource" ref="dataSource" />


    <property name="configLocation" value="/WEB-INF/roadrantz-ibatis.xml" />



    </bean>



    Spring-servlet.xml

    Mvc mapping对应文件applicationContent.xml加载过
    <
    bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">


    <prop key="/home.do">homePageController</prop>
    加载bean
    <
    bean id="homePageController" class="com.roadrantz.mvc.HomePageController" >


    <property name="sqlDao" ref="sqlDao"/>


    </bean>




    Spring-ibatis.xml

    加载 ibatis 配置文件,本文件在
    applicationContent.xml


    对应模板文件
    <
    bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">



    <property name="prefix">



    <value>/tpl/</value>



    </property>





    <property name="suffix">



    <value>.jsp</value>



    </property>



    </bean>
    <
    sqlMapConfig>



    <sqlMap resource="com/roadrantz/entity/testst.xml" />



    <sqlMap resource="com/roadrantz/entity/testst_msbv.xml" />


    </sqlMapConfig>
    Jdboc.properties

    jdbc.driverClassName = org.gjt.mm.mysql.Driver


    jdbc.password
    =
    admin


    jdbc.url
    =
    jdbc:mysql://localhost/mspring?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8


    jdbc.username
    =
    root






    4)
    创建java文件
    文件
    描述
    HomePageController
      需要
    extends SimpleFormController
    默认找 handleRequestInternal 方法

    Test
    实体文件,对应数据test属性值

    Test.xml

    Ibatis配置文件,对应 class和数据表文件配置
    <sqlMap namespace="test">



    <resultMap class="com.roadrantz.entity.Test" id="result">


    <result property="id" column="id" jdbcType="Integer"/>



    <result property="name" column="name" jdbcType="VARCHAR" />



    </resultMap>



    <select id="getAllTests" esultMap="result">



    select * from Testst



    </select>


    </sqlMap>
    Dao执行文件

    public List getAll() {



    return
    this.getSqlMapClientTemplate().queryForList("getAllTests", null);



    }


    Web-inf/tpl/

    模板文件
    return new ModelAndView("home","rants","test==========");
    对应文件名



    5)目录文件结构
    Project_test
      Src

         Com.test.dao

            SqlMapTestDao.java
         Com.test.dao.Impl

            SqlMapTestDaoImpl.java

        Com.test.dao.entity

            Test.java

        Test.xml

      WebContent

         Tpl/
            Home.jsp
          WEB-INF/

              Lib/
                 Spring-web.jar

    Spring-webmvc.jar
    Spring.jar
    Commons-io.jar
    Log4j.jar
    Commons-dbcp.jar
    Commons-lang.jar
    Commons-pool.jar
    Ibatis.jar
    Mysql-connector-java.jar

    Web.xml


    applicationContext.xml


    jdbc.properties


    log4j.properties


    spring -ibatis


    spring-servlet.xml

  • 开源的质量控制工具 Sonar

    2008-11-23 17:58:41


    http://sonar.codehaus.org/documentation/

    http://www.javaread.com/article/show/195

     

    安装指南:http://docs.codehaus.org/display/SONAR/Installation+guide

    http://docs.codehaus.org/display/SONAR/Frequently+Asked+Questions

     

    下载

    http://sonar.codehaus.org/downloads/

     

    sonar 整合代码覆盖率/规则检查等数据WEB图形化展现。

    预先条件

    window xp 上环境变量PATH已经加入D:\apache-maven-2.0.9\bin

    D:\apache-maven-2.0.9\my-webapp>java -version

    java version "1.5.0_14"

    Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_14-b03)

    Java HotSpot(TM) Client VM (build 1.5.0_14-b03, mixed mode)

    D:\apache-maven-2.0.9\my-webapp>mvn -v

    Maven version: 2.0.9

    Java version: 1.5.0_14

    OS name: "windows xp" version: "5.1" arch: "x86" Family: "windows"

     

    安装

    安装在,D:\sonar-1.4.3\conf

    InstallNTService.bat 安装服务

    StartNTService.bat启动服务

    IEhttp://127.0.0.1:9000/ 初步测试。

     

    缺省用户名密码:admin/admin

    WEB 页面上创建DB 创建后可以看到D:\sonar-1.4.3\conf\ sonar.properties

    sonar.jdbc.url:                            jdbc:derby://localhost:1527/sonar;create=true

    sonar.jdbc.driverClassName:                org.apache.derby.jdbc.ClientDriver

     

    IE展现图如下:

     

     

    配置与maven2的关联

    $MAVEN_HOME/conf (如D:\apache-maven-2.0.9\conf)或者 ~/.m2 下的settings.xml 文件加入下面内容

     

    <profile>

                <id>sonar</id>

                <activation>

                    <activeByDefault>true</activeByDefault>

                </activation>

                <properties>

                                    

                     <sonar.jdbc.url>

                      jdbc:derby://localhost:1527/sonar

                    </sonar.jdbc.url>

                    <sonar.jdbc.driver>org.apache.derby.jdbc.ClientDriver</sonar.jdbc.driver>

                    <sonar.jdbc.username>sonar</sonar.jdbc.username>

                    <sonar.jdbc.password>sonar</sonar.jdbc.password>              

                    <sonar.host.url>http://127.0.0.1:9000/</sonar.host.url>

                   

                </properties>

            </profile>

     

    配置一个maven2 工程pom.xml

     

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

      <modelVersion>4.0.0</modelVersion>

      <groupId>com.mycompany.app</groupId>

      <artifactId>my-webapp</artifactId>

      <packaging>jar</packaging>

      <version>1.0-SNAPSHOT</version>

      <name>my-webapp</name>

      <url>http://maven.apache.org</url>

      <dependencies>

        <dependency>

          <groupId>junit</groupId>

          <artifactId>junit</artifactId>

          <version>3.8.1</version>

          <scope>test</scope>

        </dependency>

      </dependencies>

    </project>

     

     

    编译发布

     

     

    D:\apache-maven-2.0.9\my-webapp>mvn org.codehaus.sonar:sonar-maven-plugin:1.4.3:sonar -Dsonar.skipInstall=true

     

     

    重新刷新IE数据,漂亮的数据图表展现在面前。

  • JAVA持续集成解决方案

    2008-11-21 00:22:46

    敏捷方法倡导java持续集成,并输送很多有用的工具。
    当前比较流行的持续集成服务工具有
    1) apache continuum
    2) CruiseControl
     
       配套做持续集成的工具包有
       1) JUnit 单元测试
       2) JUnitPerft或者eclipse tptp 做单元性能测试
       3) 数据库DDL初始化语句
       4) EasyMock 等模拟工具
       5) PMD,checkStyle,FindBug分析工具
       6)httpUnit HTTP接口测试
       7) purify/Jprofile 动态分析
       8) EMMA/Clover度量代码覆盖率
       9) JAVANCSS度量代码复杂度
       10) JDepend 度量耦合度
       10) 构建工具ant,
       11) 部署脚本
       12)分布式分发框架staf/stax
      
       如上工具通过与持续集成工具粘合,将产生强大威力。
      
       当前阿里巴巴平台架构师采用continuum+maven+mylyn+trac,淘宝采用cruisecontrol做接口测试。
      
  • [论坛] jmeter的linux资源监控器改进

    2008-10-31 22:55:31

    by jack


    针对之前所写的linux服务器资源监控http://bbs.51testing.com/viewthread.php?tid=122321做了改进
    ajm是新的linux服务器端监控,不依赖web server,无需http服务器
    使用方法:
    登录到服务器host_xxx上
    将ajm.tar.gz放到服务器上
    解压缩
    tar -xvzf ajm.tar.gz
    进入ajm目录
    cd ajm
    运行ajm
    ./ajmctl start
    停止ajm
    ./ajmctl stop
    在客户端监控时,可以用
    http://host_xxx:6688/status来获取监控结果的xml
    注意:监控端口为6688,须确保该端口不被占用

    附件中是打好的工具包,欢迎大家下载试用,请不要吝惜您的意见建议!

    [ 本帖最后由 qaarchitech 于 2008-10-31 22:54 编辑 ]

    ajm.tar.gz
    (2008-10-31 22:52:25, Size: 4.98 kB, Downloads: 0)

  • java web tomcat eclipse环境搭建

    2008-10-30 19:28:31

    一.基本工具安装

    JDK安装

    下载安装文件点击安装就可

    环境变量的设置

    JAVA_HOME C:\Program Files\Java\jdk1.5.0_07\

    Path 中加 C:\Program Files\Java\jdk1.5.0_07\bin;

    Eclipse安装

           下载,解压目录就可以

    Tomcat 安装

    二.几种搭建方法

    方法

    Jsp页面

    特点

    方便性

    antx + tomcatPluginV321.zip

    不支持

    需要同步
    antx
    自动创建web框架

    一般

    myeclipse

    支持

    创建j2ee框架

    方便

    lomboz

    支持

    能创建动态的web
    没有框架

    一般

    运用 tomcatPluginV321.zip

    不支持

    纯框架配置

    不方便

     

    1)      运用 myeclipse 插件安装

    Myeclipse安装
    选择你的eclipse所在目录,其它都点下一步,默认安装。 
    .
    安装完毕之后,找到myeclipse的安装目录

     
    featuresplugins2个目录复制在eclipse目录中就可以

    由于myeclipse是不是免费软件,需要注册,如果公司用就要用正版的了!

    注册过程

    点击 Window ----> Preferences ----> Subscrīption ----> Enter Subscrīption, 输入注册码

     

    设定Eclipse+MyEclipseJRE
    一般情况下,Eclipse可以自动找到JRE,我们不用进行过多的设置

    主要注意

    Window ----> Preferences -> myeclipse ->Tomcat5 配置相应的目录就可以

     

    2)      运用 lomboz 插件安装

    Lomboz 安装,

    lomboz-S-3.2RC2-200608081203.zip
    lomboz-wtp-emf-gef-jem-3.1.2.zip 
    lomboz-and-prereqs-S-3.2RC2-200608081203.zip

    解压文件,把目录文件拷贝到eclipse目录中就可

    配置tomcat ,新建server服务就可以运行了

    3)      直接运用 tomcatPluginV321.zip

    解压文件,把目录文件拷贝到eclipse目录中就可

    配置tomcat
    Window ----> Preferences -> Tomcat5
    配置相应的目录就可以

    注意 context declaration mode 选择server.xml 就可以了

     

    4)      运用antx + tomcatPluginV321.zip

    Antx是公司技术运行环境,使用也很简单

    首先我们得到antx,在公司的svn下载
    http://opentech.alibaba-inc.com/community/entry.jspa?externalID=649&categoryID=73
    有详细的说明

    注要注意几点:

    添加PATH路径:将antx\dist\antx\bin目录添加到PATH环境变量中。

    Checkout Antx 第二方类库。
    新建
    antx.properties文件,在新建项目文档中创建文件就可以

    antx.repository.external  = mydir/repository          # 第三方类库
    antx.repository.project   = mydir/repository.project    #
    第二方类库

    petstore.work    = D:/Tomcat/webapps/workshop     //

    安装Antxclipse插件

    根据同步配置 D:/Tomcat/webapps/workshop

    然后我们利用 tomcatPluginV321.zip就可以看到tomcat调试日志了

  • watir 对象tag与attribute扩展简例

    2008-10-28 20:15:10

     

    By Wiston Li

    一,属性扩展在element.rb中

    一段代码,需要实现某个表中单元格判断是否有文本和图片,再进行点击操作

    t = ie.table(:index,  7)     
      for i in 1..t.row_count 
          t[i].each do |cell| 
              if cell.text == _userid.to_s
                      if cell.image(:src, /enabled/).exists?
                        $atag = cell.link(:index,1)
                      end
             end
          end
         end

    若在element中扩展如下代码:

       class Watir::Element
         def has_enabled_image_and_text_is name
           text == name && self.image(:src, /enabled/).exists?
           end
         end

    就可以方便在属性直接来进行对象识别,如下:

     $atag = t.cell(:has_enabled_image_and_text_is =>
      _userid.to_s).link(:index, 1)

     

     

    二,tag扩展在NonControlElement中

    看了一下NonControlElement中的代码,扩展了很多pre, map, li之类的tag对象识别,如在我们的程序中有一叫做object的tag, 我想可以类推如下:

    先添加tag

    module Watir
      class Object < NonControlElement
        TAG = 'OBJECT'
      end
    end

    然后再用脚本

    ie.frame(:id, 'url').object(:id, 'xobject')

     

  • 快速生成页面对象,高效开发watir脚本

    2008-10-28 19:57:18

    By Wiston Li

    在watir对象识别时,需要借助第三方工具来进行页面对象识别,下面的方法类似QTP描述性编程

    生成某类型的对象集合,因而从控制台上可以批量获得对象属性。

    实际上在watir中已经给出部分show_object的方法,下面代码主要给出watir暂且不提供对

    input tag的对象解析的解决方案。

    =begin rdoc
          功能目的:计算某对象的xpath
          输入参数及描述:object
          返回参数及描述:
          调用方法:               
    =end
        def calculate_xpath(object)
          s = ""
          curr = object
          s = "/#{curr.invoke("tagName")}[#{get_index(curr)}]" + s
          par = curr.invoke("parentElement")
          while par.invoke("tagName").downcase != "body"
            s = "/#{par.invoke("tagName")}[#{get_index(par)}]" + s
            par = par.invoke("parentElement")
          end
          return s.gsub(/\[1\]/, "").downcase
        end

    =begin rdoc
          功能目的:计算某对象的xpath tag中索引
          输入参数及描述:object
          返回参数及描述:
          调用方法:               
    =end

        def get_index(currObj)
          par = currObj.invoke("parentElement")
          valuecurr =  currObj.invoke("uniqueID")
          valuepar = par.invoke("uniqueID")
          currtagname = currObj.invoke('tagName').downcase
          count = 0
          par.invoke("children").each { |i|
            val = i.invoke('tagName').downcase
            if val.eql?(currtagname)
              count += 1
              return count if valuecurr.eql?("#{i.invoke("uniqueID")}")
            end
          }
        end

       
    =begin rdoc
       
          功能目的:生成当前document中对象集合
          输入参数及描述:objecttype生成指定的对象类型, props=nil 属性名称
          返回参数及描述:
          调用方法:
                   
    =end
       
        def show_inputs( objecttype, props=nil )
        
          props = ["type","id","name","value","tabIndex","readonly"] unless props
      
      
          divs = document.getElementsByTagName("INPUT")
          puts "Found #{divs.length} Input tags"
          s = ""
          index = 0
          divs.each do |d|
            val = d.invoke('type').downcase
            case  objecttype
            when "edit"
              result=val.eql?("text") || val.eql?("password")
            when "button"
              result=val.eql?("submit")|| val.eql?("button")
            when "checkbox"
              result=val.eql?("checkbox")
            when "radio"
              result=val.eql?("radio")
            end
          
            if result
              index += 1
              s = "#{index} "
              props.each_with_index { |prop,i|
                begin
                  s += prop +":" + d.invoke(prop) + " | "
                rescue
                  #puts "got error - #{prop}"
                end
              }
              s = s + "Xpath: " + calculate_xpath(d)
              puts s
            end
          end
        end

      end
    end

  • [watir] 弹出框的另一种解决方法

    2008-10-28 14:22:37

      watir对于弹出框的处理一直都不是非常的好,网上很多的解决方案都是采用autoit的方法来解决的。其实,使用win32api中自带的方法,也能解决这个问题,而且,可能效率更高。

     我们主要用到以下几个win32api的函数:

     FindWindowEx #可以根据handle值获取特定类的子类的句柄

     SendMessage #发送win32消息

     GetWindowText #取得空间的caption或者title属性

    其中的几个常量

    WM_CLICK = 0x00F5

    IDC_BUTTON1 = 1000

    我们先声明这些win32函数

    require 'win32API'

     SendMessage = Win32API.new('user32.dll','SendMessageA',['l','l','l','l'],'v')

    FindWindowEx = Win32API.new('user32.dll','FindWindowExA',['l','l','p','p'],'l')

    GetWindowText = Win32API.new('user32.dll','GetWindowTextA',['l','p','l'],'l')

    我们先找到ie的弹出框。

    hwnd =ie.hwnd #根据ie对象获取他的hwnd值

    popup_hwnd = FindWindowEx.call(hwnd,0,"#32770",nil) #'#32770'是ie弹出框的类名

    #找到弹出框后,遍历弹出框上的button控件

    button_hwnds =Array.new

    button_hwnd = FindWindowEx.call(popup_hwnd,0,"button",nil)

    while button_hwnd!=0

     button_hwnds << button_hwnd

     button_hwnd = FindWindowEx.call(popup_hwnd,0,"button",nil)

    end

    #找到button的集合后,要点第i个button,直接使用button_hwnd[i]

    #调用sendmessage点击按钮

    SendMessage.call(button_hwnd[i], WM_CLICK,IDC_BUTTON1,0)

    SendMessage.call(button_hwnd[i], WM_CLICK,IDC_BUTTON1,0) #在实际的使用过程中,发现需要调用2次wm_click消息,不知道为什么

     

    使用这个方法,还可以根据button上的文字来点击

    主要是使用GetWindowText方法,这里不做详细的讲解

     

  • [ruby] 创建自己的gem包

    2008-10-28 09:45:52

                                           -----by nish

    RubyGems是一个库和程序的标准化打包以及安装框架,它使定位、安装、升级和卸载Ruby包变的很容易。rails以及它的大部分插件都是以gem形式发布的。本文描述一个自己创建ruby Gems的过程。 gem可以使用你现有的文件夹结构,也可以使用命令创建一个标准的gem包结构。下面是用命令创建一个标准的gem包。

    运行: gpgen yourgem  

    运行完后,会自动生成一个标准的gem包结构:

    yourgem

      COPYING

      LICENSE

      Rakefile

      README

    ├─lib

      └─yourgem

              init.rb

    └─resources

            defaults.yaml

     

    将自己的代码放在lib/yourgem文件夹下,如果有测试代码,则创建一个test目录,将单元测试的文件都放在这个文件夹下。

    将你自己写的rb文件都放在lib/yourgem文件夹下面,比如有a.rb,b.rb

    一般的做法,会在lib的根目录下建立一个 yourgem.rb文件,这个文件用来引入你lib/yourgem文件夹下的所有rb文件。yourgem.rb文件的内容为:

    #yourgem.rb

     $:.unshift"#{File.dirname(__FILE__)}/yourgem"

    require ‘a’

    require ‘b’

     

    制作完rb文件后,修改Rakefile

    # Rakefile

    require 'rake'

    require 'rake/testtask'

    require 'rake/clean'

    require 'rake/gempackagetask'

    require 'rake/rdoctask'

    require 'fileutils'

    include FileUtils

     

    version="0.1.1"  #改为你的version

    name="yourgem"    #改为你的gem名字

     

    spec = Gem::Specification.new do |s|

      s.name = name

      s.version = version

      s.email="your-email@email.com" 

      s.homepage = "http://localhost"

      s.descrīption = s.summary = "xxxxxxxxxxxxx”

      s.author = "xxxx"

      s.add_dependency('gem_plugin', '>= 0.2.3')

     

      s.platform = Gem::Platform::RUBY

      s.has_rdoc = true

      s.extra_rdoc_files = ["README"]

     

     

     

      candidates = %w(COPYING LICENSE README Rakefile) +

        Dir.glob("{bin,doc/rdoc,test,lib}/**/*") +

        Dir.glob("ext/**/*.{h,c,rb}") +

        Dir.glob("examples/**/*.rb") +

        Dir.glob("tools/*.rb") +

        Dir.glob("resources/**/*")

     

      s.files = candidates.delete_if do |item|   #去掉svvrdoc目录

                            item.include?(".svn") || item.include?("rdoc")

                        end

     

      s.require_path = "lib"

      s.bindir = "bin"

    end

     

    Rake::GemPackageTask.new(spec) do |p|

      p.need_tar = true if RUBY_PLATFORM !~ /mswin/

    end

     

    task :install => [:test, :package] do

      sh %{sudo gem install pkg/#{name}-#{version}.gem}

    end

     

    task :uninstall => [:clean] do

      sh %{sudo gem uninstall #{name}}

    end

     

    Rake::TestTask.new do |t|

      t.libs << "test"

      t.test_files = FileList['test/test*.rb']

      t.verbose = true

    end

     

    Rake::RDocTask.new do |rdoc|

      rdoc.rdoc_dir = 'doc/rdoc'

      rdoc.options << '--line-numbers'

      rdoc.rdoc_files.add ['README', 'LICENSE', 'COPYING', 'lib/**/*.rb', 'doc/**/*.rdoc']

    end

     

    task :default => [:test, :package]

     

    CLEAN.include ['build/*', '**/*.o', '**/*.so', '**/*.a', 'lib/*-*', '**/*.log', 'pkg', 'lib/*.bundle', '*.gem', '.config']

     

     

    在当前目录运行

    Gem build Rakefile

     

    运行完成后就会自动生成一个gem,然后你就可以按照gem的语法安装,卸载,升级(可以自己制定gem的地址,或者把它上传到gem pluginserver)这个gem包了

     

  • 改写jQuery实现固定表头,滚动内容

    2008-10-26 01:00:18

     

     

    参考 http://blog.csdn.net/hu_zhenghui/archive/2007/12/02/1911733.aspx

     

     

    原来事件处理采用:

     

    <scrīpt src="scrīpts/jQuery.js"></scrīpt>

      <scrīpt>

          $(document).ready(function () {

           

              $("#tableContainer").scroll(function () {

                 // $("#divx").get(0).scrollLeft = this.scrollLeft;

                  $("#divy").get(0).scrollTop = this.scrollTop;

              });

             

             

          });

      </scrīpt>

     

    例子采用3个表,存在列宽/行高同步的问题。

     

    偶改写了事件,特别注意标红色的style 要素overflow

     

     

           <div id="tableContainer" style="width:1000px; height:600px; overflow:scroll">

    <table border="1" cellpadding="0" cellspacing="0" width="100%" class="scrollTable"  id="scrollTable" >

    <thead>

           <tr>

           <th>

                         <div> 标题</div>

    </th>

    <tr>

    </thead>

    <tbody id="tbSCMProject" class="tbSCMProject">

    </tbody> 

     

     

    <td valign="top"  >

                                       <div id="divy" style="width:300px; height:600px; overflow:hidden">  

    <table id="table_y" border="3">

                                                       

                        <tr><div style="height:51.5px">内容       </div>

                                </tr>

                                                                                                                                         </table>          

     

    </div>

     

     

    <scrīpt   language="javascrīpt">  

     

     var divScrollHander= function()

    {

                                       var thisContainer = document.getElementById('tableContainer');

                                       var ōbjdivy =    document.getElementById('divy');

                                       if (!thisContainer || !objdivy)

                                       {

                                                           

                                                      return;

                                       }    

                                      

                                       objdivy.scrollTop=thisContainer.scrollTop;

        }

       

       

      tableContainer.attachEvent('onscroll',divScrollHander);

       

    </scrīpt>

     

    </body>

     

     

    由于采用2个表,如何让2个表的行高度一致,不至于适配?下面的图看到,需要2个表的同一行移动需要同步。

     

     

     

  • 子html 页面刷新父页面并关闭

    2008-10-16 01:11:58

    Child.html 关闭刷新父页面并关闭

     

     

    if (window.opener && !window.opener.closed) {

                                      

                                              var site=document.getElementById("hidden_currSite").value;

                                             

                                              var publishdate=document.getElementById("publishdate").value;

                                             

                                              var str_url="project.do?site="+site +"&publishdate="+publishdate;

                                                                                        window.opener.location.href=str_url;          

                                              //window.opener.location.reload();                         

             }

     

    window.close();

     

     

    html页面:

     

    window.open("child.htm ?projectid="+projectid+"&site="+site);

     

    同时为了保证取到更新的数据,应该禁止cache

    <Html>

    <head>

           <meta http-equiv="pragma" content="no-cache">

     <meta http-equiv="cache-control" content="no-cache, must-revalidate"> 

        <meta http-equiv="expires" content="0">

    </head>

     

     

    有朋友可能对不用window.opener.location.reload(); 存疑。

     

    当父页面之前是http post 请求,用window.opener.location.reload(); 会导致再次Post,这个可能不是我们期望的结果。

     

  • Spring Velocity macro应用与调试

    2008-09-26 22:14:24

     

      默认情况下,velocity macro文件修改没有被应用服务器检测,必须重启才能生效。

     

     

    Spring  web.xml contextConfigLocation配置包含属性文件mvc-config.xml

     

    <servlet>

    <servlet-name>dispatcherServlet</servlet-name>     

    <servlet-class>  org.springframework.web.servlet.DispatcherServlet        </servlet-class>      

    <init-param>          

    <param-name>contextConfigLocation</param-name>         

    <param-value>

    /WEB-INF/mvc-config.xml

    /WEB-INF/alert-config.xml

    </param-value>   

    </init-param>  

    <load-on-startup>1</load-on-startup>  

     </servlet>

     

     

    mvc-config.xml 部分内容如下:

     

                  <bean id="velocityConfigurer"                           class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">

                  <property name="resourceLoaderPath">

                  <value>WEB-INF/velocity/</value>  

                  </property>

                  <property name="velocityProperties">

                         <props>

                         <prop key="input.encoding">gb2312</prop>

                         <prop key="output.encoding">gb2312</prop>

                         <prop key="contentType">text/html;charset=gb2312</prop>

                         <prop key="file.resource.loader.cache">false</prop>

                         <prop key="file.resource.loader.modificationCheckInterval">1</prop>

                         <prop key="velocimacro.library.autoreload">true</prop>

                         <prop key="velocimacro.library">templates.vm</prop>

                         <prop key="runtime.log.logsystem.class">org.apache.velocity.runtime.log.SimpleLog4JLogSystem</prop>

                         <prop key="runtime.log">com.ali</prop>

                         <prop key="runtime.log.error.stacktrace">true</prop>

                         <prop key="runtime.log.warn.stacktrace">true</prop>

                         <prop key="runtime.log.info.stacktrace">false</prop>

                         <prop key="runtime.log.invalid.reference">true</prop>

                  </props>

                  </property>

     

           </bean>

          

             <bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">

               <property name="suffix"><value>.vm</value></property>

                         <property name="exposeSpringMacroHelpers"><value>true</value></property>

                         <property name="exposeRequestAttributes"><value>true</value></property>

                         <property name="exposeSessionAttributes"><value>true</value></property>

                         <property name="contentType" value="text/html;charset=gb2312" />

                         <property name="dateToolAttribute">

          <value>dateTool</value>

               </property>

            </bean>

     

     

     

    Velocity 文件包括库文件templates.vm都放在WEB-INF/velocity/

    确保velocity文件被修改都立即重新扫描,关键的参数:

    <prop key="file.resource.loader.cache">false</prop>

                         <prop key="file.resource.loader.modificationCheckInterval">1</prop>

                         <prop key="velocimacro.library.autoreload">true</prop>

     

     

    index.vm上通过:

    #parse("templates.vm") 引入velocity 模版。

     

  • 一次mysql部分汉字乱码解决过程

    2008-09-26 22:09:53

     

        从Confluence db导出数据在mysql控制台上乱码,在SPRING MVC页面也乱码,如。从confunce应用页面上看,无乱码。到底原因在哪里呢?

     

    由于涉及的层非常多,只能用隔离法。

        主要有几种可能

    1)      db里面的数据是否真有乱码

    2)      输出到页面上的汉字有乱码

    3)      页面编码识别有错

     

    1.1.1    mysql 控制台检查:

    mysql> show variables  like  'char%';

    +--------------------------+-----------------------------------+

    | Variable_name            | Value                             |

    +--------------------------+-----------------------------------+

    | character_set_client     | gb2312                            |

    | character_set_connection | gb2312                            |

    | character_set_database   | utf8                              |

    | character_set_filesystem | binary                            |

    | character_set_results    | gb2312                            |

    | character_set_server     | utf8                              |

    | character_set_system     | utf8                              |

    | character_sets_dir       | D:\MySQLServer5.0\share\charsets\ |

    +--------------------------+-----------------------------------+

    8 rows in set (0.05 sec)

     

    mysql> show variables  like  'coll%';

    +----------------------+-------------------+

    | Variable_name        | Value             |

    +----------------------+-------------------+

    | collation_connection | gb2312_chinese_ci |

    | collation_database   | utf8_general_ci   |

    | collation_server     | utf8_general_ci   |

    +----------------------+-------------------+

    3 rows in set (0.00 sec)

     

     

    在控制台依然乱码。

     

    下载MYSQL Administrator,用Mysql query browser查看,OK的。

     

    只能剩下2种可能了。

     

    1.1.2    JDBC直接连接DB

    String url =     "jdbc:mysql://127.0.0.1:3306/scmproj?user=root&password=mysql&useUnicode=true&characterEncoding=GB2312";

     

                         java.sql.Connection con = DriverManager.getConnection(url);

     

                         Statement stmt = con.createStatement();

     

          

                         String query = "select * from users where email='yi.suy@alibaba-inc.com'";

     

                         ResultSet rs = stmt.executeQuery(query);

     

                while (rs.next())

     

                         {

                                // System.out.println(new

                                // String(rs.getString(1).getBytes("UTF8")).toString());

                                System.out.println(new String(rs.getString("fullname")));

                         }

      

      同样输出正确。

     

    1.1.3    IBATIS API连接DB

    private static SqlMapClient sqlMapper;

     

    private static SqlMapClient sqlMapper;  Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");

                         // Reader reader =

                         // Resources.getResourceAsReader("D:/eclipse-SDK-3.3.2-win32/project/SCMProj/bin/SqlMapConfig.xml");

                         sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader);

                         reader.close();

     

    List list =sqlMapper.queryForList("getProjectByName", queryStr);

                                        SCMProject proj=(SCMProject) list.get(0);

     

    正常。

     

    剩下来的就是检查SPRING的编码格式了。

     

    最后锁定SPRING   VelocityViewResolver

    <property name="contentType" value="text/html;charset=UTF-8" />

     

  • [Ruby学习] 在ruby中调用dll

    2008-09-24 17:19:10

                                                                          -----by Nish 

      开源测试工具watir是采用的ruby语言进行开发的。在研究watir框架的时候,发现有一部分函数watir没有提供而且暂时没找到合适的gem包,而很多功能在我们原来的自动化测试框架中都通过c写的dll进行了实现,于是我们希望能够把这部分的dll无缝的移植到watir上,减少我们的工作量,而且可以更高效的实现我们需要的功能。

      在ruby的开源项目中,Win32Api这个gem可以实现我们需要的功能。通过以下方法 ,我们就可以调用外部dll中的函数。

    Win32Api.new(dllname, proc, import, export)

    参数说明

    dllname:dll文件的名字,如果想只写dll的名字,可以将dll放到system32目录或者当前目录下,或者写上dll文件所在的路径

    proc: dll中函数的名字

    import:函数传入参数的参数类型,其中 "p" 对应指针,"n","l"对应long,"i"对应 int,"v" 对应void,如果有多个参数,可以通过 ["p","n"]数组的方式来实现,其中置为nil可以表示没有参数

    export:函数的返回值类型,参数类型同上

     

    Win32API#call([args ...])

    调用dll中的函数,参数和返回值应该与new申明中的一致,如果返回一个指针,需要事前初始化,否则可能会有内存溢出问题。

     

    例子:

    有个dll的头文件的申明为:

    extern "C" long PASCAL EXPORT BMPToJPG(char *jpg,char *bmp);

    那么在将指定的dll文件放在当前目录,ruby代码如下

    require 'rubygems'

    require 'Win32Api'

    JPG=Win32API.new(File.dirname(__FILE__)+"\\JpgDll.dll","BmpToJpg",["p","p"],"l")

    JPG.call("D:\\1.bmp","D:\\1.jpg")

    执行上述代码后,就能把D盘下的1.bmp文件另存为 1.jpg文件

  • HTTP GET请求传输汉字给SPRING MVC的处理

    2008-09-15 12:58:14

    HTTP GET请求在提交数据给服务器方面和POST有很多差异。比如传输字节数大小,编码要求等。

    HTTP GET请求要求对汉字进行URL 编码。

     

    IE客户端javascrīpt/vbscrīpt代码。

        

     

    <scrīpt language="vbscrīpt">

    Function GetByteCode(ch)   

        code = Asc(ch)          ' -20001

        GetByteCode = Hex(code) ' "B1DF"

    End Function

    </scrīpt>


    <scrīpt language="javascrīpt">

    String.prototype.urlEncode = function() {

        var r = "";

        for (var i = 0; i < this.length; i++) {

            var code = "" + GetByteCode(this.charAt(i));

            if (code.length > 2) {

                var b1 = code.substr(0, code.length - 2);

                var b2 = code.substr(code.length - 2);

                if (i == 0) {

                    //alert("" + code + ", " + b1 + ", " + code.length + ", " + b2);

                }

                r += "%" + b1 + "%" + b2;

            } else {

                r += "%" + code;
            }
        }
        return r;
    }

    </scrīpt>

     

     

     

    调用上述函数编码

    Var  projectname=”项目1”;

    var urlEncoded=projectname.urlEncode();

     var url="insertCheckList.do?projectname="+urlEncoded;

    接下来就是用AJAX  httprequest发送给JBOSS/TOMCAT。

     

     

     

    服务器端SPRING 接收到字符串解码:

     

    public ModelAndView handleRequestInternal(HttpServletRequest request,

               HttpServletResponse response) throws Exception {

     

    String encodeProj = request.getParameter("projectname");

          

               //客户端经过编码后的汉字

              

               String projectname= new String( encodeProj.getBytes( "8859_1" ) , "gb2312" );

               System.out.println(projectname);      

     

    }

  • spring+ibatis+velocity+ajax开发WEB应用小结

    2008-09-06 23:14:27

    这二周闭关开发内部配置管理员用的发布需求流程工具。

    主要的技术为:java spring+ ibatis+ velocity+ ajax/javascrīpt/css+mysql。

    IDE: eclipse。

    以下简要描述各个技术点应用状况。

    (1) java spring: spring很好整合了当下成熟的框架,最突出的概念有2点: IOC 和 AOP。
    spring支持ibatis,hibernate等 O/R MAP工具。支持 JSP/Velocity/struct等V层展现。
    另外,有jpetstore经典的例子、台湾林信良的spring2技术手册引导入门。

    可以运行在JBOSS/TOMCAT上,且其轻量。第一个念头就是用它实现。

    偶高频率应用SimpleFormController完成http请求以及响应。

    比较不爽的是,一堆的XML 配置文件。

    2) 数据方面有同步 confluence数据的需求、导入EXCEL数据需求,且数据量不大。故用单机版的MYSQL足够了。

    本次采用gb2312编码保存数据、页面信息。

    3)  O/R映射方面采用ibatis。 ibatis比hibernate轻量,又能自由操作SQL。

    ibatis 在被JBOSS/TOMCAT运行时加载 sql-map文件,如果SQL和数据库、配置文件有错误,将导致deploy失败。

    数据库如何设计得更合理,适应未来应用增加、环境增加是我考虑最多的点。

    4)  界面展现采用velocity。 这个是偶最不熟悉的。

    感觉最麻烦是它的调试。貌似语言能力偏弱,一些复杂类型的读写有困难。 复杂运算都在SPRING内计算。

    后来直接在spring ModelAndView方法,将简单对象或者List、数组保存为 session 在页面间传递。如
    request.getSession().setAttribute("currUsername", user.getUsername());

    5) ajax/javascrīpt/css应用在2个场景:

     第一个是表格的动态增加, 采用ajax定期更新部分页面信息达到提醒功能,一些常用控件(如日期选取),客户端输入验证等
     
     第二个就是界面美化。 基本功能完成后,看到页面太简陋了。偶从http://www.okajax.com/a/200806/062322552008.html 找了一些特效嵌入。

  • [论坛] jmeter资源监控器开发——增加监控数据

    2008-07-31 22:14:50

    by jack

        jmeter自带的监控器输出的只有四条曲线,其中health和load曲线还是根据mem和thread算出来的,所以真正意义上输出的数据只有两个而已。显然这远远满足不了我们对性能监控的需要么。

        既然jmeter没有,那我就有用武之地了(要不然要我这QA架构师干啥,哈),于是我自己添了几个,用着还不错,现在把添加一个参数的过程完整叙述如下:

    以增加swapout为例,取xml中的currentThreadsBusy作为swapout的值。

    蓝色字注明关键点:

    Stats.java

    增加新的数据解析方法

     

           public static int calculateSwapout(Status stat) {

                  double swapout = 0;

                  if (stat != null && stat.getConnector().size() > 0) {

                         Connector cntr = (Connector) stat.getConnector().get(0);

                         swapout = cntr.getRequestInfo().getCurrentThreadsBusy();

                  }

                  return (int) swapout;

           }

     

    MonitorStats.java

    增加私有静态变量

     

           private static final String SWAPOUT = "stats.swapout";

     

    增加构造函数入参、赋值语句

     

           public MonitorStats(int health, int load, int cpuload, int memload, int threadload, int swapin, int swapout, String host, String port,

                         String protocol, long time) {

                  this.setHealth(health);

                  this.setLoad(load);

                  this.setCpuLoad(cpuload);

                  this.setMemLoad(memload);

                  this.setThreadLoad(threadload);

                  this.setSwapin(swapin);

                  this.setSwapout(swapout);

                  this.setHost(host);

                  this.setPort(port);

                  this.setProtocol(protocol);

                  this.setTimeStamp(time);

           }

     

    增加相应setget方法

     

           public void setSwapout(int load) {

                  this.setProperty(SWAPOUT, String.valueOf(load));

           }

     

           public int getSwapout() {

                  return this.getPropertyAsInt(SWAPOUT);

           }

     

    MonitorModel.java

    增加私有变量对象current初始化中MonitorStats实例化的入参

     

           private MonitorStats current = new MonitorStats(0, 0, 0, 0, 0, 0, 0, "", "", "", System.currentTimeMillis());

     

    增加clearData方法中MonitorStats实例化的入参

     

                  current = new MonitorStats(0, 0, 0, 0, 0, 0, 0, "", "", "", System.currentTimeMillis());

     

    增加相应get方法

     

           public int getSwapout() {

                  return this.current.getSwapout();

           }

     

    增加cloneMonitorStats方法的入参

     

           public MonitorStats cloneMonitorStats() {

                  return new MonitorStats(current.getHealth(), current.getLoad(), current.getCpuLoad(), current.getMemLoad(),

                                current.getThreadLoad(), current.getSwapin(), current.getSwapout(), current.getHost(), current.getPort(), current.getProtocol(), current

                                              .getTimeStamp());

           }

     

    MemoryBenchmark.java

    增加main方法中MonitorStats实例化的入参

     

                                MonitorStats mstats = new MonitorStats(Stats.calculateHealth(st), Stats.calculateLoad(st), Stats.calculateCpuLoad(st), Stats

                                              .calculateMemLoad(st), Stats.calculateThreadLoad(st), Stats.calculateSwapin(st), Stats.calculateSwapout(st), "localhost", "8080", "http", System

                                              .currentTimeMillis());

     

    MonitorAccumModel.java

    增加addSample方法中MonitorStats实例化的入参

     

                                   MonitorStats stat = new MonitorStats(Stats.calculateHealth(st), Stats.calculateLoad(st), Stats.calculateCpuLoad(st), Stats

                                                 .calculateMemLoad(st), Stats.calculateThreadLoad(st), Stats.calculateSwapin(st), Stats.calculateSwapout(st), surl.getHost(), String.valueOf(surl

                                                 .getPort()), surl.getProtocol(), System.currentTimeMillis());

     

    增加createNewMonitorModel方法中MonitorStats实例化的入参

     

                  MonitorStats stat = new MonitorStats(Stats.DEAD, 0, 0, 0, 0, 0, 0, url.getHost(), String.valueOf(url.getPort()), url

                                .getProtocol(), System.currentTimeMillis());

     

    MonitorPerformancePanel.java

    增加公共静态变量(显示文案和图例,同时增加资源文件中对应项,及相应图片)

     

           public static final String LEGEND_SWAPOUT = JMeterUtils.getResString("monitor_legend_swapout_per");

     

           public static final ImageIcon LEGEND_SWAPOUT_ICON = JMeterUtils.getImage("monitor-yellow-legend.gif");

     

     

    资源文件messages.properties

    monitor_legend_swapout_per=Swap Out

     

    图片文件monitor-yellow-legend.gif

     

    增加createLegend方法中的JLabel实例化语句

     

                  JLabel jswapout = new JLabel(LEGEND_SWAPOUT);

                  jswapout.setFont(plaintext);

                  jswapout.setPreferredSize(lsize);

                  jswapout.setIcon(LEGEND_SWAPOUT_ICON);

                  legend.add(jswapout);

     

    MonitorGraph.java

    增加私有变量

     

           private boolean SWAPOUT = true;

     

    增加相应set方法

     

           public void setSwapout(boolean swapout) {

                  this.SWAPOUT = swapout;

           }

     

    增加drawSample方法中相应绘图语句

     

                  if (SWAPOUT) {

                         int swoy = (int) (height - (height * (model.getSwapout() / 10000.0)));

                         int lastswoy = (int) (height - (height * (last.getSwapout() / 10000.0)));

     

                         g.setColor(Color.yellow);

                         g.drawLine(lastx, lastswoy, xaxis, swoy);

                  }

     

     

  • [论坛] jmeter资源监控器开发——关键代码分析

    2008-07-31 22:14:50

    by jack

    代码分析也无需事无巨细皆列而剖之,只要找到关键所在也就是了;又不然列一堆的声明上来,纵然有人有耐心看下去,我也没耐心写下去啊。特别关注了三个类,Stats、MonitorPerformancePanel、MonitorGraph。分别是获取解析得到的数据、监控器面板显示和监视器上的图像绘制。下面选取了一些关键代码来进行分析:

    首先是Stats.java,下面是计算内存使用率的方法

    public static int calculateMemoryLoad(Status stat) {
      double load = 0;
      if (stat != null) {
       double total = stat.getJvm().getMemory().getTotal();
       double free = stat.getJvm().getMemory().getFree();
       double used = total - free;
       load = (used / total);
      }
      return (int) (load * 100);
     }

    很简单吧?就是获取total值和free值,然后计算内存使用率,那么它解析的是什么东西呢?我们取了一份tomcat上的status的xml,内容如下:

    <?xml version="1.0" encoding="utf-8"?><status><jvm><memory free='937000' total='5177344' max='66650112'/></jvm><connector name='http-8080'><threadInfo  maxThreads="40" currentThreadCount="2" currentThreadsBusy="1" /><requestInfo  maxTime="1715" processingTime="2819" requestCount="20" errorCount="2" bytesReceived="0" bytesSent="108662" /><workers><worker  stage="S" requestProcessingTime="0" requestBytesSent="0" requestBytesReceived="0" remoteAddr="127.0.0.1" virtualHost="localhost" method="GET" currentUri="/manager/status" currentQueryString="XML=true" protocol="HTTP/1.1" /><worker  stage="R" requestProcessingTime="0" requestBytesSent="0" requestBytesRecieved="0" remoteAddr="&#63;" virtualHost="&#63;" method="&#63;" currentUri="&#63;" currentQueryString="&#63;" protocol="&#63;" /></workers></connector><connector name='jk-8009'><threadInfo  maxThreads="200" currentThreadCount="4" currentThreadsBusy="1" /><requestInfo  maxTime="0" processingTime="0" requestCount="0" errorCount="0" bytesReceived="0" bytesSent="0" /><workers></workers></connector></status>

    这乱七八糟的,谁看得清啊,不要急,保存下来命名为.xml文件,扔到ie里再看一下

     

    其实上面那段代码所取的,就是这个xml里面的memory free和total。

    这个xml里这么多可以利用的内容,要是我们都解析出来,不就可以有很多资源数据了?有人也许会问,这些都是什么tread信息什么,又没有cpu啊,io之类的信息,解析出来也没用;要知道,这个xml文件你自己可以生成的,里面存什么数据,你自己怎么定义都行啊,定义好了,写一个动态更新这里面的数据的脚本或程序,再利用web去展现这个xml,jmeter不就可以取来用了?

    我们再看看MonitorPerformancePanel.java

     public static final String LEGEND_MEM = JMeterUtils.getResString("monitor_legend_memory_per"); //$NON-NLS-1$
     public static final ImageIcon LEGEND_MEM_ICON = JMeterUtils.getImage("monitor-orange-legend.gif"); //$NON-NLS-1$
    这两句就是设置监视器上显示的图例,是啥东西呢?就是这个:

    标识了图线的颜色和内容标签

    上面两句设置好了,要显示就要看下面这段的了:

      JLabel mem = new JLabel(LEGEND_MEM);
      mem.setFont(plaintext);
      mem.setPreferredSize(lsize);
      mem.setIcon(LEGEND_MEM_ICON);
      legend.add(mem);

    做过java的gui编程的朋友一定不会觉得陌生,呵呵

    再下来看一下MonitorGraph.java

      if (MEM) {
       int mmy = (int) (height - (height * (model.getMemload() / 10000.0)));
       int lastmmy = (int) (height - (height * (last.getMemload() / 10000.0)));

       g.setColor(Color.orange);
       g.drawLine(lastx, lastmmy, xaxis, mmy);
      }

    这段就是展现曲线的代码,可以产生如下的效果:

    用jmeter做过tomcat监控的人一定会觉得很熟悉。不过也许会问,为啥这个图像上曲线这么多呢,jmeter不是就四条么?

    呵呵,不忙,且听我慢慢道来。

401/212>
Open Toolbar