#! /usr/bin/env perl
##**************************************************************
## Copyright 2011 Red Hat, Inc.
##
## 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 strict;
use warnings;

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

#testreq: personal
my $config = <<CONDOR_TESTREQ_CONFIG;
  VIEW_COLLECTOR = $(COLLECTOR)
  VIEW_COLLECTOR.COLLECTOR_LOG = $(LOG)/ViewCollectorLog
  VIEW_COLLECTOR.COLLECTOR_ADDRESS_FILE = $(SPOOL)/.VIEWcollector_address

  DAEMON_LIST = $(DAEMON_LIST) VIEW_COLLECTOR

  CONDOR_VIEW_CLASSAD_TYPES = Negotiator
  COLLECTOR_DEBUG = $(COLLECTOR_DEBUG) D_CAT D_ALWAYS:2 D_STATUS:1 D_COMMAND:1
  MASTER_DEBUG    = $(MASTER_DEBUG)    D_CAT D_ALWAYS:2 D_STATUS:1 D_COMMAND:1

  use Feature : PartitionableSlot(1)

  SETTABLE_ATTRS_CONFIG = CONDOR_VIEW_CLASSAD_TYPES, CONDOR_VIEW_HOST
  ENABLE_RUNTIME_CONFIG = TRUE
  ALLOW_CONFIG = $(ALLOW_ADMINISTRATOR) $(FULL_HOSTNAME) $(IP_ADDRESS) 127.0.0.1

  ALLOW_ADVERTISE = $(ALLOW_ADVERTISE) $(FULL_HOSTNAME) $(IP_ADDRESS) 127.0.0.1
  ALLOW_NEGOTIATOR = $(ALLOW_NEGOTIATOR) $(FULL_HOSTNAME) $(IP_ADDRESS) 127.0.0.1
  ALLOW_ADMINISTRATOR = $(ALLOW_ADMINISTRATOR) $(FULL_HOSTNAME) $(IP_ADDRESS) 127.0.0.1
CONDOR_TESTREQ_CONFIG
#endtestreq


# Sanity, the Negotiator showed up in the Collector
CondorLog::RunCheck(
    daemon => "COLLECTOR",
    match_regexp => "(NegotiatorAd +: Inserting)|(Inserting Negotiator ad)",
    num_retries => 120
);

# Figure out what port the view collector started with
my $spool_dir = `condor_config_val SPOOL`;
CondorUtils::fullchomp($spool_dir);
my $view_addr_file = "$spool_dir/.VIEWcollector_address";
open(IN, '<', $view_addr_file) or die("Cannot open $view_addr_file for reading: $!");
my $first_line = <IN>;
close(IN);

TLOG "The first line of the View Collector address file ($view_addr_file):\n";
print "\t$first_line";

# FIXME: Write a single shared module for parsing sinful strings.
my $viewCollector = $first_line;
CondorUtils::fullchomp( $viewCollector );
if( ! ($viewCollector =~ m/^</ && $viewCollector =~ m/>$/) ) {
	print( "\t'${viewCollector}' doesn't look like a sinful. failing test.\n" );
	exit( 1 );
}
$viewCollector =~ s/^<//;
$viewCollector =~ s/>$//;

if( $viewCollector =~ m/^[[][\d:]+]:\d+/ ) {
	print( "\t'${viewCollector}' looks like an IPv6 address.\n" );
} elsif( $viewCollector =~ m/^\d+\.\d+\.\d+\.\d+:\d+/ ) {
	print( "\t'${viewCollector}' looks like an IPv4 address.\n" );
} else {
	print( "\t'${viewCollector}' doesn't look like an address. failing test.\n" );
	exit( 1 );
}

my $viewPool = quoteMyString("$viewCollector");
CondorTest::runCondorTool("condor_status -any -pool $viewPool -af:h MyType Name MyAddress");

# Note: you must run condor_reconfig after rset'ing a variable
my $quote = quoteMyString("CONDOR_VIEW_HOST=$viewCollector");
my $quote2 = quoteMyString("CONDOR_VIEW_CLASSAD_TYPES=Negotiator");
CondorTest::runCondorTool("condor_config_val -collector -rset $quote $quote2");
CondorTest::runCondorTool("condor_reconfig -collector");

# Validate that we set this properly
my $cmd = "condor_config_val -collector CONDOR_VIEW_HOST";
TLOG "Running $cmd:\n";
print "\t" . `$cmd`;

CondorLog::RunCheck(
    daemon => "COLLECTOR",
    match_regexp => "Will forward ads on to View Server",
    num_retries => 20,
    echo => ">",
);

#CondorTest::runCondorTool("condor_status -any -af:h MyType Name MyAddress");
#CondorTest::runCondorTool("condor_status -any -pool $viewPool -af:h MyType Name MyAddress");

# After setting up the collector to forward ads, we need to reconfig the 
# negotiator to get it to re-send its ad to the collector (and hence, on
# to the View collector)
CondorTest::runCondorTool("condor_reconfig -negotiator");

#sleep(5);
#CondorTest::runCondorTool("condor_status -any -af:h MyType Name MyAddress");
#CondorTest::runCondorTool("condor_status -any -pool $viewPool -af:h MyType Name MyAddress");

TLOG "Searching CollectorLog for any mention of the Negotiator\n";
my @lines = ();
CondorLog::RunCheck(
    daemon => "COLLECTOR",
    match_regexp => "[Nn]egotiator|NEGOTIATOR",
    num_retries => 10,
    all => \@lines,
);
for (@lines) { print ">" . $_; }

# The Negotiator got forwarded to the View Collector
TLOG "Searching ViewCollectorLog for Negotiator ad insertion:\n";
CondorLog::RunCheck(
    daemon => "VIEW_COLLECTOR.COLLECTOR",
    match_regexp => "(NegotiatorAd +: Inserting)|(Inserting Negotiator ad)|(Replacing Negotiator ad)",
    num_retries => 10,
    echo => ">",
);

CondorTest::runCondorTool("condor_off -negotiator");

TLOG "Waiting for Negotiator to leave - ";
my $backoff = 2;
my $runlimit = 8;
my $loopcount = 0;
my $done = "no";
while( $done eq "no") {
    $loopcount += 1;
    chomp(my @cmd = `condor_status -negotiator -format \"%s\\n\" Name`);

    if (!@cmd) {
	$done = "yes";
	TLOG "Negotiator Ad is gone from collector. checking logs...\n";
	last;
    }
    if ($loopcount == $runlimit) { 
	TLOG "Loop count exceeded, but negotiator Ad is still in collector. checking logs...\n";
	last; 
    }
    sleep ($loopcount * $backoff);
}

# Sanity, the Negotiator was removed from the Collector
CondorLog::RunCheck(
    daemon => "COLLECTOR",
    match_regexp => "Got INVALIDATE_NEGOTIATOR_ADS",
    num_retries => 60,
    echo => ">",
);
CondorLog::RunCheck(
    daemon => "COLLECTOR",
    match_regexp => "Forwarding ad: type=Negotiator command=INVALIDATE_NEGOTIATOR_ADS",
    num_retries => 10,
    echo => ">",
);

# The Negotiator was removed from the View Collector
CondorLog::RunCheck(
    daemon => "VIEW_COLLECTOR.COLLECTOR",
    match_regexp => "Got INVALIDATE_NEGOTIATOR_ADS",
    num_retries => 10,
);

CondorTest::runCondorTool("condor_config_val -collector -rset \"CONDOR_VIEW_CLASSAD_TYPES=Negotiator,Machine\"");
CondorTest::runCondorTool("condor_reconfig -collector");
CondorTest::runCondorTool("condor_reconfig -startd");

TLOG "Waiting for Startd to show up in view collector - ";
$loopcount = 0;
$done = "no";
while( $done eq "no") {
    $loopcount += 1;
    chomp(my @cmd = `condor_status -pool \"<$viewCollector>\" -startd -af Name`);

    if (@cmd) {
	$done = "yes";
	TLOG "Saw Startd ad in view collector. checking logs...\n";
	last;
    }
    if ($loopcount == $runlimit) { 
	TLOG "Loop count exceeded, but no Startd ad in view collector. checking logs\n";
	last; 
    }
    sleep ($loopcount * $backoff);
}

# The Machine ads now get forwarded to the View Collector
CondorLog::RunCheck(
    daemon => "COLLECTOR",
    match_regexp => "Forwarding ad: type=(Machine|Slot) command=UPDATE_STARTD_AD",
    num_retries => 20,
);
CondorLog::RunCheck(
    daemon => "VIEW_COLLECTOR.COLLECTOR",
    match_regexp => "(Startd(Slot)*Ad +: Inserting)|(Inserting (Machine|Slot) ad)",
    num_retries => 10,
);


CondorTest::EndTest();
