发布新日志

  • 开发自动化脚步录制器

    2013-12-16 18:47:52

    原理:

    1.   利用BHO(Browser Helper Object),在页面内装入event监听事件,当然动态装入事件,可以多种方式,用pwatir也可以。

    2.   监听事件的处理:在页面内所有元素上装一遍事件来监听,不靠谱, 这里用到了JS事件冒泡原理,因为事件会向上传递,所以只需简单的在最上次document装入监听事件。

    document.attachEvent('onmouseover', myonmouseover);

    document.attachEvent('onclick', myonclick);

    function myonclick(event){

    var element = event.srcElement;//就是被点击的元素

    //element.id, name, tagName, value ,

    //className, innerText

    //可根据以上元素来定位元素

    }

    Event参考:http://msdn.microsoft.com/en-us/library/ms535863(v=VS.85).aspx

    Element参考: http://msdn.microsoft.com/en-us/library/ms533054(v=VS.85).aspx


    安装: (win7权限问题,注册不成功,用管理员权限运行

    CBURecordBHO.rar(46.7 KB)

        regsvr32 D:\CBURecordBHO.dll

    卸载:

    regsvr32 D:\CBURecordBHO.dll /u

    使用:(IE8上可用,IE9上有问题)

    1.   F12打开开发人员工具

    2.   操作页面即可录制,按住CTRL,鼠标移到元素上即生成check

    缺点:

    1.因直接利用window.console输出,因此不支持IE6, ActiveXObject("Scripting.FileSystemObject")支持本地输出,但需要降低IE安全级别。

    2.      不是pwatir完整解决方案,只是录制环节。

    优点:

    1. JS生成录制脚步,跟Selenium一样,可根据需要生成不同语言的脚本

    2.录制反向定位可以变成回放,当然写出Selenium corejs脚本考验能力。


  • windows服务程序开发--电源计划自动切换

    2012-01-13 10:30:07

    windows服务程序开发---电源计划自动切换

    windows服务程序(Windows Service)就像系统的一些服务一样,能够自动地启动,并执行相应的操作; 而且因为服务程序的在层次上和一般的应用程序不同,其能够在系统启动时就自动地运行,而不像一般的 应用程序那样一定要在登陆后才能运行,可以暂停和重新启动而且不显示任何用户界面。这使服务非常适合在服务器上使用。 

    平台环境:  
    操作系统:windows7 企业版  
    编译环境:VS2010旗舰版  
    .Framework:4.0 

    成品展示 
    运行services.msc,启动服务控制界面 
    作用: 根据电源状态,自动切换电源计划模式( 交流电就切换成高性能模式, 电池就切换成节能模式) 
     
    使用的winAPI】 
    #根据注册表中的电源Scheme的GUID设置电源计划 
    GUID: 即Globally Unique Identifier(全球唯一标识符) 
    DWORD WINAPI PowerSetActiveScheme( 
      __in_opt  HKEY UserRootPowerKey, 
      __in      const GUID *SchemeGuid 
    ); 
    http://msdn.microsoft.com/en-us/library/windows/desktop/aa372758(v=vs.85).aspx 

    #枚举电源使用方案 
    DWORD WINAPI PowerEnumerate( 
      __in_opt   HKEY RootPowerKey, 
      __in_opt   const GUID *SchemeGuid, 
      __in_opt   const GUID *SubGroupOfPowerSettingsGuid, 
      __in       POWER_DATA_ACCESSOR AccessFlags, 
      __in       ULONG Index, 
      __out_opt  UCHAR *Buffer, 
      __inout    DWORD *BufferSize 
    ); 
    http://msdn.microsoft.com/en-us/library/windows/desktop/aa372730(v=vs.85).aspx 

    #检索指定的电源计划的友好名称(节能,高性能,平衡) 
    DWORD WINAPI PowerReadFriendlyName( 
      __in_opt   HKEY RootPowerKey, 
      __in_opt   const GUID *SchemeGuid, 
      __in_opt   const GUID *SubGroupOfPowerSettingsGuid, 
      __in_opt   const GUID *PowerSettingGuid, 
      __out_opt  PUCHAR Buffer, 
      __inout    LPDWORD BufferSize 
    ); 
    http://msdn.microsoft.com/en-us/library/windows/desktop/aa372740(v=vs.85).aspx 

    #检索系统的电源状态 
    BOOL WINAPI GetSystemPowerStatus( 
      __out  LPSYSTEM_POWER_STATUS lpSystemPowerStatus 
    ); 
    http://msdn.microsoft.com/en-us/library/windows/desktop/aa372693(v=vs.85).aspx 

    这四个电源管理API,已能满足我们serviceDemo的需求, 
    但还缺电源状态变更事件, 
    public: static  event PowerModeChangedEventHandler^ PowerModeChanged { 
    void add (PowerModeChangedEventHandler^ value); 
    void remove (PowerModeChangedEventHandler^ value); 

    http://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.powermodechanged.aspx 
    [HostProtectionAttribute(SecurityAction::LinkDemand, MayLeakOnAbort = true)] 
    public delegate void PowerModeChangedEventHandler( 
    Object^ sender,  
    PowerModeChangedEventArgs^ e 

    http://msdn.microsoft.com/en-us/library/microsoft.win32.powermodechangedeventhandler.aspx 


    事件处理句柄函数中重要参数PowerModeChangedEventArgs 
    http://msdn.microsoft.com/en-us/library/microsoft.win32.powermodechangedeventargs.aspx 

    准备的差不多了,开始组装 

    [注册事件code] 
    #include <PowrProf.h> 
    #pragma comment(lib,"powrprof.lib") 
    using namespace System; 
    SystemEvents::PowerModeChanged += gcnew  ::PowerModeChangedEventHandler(SystemEvents_PowerModeChanged/*自定义的事件处理函数*/); 

    [自定义事件处理函数] 
    void SystemEvents_PowerModeChanged(Object^ sender, PowerModeChangedEventArgs ^ e) 
    { 
    if(e->Mode==PowerModes::StatusChange){  //供电模式变更 
    SYSTEM_POWER_STATUS lpPwrStatus;    //存储电源状态 
    GetSystemPowerStatus(&lpPwrStatus); //获取电源状态 
    GUID GuidActiveSheme; //存储电源计划GUID 即Globally Unique Identifier(全球唯一标识符) 
    if(lpPwrStatus.ACLineStatus==0){    //非AC(交流电), 也就是电池模式 
    //电池模式,改成节能模式 
    FindPowerSheme("节能", &GuidActiveSheme);     //查“节能”电源计划的GUID 
    PowerSetActiveScheme(NULL, &GuidActiveSheme); //直接调用API 切换电源计划 //printf("转为节能模式\n"); 
    //printf("电池余量=%d\n", lpPwrStatus.BatteryLifePercent); 
    }else if(lpPwrStatus.ACLineStatus==1){ //AC(交流电)模式 
    //交流电模式,改成高效模式 
    FindPowerSheme("高性能", &GuidActiveSheme);   //查“高性能”电源计划的GUID 
    PowerSetActiveScheme(NULL, &GuidActiveSheme); //直接调用API 切换电源计划   //printf("转为 高性能 模式\n");  
    // printf("电池余量=%d\n", lpPwrStatus.BatteryLifePercent); 
    } 
    } 
    } 

    上面的事件函数中使用了一个根据电源计划友好名称(中文名称)查电源计划GUID的方法 
    [FindPowerSheme实现] 
    //pShemeName:  输入电源计划友好名称  
    //pGUID:       输出电源计划GUID 
    bool FindPowerSheme(LPSTR pShemeName, GUID* pGUID) 
    { 
    GUID SchemeGuid; 
    ULONG index = 0; 
    DWORD BufferSize = sizeof(GUID); 

    UCHAR pSchemeBuf[2*MAX_PATH]; 
    DWORD dwSchemeSize=2*MAX_PATH; 
    CHAR szSchemeName[2*MAX_PATH]; 

    if(!pGUID || !pShemeName) false; 

    //遍历电源计划 
    while(ERROR_SUCCESS == PowerEnumerate(NULL, NULL, NULL, ACCESS_SCHEME, index, (PUCHAR)&SchemeGuid, &BufferSize)) 
    { 
    //根据电源计划guid获取电源计划友好名称 
    PowerReadFriendlyName(NULL, (GUID*)&SchemeGuid, NULL, NULL,  (PUCHAR)pSchemeBuf, &dwSchemeSize); 
    //unicode字符串到一个多字节字符串 
    WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pSchemeBuf, -1, (LPSTR)szSchemeName, MAX_PATH, NULL, NULL); 
    if(strcmp(szSchemeName, pShemeName) == 0) //找到输入电源计划友好名称,返回 
    { 
    memcpy(pGUID, &SchemeGuid, sizeof(GUID)); 
    //printf("find ok\n"); 
    return true; 
    } 
    index++;  
    } 
    return false; 
    } 


    关于电源管理的所有代码,都已列出 
    a.编译,运行 
    b.插入拔出电源测试一下,会自动切换电源计划 


    如果是作为普通windows应用程序, 那到此已经完工, 
    但我们是要做成windows服务程序,因此需后续工作。 

    //==================[windows服务程序]=================================================== 
    ATL,Active Template Library活动模板库,是一种微软程序库, 
    支持利用C++语言编写ASP代码以及其它ActiveX程序。 
    通过活动模板库,可以建立COM组件,然后通过ASP页面中的脚本对COM对象进行调用。 
    这种COM组件可以包含属性页、对话框等等控件。 


    利用ATL来创建windows服务程序是一种简单的方法, 
    只用来创建服务程序,不需要COM支持。
     


    【创建ATL windows服务步骤】 

    a. 新建工程, 选择visual C++里ATL模板创建工程 
     
    b. ATL设置向导中的应用程序类型选择服务(ExE) 
     

    oK, 这里windows服务程序的框架已经自动生成好了, 
    但是这个空框架,是启动不起来的,上面介绍了,ATL主要是用来作com组件开发的, 
    而这个空框架是来做windows服务程序,没加上COM的初始化工作,所有写代码前的 
    第一步 在stdafx.h中加上 
    #define _ATL_NO_COM_SUPPORT  //不需要COM支持 

    第二步 添加服务程序 
    这里重载CServiceDemoModule::run 方法 
    run方法可以参考父类CAtlServiceModuleT中的run方法,在atlbase.h有定义 

    HANDLE  event; 
    HRESULT Run(int nShowCmd = SW_HIDE) throw() 

      HRESULT hr = S_OK; 
    hr = __super::PreMessageLoop(nShowCmd); 
    if (hr == S_OK) 

    if (m_bService) 
         
          //可以在这里启动线程,或者什么其他东西来做自己的工作的啦 
           event = CreateEvent(NULL, FALSE, FALSE, NULL);     //这里初始化无事件状态,否则调用ReSetEvent函数,置事件为无状态 
    //HANDLE hThread  =  CreateThread( NULL, 0, ThreadFunc, NULL, 0, NULL);  //这里没有新开线程来处理 
            LogEvent(_T("CServiceDemoModule 的服务启动。。。。。。 ")); 
        SetServiceStatus(SERVICE_RUNNING); 

    LogEvent (_T("PowerModeChanged start.........")); 
    //注册电源状态变更事件 
    SystemEvents::PowerModeChanged += gcnew  ::PowerModeChangedEventHandler(SystemEvents_PowerModeChanged); 
    ::WaitForSingleObject(event,INFINITE);   //由于没在新开线程中处理,这个阻塞一定不能落下
     
    LogEvent (_T("PowerModeChanged stop.........")); 
     } 
    //进入消息循环,不停的处理消息,可能最后分发到Handler去处理,调用了OnShutdown等函数的。 
    __super::RunMessageLoop(); 

    if (SUCCEEDED(hr)) 
     { 
    hr = __super::PostMessageLoop(); 
       

    return hr; 
    }
     

    // 重写,服务退出处理 
    void OnStop() throw() 
    { 
    SetEvent(event);    //设置有事件状态, 使阻塞函数WaitForSingleObject可以退出 
    LogEvent(_T("CServiceDemoModule退出!!!! ")); 

    SetServiceStatus(SERVICE_STOP_PENDING); 
    PostThreadMessage(m_dwThreadID, WM_QUIT, 0, 0); 
    } 

    LogEvent 的输出日志,可以通过eventvwr.msc 事件查看器,浏览 

    到此所有代码完成,但编译时会有错误,需要公共语言运行时(/clr)支持 
    也就是net.Framework支持 
    Alt+F7 打开项目属性配置,在【配置属性】的【常规】栏目中选择【公共语言运行时(/clr)支持】 

     

    重新编译通过。 


    第三步 注册windows服务程序 
    a. 进入编译输出目录(如 E:\code\vc2010\ServiceDemo\Debug) 
    b. 执行ServiceDemo.exe  /service 注册服务 (ServiceDemo.exe  /UnRegServer 注销服务) 
    c. 执行services.msc,打开服务管理窗口,就可以找到ServiceDemo服务了,然后启动服务 
    本来应该已是全部完成了,但是拔出电源测试一下,没反应,原来 
    只有在消息泵运行时,才会引发此事件。 在 Windows 服务中,除非使用隐藏窗体或者手动启动消息泵,否则不会引发此事件。 有关演示如何在 Windows 服务中使用隐藏窗体来处理系统事件的代码示例,请参见 SystemEvents 类 
    http://msdn.microsoft.com/zh-cn/express/microsoft.win32.systemevents.powermodechanged(en-us,VS.100).aspx 
    所有还得再加一步 


    最后一步: ServiceDemo服务的属性中增加【允许与桌面交互】 

      
    重新启动服务,能正常工作, Demo结束!!! 
  • 自动化测试中的图片相似度

    2012-01-10 09:46:52

    c++ opencv  VS python PIL   VS java BufferedImage
    //=======================opencv============================= 
    基本介绍: 
    OpenCV的全称是:Open Source Computer Vision Library  。OpenCV于1999年由Intel建立,现在由Willow Garage提供支持。OpenCV是一个基于BSD许可证授权(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法,最新版本是2.3。 
    应用领域 
           1、人机互动 
      2、物体识别 
      3、图象分割 
      4、人脸识别 
      5、动作识别 
      6、运动跟踪 
      7、机器人 
    opencv直方图比较: 
    相关系数: 


    卡方:

     
    交集: 

     
    巴氏距离: 


    相似度的源码: 

    /* 
    引入opencv 
    在项目属性的 
    头文件目录和库文件目录 
    分别加上OpenCV的头和库目录如 
    包含目录: 
    E:\code\vc2010\OpenCV2.2\include\opencv 
    E:\code\vc2010\OpenCV2.2\include\ 
    库目录: 
    E:\code\vc2010\OpenCV2.2\lib 


    */ 
    #include <cv.h> 
    #include <highgui.h> 
    using namespace cv; 

    //直方图尺寸 
    int HistogramBins = 256; 
    float Range1[]={0,255}; 
    float *HistogramRange=Range1; 


    //两个比较图形对象 
    IplImage *Image1=cvLoadImage("E:\\code\\python\\o_1.JPG",0); 
    IplImage *Image2=cvLoadImage("E:\\code\\python\\o_2.JPG",0);
     

    //两个直方图对象 
    CvHistogram *Histogram1=cvCreateHist(1, &HistogramBins, CV_HIST_ARRAY, &HistogramRange); 
    CvHistogram *Histogram2=cvCreateHist(1, &HistogramBins, CV_HIST_ARRAY, &HistogramRange);



    //直方图 
    cvCalcHist(&Image1,Histogram1); 
    cvCalcHist(&Image2,Histogram2); 

    //归一化直方图 
    cvNormalizeHist(Histogram1,1); 
    cvNormalizeHist(Histogram2,1); 

    //相似度比较方法: 
    printf(“相关系数: %.4f\n",cvCompareHist(Histogram1,Histogram2,CV_COMP_CORREL)); 
    printf("卡方 : %.4f\n",cvCompareHist(Histogram1,Histogram2,CV_COMP_CHISQR)); 
    printf("交集 : %.4f\n",cvCompareHist(Histogram1,Histogram2,CV_COMP_INTERSECT)); 
    printf("巴氏距离 : %.4f\n",cvCompareHist(Histogram1,Histogram2,CV_COMP_BHATTACHARYYA)); 

    /* 
    接口参考 
    http://fsa.ia.ac.cn/opencv-doc-cn/opencv-doc-cn-0.9.7/ref/opencvref_cv.cn.htm 
    */ 

    //=======================python PIL============================= 
    实现最简单,缺点是无论图片大小,采样点固定为768点, 看了pil的C源码库,写死在代码中, 
    不过pil切割图片简单,大图可以切小块后,再比较
     

    #导入pil库 
    import  Image 

    #规格化图片方法 
    def make_regalur_image(img, size = (256, 256)): 
        return img.resize(size).convert('RGB') 

    #相似度计算方法 
    def hist_similar(lh, rh): 
        assert len(lh) == len(rh) 
        return sum(1 - (0 if l == r else float(abs(l - r))/max(l, r)) for l, r in zip(lh, rh))/len(lh) 

    #加载2张图片    
    img1=Image.open("E:\\code\\python\\o_1.JPG") 
    img2=Image.open("E:\\code\\python\\o_2.JPG") 

    #规格化图片 
    img1=make_regalur_image(img1) 
    img2=make_regalur_image(img2) 

    #计算相似度 
    ret=hist_similar(img1.histogram(), img2.histogram()) 
    print "similar=",ret 



    //=======================java============================= 
    使用BufferedImage 是用跟python计算相似度的算法(或者用opencv的巴氏距离,相关系数), 
    或者指定区域,指定采样点数 

    BufferedImage image1 = ImageIO.read(new File("E:\\code\\python\\o_1.JPG")); 
    BufferedImage image2 = ImageIO.read(new File("
    E:\\code\\python\\o_2.JPG"));
     

    int[] img1RGB=image1.getRGB(0, 0, image1.getWidth(), image1.getHeight(), null, 0, image1.getWidth()); 
    int[] img2RGB=image2.getRGB(0, 0, image2.getWidth(), image2.getHeight(), null, 0, image2.getWidth());
     

    //相似度计算公式 
    public double similar(int[] img1RGB, int[] img2RGB){ 
       
      int nSize = img1RGB.length < img2RGB.length ? img1RGB.length : img2RGB.length; 
      if(nSize==0) return 0; 
      double nSum=0.0; 
      for(int i=0; i<nSize; i++){ 
       nSum = nSum + (1 - Math.abs((double)(img1RGB
    -img2RGB)) / Math.abs(img1RGB < img2RGB ? img1RGB : img2RGB)); 
      } 
      return nSum / nSize; 
    }
     

    //计算相似度 
    double rt = similar(img1RGB, img2RGB); 
    System.out.println("rt="+rt);
     
  • MySQL vs2010编译调试和命令扩展

    2012-01-10 09:41:02

     最近Mysql数据库应用越来越广泛,所以,决定学学Mysql,把Mysql的源码下载了,希望能有利于对它的学习,看到淘宝测试人员能扩展mysql命令,自己决定也试一下 
    这里记录一下windows平台下编译Mysql的过程,以及命令扩展的过程,与大家分享一下。
     


    平台环境 
    操作系统:windows7 企业版 
    编译环境:VS2010旗舰版 
    辅助工具:CMake2.8【windows版本】 
    Mysql版本:mysql-5.1.60 
    Bison版本:bison-2.4.1 


    编译过程: 


    1. 下载mysql-5.1.60源码,解压到D:\mysql

    2. 使用CMake2.8生成vs2010工程(源码自带的脚本只支持到vs2008)

     

    3. 打开D:\mysql\sql\sql_local.cc文件,另存为UTF-8格式(带BOM头),覆盖原文件

    4. 打开D:\mysql\sql\mysqld.cc,  4352行:DBUG_ASSERT(0);改为DBUG_ASSERT(1);或者注释掉整个IF语句

    5. 将D:\mysql\win\data目录拷贝到D:\mysql\sql下

    6. 用vs2010打开D:\mysql\MySql.sln 编译全部


    调试过程
    1. 进入D:\mysql\sql\Debug\,  输入命令 mysqld --debug --standalone, 这时3306端口开启侦听(用netstat -anp tcp)

    2. 在VS2010中附加进程调试中选择“mysqld.exe”

    3. 在D:\mysql\sql\sql_show.cc 的make_db_list方法中设一个断点

    4. 进入 D:\mysql\client\Debug, 输入命令 mysql -u root -p ,进入mysql命令行客户端

    5. 在mysql命令行客户端,输入命令show databases;就会跳到vs2010中设定的断点处

    6. 进入D:\mysql\client\Debug, 输入命令 mysqladmin shutdown -u root -p   关闭mysql服务

    现在有了源码,而且可以方便的在vs2010设定断点跟踪,可以好好学习了




    命令扩展过程
    主要参考:《Expert MySQL》第8章第3节

    现有SQL不能满足需要,自定义函数也解决不了,可以考虑新增SQL命令。

    通过修改源代码的方法,扩展MySQL功能,比较复杂和繁琐。

    1. 修改解析器(D:\mysql\sql\sql_yacc.yy)

    2. 添加命令路由(D:\mysql\sql\sql_parse.cc)

    3. 添加命令实现函数代码(D:\mysql\sql\sql_show.cc)

    具体步骤:
    1.修改解析器
    1.1 在lex.h 增加命令符号,
    在符号表数组static SYMBOL symbols[] = {}中增加,自定义符号DISK_USAGE
    { "DISK",  SYM(DISK_SYM)}, 
    { "DISK_USAGE",  SYM(DISK_USAGE_SYM)}, /*guoping.gugp add*/ 
    { "DISTINCT",  SYM(DISTINCT)},

    1.2 在sql_lex.h 增加助记符,命令路由时用
    在命令助记符枚举表enum enum_sql_command{}中,增加助记符SQLCOM_SHOW_DISK_USAGE
    SQLCOM_SHOW_COLUMN_TYPES, SQLCOM_SHOW_STORAGE_ENGINES, SQLCOM_SHOW_PRIVILEGES, 
    SQLCOM_SHOW_DISK_USAGE, /*guoping.gugp add*/ 
    SQLCOM_HELP, SQLCOM_CREATE_USER, SQLCOM_DROP_USER, SQLCOM_RENAME_USER,

    1.3 把新增符号添加到解析器(把1.1和1.2的符号关联起来)
    在sql_yacc.yy中增加符号
    %token  DISK_SYM 
    %token  DISK_USAGE_SYM     /* guoping.gugp add */ 
    %token  DISTINCT                      /* SQL-2003-R */
    在sql_yacc.yy中的show:增加符号处理, 注意竖线不能缺
    /* guoping.gugp add */ 
     SHOW DISK_USAGE_SYM 
     { 
      LEX *lex=Lex; 
      lex->sql_command=SQLCOM_SHOW_DISK_USAGE; 
     }| 

              SHOW
             {

    2. 添加命令路由
    2.1 在mysql_priv.h增加新命令执行函数的申明
    bool mysqld_show_authors(THD *thd); 
    bool show_disk_usage_command(THD *thd); /*guoping.gugp add*/ 
    bool mysqld_show_contributors(THD *thd);

    2.2 在sql_parse.cc的命令路由中增加新命令路由(1.3中解析器关联到新命令的执行函数show_disk_usage_command)
    case SQLCOM_SHOW_AUTHORS: 
        res= mysqld_show_authors(thd); 
        break; 
    case SQLCOM_SHOW_DISK_USAGE:    /*guoping.gugp add*/ 
       res= show_disk_usage_command(thd); 
       break; 

    case SQLCOM_SHOW_CONTRIBUTORS: 
        res= mysqld_show_contributors(thd); 
        break;

    3. 添加命令实现函数代码
    在sql_show.cc中增加命令实现函数
    /* guoping.gugp add begin */ 
    bool show_disk_usage_command(THD *thd) 

     List<Item> field_list; 
     Protocol *protocol= thd->protocol; 
     DBUG_ENTER("show_disk_usage");
     /* send fields */ 
     field_list.push_back(new Item_empty_string("CBU_Database",50)); 
     field_list.push_back(new Item_empty_string("CBU_Size (kb)",30));
     if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) 
      DBUG_RETURN(TRUE);
     /* send test data */ 
     protocol->prepare_for_resend(); 
     protocol->store("B2B_CBU_ROW", system_charset_info); 
     protocol->store("1024", system_charset_info); 
     if(protocol->write()) 
      DBUG_RETURN(TRUE);
     my_eof(thd);
     DBUG_RETURN(FALSE); 
    }/* guoping.gugp add end */

    4. 重新编译 
    4.1 在windows编译,会有符号未定义错误,需在sql_yacc.cc 中增加定义 
    /* Substitute the variable and function names.  */ 
    #define yyparse      MYSQLparse 
    #define yylex          MYSQLlex 
    #define yyerror        MYSQLerror 
    #define yylval          MYSQLlval 
    #define yychar         MYSQLchar 
    #define yydebug       MYSQLdebug 
    #define yynerrs         MYSQLnerrs 


    4.2 使用bison,重新生成解析器代码 
    bison -y -d sql_yacc.yy 
    会生成两个新文件y.tab.c 和y.tab.h,分别替换掉之前原有的sql_yacc.cc和sql_yacc.h 


    4.3 大功告成,重新编译mysql 
    启动mysql服务器  D:\mysql\sql\Debug\mysqld --debug --standalone 
    启动mysql客户端  D:\mysql\client\Debug\mysql -u root 
    执行新命令 show DISK_USAGE 

     
  • loadrunner扩展之环境准备 vc2008+LR8.1

    2010-10-29 16:21:41

    工具准备阶段: loadrunner, VC2008
    1.  Microsoft Visual Studio2008 (vc9 vc2008)
    D:\Program Files\Microsoft Visual Studio 9.0\
    vc2008个头大,安装完1.6G左右,考虑到我可怜的C盘,还是挪窝


    2.  Mercury Loadrunner (LR8.1)
    C:\Program Files\Mercury Interactive\Mercury LoadRunner
    默认路径,LR8.1个头也不小,600M左右


    3. 编译环境设置
    3.1. 菜单文件-->新建-->项目  或者快捷键 ctrl+shift+N    (看不清,点图放大)

    3.2. 确定后,再点下一步, 不要直接点完成哦(看不清,点图放大)

    3.3. 完成的,最终成果(看不清,点图放大):

    4.  洗洗手,开始上把,先来个简单的
    4.1 编辑lr_dll_test.h 头文件
    在自动生成的fnlr_dll_test函数声明前,加上extern "C"
    //自动生成的
    //LR_DLL_TEST_API int fnlr_dll_test(void);
    //修改后的, 因为LR只支持C,不支持C++,所有加上extern "C",
    //告诉编译器,用C语法编译器
    extern "C" LR_DLL_TEST_API int fnlr_dll_test(void);
    4.2 编辑 lr_dll_test.cpp
    //根据兴趣修改自动导出示例
    // 这是导出函数的一个示例。
    LR_DLL_TEST_API int fnlr_dll_test(void)
    {
        int a = 50;
        int b = 200;
        return a+b;
    }
    4.3 大功告成(简单吧,其实只加了一句extern "C" ),开始编译
    菜单 生成->生成解决方案  或 快捷键 F7, 在lr_dll_test\Debug
    目录下生成lr_dll_test.dll。

    5. LR调用DLL方法,有两种
       5.1一种是通过lr_load_dll函数,
         5.1.1直接指定路径lr_load_dll("D:\\vc2008\\lr_dll_test\\Debug\\dll_test.dll");
                注意是两反斜杠
         5.1.2 拷贝DLL到LR脚本目录,或者LR安装目录,直接lr_load_dll("dll_test.dll")
           C:\Program Files\Mercury Interactive\Mercury LoadRunner\bin
       5.2第二种是全局调用,VUGen启动时自动加载
          修改,LR安装目录,dat子目录下的mdrv.dat文件,[lrun] 字段,在末尾添加
          C:\Program Files\Mercury Interactive\Mercury LoadRunner\dat\mdrv.dat
        [lrun]
        ExtPriorityType=communication
        WINNT_EXT_LIBS=lrun50.dll
        WIN95_EXT_LIBS=lrun50.dll
        LINUX_EXT_LIBS=libLrun50.so
        SOLARIS_EXT_LIBS=libLrun50.so
        HPUX_EXT_LIBS=libLrun50.sl
        AIX_EXT_LIBS=libLrun50.so
        LibCfgFunc=lr_configure
        ExtMessageQueue=0
        WINNT_DLLS=dll_test.dll

       5.3, 写个简单的脚本,调用刚才写的 fnlr_dll_test
       


    6.注意点:
      6.1 DLL导出函数,需返回整形,如需返回char*型,
         LR调研时需加上强制转换,同理,返回结构指针也需强制转换
          p = (char*)fnlr_dll_test2(buff, 2);  不然会出错 
         “have illegal types `pointer to char' and `int'"
      6.2 DLL导出函数,动态申请的内存,无法在LR脚本中释放free,
            需另写一个free的导出函数。
            出错信息:  memory violation : Exception ACCESS_VIOLATION received
      6.3 LR不支持C++,当然无法导出类,引用调用等c++才有的特征

          


  • Loadrunner 扩展 --VC2008

    2010-10-29 15:43:57

    Loadrunner 扩展 包含部分:

    扩展介绍---怎么对loadrunner扩展

    1.  扩展一: 正则表达式支持

    2.  扩展二: MD5加密

    3.  扩展三: iconv转码

    4.  扩展四: hash支持

    5.  扩展五: URL编码

    6.  扩展六: 调用LR函数,完善select取值,eval_string内存泄露问题

    7.  扩展七: memcache验证码


    1.  扩展一: 正则表达式支持

         待选方案是boost::regex 或者微软的greta

    2.  扩展二: MD5加密

         选用网上的C语言实现MD5算法 就成,测试了几个,没问题

    3.  扩展三: iconv转码

         就用iconv静态库封装了

    4.  扩展四: hash支持

        boost, stl 等,自己手痒,看到暴雪的hash,简单实现了一下

    5.  扩展五: URL编解码

        UTF8的URL编码,16进制前加个%, 很简单的一种编解码

    6.  扩展六: 调用LR函数

        关键是项目要包含LR的头文件和库,然后就可以顺心所欲包装LR常用函数和过程

    7.  扩展七: memcache验证码

       这个还没实现

    未完,请关注后续一一实现细节




  • Testlink1.7.4 升级FCKeditor2.0到2.6

    2008-11-03 12:14:29

    Testlink1.7.4 自带的FCKeditor版本为2.0,升级到最新的2.6.3

    2.6.3更新内容见:http://www.fckeditor.net/whatsnew/all

    1. 下载最新版FCKeditor 2.6.3
     1.1进入testlink目录:
      cd testlink/third_party/
     1.2下载文件:
      wget http://nchc.dl.sourceforge.net/sourceforge/fckeditor/FCKeditor_2.6.3.tar.gz

    2. 解压文件
     2.1备份fckeditor:
      mv fckeditor fckeditor_bak
     2.2解压文件:
      tar zxvf FCKeditor_2.6.3.tar.gz
     
    3. 修改参数
    -----------------------------------------------------------------------------------------------------
    修改文件:testlink/third_party/fckeditor/fckconfig.js
    ------------------------------------------------------------------------------------------------------
     修改前:
     // FCKConfig.ProtectedSource.Add( /<\?[\s\S]*?\?>/g ) ; // PHP style server side code
     修改后:(去掉注释)
     FCKConfig.ProtectedSource.Add( /<\?[\s\S]*?\?>/g ) ; // PHP style server side code
     
     修改前:
     
     var _FileBrowserLanguage = 'asp' ; // asp | aspx | cfm | lasso | perl | php | py
     var _QuickUploadLanguage = 'asp' ; // asp | aspx | cfm | lasso | perl | php | py
        修改后:(设置成php)
        var _FileBrowserLanguage = 'php' ; // asp | aspx | cfm | lasso | perl | php | py
     var _QuickUploadLanguage = 'php' ; // asp | aspx | cfm | lasso | perl | php | py
       
       
    -----------------------------------------------------------------------------------------------------
    修改文件:testlink/third_party/fckeditor/editor/filemanager/connectors/php/config.php
    -----------------------------------------------------------------------------------------------------
    注意大小写

    修改前:
     $Config['UserFilesPath'] = '/userfiles/' ;
    修改后: 
     $Config['UserFilesPath'] = '/testlink/userfiles/' ;
     
    修改前:
     $Config['QuickUploadPath']['File']  = $Config['FileTypesPath']['File'] ;
    修改后: 
     $Config['QuickUploadPath']['File']  = $Config['FileTypesPath']['File'] ;
     $Config['QuickUploadPath']['Image']  = $Config['FileTypesPath']['Image'] ;
     $Config['QuickUploadPath']['Flash']  = $Config['FileTypesPath']['Flash'] ;
     $Config['QuickUploadPath']['Media']  = $Config['FileTypesPath']['Media'] ;


     
    4. 确认创建上传目录 
    在testlink的下传教userfiles目录
      mkdir userfiles
     
      在userfiles目录下创建4个目录
      cd userfiles
     
      mkdir file
      mkdir flash
      mkdir image
      mkdir media

    注: 关于TestLink1.7.4 自带FCKeditor上传图片的问题的解决方法:

        见:http://www.51testing.com/?66291/action_viewspace_itemid_96482.html

     

  • Testlink1.7.4 上传图片问题(linux, php)

    2008-11-03 11:30:51

    -----------------------------------------------------------------------------------------------------   
    修改文件:testlink/third_party/fckeditor/fckconfig.js
    ------------------------------------------------------------------------------------------------------   
     修改前:
     // FCKConfig.ProtectedSource.Add( /<\?[\s\S]*?\?>/g ) ;    // PHP style server side code
     修改后:(去掉注释)
     FCKConfig.ProtectedSource.Add( /<\?[\s\S]*?\?>/g ) ;    // PHP style server side code
     
     修改前:
     var _FileBrowserLanguage      = 'asp' ;       // asp | aspx | cfm | lasso | perl | php | py
        var _QuickUploadLanguage      = 'asp' ;       // asp | aspx | cfm | lasso | php
        修改后:(设置成php)
        var _FileBrowserLanguage        = 'php' ;       // asp | aspx | cfm | lasso | perl | php | py
        var _QuickUploadLanguage        = 'php' ;       // asp | aspx | cfm | lasso | php
       
    ------------------------------------------------------------------------------------------------------   
    修改文件:testlink/third_party/fckeditor_bak/editor/filemanager/browser/default/connectors/php/config.php
    ------------------------------------------------------------------------------------------------------   
        修改前:
        $Config['Enabled'] = false ;
        修改后:
     $Config['Enabled'] = true ;
     
     修改前:
     $Config['UserFilesPath'] = '/userfiles/' ;
     修改后:
     $Config['UserFilesPath'] = '/testlink/userfiles' ;
     
    ------------------------------------------------------------------------------------------------------    
    修改文件:testlink/third_party/fckeditor_bak/editor/filemanager/upload/php/config.php
    ------------------------------------------------------------------------------------------------------
     修改前:
     $Config['Enabled'] = false ;
     修改后:
     $Config['Enabled'] = true ;      
     
     修改前:
     $Config['UserFilesPath'] = '/userfiles/' ;
     修改后:
     $Config['UserFilesPath'] = '/testlink/userfiles/image/' ;
     
    ------------------------------------------------------------------------------------------------------     
    修改文件:testlink/third_party/fckeditor_bak/editor/filemanager/upload/php/upload.php
    ------------------------------------------------------------------------------------------------------ 
     修改前:
     $sServerDir .= $sType . '/' ;
     修改后:
     $sServerDir .= strtolower($sType) . '/' ;
     
     修改前:
     $sFileUrl = $Config["UserFilesPath"] . $sType . '/' . $sFileName ;
     修改后:
     $sFileUrl = $Config["UserFilesPath"] . strtolower($sType) . '/' . $sFileName ;
     
    ------------------------------------------------------------------------------------------------------
    修改文件:创建上传目录
    ------------------------------------------------------------------------------------------------------
      在testlink的下传教userfiles目录
      mkdir userfiles
     
      在userfiles目录下创建4个目录
      cd userfiles
     
      mkdir file
      mkdir flash
      mkdir image
      mkdir media

    修改文件比较多,有点复杂,请把fckeditor升级到2.6,修改比较简单

    详见:http://www.51testing.com/?66291/action_viewspace_itemid_96484.html

Open Toolbar