#!/usr/bin/env python2

# THIS FILE IS PART OF THE CYLC SUITE ENGINE.
# Copyright (C) 2008-2019 NIWA & British Crown (Met Office) & Contributors.
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

"""cylc [hook] check-triggering ARGS

This is a cylc shutdown event handler that compares the newly generated
suite log with a previously generated reference log "reference.log"
stored in the suite definition directory. Currently it just compares
runtime triggering information, disregarding event order and timing, and
fails the suite if there is any difference. This should be sufficient to
verify correct scheduling of any suite that is not affected by different
run-to-run conditional triggering.

1) run your suite with "cylc run --generate-reference-log" to generate
the reference log with resolved triggering information. Check manually
that the reference run was correct.
2) run reference tests with "cylc run --reference-test" - this
automatically sets the shutdown event handler along with a suite timeout
and "abort if shutdown handler fails", "abort on timeout", and "abort if
any task fails".

Reference tests can use any run mode:
 * simulation mode - tests that scheduling is equivalent to the reference
 * dummy mode - also tests that task hosting, job submission, job script
   evaluation, and cylc messaging are not broken.
 * live mode - tests everything (but takes longer with real tasks!)

 If any task fails, or if cylc itself fails, or if triggering is not
 equivalent to the reference run, the test will abort with non-zero exit
 status - so reference tests can be used as automated tests to check
 that changes to cylc have not broken your suites."""

import os
import sys

from cylc.log_diagnosis import LogAnalyser

if len(sys.argv) == 2 and sys.argv[1] == '--help':
    print __doc__
    sys.exit(0)

print "\nThis is the cylc check-triggering shutdown event handler"

event, suite = sys.argv[1], sys.argv[2]

if event != 'shutdown':
    raise SystemExit("ERROR: run this as a shutdown event handler")

try:
    log_dir = os.path.expandvars(os.environ['CYLC_SUITE_LOG_DIR'])
    suite_dir = os.path.expandvars(os.environ['CYLC_SUITE_DEF_PATH'])
except KeyError, x:
    raise SystemExit(x)

new_log = os.path.join(log_dir, 'log')
ref_log = os.path.join(suite_dir, 'reference.log')

try:
    lanal = LogAnalyser(new_log, ref_log)
    lanal.verify_triggering()
except Exception, x:
    print >> sys.stderr, x
    raise SystemExit("ERROR: Triggering check FAILED")
else:
    print "Triggering check passed"
