#!/usr/bin/python
""" testHarness.py -- GRDDL Test Suite Test Harness

USAGE:
  python testHarness.py --help
     to show this message
  
  python  testHarness.py [opts] --run <grddlProcessor> <list of tests>
     to run all the tests in the test suite for <grddlProcessor>

  python testHarness.py [opts] --update <grddlProcessor> <list of tests>
     to update the output 

  <grddlProcessor> must be executable 
  <list of tests> is an RDF list of test cases
  [opts] is one of "--debug" to get debug info

REQUIREMENTS:
 python-librdf
 delta.py (in SWAP package)

REFERENCES:
 GRDDL Data Views: Getting Started, Learning More
 http://www.w3.org/2003/g/data-view
and
 Gleaning Resource Descriptions from Dialects of Languages (GRDDL)
 http://www.w3.org/TR/grddl/
"""

#LICENSE: Open Source: Share and Enjoy.
#
#GRDDL Test Workspace: http://www.w3.org/2001/sw/grddl-wg/td/
#
#Copyright 2002-2006 World Wide Web Consortium, (Massachusetts
#Institute of Technology, European Research Consortium for
#Informatics and Mathematics, Keio University). All Rights
#Reserved. This work is distributed under the W3C(R) Software License
#  http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
#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 change log at end
__version__ = '$Id: testHarness.py,v 1.2 2007/01/17 19:27:50 connolly Exp $'

import sys, getopt
import os, tempfile
import urllib2

# delta.py, part of the SWAP package
# http://www.w3.org/2000/10/swap/
DELTA = "/usr/bin/delta.py"
DELTA = "/Users/connolly/w3ccvs/WWW/2000/10/swap/delta.py"

from swap import myStore, uripath # http://www.w3.org/2000/10/swap/

RDF = myStore.Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
Test = myStore.Namespace("http://www.w3.org/2000/10/rdf-tests/rdfcore/testSchema#")

def runProcessor(processor,inputUri):
    return os.popen(processor + " " + inputUri,"r")    

def updateTest(processor,inputUri,outputUri):
    outputfilename = outputUri[outputUri.rfind('/')+1:]
    print "Updating ",outputfilename
    outputfile = open(outputfilename,"w")
    output = runProcessor(processor,inputUri)
    outputfile.write(output.read())
    outputfile.close()

def runTest(processor, inputUri, outputUri):
    """Returns false when applying processor on inputUri differs from outputUri
    """
    output = runProcessor(processor,inputUri)
    outputfilename = outputUri[outputUri.rfind('/')+1:] + ".result"
    if DEBUG:
        print "Saving result to ",outputfilename
    outputfile = open(outputfilename,"w")
    outputfile.write(output.read())
    outputfile.close()
    command = DELTA + " -f " + outputUri + " -t " + outputfilename
    if DEBUG:    
        print "Executing ",command
    input,diff,err = os.popen3(command)
    res =  (diff.read().strip() + err.read()).strip()
    if DEBUG:
        print "diff: %s" % res
    return not res

def process(action, uri, processor):
    # RDF model of the tests list
    data = myStore.load(uri)

    hasFailure = 0

    for t in data.each(pred=RDF.type, obj=Test.Test):
        i = data.the(subj=t, pred=Test.inputDocument)
        o = data.the(subj=t, pred=Test.outputDocument)
        if action=="update":
            updateTest(processor, i.uriref(), o.uriref())
        elif action=="run":
            if not runTest(processor, i.uriref(), o.uriref()):
                print "* %s failed" % t
                hasFailure = 1
    if not hasFailure and action=="run":
        print "All tests were passed!"

# All Things Pythonic
# Python main() functions
# by Guido van Rossum
# May 15, 2003
# http://www.artima.com/weblogs/viewpost.jsp?thread=4829
def main(argv=None):
    if argv is None: argv = sys.argv

    try:
        opts, args = getopt.getopt(argv[1:], "dhr:u:",
                                   ["help", "run=", "update=","debug"])
    except getopt.GetoptError:
        usage()
        return 2
    processor = None
    action = None
    tests = None
    global DEBUG
    DEBUG=0
    for o, a in opts:
        if o in ("-d", "--debug"):
            DEBUG = 1
        if o in ("-h", "--help"):
            usage()
            return 0
        if o in ("-r", "--run"):
            processor = a
            action = "run"
        if o in ("-u", "--update"):
            processor = a
            action = "update"
    if not (processor and action and len(args) == 1):
        usage()
        return 2

    # URIref of the list of tests
    tests = uripath.join(uripath.base(), args[0])

    process(action, tests, processor)

    return 0

def usage():
    print __doc__
    print __version__
    
if __name__ == '__main__':
    sys.exit(main())



