#!/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
#
# LVM2 script for testing container expands and shrinks.
#
# Test1: Create an LVM2 container with one PV. Then add a second PV.
# Test2: Create a container with two PVs. Then remove the first PV.
# Test3: Create a container with one PV and try to remove the PV.

use strict;
use warnings;

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

# Setup
# Create 10 segments to test with.
sub Setup
{
	my $disk = $_[0];
	my $rc;

	log_info("Create 4 DOS segments.\n");

	$rc = create_dos_segments($disk, 4, "250MB");

	log_info(($rc ? "Failed" : "Success") . "\n\n");
	return $rc;
}

# Test1
# Create an LVM2 container with one PV. Then add a second PV.
sub Test1
{
	my $disk = $_[0];
	my @pvs = ($disk . "5", $disk . "6");
	my $pv;
	my $name = "Litespeed";
	my %options;
	my @output;
	my $rc;

	$options{"name"} = $name;

	log_info("Test expanding an LVM2 container.\n");

	log_info("1. Creating an LVM2 container $name with PV $pvs[0].\n");

	$rc = create_lvm2_container(\%options, $pvs[0]);
	if ($rc) {
		log_error("Error creating container $name.\n");
		goto out;
	}

	log_info("2. Adding PV $pvs[1] to container $name.\n");

	$rc = expand_lvm2_container($name, $pvs[1]);
	if ($rc) {
		log_error("Error expanding container $name.\n");
		goto out;
	}

	log_info("3. Verifying all PVs consumed by container $name.\n");

	@output = get_lvm2_container_pvs($name);
	if (!@output) {
                log_error("Error querying for pvs in container $name.\n");
		$rc = 1;
		goto out;
	}

	foreach $pv (@pvs) {
		if (!grep(/$pv/, @output)) {
			log_error("Error finding PV $pv in container $name.\n");
			$rc = 1;
			goto out;
		}
	}

	delete_lvm2_container($name);

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

# Test2
# Create a container with two PVs. Then remove the first PV.
sub Test2
{
	my $disk = $_[0];
	my @pvs = ($disk . "7", $disk . "8");
	my $name = "Trek";
	my %options;
	my @output;
	my $rc;

	$options{"name"} = $name;

	log_info("Test shrinking an LVM2 container.\n");

	log_info("1. Creating an LVM2 container $name with PVs: @pvs.\n");

	$rc = create_lvm2_container(\%options, @pvs);
	if ($rc) {
		log_error("Error creating container $name.\n");
		goto out;
	}

	log_info("2. Removing PV $pvs[0] from container $name.\n");

	$rc = shrink_lvm2_container($name, $pvs[0]);
	if ($rc) {
		log_error("Error shrinking container $name.\n");
		goto out;
	}

	log_info("3. Verifying PV $pvs[0] was removed from container $name.\n");

	@output = get_lvm2_container_pvs($name);
	if (!@output) {
                log_error("Error querying for pvs in container $name.\n");
		$rc = 1;
		goto out;
	}

	if (grep(/$pvs[0]/, @output)) {
		log_error("Error: PV $pvs[0] still part of container $name.\n");
		$rc = 1;
		goto out;
	}

	delete_lvm2_container($name);

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

# Test3
# Create a container with one PV and try to remove the PV (shouldn't work).
sub Test3
{
	my $disk = $_[0];
	my $pv = $disk . "5";
	my $name = "Cannondale";
	my %options;
	my @output;
	my $rc;

	$options{"name"} = $name;

	log_info("Test attempting to remove the last PV from an " .
		 "LVM2 container.\n");

	log_info("1. Creating an LVM2 container $name with PV $pv.\n");

	$rc = create_lvm2_container(\%options, $pv);
	if ($rc) {
		log_error("Error creating container $name.\n");
		goto out;
	}

	log_info("2. Attempting to removing PV $pv from container $name.\n");

	shrink_lvm2_container($name, $pv);
	# KMC: Can't check the return code. This returns 0, even when the
	# shrink attempt fails. Should we change this???

	log_info("3. Verifying PV $pv is still in container $name.\n");

	@output = get_lvm2_container_pvs($name);
	if (!@output) {
                log_error("Error querying for pvs in container $name.\n");
		$rc = 1;
		goto out;
	}

	if (!grep(/$pv/, @output)) {
		log_error("Error: PV $pv not found in container $name.\n");
		$rc = 1;
		goto out;
	}

	delete_lvm2_container($name);
	$rc = 0;

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

MAIN:
{
	my $disk;
	my $rc;

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

	# Check for minimum-sized disk.
	$rc = check_minimum_object_size($disk, "1GB");
	if ($rc) {
		goto finish;
	}

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

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

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

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

finish:
}

