#!/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 file system functions on 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;
}

# Make a file system on a volume.
sub Test1
{
	my $object = $_[0];
	my $volume_name = "Gill";
	my $evms_volume = "/dev/evms/$volume_name";
	my $fsim = "Ext2/3";
	my %mkfs_options = ("journal"  => "FALSE",
			    "vollabel" => $volume_name);
	my @output;
	my $rc = 0;
	my $filesystem = "";

	log_info("Test making a file system on a volume.\n");
	
	log_info("1. Create volume $evms_volume on object $object.\n");
	$rc = create_evms_volume($object, $volume_name);
	if ($rc) {
		log_error("Test1: Error creating EVMS volume on $object.\n");
		$rc = 1;
		goto test1_out;
	}

	log_info("2. Verify creation of 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 test1_out;
	}

	log_info("3. Make $fsim file system on volume $evms_volume.\n");
	log_info("   mkfs options are:\n");
	foreach my $name (keys(%mkfs_options)) {
		log_info("     $name = $mkfs_options{$name}\n");
	}
	$rc = mkfs_volume($evms_volume, $fsim, \%mkfs_options);
	if ($rc) {
		log_error("Error making $fsim file system on volume $evms_volume.\n");
		$rc = 1;
		goto test1_out;
	}

	log_info("4. Verify $fsim file system is on volume $evms_volume.\n");
	$filesystem = get_volume_filesystem($evms_volume);
	if ($filesystem eq "") {
		log_error("Could not find the line with the file system name in the query volume output.\n");
		$rc = 1;
		goto test1_out;
	}

	if ($filesystem ne $fsim) {
		log_error("Volume $evms_volume does not have file system $fsim.  It has $filesystem instead.\n");
		$rc = 1;
		goto test1_out;
	}

	clean_object($object);

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

# fsck a file system on a volume.
sub Test2
{
	my $object = $_[0];
	my $volume_name = "Peach";
	my $evms_volume = "/dev/evms/$volume_name";
	my $fsim = "Ext2/3";
	my %mkfs_options = ("journal"  => "FALSE",
			    "vollabel" => $volume_name);
	my %fsck_options = ("force" => "TRUE");
	my @output;
	my $rc = 0;
	my $filesystem = "";

	log_info("Test fsck-ing a file system on a volume.\n");

	log_info("1. Create volume $evms_volume 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 test2_out;
	}

	log_info("2. Verify creation of 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;
	}

	log_info("3. Make $fsim file system on volume $evms_volume.\n");
	log_info("   mkfs options are:\n");
	foreach my $name (keys(%mkfs_options)) {
		log_info("     $name = $mkfs_options{$name}\n");
	}
	$rc = mkfs_volume($evms_volume, $fsim, \%mkfs_options);
	if ($rc) {
		log_error("Error making $fsim file system on volume $evms_volume.\n");
		$rc = 1;
		goto test2_out;
	}

	log_info("4. Verify $fsim file system is on volume $evms_volume.\n");
	$filesystem = get_volume_filesystem($evms_volume);
	if ($filesystem eq "") {
		log_error("Could not find the line with the file system name in the query volume output.\n");
		$rc = 1;
		goto test2_out;
	}

	if ($filesystem ne $fsim) {
		log_error("Volume $evms_volume does not have file system $fsim.  It has $filesystem instead.\n");
		$rc = 1;
		goto test2_out;
	}

	log_info("5. fsck the $fsim file system on volume $evms_volume.\n");
	log_info("   fsck options are:\n");
	foreach my $name (keys(%fsck_options)) {
		log_info("     $name = $fsck_options{$name}\n");
	}
	$rc = fsck_volume($evms_volume, \%fsck_options);
	if ($rc) {
		log_error("Error fsck-ing $fsim file system on volume $evms_volume.\n");
		$rc = 1;
		goto test2_out;
	}

	clean_object($object);

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

# Remove a file system from a volume.
sub Test3
{
	my $object = $_[0];
	my $volume_name = "Bloat";
	my $evms_volume = "/dev/evms/$volume_name";
	my $fsim = "Ext2/3";
	my %mkfs_options = ("journal"  => "FALSE",
			    "vollabel" => $volume_name);
	my @output;
	my $rc = 0;
	my $filesystem = "";

	log_info("Test removing a file system from a volume.\n");

	log_info("1. Create volume $evms_volume 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 test3_out;
	}

	log_info("2. Verify creation of 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. Make $fsim file system on volume $evms_volume.\n");
	log_info("   mkfs options are:\n");
	foreach my $name (keys(%mkfs_options)) {
		log_info("     $name = $mkfs_options{$name}\n");
	}
	$rc = mkfs_volume($evms_volume, $fsim, \%mkfs_options);
	if ($rc) {
		log_error("Error making $fsim file system on volume $evms_volume.\n");
		$rc = 1;
		goto test3_out;
	}

	log_info("4. Verify $fsim file system is on volume $evms_volume.\n");
	$filesystem = get_volume_filesystem($evms_volume);
	if ($filesystem eq "") {
		log_error("Could not find the line with the file system name in the query volume output.\n");
		$rc = 1;
		goto test3_out;
	}

	if ($filesystem ne $fsim) {
		log_error("Volume $evms_volume does not have file system $fsim.  It has $filesystem instead.\n");
		$rc = 1;
		goto test3_out;
	}

	log_info("5. Remove $fsim file system from volume $evms_volume.\n");
	$rc = unmkfs_volume($evms_volume);
	if ($rc) {
		log_error("Error removing $fsim file system from volume $evms_volume.\n");
		$rc = 1;
		goto test3_out;
	}

	log_info("6. Verify $fsim file system was removed from volume $evms_volume.\n");
	$filesystem = get_volume_filesystem($evms_volume);
	if ($filesystem ne "") {
		log_error("Volume $evms_volume has the $filesystem file system on it.\n");
		$rc = 1;
		goto test3_out;
	}

	clean_object($object);

test3_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;
	}
	
	clean_object($disk);

finish:
}

