aboutsummaryrefslogtreecommitdiff
path: root/perl/t/object/file.t
blob: 80173cd313c2c81bfbcac8fde5c2f8b75a1ea741 (plain)
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');
}