#!/usr/bin/perl
#
# (C) Copyright IBM Corp. 2004
#
# This program is free software;  you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY;  without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
# the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program;  if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Engine tests for creating volumes

use strict;
use warnings;

use Evms::Common;
use Evms::Log;
use Evms::Dos;
use Evms::Volume;
use Evms::Object;

# Setup
# Assign the DOS Segment Manager to the disk.
# Make one segment that is no more than 100MB.
sub Setup
{
	my $disk = $_[0];
	my $rc;
	my $freespace;
	my $max_size = "100MB";
	my $size;

	log_info("Assign DOS Segment Manger to disk $disk.\n");
	$rc = assign_dos_plugin($disk);
	if ($rc) {
		log_error("Error assigning DOS Segment Manager to disk $disk.\n");
		goto setup_out;
	}

	# Make one segment no bigger than the max size.
	$freespace = "$disk" . "_freespace1";

	$size = get_object_size($freespace);

	if (size_to_sectors($size) > size_to_sectors($max_size)) {
		$size = $max_size;
	}

	log_info("Create a $size segment.\n");
	$rc = create_dos_logical_segment($freespace, $size);
	if ($rc) {
		log_error("Error creating logical segment from $freespace.\n");
		goto setup_out;
	}

setup_out:
	log_result($rc);
	return $rc;
}

# Test1
# Create a compatibility volume.
sub Test1
{
	my $object = $_[0];
	my $compat_volume = "/dev/evms/$object";
	my @output;
	my $rc = 0;

	log_info("Test creating a compatibility volume.\n");

	log_info("1. Create a compatibility volume on object $object.\n");
	$rc = create_compatibility_volume($object);
	if ($rc) {
		log_error("Error creating compatibility volume on $object.\n");
		$rc = 1;
		goto test1_out;
	}

	log_info("2. Verify creation of compatibility volume $compat_volume.\n");
	@output = query_volume($compat_volume);
	if (@output == 0) {
		log_error("Error querying info for volume $compat_volume.\n");
		$rc = 1;
		goto test1_out;
	}

	clean_object($object);

test1_out:
	log_result($rc);
	return $rc;
}

# Test2
# Create an EVMS volume.
sub Test2
{
	my $object = $_[0];
	my $name = "Marlin";
	my $evms_volume = "/dev/evms/$name";
	my @output;
	my $rc = 0;

	log_info("Test creating an EVMS volume.\n");

	log_info("1. Create an EVMS volume named $name on object $object.\n");
	$rc = create_evms_volume($object, $name);
	if ($rc) {
		log_error("Error creating EVMS volume on $object.\n");
		$rc = 1;
		goto test2_out;
	}

	log_info("2. Verify creation of EVMS volume $evms_volume.\n");
	@output = query_volume($evms_volume);
	if (@output == 0) {
		log_error("Error querying info for volume $evms_volume.\n");
		$rc = 1;
		goto test2_out;
	}

	clean_object($object);

test2_out:
	log_result($rc);
	return $rc;
}

# Test3
# Rename an EVMS volume.
sub Test3
{
	my $object = $_[0];
	my $name = "Nemo";
	my $evms_volume = "/dev/evms/$name";
	my $new_name = "Shark-Bait";
	my $new_evms_volume = "/dev/evms/$new_name";
	my @output;
	my $rc = 0;

	log_info("Test renaming an EVMS volume.\n");

	log_info("1. Create an EVMS volume named $name on object $object.\n");
	$rc = create_evms_volume($object, $name);
	if ($rc) {
		log_error("Error creating EVMS volume on $object.\n");
		$rc = 1;
		goto test3_out;
	}

	log_info("2. Verify creation of EVMS volume $evms_volume.\n");
	@output = query_volume($evms_volume);
	if (@output == 0) {
		log_error("Error querying info for volume $evms_volume.\n");
		$rc = 1;
		goto test3_out;
	}

	log_info("3. Rename EVMS volume $evms_volume to $new_name.\n");
	$rc = rename_volume($evms_volume, $new_name);
	if ($rc) {
		log_error("Error renaming volume $evms_volume.\n");
		$rc = 1;
		goto test3_out;
	}

	log_info("4. Verify rename of EVMS volume $evms_volume to $new_evms_volume.\n");
	@output = query_volume($new_evms_volume);
	if (@output == 0) {
		log_error("Error querying info for volume $new_evms_volume.\n");
		$rc = 1;
		goto test3_out;
	}

	clean_object($object);

test3_out:
	log_result($rc);
	return $rc;
}

# Test4
# Convert a compatibility volume to an EVMS volume.
sub Test4
{
	my $object = $_[0];
	my $compat_volume = "/dev/evms/$object";
	my $name = "Coral";
	my $evms_volume = "/dev/evms/$name";
	my @output;
	my $rc = 0;

	log_info("Test converting a compatibility volume to an EVMS volume.\n");

	log_info("1. Create a compatibility volume on object $object.\n");
	$rc = create_compatibility_volume($object);
	if ($rc) {
		log_error("Error creating compatibility volume on $object.\n");
		$rc = 1;
		goto test4_out;
	}

	log_info("2. Verify creation of compatibility volume $compat_volume.\n");
	@output = query_volume($compat_volume);
	if (@output == 0) {
		log_error("Error querying info for volume $compat_volume.\n");
		$rc = 1;
		goto test4_out;
	}

	log_info("3. Convert compatibility volume $compat_volume to and EVMS volume named $name.\n");
	$rc = convert_to_evms_volume($compat_volume, $name);
	if ($rc) {
		log_error("Error converting volume $compat_volume to an EVMS volume.\n");
		$rc = 1;
		goto test4_out;
	}

	log_info("4. Verify conversion of compatibility volume $compat_volume to EVMS volume $evms_volume.\n");
	@output = query_volume($evms_volume);
	if (@output == 0) {
		log_error("Error querying info for volume $evms_volume.\n");
		$rc = 1;
		goto test4_out;
	}

	clean_object($object);

test4_out:
	log_result($rc);
	return $rc;
}

# Test5
# Convert an EVMS volume to a compatibility volume.
sub Test5
{
	my $object = $_[0];
	my $name = "Dory";
	my $evms_volume = "/dev/evms/$name";
	my $compat_volume = "/dev/evms/$object";
	my @output;
	my $rc = 0;

	log_info("Test converting an EVMS volume to a compatibility volume.\n");

	log_info("1. Create an EVMS volume named $name on object $object.\n");
	$rc = create_evms_volume($object, $name);
	if ($rc) {
		log_error("Error creating EVMS volume on $object.\n");
		$rc = 1;
		goto test5_out;
	}

	log_info("2. Verify creation of EVMS volume $evms_volume.\n");
	@output = query_volume($evms_volume);
	if (@output == 0) {
		log_error("Error querying info for volume $evms_volume.\n");
		$rc = 1;
		goto test5_out;
	}

	log_info("3. Convert EVMS volume $evms_volume to a compatibility volume.\n");
	$rc = convert_to_compatibility_volume($evms_volume);
	if ($rc) {
		log_error("Error converting volume $evms_volume to a compatibility volume.\n");
		$rc = 1;
		goto test5_out;
	}

	log_info("4. Verify conversion of EVMS volme $evms_volume to compatibility volume $compat_volume.\n");
	@output = query_volume($compat_volume);
	if (@output == 0) {
		log_error("Error querying info for volume $compat_volume.\n");
		$rc = 1;
		goto test5_out;
	}

	clean_object($object);

test5_out:
	log_result($rc);
	return $rc;
}

# Add a feature to an EVMS volume.
sub Test6
{
	my $object = $_[0];
	my $volume_name = "School";
	my $evms_volume = "/dev/evms/$volume_name";
	my $feature = "DriveLink";
	my $feature_obj_name = "Mr-Ray";
	my %options = ("name" => $feature_obj_name);
	my @output;
	my $line;
	my $rc = 0;
	my $child = "";

	log_info("Test adding a feature to an EVMS volume.\n");

	log_info("1. Create an EVMS volume named $volume_name on object $object.\n");
	$rc = create_evms_volume($object, $volume_name);
	if ($rc) {
		log_error("Error creating EVMS volume on $object.\n");
		$rc = 1;
		goto test6_out;
	}

	log_info("2. Verify creation of EVMS volume $evms_volume.\n");
	@output = query_volume($evms_volume);
	if (@output == 0) {
		log_error("Error querying info for volume $evms_volume.\n");
		$rc = 1;
		goto test6_out;
	}

	log_info("3. Add $feature feature object named $feature_obj_name to EVMS volume $evms_volume.\n");
	$rc = add_feature_to_volume($evms_volume, $feature, \%options);
	if ($rc) {
		log_error("Error adding $feature feature to volume $evms_volume.\n");
		$rc = 1;
		goto test6_out;
	}

	log_info("4. Verify $feature_obj_name was created.\n");
	@output = query_object($options{"name"});
	if (@output == 0) {
		log_error("Error querying info for object " . $options{"name"} . ".\n");
		$rc = 1;
		goto test6_out;
	}

	log_info("5. Verify $feature_obj_name is the child of EVMS volume $evms_volume.\n");
	$rc = run_evms_command("query:children,$evms_volume", \@output);
	if ($rc) {
		log_error("Error querying child of volume $evms_volume.\n");
		$rc = 1;
		goto test6_out;
	}

	($line) = grep(/Name:/, @output);
	if ($line =~ /Name:\s+(\S+)/) {
		$child = $1;
	}

	if ($child eq "") {
		log_error("Could not find the line with the child object name in the query children output.\n");
		$rc = 1;
		goto test6_out;
	}

	if ($child ne $options{"name"}) {
		log_error("Volume $evms_volume does not have child object " . $options{"name"} . ".  It has object $child instead.\n");
		$rc = 1;
		goto test6_out;
	}

	clean_object($object);

test6_out:
	log_result($rc);
	return $rc;
}

# Create an EVMS volume with a name that is not valid..
sub Test7
{
	my $object = $_[0];
	my $volume_name = $object;
	my $evms_volume = "/dev/evms/$volume_name";
	my @output;
	my $rc = 0;

	log_info("Test creating an EVMS volume with a name that is not valid.\n");

	log_info("1. Create an EVMS volume named $volume_name on object $object.\n");
	$rc = create_evms_volume($object, $volume_name);
	if ($rc) {
		$rc = 0;
	} else {
		log_error("Error:  EVMS volume $volume_name was created on $object.\n");
		$rc = 1;
		goto test7_out;
	}

	log_info("2. Verify EVMS volume $evms_volume was *not* created.\n");
	@output = query_volume($evms_volume);
	if (@output != 0) {
		log_error("Error:  Querying info for volume $evms_volume was successful.\n");
		$rc = 1;
		goto test7_out;
	}

	clean_object($object);

test7_out:
	log_result($rc);
	return $rc;
}


MAIN:
{
	my $disk;
	my $segment;
	my $rc;

	# Only use the first disk specified.
	$disk = $ARGV[0];
	$disk || die("USAGE: $0 disk\n");

	$rc = Setup($disk);
	if ($rc) {
		goto finish;
	}

	$segment = $disk.5;

	$rc = Test1($segment);
	if ($rc) {
		goto finish;
	}
	
	$rc = Test2($segment);
	if ($rc) {
		goto finish;
	}
	
	$rc = Test3($segment);
	if ($rc) {
		goto finish;
	}
	
	$rc = Test4($segment);
	if ($rc) {
		goto finish;
	}
	
	$rc = Test5($segment);
	if ($rc) {
		goto finish;
	}
	
	$rc = Test6($segment);
	if ($rc) {
		goto finish;
	}

	$rc = Test7($segment);
	if ($rc) {
		goto finish;
	}

	clean_object($disk);

finish:
}

