#! /usr/bin/env perl
##**************************************************************
##
## Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
## University of Wisconsin-Madison, WI.
## 
## Licensed under the Apache License, Version 2.0 (the "License"); you
## may not use this file except in compliance with the License.  You may
## obtain a copy of the License at
## 
##    http://www.apache.org/licenses/LICENSE-2.0
## 
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
##**************************************************************
##
## This test check availability and usage contol of the new
## local, resources in both a static configuration and in psolts.
## It is model after what we did to test concurrency limits
## as we are checking the same sorts of things. bt
##
##**************************************************************

use CondorTest;
use CondorUtils;
use Check::SimpleJob;
use Check::CondorLog;

my $testname = "basic_startd_slot_attrs";

#testreq: personal
my $config = <<CONDOR_TESTREQ_CONFIG;
	DAEMON_LIST = MASTER,SCHEDD,COLLECTOR,NEGOTIATOR,STARTD
	WANT_SUSPEND = FALSE
	KILLING_TIMEOUT = 1
	MachineMaxVacateTime = 5
	KILL = FALSE
	START = TRUE
	TOOL_DEBUG = D_FULLDEBUG
	ALL_DEBUG = D_ALWAYS

	NUM_CPUS = 4
	STARTD_SLOT_ATTRS = activity,state,memory
	SLOT_TYPE_1 = cpus=25%,mem=500
	SLOT_TYPE_1_PARTITIONABLE = FALSE
	NUM_SLOTS_TYPE_1 = 1
	SLOT_TYPE_2 = cpus=25%,mem=200
	SLOT_TYPE_2_PARTITIONABLE = FALSE
	NUM_SLOTS_TYPE_2 = 1
	SLOT_TYPE_3 = cpus=25%,mem=700
	SLOT_TYPE_3_PARTITIONABLE = FALSE
	NUM_SLOTS_TYPE_3 = 1
	SLOT_TYPE_4 = cpus=25%,mem=300
	SLOT_TYPE_4_PARTITIONABLE = FALSE
	NUM_SLOTS_TYPE_4 = 1
CONDOR_TESTREQ_CONFIG
#endtestreq

my %memoryhash = (
	slot1 => 500,
	slot2 => 200,
	slot3 => 700,
	slot4 => 300,
);

my $ClusterId = 0;
my $expect_return = 0;


my $on_abort = sub {
	CondorTest::debug("Abort from removing trap signal job.\n",1);
};

my %startdslotattrs = ();
my $return = "";
my $executecount = 0;
my $namelist = "";
my $result = 1;
my $on_execute = sub {
	print "********************************** OnExecute *****************************\n";
	$namelist = GetSlotNames(4);
	print "SlotNames:<$namelist>\n";
	GetStartdSlotAttrs($namelist);
	system("condor_rm $ClusterId");
};

my $on_evictedwithoutcheckpoint = sub {
	print "Evicted Without Checkpoint\n";
};

my $GetClusterId = sub {
	my $cid = shift;
	$ClusterId = $cid;
	print "Resquestd Cluster Got $ClusterId\n";
	##########################
	#
	# Convoluted: This function is paased to RunCheck which uses it in RunTest in the fourth
	# position which is always an undefined variable EXCEPT when it is a call back routine 
	# to pass out the cluster Id.
	#
	##########################
	#runcmd("condor_q",{emit_output => 1});
};

#Do a job before setting tesing exit codes
print "First test basic job\n";
$result = SimpleJob::RunCheck(); # jobid 1

$expect_return = 0;
$result = SimpleJob::RunCheck(
	test_name => "$testname",
	on_abort => $on_abort,
	on_evictedwithoutcheckpoint => $on_evictedwithoutcheckpoint,
	on_execute => $on_execute,
	timeout => 120,
	queue_sz => 1,
	duration => $expect_return,
	GetClusterId => $GetClusterId,
);
print "******************** Test for startd slot attrs/publishing\n";
if($result == 1) {
	print "ok\n\n\n";
} else {
	print "bad\n\n\n";
}

CondorTest::EndTest();

sub GetSlotNames
{
	my $target = shift;
	my $line = "";
	my $names = "";
	my $count = 0;

	my @name = ();
	runCondorTool("condor_status -af name",\@name,2,{emit_output=>0});
	foreach my $try (@name) {
		CondorUtils::fullchomp($try);
		if($count == 0) {
			$names = $try;
		} else {
			$names = $names . ",$try"
		}
		$count += 1;
		#print "$names\n";
		if($count == $target) {
			last;
		}
	}
	return($names);
}

# stash expected atrributs into hash and expect the counts of all
# to match count of slots passed  %stardslotattrs

sub GetStartdSlotAttrs
{
	my $names = shift;
	my @namearray = split /,/, $names;
	my $namecount = @namearray;
	my @fullslot1 = ();
	my $cmdstatus = 1;
	my $simpleslot = "";

	foreach my $slot (@namearray) {
		# extract simple slot name for access to memory hash
		if($slot =~ /^(slot\d).*$/) {
			print "looking at $1 information\n";
			$simpleslot = $1;
		} else {
			die "Something horribly wrong. Could not extract simple slot name\n";
		}
		# get slot memmory from condor_status
		$cmdstatus = runCondorTool("condor_status $slot -af memory ",\@fullslot1,2,{emit_output=>0});
		if(!$cmdstatus) {
			print "This:condor_status $slot -af memory : should not have failed\n";
		}
		# there is but one line for memory
		my $mem = "";
		CondorUtils::fullchomp($fullslot1[0]);
		$mem = $fullslot1[0];
		if($mem == $memoryhash{$simpleslot}) {
			print "condor status for $simpleslot reporting config requested memory\n";
			CondorTest::RegisterResult(1,test_name,$testname);
		} else {
			print "condor status for $simpleslot NOT reporting config requested memory\n";
			print "Configured:$memoryhash{$simpleslot} Reported:$mem\n";
			CondorTest::RegisterResult(0,test_name,$testname);
		}

		my @results = ();
		# TODO: This used to have "-debug" and it would be nifty if it did again. However
		# the IPv4/6 mixed-mode work seems to break that case. NEEDS TO BE INVESTIGATED.
		$cmdstatus = runCondorTool("condor_status -l $slot ",\@results, 2,{emit_output=>0});
			if(!$cmdstatus) {
				print "This:condor_status -l $slot should not have failed\n";
			}
		my $statusres = @results;
		#print "condor_status for slot <$slot> returned <$statusres> lines\n";
		foreach my $item (@results) {
			CondorUtils::fullchomp($item);
			#print "$slot: $item\n";
			if($item =~ /(slot\d_memory)\s*=\s*(\d+).*/) {
				#ensure reported slot memory matches configured memory
				my $memory = $2;
				my $attr = $1;
				# dig out simple slot for hash comparison
				my $sslot = "";
				if($attr =~ /(slot\d)/) { # does by definition
					$sslot = $1;
					if($memory == $memoryhash{$sslot}) {
						print "$attr memory being advertised correctly to $slot\n";
						CondorTest::RegisterResult(1,test_name,$testname);
					} else {
						print "$attr memory NOT being advertised correctly to $slot\n";
						print "Configured:$memoryhash{$simpleslot} Reported:$memory\n";
						CondorTest::RegisterResult(0,test_name,$testname);
					}
				}
				#print "*************** $attr *********************\n";
				if(exists $stardslotattrs{$attr}) {
					$stardslotattrs{$attr} += 1;
				} else {
					$stardslotattrs{$attr} = 1;
				}
			} elsif($item =~ /(slot\d_state)\s.*/) {
				#print "*************** $1 *********************\n";
				if(exists $stardslotattrs{$1}) {
					$stardslotattrs{$1} += 1;
				} else {
					$stardslotattrs{$1} = 1;
				}
			} elsif($item =~ /(slot\d_activity)\s.*/) {
				#print "*************** $1 *********************\n";
				if(exists $stardslotattrs{$1}) {
					$stardslotattrs{$1} += 1;
				} else {
					$stardslotattrs{$1} = 1;
				}
			}

		}
	}
	foreach my $key(sort keys %stardslotattrs) {
		if($stardslotattrs{$key} != $namecount) {
			die "Ad<$key> has $stardslotattrs{$key} and should be $namecount\n";
		}
	}
	print "Slot attributes equally advertised across all slots\n";
	CondorTest::RegisterResult(1,test_name,$testname);
}
