cache_check work

This commit is contained in:
Joe Thornber 2013-03-21 15:44:28 +00:00 committed by Joe Thornber
parent 81d4e5523f
commit 52f1aa8a8a
6 changed files with 221 additions and 19 deletions

5
.gitignore vendored
View File

@ -3,9 +3,14 @@
*_t *_t
*.d *.d
test.data test.data
thin_check
thin_dump thin_dump
thin_restore thin_restore
thin_repair thin_repair
cache_check
*.metadata *.metadata
bad-metadata bad-metadata
Makefile Makefile

7
Rakefile Normal file
View File

@ -0,0 +1,7 @@
require 'rubygems'
require 'cucumber'
require 'cucumber/rake/task'
Cucumber::Rake::Task.new(:features) do |t|
t.cucumber_opts = "features --format progress"
end

94
cache/check.cc vendored
View File

@ -17,21 +17,71 @@
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
#include <iostream> #include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h> #include <getopt.h>
#include <libgen.h> #include <libgen.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#if 0
#include "array.h"
#include "metadata.h"
#include "metadata_checker.h"
#include "version.h"
using namespace persistent_data;
using namespace std; using namespace std;
using namespace thin_provisioning;
//----------------------------------------------------------------
namespace { namespace {
struct stat guarded_stat(string const &path) {
struct stat info;
int r = ::stat(path.c_str(), &info);
if (r) {
ostringstream msg;
char buffer[128], *ptr;
ptr = ::strerror_r(errno, buffer, sizeof(buffer));
msg << path << ": " << ptr;
throw runtime_error(msg.str());
}
return info;
}
int open_file(string const &path, int mode) {
int fd = open(path.c_str(), mode);
if (fd < 0) {
ostringstream msg;
char buffer[128], *ptr;
ptr = strerror_r(errno, buffer, sizeof(buffer));
msg << path << ": " << ptr;
throw runtime_error(msg.str());
}
return fd;
}
int check(string const &path, bool quiet) { int check(string const &path, bool quiet) {
struct stat info = guarded_stat(path);
if (!S_ISREG(info.st_mode) && !S_ISBLK(info.st_mode)) {
ostringstream msg;
msg << path << ": " << "Not a block device or regular file";
throw runtime_error(msg.str());
}
int fd = open_file(path, O_RDONLY);
ostringstream msg;
msg << path << ": " << "No superblock found";
throw runtime_error(msg.str());
return 0;
#if 0
try { try {
metadata::ptr md(new metadata(path, metadata::OPEN)); metadata::ptr md(new metadata(path, metadata::OPEN));
@ -48,6 +98,7 @@ namespace {
} }
return 0; return 0;
#endif
} }
void usage(ostream &out, string const &cmd) { void usage(ostream &out, string const &cmd) {
@ -57,8 +108,12 @@ namespace {
<< " {-h|--help}" << endl << " {-h|--help}" << endl
<< " {-V|--version}" << endl; << " {-V|--version}" << endl;
} }
char const *TOOLS_VERSION = "0.1.6";
} }
//----------------------------------------------------------------
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int c; int c;
@ -82,7 +137,7 @@ int main(int argc, char **argv)
break; break;
case 'V': case 'V':
cout << THIN_PROVISIONING_TOOLS_VERSION << endl; cout << TOOLS_VERSION << endl;
return 0; return 0;
default: default:
@ -94,15 +149,18 @@ int main(int argc, char **argv)
if (argc == optind) { if (argc == optind) {
cerr << "No input file provided." << endl; cerr << "No input file provided." << endl;
usage(cerr, basename(argv[0])); usage(cerr, basename(argv[0]));
exit(1); return 1;
} }
return check(argv[optind], quiet); try {
check(argv[optind], quiet);
} catch (exception const &e) {
cerr << e.what() << endl;
return 1;
}
return 0;
} }
#else
int main(int argc, char **argv) //----------------------------------------------------------------
{
cerr << "not implemented" << endl;
return 1;
}
#endif

View File

@ -0,0 +1,76 @@
Feature: cache_check
Scenario: print version (-V flag)
When I run `cache_check -V`
Then it should pass
And version to stdout
Scenario: print version (--version flag)
When I run `cache_check --version`
Then it should pass
And version to stdout
Scenario: print help
When I run `cache_check --help`
Then it should pass
And usage to stdout
Scenario: print help
When I run `cache_check -h`
Then it should pass
And usage to stdout
Scenario: Metadata file must be specified
When I run `cache_check`
Then it should fail
And usage to stderr
And the stderr should contain:
"""
No input file provided.
"""
Scenario: Metadata file doesn't exist
When I run `cache_check /arbitrary/filename`
Then it should fail
And the stderr should contain:
"""
/arbitrary/filename: No such file or directory
"""
Scenario: Metadata file cannot be a directory
Given a directory called foo
When I run `cache_check foo`
Then it should fail
And the stderr should contain:
"""
foo: Not a block device or regular file
"""
Scenario: Metadata file exists, but can't be opened
Given input without read permissions
When I run `cache_check input`
Then it should fail
And the stderr should contain:
"""
input: Permission denied
"""
Scenario: Metadata file full of zeroes
Given input file
And block 1 is zeroed
When I run `cache_check input`
And the stderr should contain:
"""
input: No superblock found
"""

View File

@ -0,0 +1,57 @@
DEFAULT_INPUT = 'input'
BLOCK_SIZE = 4096
Given /^a directory called (.*)\s*$/ do |dir|
create_dir(dir)
end
Given /^input without read permissions$/ do
write_file(DEFAULT_INPUT, "\0" * 4096)
in_current_dir do
f = File.new(DEFAULT_INPUT)
f.chmod(0000)
end
end
Given(/^input file$/) do
write_file(DEFAULT_INPUT, "\0" * BLOCK_SIZE * 1024)
end
Given(/^block (\d+) is zeroed$/) do |b|
in_current_dir do
File.open(DEFAULT_INPUT, 'w') do |f|
f.seek(BLOCK_SIZE * b.to_i, IO::SEEK_SET)
f.write("\0" * BLOCK_SIZE)
end
end
end
Then /^it should pass$/ do
assert_success(true)
end
Then /^it should fail$/ do
assert_success(false)
end
VERSION="0.1.6\n"
Then /^version to stdout$/ do
assert_exact_output(VERSION, all_stdout)
end
USAGE =<<EOF
Usage: cache_check [options] {device|file}
Options:
{-q|--quiet}
{-h|--help}
{-V|--version}
EOF
Then /^usage to stdout$/ do
assert_partial_output(USAGE, all_stdout)
end
Then /^usage to stderr$/ do
assert_partial_output(USAGE, all_stderr)
end

View File

@ -1,4 +1,3 @@
require 'aruba/cucumber' require 'aruba/cucumber'
STDERR.puts "pwd = #{Dir::pwd}"
ENV['PATH'] = "#{Dir::pwd}:#{ENV['PATH']}" ENV['PATH'] = "#{Dir::pwd}:#{ENV['PATH']}"