<commit_before>// Copyright (c) 2016, Baidu.com, Inc. All Rights Reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#define private public
#include "chunkserver/block_manager.h"
#include "chunkserver/data_block.h"

#include <gflags/gflags.h>
#include <gtest/gtest.h>

DECLARE_string(namedb_path);
DECLARE_int32(write_buf_size);


namespace baidu {
namespace bfs {

void sleep_task() {
    sleep(1);
}

void write_task(Block* block, int32_t seq, int64_t offset, std::string write_data) {
    block->Write(seq, offset, write_data.data(), write_data.size(), NULL);
}

class BlockManagerTest : public ::testing::Test {
public:
    BlockManagerTest() {}
protected:
};

TEST_F(BlockManagerTest, RemoveBlock) {
    mkdir("./test_dir", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
    BlockManager block_manager("./test_dir");
    bool ret = block_manager.LoadStorage();
    ASSERT_TRUE(ret);

    //normal case
    int64_t block_id = 123;
    int64_t sync_time;
    StatusCode status;
    Block* block = block_manager.CreateBlock(block_id, &sync_time, &status);
    ASSERT_TRUE(block != NULL);
    std::string disk_file_path = block->disk_file_;
    // now ref count for block is 2
    ret = block->Write(0, 0, NULL, 0, NULL);
    ASSERT_TRUE(ret);
    FLAGS_write_buf_size = 5;
    std::string test_write_data("hello world");
    ret = block->Write(1, 0, test_write_data.data(), test_write_data.size(), NULL);
    ASSERT_TRUE(ret);
    block_manager.CloseBlock(block);
    //after RemoveBlock, ref count for block is 1
    block_manager.RemoveBlock(block_id);
    ASSERT_EQ(block->refs_, 1);
    ASSERT_EQ(block->deleted_, true);
    struct stat st;
    ASSERT_TRUE(stat(disk_file_path.c_str(), &st) == 0);
    //after the last ref is released, disk file should be removed
    block->DecRef();
    ASSERT_TRUE(stat(disk_file_path.c_str(), &st) != 0);
    ASSERT_EQ(errno, ENOENT);

    // close before write
    block_id = 456;
    block = block_manager.CreateBlock(block_id, &sync_time, &status);
    ASSERT_TRUE(block != NULL);
    block_manager.CloseBlock(block);
    ASSERT_EQ(block->finished_, true);
    ASSERT_EQ(block->file_desc_, Block::kClosed);
    block_manager.RemoveBlock(block_id);
    ASSERT_EQ(block->refs_, 1);
    ASSERT_EQ(block->deleted_, 1);
    disk_file_path = block->disk_file_;
    block->DecRef();
    ASSERT_TRUE(stat(disk_file_path.c_str(), &st) != 0);
    ASSERT_EQ(errno, ENOENT);

    // delete before write
    block_id = 789;
    block = block_manager.CreateBlock(block_id, &sync_time, &status);
    ASSERT_TRUE(block != NULL);
    block_manager.RemoveBlock(block_id);
    ASSERT_EQ(block->refs_, 1);
    ASSERT_EQ(block->deleted_, true);
    ASSERT_EQ(block->finished_, false);
    ASSERT_EQ(block->file_desc_, Block::kNotCreated);
    // Write will fail
    ret = block->Write(0, 0, NULL, 0, NULL);
    ASSERT_EQ(ret, false);
    disk_file_path = block->meta_.store_path() + Block::BuildFilePath(block_id);
    ASSERT_TRUE(stat(disk_file_path.c_str(), &st) != 0);
    ASSERT_EQ(errno, ENOENT);
    block->DecRef();
    ASSERT_TRUE(stat(disk_file_path.c_str(), &st) != 0);
    ASSERT_EQ(errno, ENOENT);

    rmdir("./test_dir");
}

TEST_F(BlockManagerTest, Out_of_order) {<commit_msg>FIx unit-test case for BlockManager<commit_after>// Copyright (c) 2016, Baidu.com, Inc. All Rights Reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#define private public
#include "chunkserver/block_manager.h"
#include "chunkserver/data_block.h"

#include <gflags/gflags.h>
#include <gtest/gtest.h>

DECLARE_string(namedb_path);
DECLARE_int32(write_buf_size);


namespace baidu {
namespace bfs {

void sleep_task() {
    sleep(1);
}

void write_task(Block* block, int32_t seq, int64_t offset, std::string write_data) {
    block->Write(seq, offset, write_data.data(), write_data.size(), NULL);
}

class BlockManagerTest : public ::testing::Test {
public:
    BlockManagerTest() {}
protected:
};

TEST_F(BlockManagerTest, RemoveBlock) {
    mkdir("./test_dir", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
    BlockManager block_manager("./test_dir");
    bool ret = block_manager.LoadStorage();
    ASSERT_TRUE(ret);

    //normal case
    int64_t block_id = 123;
    int64_t sync_time;
    StatusCode status;
    Block* block = block_manager.CreateBlock(block_id, &sync_time, &status);
    ASSERT_TRUE(block != NULL);
    std::string disk_file_path = block->disk_file_;
    ret = block->Write(0, 0, NULL, 0, NULL);
    ASSERT_TRUE(ret);
    FLAGS_write_buf_size = 5;
    std::string test_write_data("hello world");
    ret = block->Write(1, 0, test_write_data.data(), test_write_data.size(), NULL);
    ASSERT_TRUE(ret);
    block_manager.CloseBlock(block);
    block_manager.RemoveBlock(block_id);
    ASSERT_EQ(block->deleted_, true);
    struct stat st;
    ASSERT_TRUE(stat(disk_file_path.c_str(), &st) == 0);
    block->DecRef();

    // close before write
    block_id = 456;
    block = block_manager.CreateBlock(block_id, &sync_time, &status);
    ASSERT_TRUE(block != NULL);
    block_manager.CloseBlock(block);
    ASSERT_EQ(block->finished_, true);
    ASSERT_EQ(block->file_desc_, Block::kClosed);
    block_manager.RemoveBlock(block_id);
    ASSERT_EQ(block->refs_, 1);
    ASSERT_EQ(block->deleted_, 1);
    block->DecRef();

    // delete before write
    block_id = 789;
    block = block_manager.CreateBlock(block_id, &sync_time, &status);
    ASSERT_TRUE(block != NULL);
    block_manager.RemoveBlock(block_id);
    ASSERT_EQ(block->refs_, 1);
    ASSERT_EQ(block->deleted_, true);
    ASSERT_EQ(block->finished_, false);
    ASSERT_EQ(block->file_desc_, Block::kNotCreated);
    // Write will fail
    ret = block->Write(0, 0, NULL, 0, NULL);
    ASSERT_EQ(ret, false);
    block->DecRef();

    rmdir("./test_dir");
}

TEST_F(BlockManagerTest, Out_of_order) {
{'fraction_non_alphanumeric': 0.13870586247676972, 'fraction_numerical': 0.013684744044602128, 'mean_word_length': 4.125541125541125, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 44, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3095287', 'n_tokens_mistral': 2121, 'n_tokens_neox': 2036, 'n_words': 433}