Symfoware(R) Server RDBユーザーズガイド 応用プログラム開発編 - FUJITSU -
目次 索引 前ページ次ページ

上へ第3章 ルーチンを利用する応用プログラムの作成方法
上へ3.2 ファンクションルーチンを利用する場合

3.2.7 テストドライバの作成および単体テストの実施

作成したファンクションルーチンは、Symfoware/RDBを介して実行する前に、テストドライバを利用して単体テストを行い、十分な品質を確保しておく必要があります。

テストドライバが直接ファンクションルーチンのライブラリを呼び出すことで、Symfoware/RDBを介さずに単体テストを行うことができます。

また、SQLSignalMSG関数を使用してファンクションルーチンから異常通知するプログラムを作成した場合の単体テストは、ダミーのSQLSignalMSG関数を用意し、Symfoware/RDBを介さずにテストを行う必要があります。

image

(1) ファンクションルーチンのライブラリ作成

(2) テストドライバの実行形式作成

(3) ダミーSQLSignalMSG関数のライブラリ作成

(4) リンクするライブラリの設定

(5) リンクするライブラリの再設定

■ファンクションルーチンのライブラリ作

ファンクションルーチンのライブラリを作成します。

ライブラリ作成についての詳細は“ライブラリの作成”を参照してください。

以下にファンクションルーチンのライブラリ作成例を示します。

[Solaris OEの場合]

ファンクションルーチンのライブラリ作成例

cc -G -o /usr/local/lib/libuserfunc001.so userfunc001.c -mt

[Linuxの場合]

ファンクションルーチンのライブラリ作成例

gcc -shared -o /usr/local/lib/libuserfunc001.so userfunc001.c -D_REENTRANT

■テストドライバの実行形式作

ファンクションルーチンをテストするためのテストドライバの実行形式を作成します。

テストドライバのプログラム例およびテストドライバ実行形式の作成例を以下に示します。

ファンクションルーチン“USERFUNC002”用テストドライバ(ftestdrv001.c)のプログラム例

/*-------------------------------------------------------------*/
/* ファンクションルーチン"USERFUNC002"用テストドライバ         */
/*-------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#ifdef NT
#include <windows.h>
#else
#include <dlfcn.h>
#endif

/* 引数データのポインタリスト */
typedef struct in_ptr_list_tag {
    void  *ptr[2];    /* ファンクションのパラメタの個数×2 */
} in_ptr_list_t;

/* 結果データのポインタリスト */
typedef struct out_ptr_list_tag {
    void  *ptr[2];    /* 返却データと標識データの格納先 */
} out_ptr_list_t;

/* 呼び出し関数名 */
#define FUNC_NAME  "UserFunc002"
/* ライブラリのパス */
#ifdef NT
#define FUNC_PATH  "D:\\FORSYMFO\\FUNCLIB\\USERFUNC002.DLL"
#else
#define FUNC_PATH  "/export/home/kanda/Function/libuserfunc002.so"
#endif

int main()
{
    void        *handle_p;       /* dlopenのハンドラ       */
    void        (*sym_p)();      /* アドレスベクタ         */
    int         data1;           /* 引数1データ格納用     */
    short       ind1;            /* 引数1標識データ格納   */
    char        ret[43];         /* 結果データ格納用       */
    short       r_ind;           /* 結果の標識データ格納用 */
    short       ret_size;        /* 結果データの実データ長 */
    char        buf[41];         /* 結果データ表示用       */

    /* 入出力のポインタリスト */
    in_ptr_list_t   in_ptr_list;
    out_ptr_list_t  out_ptr_list;

#ifdef NT
    printf("drv002:LoadLibrary start\n");
    /* ファンクションルーチンのライブラリをオープン */
    handle_p = LoadLibrary(FUNC_PATH);
#else
    printf("drv002:dlopen start\n");
    /* ファンクションルーチンのライブラリをオープン */
    handle_p = dlopen(FUNC_PATH, RTLD_NOW);
#endif
    if (handle_p == NULL) {
        return(1);
    }

#ifdef NT
    printf("drv002:GetProcAddress start\n");
    /* ライブラリの入口アドレスの取得 */
    sym_p = (void (*)())GetProcAddress(handle_p, FUNC_NAME);
    if (sym_p == NULL) {
        FreeLibrary(handle_p);
        return(2);
    }
#else
    printf("drv002:dlsym start\n");
    /* ライブラリの入口アドレスの取得 */
    sym_p = (void (*)())dlsym(handle_p, FUNC_NAME);
    /* ライブラリの入口アドレスの取得 */
    sym_p = (void (*)())dlsym(handle_p, FUNC_NAME);
    if (sym_p == NULL) {
        dlclose(handle_p);
        return(2);
    }
#endif

    printf("drv002:make indata\n");
    /* 入力データの作成 */
    data1 = -100;                   /* 負の値 */
    ind1  = 0;
    in_ptr_list.ptr[0] = &data1;    /* 引数1のデータ     */
    in_ptr_list.ptr[1] = &ind1;     /* 引数1の標識データ */

    printf("drv002:make outdata area\n");
    /* 結果データ格納先の準備 */
    memset(ret, 0x00, sizeof(ret));
    r_ind = -1;
    out_ptr_list.ptr[0] = ret;      /* 結果データ格納先     */
    out_ptr_list.ptr[1] = &r_ind;   /* 結果標識データ格納先 */

    /* ファンクションルーチンの呼び出し */
    printf("drv002:call func\n");
    (*sym_p)(&in_ptr_list, &out_ptr_list);
    printf("drv002:call func end\n");

    if (r_ind < 0) {
        /* NULL値 */
        printf("drv002:ret = NULL\n");
    }
    else {
        /* VARCHARデータ長の取り出し */
        memcpy(&ret_size, ret, sizeof(short));
        printf("drv002:ret_size=%d\n", ret_size);
        /* VARCHARデータの取り出し */
        memset(buf, 0x00, sizeof(buf));
        memcpy(buf, ret + sizeof(short), ret_size);
        printf("drv002:return value = %s\n", buf);
    }

    /* ライブラリのクローズ */
#ifdef NT
    FreeLibrary(handle_p);
#else
    dlclose(handle_p);
#endif
    printf("drv002:end\n");
    return(0);
}

[Solaris OEの場合]

テストドライバ実行形式(ftestdrv001)の作成例

cc -o ftestdrv001 ftestdrv001.c -ldl

[Linuxの場合]

テストドライバ実行形式(ftestdrv001)の作成例

gcc -o ftestdrv001 ftestdrv001.c -ldl

■ダミーSQLSignalMSG関数のライブラリ作

ファンクションルーチンから異常通知する場合のテストで使用するダミーSQLSignalMSG関数のライブラリを作成します。

ダミーSQLSignalMSG関数のプログラム例およびダミーSQLSignalMSG関数のライブラリ作成例を以下に示します。

ダミーSQLSignalMSG関数“SQLSignalMSG”(fdummymsg.c)のプログラム例

/*-----------------------------------------------------------*/
/* SQLSignalMSG関数のダミープログラム                        */
/*-----------------------------------------------------------*/
#include <stdio.h>
#include <string.h>

#define MSG1 "JYP4557E ファンクションルーチン“%s”から例外が送信されました.例外メッセージ=“%s”"
void  SQLSignalMSG(char *msg_p)
{
    char    msg_data[1024];
    memset(msg_data,0x00,sizeof(msg_data));
    sprintf(msg_data,MSG1,"TestFunction",msg_p);
    /* SQLSTATE 出力  */
    printf("SQLSTATE = 60000\n");
    /* SQLMSG 出力 */
    printf("SQLMSG   = %s\n",msg_data);
    return;
}

[Solaris OEの場合]

ダミーSQLSignalMSG関数のライブラリ作成例

cc -G -o /usr/local2/lib/libsqlsigm.so  fdummymsg.c

[Linuxの場合]

ダミーSQLSignalMSG関数のライブラリ作成例

gcc -shared -o /usr/local/lib/libsqlsigm.so  fdummymsg.c

■リンクするライブラリの設

単体テストを実行するために、ダミーSQLSignalMSG関数のライブラリおよびファンクションルーチンのライブラリをLD_LIBRARY_PATHに設定します。

以下に、2つのライブラリの設定例を示します。

[UNIX系の場合]

ダミーSQLSignalMSG関数のライブラリおよびファンクションルーチンのライブラリの設定例

setenv LD_LIBRARY_PATH /usr/local2/lib:/usr/local/lib
                            (1)              (2)

(1) ダミーSQLSignalMSG関数のライブラリ

(2) ファンクションルーチンのライブラリ

■リンクするライブラリの再設

単体テストの終了後は、ダミーSQLSignalMSG関数のライブラリをLD_LIBRARY_PATHから外し、Symfoware/RDBのSQLSignalMSG関数のライブラリをLD_LIBRARY_PATHに設定する必要があります。

以下に、ライブラリの再設定例を示します。

[UNIX系の場合]

ライブラリの再設定例

setenv LD_LIBRARY_PATH /usr/local/lib:/opt/FSUNrdb2b/lib: …
                            (1)              (2)

(1) ファンクションルーチンのライブラリ

(2) Symfoware/RDB のSQLSignalMSG関数ライブラリ

image

テストドライバの実行例

drv002:dlopen start
drv002:dlsym start
drv002:make indata
drv002:make outdata area
drv002:call func
SQLSTATE = 60000
SQLMSG   = JYP4557E ファンクションルーチン“TestFunction”から例外
が送信されました.例外メッセージ=“引数1が負の値です”
drv002:call func end
drv002:ret = NULL
drv002:end

目次 索引 前ページ次ページ

All Rights Reserved, Copyright (C) 富士通株式会社 2003