diff --git a/Makefile.in b/Makefile.in index 3f78399..996ae6c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -41,7 +41,7 @@ PDATA_SOURCE=\ persistent-data/space-maps/disk.cc \ persistent-data/space-maps/recursive.cc \ persistent-data/space-maps/careful_alloc.cc -PDATA_OBJECTS=$(subst .cc,.o,$(PDATA_SOURCE)) +#PDATA_OBJECTS=$(subst .cc,.o,$(PDATA_SOURCE)) SOURCE=\ $(PDATA_SOURCE) \ @@ -56,6 +56,7 @@ SOURCE=\ thin-provisioning/restore_emitter.cc \ thin-provisioning/thin_pool.cc \ thin-provisioning/xml_format.cc +PDATA_OBJECTS=$(subst .cc,.o,$(SOURCE)) PROGRAM_SOURCE=\ cache/check.cc \ diff --git a/thin-provisioning/metadata.cc b/thin-provisioning/metadata.cc index 224ac60..08e4b58 100644 --- a/thin-provisioning/metadata.cc +++ b/thin-provisioning/metadata.cc @@ -83,6 +83,7 @@ namespace { ::close(fd); nr_blocks = div_down(nr_blocks, MD_BLOCK_SIZE); } else + // FIXME: needs a better message throw runtime_error("bad path"); return nr_blocks; diff --git a/unit-tests/Makefile.in b/unit-tests/Makefile.in index 559360c..6dde371 100644 --- a/unit-tests/Makefile.in +++ b/unit-tests/Makefile.in @@ -50,6 +50,7 @@ TEST_SOURCE=\ unit-tests/cache_t.cc \ unit-tests/endian_t.cc \ unit-tests/space_map_t.cc \ + unit-tests/thin_metadata_t.cc \ unit-tests/transaction_manager_t.cc TEST_OBJECTS=$(subst .cc,.gmo,$(TEST_SOURCE)) diff --git a/unit-tests/thin_metadata_t.cc b/unit-tests/thin_metadata_t.cc new file mode 100644 index 0000000..a7c69b4 --- /dev/null +++ b/unit-tests/thin_metadata_t.cc @@ -0,0 +1,70 @@ +#include "gmock/gmock.h" + +#include "thin-provisioning/metadata.h" + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace persistent_data; +using namespace testing; +using namespace thin_provisioning; + +//---------------------------------------------------------------- + +namespace { + void rm_f(string path) { + struct stat info; + int r = ::stat(path.c_str(), &info); + + if (r) { + if (errno == ENOENT) + return; + + else { + cerr << "errno == " << errno << endl; + throw runtime_error("stat failed"); + } + } + + if (!S_ISREG(info.st_mode)) + throw runtime_error("path isn't a file"); + + ::unlink(path.c_str()); + } + + // FIXME: duplication with block.tcc, factor out a file_utils unit + void create_sized_file(string const &path, uint64_t file_size) { + int fd = ::open(path.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0666); + if (fd < 0) + throw runtime_error("open_file failed"); + + int r = ::lseek(fd, file_size - 1, SEEK_SET); + if (r < 0) + throw runtime_error("lseek failed"); + + char c = '\0'; + r = ::write(fd, &c, 1); + if (r < 0) + throw runtime_error("::write failed"); + + if (r != 1) + throw runtime_error("insufficient bytes written"); + + ::close(fd); + } +} + +//---------------------------------------------------------------- + +TEST(ThinMetadataTests, create) +{ + string path("./metadata.bin"); + rm_f(path); + create_sized_file(path, 4096 * 1024); + metadata::ptr md(new metadata(path, metadata::CREATE, 128, 102400)); +}