static void pack_test(void)
{
    /***************  Test of pack  *****************/
    
    cw_pack_context pc;
    cmp_ctx_t cc;
    mpack_writer_t mw;
    
    int ii, itemSize;
    for (ii=0; ii<BUF_Length; ii++) buffer[ii] = 0; /*Load pages in memory*/
    uint8_t item[40];
    
    
    BEFORE_PTEST(cw_pack_nil(&pc));
    PTEST("CMP",cmp_write_nil(&cc));
    PTEST("MPack", mpack_write_nil(&mw));
    PTEST("CWPack", cw_pack_nil(&pc));
    AFTER_PTEST;
    
    BEFORE_PTEST(cw_pack_signed(&pc, -1));
    PTEST("CMP",cmp_write_integer(&cc, -1));
    PTEST("MPack", mpack_write_i64(&mw, -1));
    PTEST("CWPack", cw_pack_signed(&pc, -1));
    AFTER_PTEST;
    
    BEFORE_PTEST(cw_pack_signed(&pc, 200));
    PTEST("CMP",cmp_write_integer(&cc, 200));
    PTEST("MPack", mpack_write_i64(&mw, 200));
    PTEST("CWPack", cw_pack_signed(&pc, 200));
    AFTER_PTEST;
    
    BEFORE_PTEST(cw_pack_signed(&pc, 10000));
    PTEST("CMP",cmp_write_integer(&cc, 10000));
    PTEST("MPack", mpack_write_i64(&mw, 10000));
    PTEST("CWPack", cw_pack_signed(&pc, 10000));
    AFTER_PTEST;
    
    BEFORE_PTEST(cw_pack_signed(&pc, 100000));
    PTEST("CMP",cmp_write_integer(&cc, 100000));
    PTEST("MPack", mpack_write_i64(&mw, 100000));
    PTEST("CWPack", cw_pack_signed(&pc, 100000));
    AFTER_PTEST;
    
    BEFORE_PTEST(cw_pack_float(&pc, (float)3.14));
    PTEST("CMP",cmp_write_float(&cc, (float)3.14));
    PTEST("MPack", mpack_write_float(&mw, (float)3.14));
    PTEST("CWPack", cw_pack_float(&pc, (float)3.14));
    AFTER_PTEST;
    
    BEFORE_PTEST(cw_pack_double(&pc, 3.14));
    PTEST("CMP",cmp_write_decimal(&cc, 3.14));
    PTEST("MPack", mpack_write_double(&mw, 3.14));
    PTEST("CWPack", cw_pack_double(&pc, 3.14));
    AFTER_PTEST;
    
    BEFORE_PTEST(cw_pack_str(&pc, "Claes",5));
    PTEST("CMP",cmp_write_str(&cc, "Claes",5));
    PTEST("MPack", mpack_write_str(&mw, "Claes",5));
    PTEST("CWPack", cw_pack_str(&pc, "Claes",5));
    AFTER_PTEST;
    
    BEFORE_PTEST(cw_pack_str(&pc, "Longer string than the other one.",33));
    PTEST("CMP",cmp_write_str(&cc, "Longer string than the other one.",33));
    PTEST("MPack", mpack_write_str(&mw, "Longer string than the other one.",33));
    PTEST("CWPack", cw_pack_str(&pc, "Longer string than the other one.",33));
    AFTER_PTEST;
}
TEST test_multiple_entry_and_readback(void)
{
    cmp_ctx_t *ctx;
    ctx = _log_entry_create(&test_logger, "a");
    cmp_write_integer(ctx, 42);
    _log_entry_write_to_flash(&test_logger);
    uint32_t end_a = test_logger.flash_write_pos;

    ctx = _log_entry_create(&test_logger, "b");
    cmp_write_integer(ctx, 23);
    _log_entry_write_to_flash(&test_logger);
    uint32_t end_b = test_logger.flash_write_pos;

    uint8_t buf[LOG_ENTRY_DATA_LEN];
    uint32_t next_entry = 0;
    size_t len;
    if (!log_read_entry(next_entry, buf, &len, &next_entry)) {
        FAILm("CRC missmatch");
    }
    ASSERT_EQ(end_a, next_entry);
    ASSERT_EQ(buf[len-1], 42);
    if (!log_read_entry(next_entry, buf, &len, &next_entry)) {
        FAILm("CRC missmatch");
    }
    ASSERT_EQ(end_b, next_entry);
    ASSERT_EQ(buf[len-1], 23);
    if (log_read_entry(next_entry, buf, &len, &next_entry)) {
        FAILm("dont detect last entry");
    }
    PASS();
}
TEST test_entry_write_multiple(void)
{
    uint32_t pos_a = test_logger.flash_write_pos;
    cmp_ctx_t *ctx;
    ctx = _log_entry_create(&test_logger, "a");
    cmp_write_integer(ctx, 42);
    _log_entry_write_to_flash(&test_logger);

    uint32_t pos_b = test_logger.flash_write_pos;
    ASSERT(pos_a < pos_b);
    ctx = _log_entry_create(&test_logger, "b");
    cmp_write_integer(ctx, 23);
    _log_entry_write_to_flash(&test_logger);

    cmp_ctx_t reader;
    cmp_mem_access_t cma;
    cmp_mem_access_ro_init(&reader, &cma, &flash_array[pos_a + LOG_ENTRY_HEADER_LEN], LOG_ENTRY_DATA_LEN);
    uint32_t size = 0;
    uint64_t timestamp = 0;
    int64_t val = 0;
    char name[10];
    bool ok;
    size = sizeof(name);
    ok = true;
    ok &= cmp_read_array(&reader, &size);
    ok &= cmp_read_uinteger(&reader, &timestamp);
    ok &= cmp_read_str(&reader, name, &size);
    ok &= cmp_read_integer(&reader, &val);
    ASSERT(ok);
    ASSERT_EQ(val, 42);

    size_t pos = cmp_mem_access_get_pos(&cma);
    ASSERT_EQ(pos, flash_array[0]);
    ASSERT_EQ(pos + LOG_ENTRY_HEADER_LEN, pos_b);

    cmp_mem_access_ro_init(&reader, &cma, &flash_array[pos_b + LOG_ENTRY_HEADER_LEN], LOG_ENTRY_DATA_LEN);
    size = sizeof(name);
    ok = true;
    ok &= cmp_read_array(&reader, &size);
    ok &= cmp_read_uinteger(&reader, &timestamp);
    ok &= cmp_read_str(&reader, name, &size);
    ok &= cmp_read_integer(&reader, &val);
    ASSERT(ok);
    ASSERT_EQ(val, 23);
    ASSERT_EQ(flash_array[pos_b], cmp_mem_access_get_pos(&cma));

    PASS();
}
TEST test_entry_crc_and_length(void)
{
    cmp_ctx_t *ctx = _log_entry_create(&test_logger, "entry");
    cmp_write_integer(ctx, 42);
    _log_entry_write_to_flash(&test_logger);

    size_t entry_length = cmp_mem_access_get_pos(&test_logger.cma);
    uint8_t len = flash_array[0];
    uint8_t crc = flash_array[1];
    if (crc8(0, &flash_array[2], len) != crc) {
        FAILm("CRC missmatch");
    }
    if (entry_length != len) {
        FAILm("entry length missmatch");
    }
    PASS();
}
TEST test_entry_write_and_readback(void)
{
    cmp_ctx_t *ctx = _log_entry_create(&test_logger, "entry");
    cmp_write_integer(ctx, 42);
    _log_entry_write_to_flash(&test_logger);

    uint8_t buf[LOG_ENTRY_DATA_LEN];
    uint32_t next_entry = 0;
    size_t len = 0;
    if (!log_read_entry(0, buf, &len, &next_entry)) {
        FAILm("CRC missmatch");
    }
    ASSERT_EQ(test_logger.flash_write_pos, next_entry);

    // readback entry
    cmp_ctx_t reader;
    cmp_mem_access_t cma;
    cmp_mem_access_ro_init(&reader, &cma, buf, sizeof(buf));
    uint32_t size = 0;
    if (!cmp_read_array(&reader, &size) || size != 3) {
        FAIL();
    }
    uint64_t timestamp = 0;
    if (!cmp_read_uinteger(&reader, &timestamp) || timestamp != logger_timestamp_sec()) {
        FAIL();
    }
    char name[10];
    size = sizeof(name);
    if (!cmp_read_str(&reader, name, &size) || strcmp(name, "entry") != 0) {
        FAIL();
    }
    int64_t data = 0;
    if (!cmp_read_integer(&reader, &data) || data != 42) {
        FAIL();
    }
    PASS();
}