blob: c5b86d0cb1a971f68dd677872b9367925bc996f9 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include "block_service/block_service_manager.h"
#include "block_service/block_service.h"
#include "utils/filesystem.h"
namespace dsn {
namespace dist {
namespace block_service {
class block_file_mock : public block_file
{
public:
block_file_mock(const std::string &_name, int64_t _size, const std::string &_md5)
: block_file(_name),
size(_size),
md5(_md5),
enable_write_fail(false),
enable_read_fail(false),
enable_upload_fail(false)
{
}
virtual uint64_t get_size() { return static_cast<uint64_t>(size); }
virtual const std::string &get_md5sum() { return md5; }
virtual dsn::task_ptr write(const write_request &req,
dsn::task_code code,
const write_callback &cb,
dsn::task_tracker *tracker = nullptr)
{
write_response resp;
if (enable_write_fail) {
resp.err = ERR_MOCK_INTERNAL;
} else {
resp.err = ERR_OK;
context = std::move(req.buffer);
resp.written_size = context.length();
}
cb(resp);
return task_ptr();
}
virtual dsn::task_ptr read(const read_request &req,
dsn::task_code code,
const read_callback &cb,
dsn::task_tracker *tracker = nullptr)
{
read_response resp;
if (enable_read_fail) {
resp.err = ERR_MOCK_INTERNAL;
} else {
resp.err = ERR_OK;
if (size <= 0 && md5.empty()) {
resp.buffer = blob();
} else {
resp.buffer = context;
}
}
cb(resp);
return task_ptr();
}
virtual dsn::task_ptr upload(const upload_request &req,
dsn::task_code code,
const upload_callback &cb,
dsn::task_tracker *tracker = nullptr)
{
upload_response resp;
if (enable_upload_fail) {
resp.err = ERR_MOCK_INTERNAL;
} else {
resp.err = ERR_OK;
// just return the file size
resp.uploaded_size = size;
}
cb(resp);
return task_ptr();
}
virtual dsn::task_ptr download(const download_request &req,
dsn::task_code code,
const download_callback &cb,
dsn::task_tracker *tracker = nullptr)
{
download_response resp;
resp.err = ERR_OK;
resp.downloaded_size = size;
cb(resp);
return task_ptr();
}
// make file exist,
void file_exist(const std::string &_md5, int64_t _size)
{
md5 = _md5;
size = _size;
}
// make file not exist
void clear_file_exist()
{
size = 0;
md5.clear();
}
void set_context(const std::string &value)
{
auto len = value.length();
std::shared_ptr<char> buf = utils::make_shared_array<char>(len);
::memcpy(buf.get(), value.c_str(), len);
blob write_buf(std::move(buf), static_cast<unsigned int>(len));
context = std::move(write_buf);
}
void clear_context() { context = blob(); }
public:
int64_t size;
std::string md5;
blob context;
bool enable_write_fail;
bool enable_read_fail;
bool enable_upload_fail;
};
class block_service_mock : public block_filesystem
{
public:
block_service_mock()
: block_filesystem(), enable_create_file_fail(false), enable_list_dir_fail(false)
{
}
virtual error_code initialize(const std::vector<std::string> &args) { return ERR_OK; }
virtual dsn::task_ptr list_dir(const ls_request &req,
dsn::task_code code,
const ls_callback &callback,
dsn::task_tracker *tracker = nullptr)
{
ls_response resp;
if (enable_list_dir_fail) {
resp.err = ERR_MOCK_INTERNAL;
} else {
resp.err = ERR_OK;
std::string dir_name = ::dsn::utils::filesystem::get_file_name(req.dir_name);
if (dir_files.find(dir_name) != dir_files.end()) {
resp.entries = std::make_shared<std::vector<ls_entry>>();
(*resp.entries) = dir_files[dir_name];
} else {
resp.err = ERR_OBJECT_NOT_FOUND;
}
}
callback(resp);
return task_ptr();
}
virtual dsn::task_ptr create_file(const create_file_request &req,
dsn::task_code code,
const create_file_callback &cb,
dsn::task_tracker *tracker = nullptr)
{
create_file_response resp;
if (enable_create_file_fail) {
resp.err = ERR_MOCK_INTERNAL;
} else {
resp.err = ERR_OK;
auto it = files.find(req.file_name);
if (it != files.end()) {
resp.file_handle =
new block_file_mock(req.file_name, it->second.first, it->second.second);
} else {
resp.file_handle = new block_file_mock("", 0, "");
std::cout << "regular_file is selected..." << std::endl;
}
}
cb(resp);
return task_ptr();
}
dsn::task_ptr remove_path(const remove_path_request &req,
dsn::task_code code,
const remove_path_callback &cb,
dsn::task_tracker *tracker)
{
return task_ptr();
}
public:
std::map<std::string, std::vector<ls_entry>> dir_files;
std::map<std::string, std::pair<int64_t, std::string>> files;
bool enable_create_file_fail;
bool enable_list_dir_fail;
};
} // namespace block_service
} // namespace dist
} // namespace dsn