-# Copyright (c) 2008, 2009, 2010 Zmanda, Inc. All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 as published
# Contact information: Zmanda Inc, 465 S. Mathilda Ave., Suite 300
# Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
-use Test::More tests => 505;
+use Test::More tests => 609;
use File::Path qw( mkpath rmtree );
use Sys::Hostname;
use Carp;
use Amanda::Xfer qw( :constants );
use Amanda::Header qw( :constants );
use Amanda::Paths;
+use Amanda::Constants;
use Amanda::Util;
use Amanda::MainLoop;
use IO::Socket;
ok($dev->property_set("block_size", 32768),
"set an integer property to an integer");
+ok(!($dev->property_set("invalid-property-name", 32768)),
+ "set an invalid-property-name");
+
$dev->read_label();
ok($dev->status() & $DEVICE_STATUS_VOLUME_UNLABELED,
"initially unlabeled")
"set MAX_VOLUME_USAGE to test LEOM");
ok($dev->property_set("LEOM", 1),
"set LEOM");
+ok($dev->property_set("ENFORCE_MAX_VOLUME_USAGE", 0),
+ "set ENFORCE_MAX_VOLUME_USAGE");
+
+ok($dev->start($ACCESS_WRITE, 'TESTCONF23', undef),
+ "start in write mode")
+ or diag($dev->error_or_status());
+
+ok($dev->start_file($dumpfile),
+ "start file 1")
+ or diag($dev->error_or_status());
+
+ok(Amanda::Device::write_random_to_device(0xCAFE, 440*1024, $dev),
+ "write random data into the early-warning zone");
+
+ok(!$dev->is_eom,
+ "device does not indicates LEOM after writing when ENFORCE_MAX_VOLUME_USAGE is FALSE");
+
+ok($dev->finish_file(),
+ "..but a finish_file is allowed to complete")
+ or diag($dev->error_or_status());
+
+ok($dev->finish(),
+ "finish device after LEOM test")
+ or diag($dev->error_or_status());
+
+$dev = undef;
+$dev = Amanda::Device->new($dev_name);
+is($dev->status(), $DEVICE_STATUS_SUCCESS,
+ "$dev_name: re-create successful")
+ or diag($dev->error_or_status());
+ok($dev->property_set("MAX_VOLUME_USAGE", "512k"),
+ "set MAX_VOLUME_USAGE to test LEOM");
+ok($dev->property_set("LEOM", 1),
+ "set LEOM");
+ok($dev->property_set("ENFORCE_MAX_VOLUME_USAGE", 1),
+ "set ENFORCE_MAX_VOLUME_USAGE");
ok($dev->start($ACCESS_WRITE, 'TESTCONF23', undef),
"start in write mode")
"finish device after LEOM test")
or diag($dev->error_or_status());
+$dev = undef;
+$dev = Amanda::Device->new($dev_name);
+is($dev->status(), $DEVICE_STATUS_SUCCESS,
+ "$dev_name: re-create successful")
+ or diag($dev->error_or_status());
+ok($dev->property_set("MAX_VOLUME_USAGE", "512k"),
+ "set MAX_VOLUME_USAGE to test LEOM");
+ok($dev->property_set("LEOM", 1),
+ "set LEOM");
+
+ok($dev->start($ACCESS_WRITE, 'TESTCONF23', undef),
+ "start in write mode")
+ or diag($dev->error_or_status());
+
+ok($dev->start_file($dumpfile),
+ "start file 1")
+ or diag($dev->error_or_status());
+
+ok(!$dev->is_eom,
+ "device does not indicate LEOM before writing");
+
+ok(Amanda::Device::write_random_to_device(0xCAFE, 440*1024, $dev),
+ "write random data into the early-warning zone");
+
+ok($dev->is_eom,
+ "device indicates LEOM after writing as default value of ENFORCE_MAX_VOLUME_USAGE is true for vfs device");
+
+ok($dev->finish_file(),
+ "..but a finish_file is allowed to complete")
+ or diag($dev->error_or_status());
+
+ok($dev->finish(),
+ "finish device after LEOM test")
+ or diag($dev->error_or_status());
+
$dev = undef;
$dev = Amanda::Device->new($dev_name);
is($dev->status(), $DEVICE_STATUS_SUCCESS,
SKIP: {
skip "define \$INSTALLCHECK_S3_{SECRET,ACCESS}_KEY to run S3 tests",
- 71 +
+ 101 +
1 * $verify_file_count +
- 4 * $write_file_count +
- 10 * $s3_make_device_count
+ 7 * $write_file_count +
+ 13 * $s3_make_device_count
unless $run_s3_tests;
$dev_name = "s3:";
"erase device right after creation")
or diag($dev->error_or_status());
+ $dev = s3_make_device($dev_name, "s3");
+
+ # set MAX_VOLUME_USAGE, LEOM=true, ENFORCE_MAX_VOLUME_USAGE=false
+ ok($dev->property_set('MAX_VOLUME_USAGE', "512k"),
+ "set MAX_VOLUME_USAGE to test LEOM");
+
+ ok($dev->property_set("LEOM", 1),
+ "set LEOM");
+
+ ok($dev->start($ACCESS_WRITE, "TESTCONF13", undef),
+ "start in write mode")
+ or diag($dev->error_or_status());
+
+ write_file(0x2FACE, 440*1024, 1);
+
+ ok(!$dev->is_eom,
+ "device does not indicate LEOM after writing as property ENFORCE_MAX_VOLUME_USAGE not set and its default value is false");
+
+ ok($dev->finish(),
+ "finish device after LEOM test")
+ or diag($dev->error_or_status());
+
+ ok($dev->erase(),
+ "erase device")
+ or diag($dev->error_or_status());
+
+ $dev = s3_make_device($dev_name, "s3");
+
+ # set MAX_VOLUME_USAGE, LEOM=true, ENFORCE_MAX_VOLUME_USAGE=true
+ ok($dev->property_set('MAX_VOLUME_USAGE', "512k"),
+ "set MAX_VOLUME_USAGE to test LEOM");
+
+ ok($dev->property_set('ENFORCE_MAX_VOLUME_USAGE', 1 ),
+ "set ENFORCE_MAX_VOLUME_USAGE");
+
+ ok($dev->property_set("LEOM", 1),
+ "set LEOM");
+
+ ok($dev->start($ACCESS_WRITE, "TESTCONF13", undef),
+ "start in write mode")
+ or diag($dev->error_or_status());
+
+ write_file(0x2FACE, 440*1024, 1);
+
+ ok($dev->is_eom,
+ "device indicates LEOM after writing, when property ENFORCE_MAX_VOLUME_USAGE set to true");
+
+ ok($dev->finish(),
+ "finish device after LEOM test")
+ or diag($dev->error_or_status());
+
+ ok($dev->erase(),
+ "erase device")
+ or diag($dev->error_or_status());
+
+ $dev = s3_make_device($dev_name, "s3");
+
+ # set MAX_VOLUME_USAGE, LEOM=true, ENFORCE_MAX_VOLUME_USAGE=false
+ ok($dev->property_set('MAX_VOLUME_USAGE', "512k"),
+ "set MAX_VOLUME_USAGE to test LEOM");
+
+ ok($dev->property_set('ENFORCE_MAX_VOLUME_USAGE', 0 ),
+ "set ENFORCE_MAX_VOLUME_USAGE");
+
+ ok($dev->property_set("LEOM", 1),
+ "set LEOM");
+
+ ok($dev->start($ACCESS_WRITE, "TESTCONF13", undef),
+ "start in write mode")
+ or diag($dev->error_or_status());
+
+ write_file(0x2FACE, 440*1024, 1);
+
+ ok(!$dev->is_eom,
+ "device does not indicate LEOM after writing, when property ENFORCE_MAX_VOLUME_USAGE set to false");
+
+ ok($dev->finish(),
+ "finish device after LEOM test")
+ or diag($dev->error_or_status());
+
+ ok($dev->erase(),
+ "erase device")
+ or diag($dev->error_or_status());
+
# try with empty user token
$dev_name = lc("s3:$base_name-s3");
$dev = s3_make_device($dev_name, "s3");
ok(!$dev->property_set('S3_BUCKET_LOCATION', 'EU'),
"should not be able to set S3 bucket location with an incompatible name")
or diag($dev->error_or_status());
+
+ $dev_name = lc("s3:$base_name-s3-eu");
+ $dev = s3_make_device($dev_name, "s3");
+ ok($dev->property_set('S3_BUCKET_LOCATION', 'XYZ'),
+ "should be able to set S3 bucket location with a compatible name")
+ or diag($dev->error_or_status());
+ $dev->read_label();
+ $status = $dev->status();
+ ok(($status == $DEVICE_STATUS_DEVICE_ERROR),
+ "status is DEVICE_STATUS_DEVICE_ERROR")
+ or diag($dev->error_or_status());
+ my $error_msg = $dev->error_or_status();
+ ok(($dev->error_or_status() == "While creating new S3 bucket: The specified location-constraint is not valid (Unknown) (HTTP 400)"),
+ "invalid location-constraint")
+ or diag("bad error: " . $dev->error_or_status());
+
}
SKIP: {
}
SKIP: {
- skip "not built with ndmp and server", 78 unless
+ skip "not built with ndmp and server", 94 unless
Amanda::Util::built_with_component("ndmp") and
Amanda::Util::built_with_component("server");
}
}
+ #
+ # Test indirecttcp
+ #
+
+ {
+ ok($dev->directtcp_supported(), "is a directtcp target");
+
+ $dev->property_set("indirect", 1);
+
+ my $addrs = $dev->listen(1);
+ ok($addrs, "listen returns successfully") or die($dev->error_or_status());
+
+ # fork off to evaluate the indirecttcp addresses and then set up an
+ # xfer to write to the device
+ if (POSIX::fork() == 0) {
+ # allow other process to start listening.
+ sleep 1;
+ my $nc = $Amanda::Constants::NC;
+ $nc = $Amanda::Constants::NC6 if !$nc;
+ $nc = $Amanda::Constants::NETCAT if !$nc;
+ my $sockresult = `$nc localhost $addrs->[0][1] < /dev/null`;
+
+ my @sockresult = map { [ split(/:/, $_) ] } split(/ /, $sockresult);
+ $addrs = [ map { $_->[1] = 0 + $_->[1]; $_ } @sockresult ];
+
+ my $xfer = Amanda::Xfer->new([
+ Amanda::Xfer::Source::Random->new(32768*34, 0xB00),
+ Amanda::Xfer::Dest::DirectTCPConnect->new($addrs) ]);
+
+ $xfer->start(make_cb(xmsg_cb => sub {
+ my ($src, $msg, $xfer) = @_;
+ if ($msg->{'type'} == $XMSG_ERROR) {
+ die $msg->{'elt'} . " failed: " . $msg->{'message'};
+ } elsif ($msg->{'type'} == $XMSG_DONE) {
+ Amanda::MainLoop::quit();
+ }
+ }));
+
+ Amanda::MainLoop::run();
+ exit(0);
+ }
+
+ # write files from the connection until EOF
+ my @messages;
+ my $num_files;
+ my $conn;
+ my ($call_accept, $start_device, $write_file_cb);
+
+ $call_accept = make_cb(call_accept => sub {
+ $conn = $dev->accept();
+ Amanda::MainLoop::call_later($start_device);
+ });
+
+ $start_device = make_cb(start_device => sub {
+ ok($dev->start($ACCESS_WRITE, "TEST2", "20090915000000"),
+ "start device in write mode")
+ or diag $dev->error_or_status();
+
+ Amanda::MainLoop::call_later($write_file_cb);
+ });
+
+ $write_file_cb = make_cb(write_file_cb => sub {
+ ++$num_files < 20 or die "I seem to be in a loop!";
+
+ ok($dev->start_file($hdr), "start file $num_files for writing");
+ is($dev->file, $num_files, "..file number is correct");
+
+ my ($ok, $size) = $dev->write_from_connection(32768*15);
+ push @messages, sprintf("WRITE-%s-%d-%s-%s",
+ $ok?"OK":"ERR", $size,
+ $dev->is_eof()? "EOF":"!eof",
+ $dev->is_eom()? "EOM":"!eom");
+ ok($ok, "..write from connection succeeds");
+ my $eof = $dev->is_eof();
+
+ ok($dev->finish_file(), "..finish file after writing");
+
+ if (!$eof) {
+ Amanda::MainLoop::call_later($write_file_cb);
+ } else {
+ Amanda::MainLoop::quit();
+ }
+ });
+
+ Amanda::MainLoop::call_later($call_accept);
+ Amanda::MainLoop::run();
+ is_deeply([@messages], [
+ 'WRITE-OK-491520-!eof-!eom',
+ 'WRITE-OK-491520-!eof-!eom',
+ 'WRITE-OK-131072-EOF-!eom',
+ ],
+ "a sequence of write_from_connection calls works correctly");
+
+ $dev->finish();
+
+ if (my $err = $conn->close()) {
+ die $err;
+ }
+ }
+
# now try reading that back piece by piece
{