Newer
Older
libkc / modules / test / src / test_memory_dump.c
#include <stdio.h>
#include <errno.h>

#include <kc.h>
#include <kc_ut.h>
#include <kc_assert.h>
#include <kc_memory_dump.h>

// プロトタイプ宣言
static void test_memory_dump(void);
static void test_memory_dump_no_binary(void);
static void test_memory_dump_no_ascii(void);
static void test_memory_dump_no_binary_no_ascii(void);
static void test_memory_dump_no_buffer(void);
static void test_memory_dump_no_column(void);
static void test_memory_dump_no_column_show_binary(void);
static void test_memory_dump_no_column_no_binary(void);
static void test_memory_dump_no_column_show_ascii(void);
static void test_memory_dump_no_column_no_ascii(void);
static void test_memory_dump_padding(void);
static void test_memory_dump_over_kb(void);
static void test_memory_dump_message_size_zero(void);
static void test_memory_dump_message_few_buf(void);

/**
 * memory_dump 単体テストスイート
 */
void suite_memory_dump(void)
{
    KcUt *ut = KcUt_get_instance();
    ut->add(ut, UT_TESTCASE, "memory_dump dump", test_memory_dump);
    ut->add(ut, UT_TESTCASE, "memory_dump dump (no binary)", test_memory_dump_no_binary);
    ut->add(ut, UT_TESTCASE, "memory_dump dump (no ASCII)", test_memory_dump_no_ascii);
    ut->add(ut, UT_TESTCASE, "memory_dump dump (no binary, no ASCII)", test_memory_dump_no_binary_no_ascii);
    ut->add(ut, UT_TESTCASE, "memory_dump dump (no buffer)", test_memory_dump_no_buffer);
    ut->add(ut, UT_TESTCASE, "memory_dump dump (no column)", test_memory_dump_no_column);
    ut->add(ut, UT_TESTCASE, "memory_dump dump (no column, show binary)", test_memory_dump_no_column_show_binary);
    ut->add(ut, UT_TESTCASE, "memory_dump dump (no column, no binary)", test_memory_dump_no_column_no_binary);
    ut->add(ut, UT_TESTCASE, "memory_dump dump (no column, show ASCII)", test_memory_dump_no_column_show_ascii);
    ut->add(ut, UT_TESTCASE, "memory_dump dump (no column, no ASCII)", test_memory_dump_no_column_no_ascii);
    ut->add(ut, UT_TESTCASE, "memory_dump dump (padding)", test_memory_dump_padding);
    ut->add(ut, UT_TESTCASE, "memory_dump dump (over KB)", test_memory_dump_over_kb);
    ut->add(ut, UT_TESTCASE, "memory_dump_message dump message (size zero)", test_memory_dump_message_size_zero);
    ut->add(ut, UT_TESTCASE, "memory_dump_message dump message (few buffer)", test_memory_dump_message_few_buf);
}

/**
 * memory_dump テスト
 *
 * @process 適宜データを用意し、KcMemoryDump_dump を実行する。
 * @result  データのダンプが指定したバッファに出力されること。
 */
static void test_memory_dump(void)
{
    {
        char test_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        KcMemoryEntry entry = {
            .size = 5,
            .mark = KC_MEMORY_ALLOCATED,
            .file = "test_file",
            .func = "test_func",
            .line = 123,
            ._prev = NULL,
            ._next = NULL,
            .data = test_data};

        char buff[256];
        bool ret = KcMemoryDump_dump(buff, sizeof(buff), &entry, 16, true, true, 130);
        assert_true(ret);
        assert_equals("test_file:123 (   5.000  B) [test_func]                     "
                      " | 41 42 43 44 45 -- -- -- -- -- -- -- -- -- -- -- "
                      " | ABCDE           "
                      "\n",
                      buff);
    }
    {
        char test_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        KcMemoryEntry entry = {
            .size = 5,
            .mark = KC_MEMORY_ALLOCATED,
            .file = "test_file",
            .func = "test_func",
            .line = 123,
            ._prev = NULL,
            ._next = NULL,
            .data = test_data};

        char buff[256];
        bool ret = KcMemoryDump_dump(buff, sizeof(buff), &entry, 16, true, true, 42);
        assert_true(ret);
        const char *ex = "test_file:123 (   5.000  B) [test_func]   \n";
        assert_equals(ex, buff);
    }
}

/**
 * memory_dump テスト(バイナリ表示無し)
 *
 * @process 適宜データを用意し、バイナリ表示無しにて、KcMemoryDump_dump を実行する。
 * @result  データのダンプが指定したバッファに出力されること。
 */
static void test_memory_dump_no_binary(void)
{
    char test_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    KcMemoryEntry entry = {
        .size = 5,
        .mark = KC_MEMORY_ALLOCATED,
        .file = "test_file",
        .func = "test_func",
        .line = 123,
        ._prev = NULL,
        ._next = NULL,
        .data = test_data};

    char buff[256];
    bool ret = KcMemoryDump_dump(buff, sizeof(buff), &entry, 16, false, true, 130);
    assert_true(ret);
    assert_equals("test_file:123 (   5.000  B) [test_func]                     "
                  "                                                   "
                  " | ABCDE           "
                  "\n",
                  buff);
}

/**
 * memory_dump テスト(ASCII 表示無し)
 *
 * @process 適宜データを用意し、ASCII 表示無しにて、KcMemoryDump_dump を実行する。
 * @result  データのダンプが指定したバッファに出力されること。
 */
static void test_memory_dump_no_ascii(void)
{
    char test_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    KcMemoryEntry entry = {
        .size = 5,
        .mark = KC_MEMORY_ALLOCATED,
        .file = "test_file",
        .func = "test_func",
        .line = 123,
        ._prev = NULL,
        ._next = NULL,
        .data = test_data};

    char buff[256];
    bool ret = KcMemoryDump_dump(buff, sizeof(buff), &entry, 16, true, false, 130);
    assert_true(ret);
    assert_equals("test_file:123 (   5.000  B) [test_func]                     "
                  "                   "
                  " | 41 42 43 44 45 -- -- -- -- -- -- -- -- -- -- -- "
                  "\n",
                  buff);
}

/**
 * memory_dump テスト(バイナリ表示無し、ASCII 表示無し)
 *
 * @process 適宜データを用意し、バイナリ表示無し、ASCII 表示無しにて、KcMemoryDump_dump を実行する。
 * @result  データのダンプが指定したバッファに出力されること。
 */
static void test_memory_dump_no_binary_no_ascii(void)
{
    char test_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    KcMemoryEntry entry = {
        .size = 5,
        .mark = KC_MEMORY_ALLOCATED,
        .file = "test_file",
        .func = "test_func",
        .line = 123,
        ._prev = NULL,
        ._next = NULL,
        .data = test_data};

    char buff[256];
    bool ret = KcMemoryDump_dump(buff, sizeof(buff), &entry, 16, false, false, 130);
    assert_true(ret);
    assert_equals("test_file:123 (   5.000  B) [test_func]                     "
                  "                                                   "
                  "                   "
                  "\n",
                  buff);
}

/**
 * memory_dump テスト(バッファ不足 [指定カラム数に満たない])
 *
 * @process 指定カラム数に対してバッファサイズが小さい状態で、KcMemoryDump_dump を実行する。
 * @result  データダンプに失敗すること。
 */
static void test_memory_dump_no_buffer(void)
{
    char test_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    KcMemoryEntry entry = {
        .size = 5,
        .mark = KC_MEMORY_ALLOCATED,
        .file = "test_file",
        .func = "test_func",
        .line = 123,
        ._prev = NULL,
        ._next = NULL,
        .data = test_data};

    char buff[80];
    bool ret = KcMemoryDump_dump(buff, sizeof(buff), &entry, 16, true, true, 130);
    assert_false(ret);
}

/**
 * memory_dump テスト(バイナリ表示指定、ASCII 表示指定 -> カラム不足により表示不可)
 *
 * @process 小さいカラム数を指定し、KcMemoryDump_dump を実行する。
 * @result  バイナリ表示、ASCII 表示のないダンプが表示されること。
 */
static void test_memory_dump_no_column(void)
{
    char test_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    KcMemoryEntry entry = {
        .size = 5,
        .mark = KC_MEMORY_ALLOCATED,
        .file = "test_file",
        .func = "test_func",
        .line = 123,
        ._prev = NULL,
        ._next = NULL,
        .data = test_data};

    char buff[256];
    bool ret = KcMemoryDump_dump(buff, sizeof(buff), &entry, 16, true, true, 45);
    assert_true(ret);
    //                      10        20        30        40        50
    //                      |         |         |         |         |
    //             1234567890123456789012345678901234567890123456789012345
    assert_equals("test_file:123 (   5.000  B) [test_func]      "
                  "\n",
                  buff);
}

/**
 * memory_dump テスト(バイナリ表示指定、-> カラム不足により、一部表示不可)
 *
 * @process 小さいカラム数を指定し、KcMemoryDump_dump を実行する。
 * @result  バイナリ表示、ASCII 表示のないダンプが表示されること。
 */
static void test_memory_dump_no_column_show_binary(void)
{
    char test_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    KcMemoryEntry entry = {
        .size = 5,
        .mark = KC_MEMORY_ALLOCATED,
        .file = "test_file",
        .func = "test_func",
        .line = 123,
        ._prev = NULL,
        ._next = NULL,
        .data = test_data};

    char buff[256];
    bool ret = KcMemoryDump_dump(buff, sizeof(buff), &entry, 16, true, false, 55);
    assert_true(ret);
    //                      10        20        30        40        50
    //                      |         |         |         |         |
    //             1234567890123456789012345678901234567890123456789012345
    assert_equals("test | 41 42 43 44 45 -- -- -- -- -- -- -- -- -- -- -- "
                  "\n",
                  buff);
}

/**
 * memory_dump テスト(バイナリ表示指定、-> カラム不足により、バイナリ表示不可)
 *
 * @process 小さいカラム数を指定し、KcMemoryDump_dump を実行する。
 * @result  バイナリ表示、ASCII 表示のないダンプが表示されること。
 */
static void test_memory_dump_no_column_no_binary(void)
{
    char test_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    KcMemoryEntry entry = {
        .size = 5,
        .mark = KC_MEMORY_ALLOCATED,
        .file = "test_file",
        .func = "test_func",
        .line = 123,
        ._prev = NULL,
        ._next = NULL,
        .data = test_data};

    char buff[256];
    bool ret = KcMemoryDump_dump(buff, sizeof(buff), &entry, 16, true, false, 45);
    assert_true(ret);
    //                      10        20        30        40        50
    //                      |         |         |         |         |
    //             1234567890123456789012345678901234567890123456789012345
    assert_equals("test_file:123 (   5.000  B) [test_func]      "
                  "\n",
                  buff);
}

/**
 * memory_dump テスト(ASCII表示指定、-> カラム不足により、一部表示不可)
 *
 * @process 小さいカラム数を指定し、KcMemoryDump_dump を実行する。
 * @result  バイナリ表示、ASCII 表示のないダンプが表示されること。
 */
static void test_memory_dump_no_column_show_ascii(void)
{
    char test_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    KcMemoryEntry entry = {
        .size = 5,
        .mark = KC_MEMORY_ALLOCATED,
        .file = "test_file",
        .func = "test_func",
        .line = 123,
        ._prev = NULL,
        ._next = NULL,
        .data = test_data};

    char buff[256];
    bool ret = KcMemoryDump_dump(buff, sizeof(buff), &entry, 16, false, true, 35);
    assert_true(ret);
    //                      10        20        30        40        50
    //                      |         |         |         |         |
    //             1234567890123456789012345678901234567890123456789012345
    assert_equals("test_file:123 (  | ABCDE           "
                  "\n",
                  buff);
}

/**
 * memory_dump テスト(ASCII表示指定、-> カラム不足により、ASCII表示不可)
 *
 * @process 小さいカラム数を指定し、KcMemoryDump_dump を実行する。
 * @result  バイナリ表示、ASCII 表示のないダンプが表示されること。
 */
static void test_memory_dump_no_column_no_ascii(void)
{
    char test_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    KcMemoryEntry entry = {
        .size = 5,
        .mark = KC_MEMORY_ALLOCATED,
        .file = "test_file",
        .func = "test_func",
        .line = 123,
        ._prev = NULL,
        ._next = NULL,
        .data = test_data};

    char buff[256];
    bool ret = KcMemoryDump_dump(buff, sizeof(buff), &entry, 16, true, false, 16);
    assert_true(ret);
    //                      10        20        30        40        50
    //                      |         |         |         |         |
    //             1234567890123456789012345678901234567890123456789012345
    assert_equals("test_file:123 ( "
                  "\n",
                  buff);
}

/**
 * memory_dump テスト(padding)
 *
 * @process カラムサイズを大きくとり、パディングされる状態とする。
 * @result  出力が指定されたカラムサイズとなるようにパディングされること。
 */
static void test_memory_dump_padding(void)
{
    char test_data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    KcMemoryEntry entry = {
        .size = 5,
        .mark = KC_MEMORY_ALLOCATED,
        .file = "test_file",
        .func = "test_func",
        .line = 123,
        ._prev = NULL,
        ._next = NULL,
        .data = test_data};

    char buff[256];
    bool ret = KcMemoryDump_dump(buff, sizeof(buff), &entry, 16, false, false, 60);
    assert_true(ret);
    //                      10        20        30        40        50        60
    //                      |         |         |         |         |         |
    //             1234567890123456789012345678901234567890123456789012345678901234
    assert_equals("test_file:123 (   5.000  B) [test_func]                     "
                  "\n",
                  buff);
}

/**
 * memory_dump テスト(KB以上のメモリ確保)
 *
 * @process KB 以上のメモリを確保し、KcMemoryDump_dump を実行する。
 * @result  サイズが単位付きで表示されること。
 */
static void test_memory_dump_over_kb(void)
{
    char test_data[] = "ABCDEFGHIJK \x00\x81\x82\x83\x84";
    KcMemoryEntry entry = {
        .size = (int)((double)12.056 * 1024),
        .mark = KC_MEMORY_ALLOCATED,
        .file = "test_file",
        .func = "test_func",
        .line = 123,
        ._prev = NULL,
        ._next = NULL,
        .data = test_data};

    // KB
    char buff[256];
    bool ret = KcMemoryDump_dump(buff, sizeof(buff), &entry, 16, true, true, 130);
    assert_true(ret);
    assert_equals("test_file:123 (  12.056 KB) [test_func]                     "
                  " | 41 42 43 44 45 46 47 48 49 4A 4B 20 00 81 82 83 "
                  " | ABCDEFGHIJK ...."
                  "\n",
                  buff);
    // MB
    entry.size = (int)((double)65.432 * (1024 * 1024));
    ret = KcMemoryDump_dump(buff, sizeof(buff), &entry, 16, true, true, 130);
    assert_true(ret);
    assert_equals("test_file:123 (  65.432 MB) [test_func]                     "
                  " | 41 42 43 44 45 46 47 48 49 4A 4B 20 00 81 82 83 "
                  " | ABCDEFGHIJK ...."
                  "\n",
                  buff);
    // GB
    entry.size = (int)((double)1.012 * (1024 * 1024 * 1024));
    ret = KcMemoryDump_dump(buff, sizeof(buff), &entry, 16, true, true, 130);
    assert_true(ret);
    assert_equals("test_file:123 (   1.012 GB) [test_func]                     "
                  " | 41 42 43 44 45 46 47 48 49 4A 4B 20 00 81 82 83 "
                  " | ABCDEFGHIJK ...."
                  "\n",
                  buff);
}

extern void _UT_KcMemoryDump_dump_message(char *info_write_ptr, int info_rest_size, const char *msg);
/**
 * [内部関数] dump_message テスト (バッファサイズ0)
 *
 * @process 残りサイズ 0 のバッファを渡して、KcMemoryDump_dump_message を実行する。
 * @result  バッファに何も格納されないこと。
 */
static void test_memory_dump_message_size_zero(void)
{
    char info_write_buf[5];
    int info_rest_size = 0;
    info_write_buf[0] = '\0';
    _UT_KcMemoryDump_dump_message(info_write_buf, info_rest_size, "MESSAGE");
    assert_equals("", info_write_buf);
}

/**
 * [内部関数] dump_message テスト (バッファ不足)
 *
 * @process バッファより多いメッセージを渡す。
 * @result  バッファに入る分のメッセージが格納されること。
 */
static void test_memory_dump_message_few_buf(void)
{
    char info_write_buf[5];
    int info_rest_size = (int)sizeof(info_write_buf);
    info_write_buf[0] = '\0';
    _UT_KcMemoryDump_dump_message(info_write_buf, info_rest_size, "MESSAGE");
    assert_equals("MESS", info_write_buf);
}
// test_file:123 (   5.000  B) [test_func]                      | 41 42 43 44 45 -- -- -- -- -- -- -- -- -- -- --  | ABCDE
// bool KcMemoryDump_dump(char *buff, size_t buff_size, const KcMemoryEntry *entry,
//   int bytes, bool binary, bool ascii, int column);
// 0x01, 0x19, 0x20, 0x21, 0x31, 0x7e, 0x7f, 0x80,
// normal
// column 数が
// ファイル名:行番号 (size bytes) [関数名] が長い。
//  binary が true / false
//  ascii が true/ false

// KcMemoryDump_dump_info(&buff_info, entry, info_column);
//