#! /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.
##
##**************************************************************

use CondorTest;
use CondorUtils;
use Condor;
use Check::SimpleJob;

my $testname = "JobAggressiveFlocking";

#testreq: personal
my $config = <<CONDOR_TESTREQ_CONFIG;
    WANT_SUSPEND = FALSE
    KILLING_TIMEOUT = 1
    MachineMaxVacateTime = 5
    UPDATE_INTERVAL = 5
    KILL = FALSE
    START = TRUE
    NUM_CPUS = 32
    DAEMON_LIST = MASTER,SCHEDD,COLLECTOR,NEGOTIATOR,STARTD
CONDOR_TESTREQ_CONFIG
#endtestreq

Condor::DebugOn;
Condor::DebugLevel(1);

select STDERR; $|=1;
select STDOUT; $|=1;

my $spooldir = `condor_config_val SPOOL`;
chomp $spooldir;

mkdir "${spooldir}/N1",0755 || die "Could not create spool directory for our negotiator\n";
mkdir "${spooldir}/N2",0755 || die "Could not create spool directory for our negotiator\n";
mkdir "${spooldir}/N3",0755 || die "Could not create spool directory for our negotiator\n";
mkdir "${spooldir}/N4",0755 || die "Could not create spool directory for our negotiator\n";
mkdir "${spooldir}/N5",0755 || die "Could not create spool directory for our negotiator\n";

my $executedir = `condor_config_val EXECUTE`;
chomp $executedir;
mkdir "${executedir}/S1",0755 || die "Could not create execute directory for our startd 1\n";
mkdir "${executedir}/S2",0755 || die "Could not create execute directory for our startd 2\n";
mkdir "${executedir}/S3",0755 || die "Could not create execute directory for our startd 3\n";
mkdir "${executedir}/S4",0755 || die "Could not create execute directory for our startd 4\n";
mkdir "${executedir}/S5",0755 || die "Could not create execute directory for our startd 5\n";

my $append_condor_config = '
C1=$(COLLECTOR)
C2=$(COLLECTOR)
C3=$(COLLECTOR)
C4=$(COLLECTOR)
C5=$(COLLECTOR)
C1_ARGS = $(COLLECTOR_ARGS)
C2_ARGS = $(COLLECTOR_ARGS)
C3_ARGS = $(COLLECTOR_ARGS)
C4_ARGS = $(COLLECTOR_ARGS)
C5_ARGS = $(COLLECTOR_ARGS)
C1.COLLECTOR_NAME = C1
C2.COLLECTOR_NAME = C2
C3.COLLECTOR_NAME = C3
C4.COLLECTOR_NAME = C4
C5.COLLECTOR_NAME = C5
N1=$(NEGOTIATOR)
N2=$(NEGOTIATOR)
N3=$(NEGOTIATOR)
N4=$(NEGOTIATOR)
N5=$(NEGOTIATOR)
#N1_ARGS = -local-name N1
#N2_ARGS = -local-name N2
#N3_ARGS = -local-name N3
#N4_ARGS = -local-name N4
#N5_ARGS = -local-name N5
N1.NEGOTIATOR_LOG=$(LOG)/NegotiatorLog.N1
N2.NEGOTIATOR_LOG=$(LOG)/NegotiatorLog.N2
N3.NEGOTIATOR_LOG=$(LOG)/NegotiatorLog.N3
N4.NEGOTIATOR_LOG=$(LOG)/NegotiatorLog.N4
N5.NEGOTIATOR_LOG=$(LOG)/NegotiatorLog.N5
N1.NEGOTIATOR_ADDRESS_FILE=$(LOG)/.negotiator_address.n1
N2.NEGOTIATOR_ADDRESS_FILE=$(LOG)/.negotiator_address.n2
N3.NEGOTIATOR_ADDRESS_FILE=$(LOG)/.negotiator_address.n3
N4.NEGOTIATOR_ADDRESS_FILE=$(LOG)/.negotiator_address.n4
N5.NEGOTIATOR_ADDRESS_FILE=$(LOG)/.negotiator_address.n5
N1.SPOOL=$(SPOOL)/N1
N2.SPOOL=$(SPOOL)/N2
N3.SPOOL=$(SPOOL)/N3
N4.SPOOL=$(SPOOL)/N4
N5.SPOOL=$(SPOOL)/N5
C1.COLLECTOR_LOG = $(LOG)/CollectorLog.C1
C2.COLLECTOR_LOG = $(LOG)/CollectorLog.C2
C3.COLLECTOR_LOG = $(LOG)/CollectorLog.C3
C4.COLLECTOR_LOG = $(LOG)/CollectorLog.C4
C5.COLLECTOR_LOG = $(LOG)/CollectorLog.C5
FLOCK_COLLECTOR_HOSTS = $(FLOCK_TO)
FLOCK_NEGOTIATOR_HOSTS = $(FLOCK_TO)
#DAEMON_LIST = $(DAEMON_LIST), C1, C2, C3, C4, C5
C1.COLLECTOR_ADDRESS_FILE=$(LOG)/.collector_address.c1
C2.COLLECTOR_ADDRESS_FILE=$(LOG)/.collector_address.c2
C3.COLLECTOR_ADDRESS_FILE=$(LOG)/.collector_address.c3
C4.COLLECTOR_ADDRESS_FILE=$(LOG)/.collector_address.c4
C5.COLLECTOR_ADDRESS_FILE=$(LOG)/.collector_address.c5
FLOCK_INCREMENT=2
START1=$(STARTD)
START2=$(STARTD)
START3=$(STARTD)
START4=$(STARTD)
START5=$(STARTD)
#START1_ARGS= -local-name START1
#START2_ARGS= -local-name START2
#START3_ARGS= -local-name START3
#START4_ARGS= -local-name START4
#START5_ARGS= -local-name START5
START1.STARTD_ADDRESS_FILE=$(LOG)/.startd_address.start1
START2.STARTD_ADDRESS_FILE=$(LOG)/.startd_address.start2
START3.STARTD_ADDRESS_FILE=$(LOG)/.startd_address.start3
START4.STARTD_ADDRESS_FILE=$(LOG)/.startd_address.start4
START5.STARTD_ADDRESS_FILE=$(LOG)/.startd_address.start5
START1.EXECUTE=$(EXECUTE)/S1
START2.EXECUTE=$(EXECUTE)/S2
START3.EXECUTE=$(EXECUTE)/S3
START4.EXECUTE=$(EXECUTE)/S4
START5.EXECUTE=$(EXECUTE)/S5
DAEMON_LIST = $(DAEMON_LIST), START1, START2, START3, START4, START5, N1, N2, N3, N4, N5, C1, C2, C3, C4, C5
#DC_DAEMON_LIST = + C1, C2, C3, C4, C5, START1, START2, START3, START4, START5, N1, N2, N3, N4, N5
START1.STARTD_LOG=$(LOG)/StartdLog.Start1
START2.STARTD_LOG=$(LOG)/StartdLog.Start2
START3.STARTD_LOG=$(LOG)/StartdLog.Start3
START4.STARTD_LOG=$(LOG)/StartdLog.Start4
START5.STARTD_LOG=$(LOG)/StartdLog.Start5
SCHEDD_DEBUG=D_FULLDEBUG
';

# Append the configuration above to our configuration and reconfig
my $condor_local_config = `condor_config_val LOCAL_CONFIG_FILE`;
open LOCAL_CONFIG, ">>$condor_local_config" || die "Could not append to the local config file $condor_local_config\n";
print LOCAL_CONFIG "$append_condor_config\n";
close LOCAL_CONFIG;
my @fig = ();

print "reconfig to add all the daemons we want - OK\n";
runCondorTool("condor_reconfig",\@fig,2,{emit_output=>0});

print "Waiting for Daemons to all be up\n";

# Wait until all our daemons start up
# We see that they start up when they drop 
# the address file.
my $count_failures = 1;
my $attempts = 0;
my $daemon_address_files = {};
while ($count_failures > 0) {
	++$attempts;	
	CondorTest::debug("Attempt number $attempts getting the configuration\n",3);
	$count_failures = 0;
	foreach my $ii (1..5) {
		$daemon_address_files->{$ii} = {};
		my $neg_file = `condor_config_val N${ii}.NEGOTIATOR_ADDRESS_FILE`;
		chomp $neg_file;
		CondorTest::debug("\$neg_file = $neg_file\n",3);
		if(! -e $neg_file ) {
			++$count_failures;
		} else {
			$daemon_address_files->{$ii}->{negotiator} = $neg_file;
		}
		my $coll_file = `condor_config_val C${ii}.COLLECTOR_ADDRESS_FILE`;
		chomp $coll_file;
		CondorTest::debug("\$coll_file = $coll_file\n",3);
		if(! -e $coll_file ) {
			++$count_failures;
		} else {
			$daemon_address_files->{$ii}->{collector} = $coll_file;
		}
		my $startd_file = `condor_config_val START${ii}.STARTD_ADDRESS_FILE`;
		chomp $startd_file;
		CondorTest::debug("\$startd_file = $startd_file\n",3);
		if(! -e $startd_file ) {
			++$count_failures;
		} else {
			$daemon_address_files->{$ii}->{startd} = $startd_file;
		}
	}
	if($count_failures > 0) {
		sleep 10;
	}
}

print "Daemons are all up\n";

# Daemons have started up.
# We need to get the collector host for each pool
open LOCAL_CONFIG, ">>$condor_local_config" || die "Could not append to the local config file $condor_local_config\n";
my $flock_string = "FLOCK_TO =";
my $daemon_string;
foreach my $ii (1..5) {
	open COLL_ADDRESS_FILE, "<$daemon_address_files->{$ii}->{collector}" ||
		die "Could not open collector address file $daemon_address_files->{$ii}->{collector}\n";
	while(<COLL_ADDRESS_FILE>) {
		chomp;
		if(/^<.+>$/) {
			my $line = $_;
			$line =~ s/<|>//g;
			$flock_string .= " $line";
			$daemon_string .= "START${ii}.COLLECTOR_HOST = $line\n";
			$daemon_string .= "N${ii}.COLLECTOR_HOST = $line\n";
		}
	}
	close COLL_ADDRESS_FILE;
}

my $flock_increment = 2+int(rand(3));
print LOCAL_CONFIG "$flock_string\n";
print LOCAL_CONFIG "$daemon_string\n";
print LOCAL_CONFIG "FLOCK_INCREMENT = $flock_increment\n";
close LOCAL_CONFIG;

my @outarray;
# Now reconfig ... again.
runCondorTool("condor_reconfig",\@outarray,2,{emit_output=>0});

print "reconfig to tune flocking and assign startds to collectors \n";

sub on_submit {
};

sub on_exitedsuccess {
	print ".";
};

#runCondorTool("condor_submit job_aggressive_flocking.cmd",\@outarray,2,{emit_output=>0});
my $res = SimpleJob::RunCheck(
		test_name => "$testname",
		duration => 3,
		timeout => 480,
		queue_sz => 100,
		on_submit => \&on_submit,
		on_success => \&on_exitedsuccess,
);

print "Submitted lots of jobs for flocking test - OK\n";

# We know when RunCheck completes all the jobs have run

my $schedlog = `condor_config_val SCHEDD_LOG`;

#ondorTest::debug("Output from Schedd log file:\n\n");
open SCHEDLOG, "<$schedlog" || die "Cannot open ScheddLog file $schedlog\n";
my @schedlog = <SCHEDLOG>;
close SCHEDLOG;

my $success = 0;
my $checked_flock = undef;
foreach (@schedlog) {
	# We only need the first one
	if(/Increasing flock level for .+ to (\d+) from (\d+)\./i) {
		CondorTest::debug($_);
		next if(defined $checked_flock);
		my $newflocklevel = $1;
		my $oldflocklevel = $2;
		my $flockdiff = $newflocklevel - $oldflocklevel;
		CondorTest::debug("\$flockdiff is $flockdiff and \$flock_increment is $flock_increment\n");
		$success = 1 if ($flockdiff != $flock_increment);
		if($success == 0) {
			CondorTest::debug("They agree!\n");
			CondorTest::RegisterResult(1, "test_name", $testname);
		} else {
			CondorTest::debug("Boo! They do not agree.\n");
			CondorTest::RegisterResult(0, "test_name", $testname);
		}
		$checked_flock = 1;	
	}
}

my @extrastartdlog = ();
my $result = runCondorTool("condor_config_val START$flock_increment.STARTD_LOG",\@extrastartdlog,2,{emit_output=>0});

my $search = "Changing activity: Idle -> Busy";
CondorUtils::fullchomp($extrastartdlog[0]);
my $startdlog = $extrastartdlog[0];

print "STARTDLOG1:$startdlog\n";
my $cmd = "grep $search $startdlog";
print "Search command is:$cmd\n";

#my @run = `grep \"$search\" $startdlog`;
my @run = ();

#my $liine = "";
#open(SL,"<$startdlog") or die "Could not open:$startdlog for searching:$!\n";
#while(<SL>) {
	#CondorUtils::fullchomp($_);
	#$line = $_;
	#if($line =~ /Changing\sactivity:\sIdle\s->\sBusy/) {
		#push @run, $line;
	#}
#}
#close(SL);
#my $runcount = @run;

#if($runcount > 0) {
	#CondorTest::RegisterResult(1, "test_name", $testname);
#} else {
	#CondorTest::RegisterResult(0, "test_name", $testname);
#}

#print "Flock_increment: $flock_increment Jobs:$runcount Log:$startdlog\n";

CondorTest::EndTest();

exit $success;
