Redis源码分析之小型测试框架testhelp.h和redis-check-aof.c日志检测

62 篇文章 0 订阅
30 篇文章 0 订阅

使用的是redis 3.2版本
test中的文件主要分为以下几个:

1.memtest.c 内存检测
2.redis_benchmark.c 用于redis性能测试的实现,后续会当做单独的一个章节进行分析
3.redis_check_aof.c 用于更新日志检查的实现。
4.redis_check_dump.c 用于本地数据库检查的实现。
5.testhelp.h 一个C风格的小型测试框架。
今天看了testhelp.h和redis_check_aof.c,主要将自己理解的写出来,要不然看了之后过一段时间又都忘记了,没有留下什么痕迹

testhelp.h一个C风格的小型测试框架:已经说是一个框架了,是不是代码量很多,其实就没几行代码,主要是里面的设计方式是值的学习的,就是函数式编程思想

// 失败的测试用例数量
int __failed_tests = 0;

// 总的测试用例数量
int __test_num = 0;


/* 宏定义测试方法,输入参数,输入描述语,判断的式子作为参数 */
/* 有完全体现了函数式编程的思想 */
#define test_cond(descr,_c) do { \
    __test_num++; printf("%d - %s: ", __test_num, descr); \
    if(_c) printf("PASSED\n"); else {printf("FAILED\n"); __failed_tests++;} \
} while(0);
#define test_report() do { \
    printf("%d tests, %d passed, %d failed\n", __test_num, \
                    __test_num-__failed_tests, __failed_tests); \
    if (__failed_tests) { \
        printf("=== WARNING === We have failed tests here...\n"); \
        exit(1); \
    } \
} while(0);

例如,在sds的测试中的使用:

        sds x = sdsnew("foo"), y;

        test_cond("Create a string and obtain the length",
            sdslen(x) == 3 && memcmp(x,"foo\0",4) == 0)

        sdsfree(x);

只需要传入_c,就可以将具体的函数传入,是不是很精妙,实际上,这就是所说的函数式编程。

/* 方法API */
int consumeNewline(char *buf) /* 消除buf前面的换行符,即比较buf字符串中的前2个字符 */
int readLong(FILE *fp, char prefix, long *target) /* 从文件中读取long类型值 */
int readBytes(FILE *fp, char *target, long length) /* 从文件中读取字节 */
int readString(FILE *fp, char** target) /* 文件中读取字符串 */
int readArgc(FILE *fp, long *target) /* 文件中读取参数,首字符以“*”开头 */
off_t process(FILE *fp) /* 返回fp文件的偏移量 */

read方法大体类似,以下用readLong()作为例子:

// 从文件中读取long型数据
int readLong(FILE *fp, char prefix, long *target) {
    char buf[128], *eptr;

    // 定位到内容部分
    epos = ftello(fp);
    if (fgets(buf,sizeof(buf),fp) == NULL) {
        return 0;
    }

    // 前缀不符合预期
    if (buf[0] != prefix) {
        ERROR("Expected prefix '%c', got: '%c'",prefix,buf[0]);
        return 0;
    }

    // 转换为long型数据
    *target = strtol(buf+1,&eptr,10);
    return consumeNewline(eptr);
}

其中有一个比较特别的方法,consumeNewline()消除换行符的方法:

// 判断buf中前2个字符是否符合预期
int consumeNewline(char *buf) {
    if (strncmp(buf,"\r\n",2) != 0) {
        // 出错
        ERROR("Expected \\r\\n, got: %02x%02x",buf[0],buf[1]);
        return 0;
    }
    return 1;
}

相对于struct部分,该部分比较容易理解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值