#!/usr/pkg/bin/python2.4

# Pinpoint changes in ATF test results

from __future__ import print_function

import sys
import os

from bracket import *
import utils

begin_rcsdate = '%04d.%02d.01.00.00.00' % \
    (int(config['report_from_year']), int(config['report_from_month']))
begin_ts = rcs2ts(rcsdate)

use_current_repository()

builds_dates = [ts for ts in existing_build_dates() if ts >= begin_ts]

def have_run_tests(ts):
    return get_cached_status_if_any(ts, 'test_status') is not None

pairs = [tsp for tsp in utils.adjacent_pairs(
        [ts for ts in build_dates if have_run_tests(ts)]) \
    if get_cached_status_if_any(tsp[0], 'failed_tests') != \
       get_cached_status_if_any(tsp[1], 'failed_tests') and \
       ts2cno(tsp[1]) - ts2cno(tsp[0]) > 1]

pairs.reverse()

for tsp in pairs:
    print("pinpointing ATF test status change between", \
          ts2rcs(tsp[0]), "and", ts2rcs(tsp[1]))
    def need_completed_tests(ts):
        if get_cached_status_if_any(ts, 'failed_tests') is not None:
            # The tests completed
            return True
        if os.path.exists(os.path.join(results_dir(ts), 'test.log.gz')):
            # At test run has been attempted, but did not complete
            return False
        # No test run has been attempted, do so now
        return not not test(test_op, ts)
    def test_unchanged(ts):
        prerequisite(need_completed_tests, ts)
        return get_cached_status_if_any(ts, 'failed_tests') == \
               get_cached_status_if_any(tsp[0], 'failed_tests')

    # It is somewhat difficult to determine whether any given
    # iteration of the loop makes progress by doing new builds,
    # running new tests, and caching new results, or merely
    # re-pinpoints a failure point that was already known by using
    # information already cached.  We solve this dilemma using a
    # horrible kludge: anything that takes more than a minute to run
    # is assumed to have made progress.
    #
    # Once we have made progress, exit to give other jobs a chance to
    # run.

    t0 = time.time()
    find_failure(tsp[0], tsp[1], test_unchanged)
    t1 = time.time()
    if t1 - t0 > 60:
        break
    print()
