#!/usr/bin/env python """ RDF Test Suite Script Author: Sean B. Palmer, inamidst.com License: GPL 2; share and enjoy! """ import sys, os, itertools, urllib, tempfile, subprocess import ntriples, rdfdiff from ntriples import Literal class Namespace(unicode): def __getattr__(self, attr): return self + attr def __getitem__(self, item): return self + str(item) rdf = Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#') test = Namespace('http://www.w3.org/2000/10/rdf-tests/rdfcore/testSchema#') def nonzero(iterable): try: iterable.next() except StopIteration: return False return True def first(iterable): try: return iterable.next() except StopIteration: return None class Graph(object): def __init__(self, uri=None): self.triples = set() self.parse(uri or 'data:text/plain,') def parse(self, uri): class Sink(object): def triple(sink, s, p, o): self.triples.add((s, p, o)) p = ntriples.NTriplesParser(sink=Sink()) u = urllib.urlopen(uri) p.parse(u) u.close() def get(self, subj=None, pred=None, objt=None): for triple in self.triples: if (((subj is None) or (subj == triple[0])) and ((pred is None) or (pred == triple[1])) and ((objt is None) or (objt == triple[2]))): yield triple def subjects(self, pred, objt): for (s, p, o) in self.get(None, pred, objt): yield s def predicates(self, subj, objt): for (s, p, o) in self.get(subj, None, objt): yield p def objects(self, subj, pred): for (s, p, o) in self.get(subj, pred, None): yield o def approved(G, testID): if nonzero(G.get(testID, test.status, Literal('APPROVED'))): return True return False def shell(script, scriptname): def command(args): status = os.spawnv(os.P_WAIT, script, [scriptname] + args) return abs(status) return command def parse(fn, base=None): # kargs = {'stdout': subprocess.PIPE, 'stderr': subprocess.PIPE} # if not base: # proc = subprocess.Popen(['./xrdfp.py', fn], **kargs) # else: proc = subprocess.Popen(['./xrdfp.py', fn, base], **kargs) # stdout = proc.stdout.read() # stderr = proc.stderr.read() # status = abs(proc.wait()) # return status, stdout, stderr import xrdfp try: status, output = 0, xrdfp.parseURI(fn, base=base) except Exception, e: status, output = 1, str(e) return status, output def mktid(uri): if '#' in uri: path, fragID = uri.rsplit('#', 1) else: path, fragID = uri, '' if '/' in path: tname = path.split('/')[-2] else: tname = path return tname + ':' + fragID def positiveTest(testID, input, output): inputfn = os.path.join(testDir, input[len(testURI):]) outputfn = os.path.join(testDir, output[len(testURI):]) tid = mktid(testID) status, stdout = parse(inputfn, base=input) if not (status > 0): if os.path.isfile('rdftests.tmp'): raise Exception('rdftests.tmp already exists') f = open('rdftests.tmp', 'w') f.write(stdout) f.close() try: diff = rdfdiff.compare('rdftests.tmp', outputfn) except ntriples.ParseError, e: print 'FAIL:', tid, 'ntriples.ParseError', e else: if diff: print 'Pass:', tid else: print 'FAIL:', tid, (stdout[:30] + '...') os.unlink('rdftests.tmp') else: print 'FAIL:', tid, (stdout[:30] + '...') def negativeTest(testID, input): inputfn = os.path.join(testDir, input[len(testURI):]) tid = mktid(testID) status, stdout = parse(inputfn, base=input) if (status > 0): print 'Pass:', tid else: print 'FAIL:', tid, (stdout[:30] + '...') def main(): global testURI, testDir testURI = 'http://www.w3.org/2000/10/rdf-tests/rdfcore/' testDir = '/desktop/rdf-test-cases' manifest = os.path.join(testDir, 'Manifest.nt') G = Graph(uri=manifest) for positive in sorted(G.subjects(rdf.type, test.PositiveParserTest)): if approved(G, positive): input = first(G.objects(positive, test.inputDocument)) output = first(G.objects(positive, test.outputDocument)) if input and output: positiveTest(positive, input, output) else: if not input: print >> sys.stderr, 'WARNING! No input document found!' if not output: print >> sys.stderr, 'WARNING! No output document found!' print for negative in sorted(G.subjects(rdf.type, test.NegativeParserTest)): if approved(G, negative): input = first(G.objects(negative, test.inputDocument)) if input: negativeTest(negative, input) else: print >> sys.stderr, 'WARNING! No input document found!' if __name__=="__main__": main()