1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
#!/usr/bin/perl
#
# Tests for the file object implementation.
#
# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2008, 2014
# The Board of Trustees of the Leland Stanford Junior University
#
# SPDX-License-Identifier: MIT
use strict;
use warnings;
use POSIX qw(strftime);
use Test::More tests => 60;
use Wallet::Admin;
use Wallet::Config;
use Wallet::Object::File;
use lib 't/lib';
use Util;
# Some global defaults to use.
my $user = 'admin@EXAMPLE.COM';
my $host = 'localhost';
my @trace = ($user, $host, time);
# Flush all output immediately.
$| = 1;
# Use Wallet::Admin to set up the database.
system ('rm -rf test-files') == 0 or die "cannot remove test-files\n";
db_setup;
my $admin = eval { Wallet::Admin->new };
is ($@, '', 'Database connection succeeded');
is ($admin->reinitialize ($user), 1, 'Database initialization succeeded');
my $schema = $admin->schema;
# Use this to accumulate the history traces so that we can check history.
my $history = '';
my $date = strftime ('%Y-%m-%d %H:%M:%S', localtime $trace[2]);
# Test error handling in the absence of configuration.
my $object = eval {
Wallet::Object::File->create ('file', 'test', $schema, @trace)
};
ok (defined ($object), 'Creating a basic file object succeeds');
ok ($object->isa ('Wallet::Object::File'), ' and is the right class');
is ($object->get (@trace), undef, ' and get fails');
is ($object->error, 'file support not configured', ' with the right error');
is ($object->store (@trace), undef, ' and store fails');
is ($object->error, 'file support not configured', ' with the right error');
is ($object->destroy (@trace), 1, ' but destroy succeeds');
# Set up our configuration.
mkdir 'test-files' or die "cannot create test-files: $!\n";
$Wallet::Config::FILE_BUCKET = 'test-files';
# Okay, now we can test. First, the basic object without store.
$object = eval {
Wallet::Object::File->create ('file', 'test', $schema, @trace)
};
ok (defined ($object), 'Creating a basic file object succeeds');
ok ($object->isa ('Wallet::Object::File'), ' and is the right class');
is ($object->get (@trace), undef, ' and get fails');
is ($object->error, 'cannot get file:test: object has not been stored',
' with the right error');
is ($object->destroy (@trace), 1, ' but destroying the object succeeds');
# Now store something and be sure that we get something reasonable.
$object = eval {
Wallet::Object::File->create ('file', 'test', $schema, @trace)
};
ok (defined ($object), 'Recreating the object succeeds');
is ($object->store ("foo\n", @trace), 1, ' and storing data in it succeeds');
ok (-d 'test-files/09', ' and the hash bucket was created');
ok (-f 'test-files/09/test', ' and the file exists');
is (contents ('test-files/09/test'), 'foo', ' with the right contents');
is ($object->get (@trace), "foo\n", ' and get returns correctly');
unlink 'test-files/09/test';
is ($object->get (@trace), undef, ' and get fails if we delete it');
is ($object->error, 'cannot get file:test: object has not been stored',
' as if it had not been stored');
is ($object->store ("bar\n\0baz\n", @trace), 1, ' but storing again works');
ok (-f 'test-files/09/test', ' and the file exists');
is (contents ('test-files/09/test'), 'bar', ' with the right contents');
is ($object->get (@trace), "bar\n\0baz\n", ' and get returns correctly');
# Try exceeding the store size.
$Wallet::Config::FILE_MAX_SIZE = 1024;
is ($object->store ('x' x 1024, @trace), 1,
' and storing exactly 1024 characters works');
is ($object->get (@trace), 'x' x 1024, ' and get returns the right thing');
is ($object->store ('x' x 1025, @trace), undef,
' but storing 1025 characters fails');
is ($object->error, 'data exceeds maximum of 1024 bytes',
' with the right error');
# Try storing the empty data object.
is ($object->store ('', @trace), 1, 'Storing the empty object works');
is ($object->get (@trace), '', ' and get returns the right thing');
# Test renaming a file object.
is ($object->rename ('test-rename', @trace), 1, 'Renaming the object works');
is ($object->{name}, 'test-rename', ' and the object is renamed');
ok (-f 'test-files/2b/test-rename', ' and the file is in the new location');
ok (! -f 'test-files/09/test', ' and nothing is in the old location');
# Test destruction.
is ($object->destroy (@trace), 1, 'Destroying the object works');
ok (! -f 'test-files/2b/test-rename', ' and the file is gone');
# Now try some aggressive names.
$object = eval {
Wallet::Object::File->create ('file', '../foo', $schema, @trace)
};
ok (defined ($object), 'Creating ../foo succeeds');
is ($object->store ("foo\n", @trace), 1, ' and storing data in it succeeds');
ok (-d 'test-files/39', ' and the hash bucket was created');
ok (-f 'test-files/39/%2E%2E%2Ffoo', ' and the file exists');
is (contents ('test-files/39/%2E%2E%2Ffoo'), 'foo',
' with the right contents');
is ($object->get (@trace), "foo\n", ' and get returns correctly');
is ($object->destroy (@trace), 1, 'Destroying the object works');
ok (! -f 'test-files/39/%2E%2E%2Ffoo', ' and the file is gone');
$object = eval {
Wallet::Object::File->create ('file', "\0", $schema, @trace)
};
ok (defined ($object), 'Creating nul succeeds');
is ($object->store ("foo\n", @trace), 1, ' and storing data in it succeeds');
ok (-d 'test-files/93', ' and the hash bucket was created');
ok (-f 'test-files/93/%00', ' and the file exists');
is (contents ('test-files/93/%00'), 'foo',
' with the right contents');
is ($object->get (@trace), "foo\n", ' and get returns correctly');
is ($object->destroy (@trace), 1, 'Destroying the object works');
ok (! -f 'test-files/93/%00', ' and the file is gone');
# Test error handling in the file store.
system ('rm -r test-files') == 0 or die "cannot remove test-files\n";
$object = eval {
Wallet::Object::File->create ('file', 'test', $schema, @trace)
};
ok (defined ($object), 'Recreating the object succeeds');
is ($object->store ("foo\n", @trace), undef,
' and storing data in it fails');
like ($object->error, qr/^cannot create file bucket 09: /,
' with the right error');
is ($object->get (@trace), undef, ' and get fails');
like ($object->error, qr/^cannot create file bucket 09: /,
' with the right error');
is ($object->destroy (@trace), 1, ' but destroying the object succeeds');
# Clean up.
$admin->destroy;
END {
unlink ('wallet-db');
}
|