Skip to content

Instantly share code, notes, and snippets.

@kasei
Created May 22, 2012 17:33
Show Gist options
  • Save kasei/2770483 to your computer and use it in GitHub Desktop.
Save kasei/2770483 to your computer and use it in GitHub Desktop.
proposed SPARQL 1.1 Protocol tests

Proposed SPARQL 1.1 Protocol Tests

This repository contains code which attempts to validate implementations of the SPARQL 1.1 Protocol. It is a work in progress, and subject to change as the Protocol spec continues towards becoming a W3C recommendation, and as we (the SPARQL Working Group) continue to evaluate existing existing implementations.

The validator is implemented as a perl CGI, and depends on packages available from CPAN:

Setup

Configuration

When accessed without any query parameters, the CGI provides an HTML form that may be used to validate a Protocol implementation. The parameters are:

  • "query_url" -- query endpoint URL
  • "update_url" -- update endpoint URL
  • "software" -- The Protocol implementation IRI that will be used if conneg is used and requests RDF

The following parameters should also be accounted for (in a future version):

  • does the default graph change based on other graphs (e.g. acts as the union of named graphs)?

Requirements

It is assumed that the Protocol implementation provides support for all of SPARQL (1.0) and also SPARQL 1.1 Query/Update support for:

  • Select expressions
  • CLEAR ALL
  • CLEAR DEFAULT
  • CLEAR NAMED

The graph store available to query and update dataset operations must contain the triples available at the following URLs (in respective named graphs):

Finally, it is assumed that implementations can produce application/rdf+xml and application/sparql-results+xml when requested using conneg.

Tests

The following tests are implemented (or are planned for implementation):

Negative tests

Negative tests are expected to fail with a 4xx response code as they represent invalid requests.


bad-query-method - invoke query operation with a method other than GET or POST

	PUT /sparql?query=ASK%20%7B%7D
  • Expect 4xx response.

bad-multiple-queries - invoke query operation with more than one query string

	GET /sparql?query=ASK%20%7B%7D&query=SELECT%20%2A%20%7B%7D
  • Expect 4xx response.

bad-query-wrong-media-type - invoke query operation with a POST with media type that's not url-encoded or application/sparql-query

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: text/plain
	Content-Length: XXX
	
	ASK {}
  • Expect 4xx response.

bad-query-missing-form-type - invoke query operation with url-encoded body, but without application/x-www-url-form-urlencoded media type

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Length: XXX
	
	query=ASK%20%7B%7D
  • Expect 4xx response.

bad-query-missing-direct-type - invoke query operation with SPARQL body, but without application/sparql-query media type

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Length: XXX
	
	ASK {}
  • Expect 4xx response.

bad-query-non-utf8 - invoke query operation with direct POST, but with a non-UTF8 encoding (UTF-16)

	### (content body encoded in utf-16)
	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-query; charset=UTF-16
	Content-Length: XXX
	
	ASK {}
  • Expect 4xx response.

bad-query-syntax - invoke query operation with invalid query syntax (4XX result)

	GET /sparql?query=ASK%20%7B
  • Expect 4xx response.

bad-update-get - invoke update operation with GET

	GET /sparql?update=CLEAR%20ALL
  • Expect 4xx response.

bad-multiple-updates - invoke update operation with more than one update string

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/x-www-url-form-urlencoded
	Content-Length: XXX
	
	update=CLEAR%20NAMED&update=CLEAR%20DEFAULT
  • Expect 4xx response.

bad-update-wrong-media-type - invoke update operation with a POST with media type that's not url-encoded or application/sparql-update

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: text/plain
	Content-Length: XXX
	
	CLEAR NAMED
  • Expect 4xx response.

bad-update-missing-form-type - invoke update operation with url-encoded body, but without application/x-www-url-form-urlencoded media type

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Length: XXX
	
	update=CLEAR%20NAMED
  • Expect 4xx response.

bad-update-missing-direct-type - invoke update operation with SPARQL body, but without application/sparql-update media type

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Length: XXX
	
	CLEAR NAMED
  • Expect 4xx response.

bad-update-non-utf8 - invoke update operation with direct POST, but with a non-UTF8 encoding

	### (content body encoded in utf-16)
	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-update; charset=UTF-16
	Content-Length: XXX
	
	CLEAR NAMED
  • Expect 4xx response.

bad-update-syntax - invoke update operation with invalid update syntax (4XX result)

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/x-www-url-form-urlencoded
	Content-Length: XXX
	
	update=CLEAR%20XYZ
  • Expect 4xx response.

bad-update-dataset-conflict - invoke update with both using-graph-uri/using-named-graph-uri parameter and USING/WITH clause

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/x-www-url-form-urlencoded
	Content-Length: XXX
	
	using-named-graph-uri=http%3A%2F%2Fexample%2Fpeople&update=%09%09PREFIX%20foaf%3A%20%20%3Chttp%3A%2F%2Fxmlns.com%2Ffoaf%2F0.1%2F%3E%0A%09%09WITH%20%3Chttp%3A%2F%2Fexample%2Faddresses%3E%0A%09%09DELETE%20%7B%20%3Fperson%20foaf%3AgivenName%20%27Bill%27%20%7D%0A%09%09INSERT%20%7B%20%3Fperson%20foaf%3AgivenName%20%27William%27%20%7D%0A%09%09WHERE%20%7B%0A%09%09%09%3Fperson%20foaf%3AgivenName%20%27Bill%27%0A%09%09%7D%0A
  • Expect 4xx response.

Positive tests

Positive tests are expected to succeed with either 2xx or 3xx response codes. Some of the following tests also test the response content for expected results.


query_get - query via GET

	GET /sparql?query=ASK%20%7B%7D
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/sparql-results+xml or application/sparql-results+json.
  • Expect true result.

query_post_form - query via URL-encoded POST

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/x-www-url-form-urlencoded
	Content-Length: XXX
	
	query=ASK%20%7B%7D
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/sparql-results+xml or application/sparql-results+json.
  • Expect true result.

query_post_direct - query via POST directly

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-query
	Content-Length: XXX
	
	ASK {}
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/sparql-results+xml or application/sparql-results+json.
  • Expect true result.

query_dataset_default_graph - query with protocol-specified default graph

	POST /sparql/?default-graph-uri=http%3A%2F%2Fkasei.us%2F2009%2F09%2Fsparql%2Fdata%2Fdata1.rdf HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-query
	Content-Length: XXX
	
	ASK { <http://kasei.us/2009/09/sparql/data/data1.rdf> ?p ?o }
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/sparql-results+xml or application/sparql-results+json.
  • Expect true result.

query_dataset_default_graphs - query with protocol-specified default graphs

	POST /sparql/?default-graph-uri=http%3A%2F%2Fkasei.us%2F2009%2F09%2Fsparql%2Fdata%2Fdata1.rdf&default-graph-uri=http%3A%2F%2Fkasei.us%2F2009%2F09%2Fsparql%2Fdata%2Fdata2.rdf HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-query
	Content-Length: XXX
	
	ASK { <http://kasei.us/2009/09/sparql/data/data1.rdf> ?p ?o . <http://kasei.us/2009/09/sparql/data/data2.rdf> ?p ?o }
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/sparql-results+xml or application/sparql-results+json.
  • Expect true result.

query_dataset_named_graphs - query with protocol-specified named graphs

	POST /sparql/?named-graph-uri=http%3A%2F%2Fkasei.us%2F2009%2F09%2Fsparql%2Fdata%2Fdata1.rdf&named-graph-uri=http%3A%2F%2Fkasei.us%2F2009%2F09%2Fsparql%2Fdata%2Fdata2.rdf HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-query
	Content-Length: XXX
	
	ASK { GRAPH ?g { ?s ?p ?o } }
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/sparql-results+xml or application/sparql-results+json.
  • Expect true result.

query_dataset_full - query with protocol-specified dataset (both named and default graphs)

	POST /sparql/?default-graph-uri=http%3A%2F%2Fkasei.us%2F2009%2F09%2Fsparql%2Fdata%2Fdata3.rdf&named-graph-uri=http%3A%2F%2Fkasei.us%2F2009%2F09%2Fsparql%2Fdata%2Fdata1.rdf&named-graph-uri=http%3A%2F%2Fkasei.us%2F2009%2F09%2Fsparql%2Fdata%2Fdata2.rdf HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-query
	Content-Length: XXX
	
	SELECT ?g ?x ?s { ?x ?y ?o  GRAPH ?g { ?s ?p ?o } }
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/sparql-results+xml or application/sparql-results+json.
  • Expect true result.

query_multiple_dataset - query specifying dataset in both query string and protocol; test for use of protocol-specified dataset (test relies on the endpoint allowing client-specified RDF datasets; returns 400 otherwise)

	POST /sparql/?default-graph-uri=http%3A%2F%2Fkasei.us%2F2009%2F09%2Fsparql%2Fdata%2Fdata2.rdf HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-query
	Content-Length: XXX
	
	ASK FROM <http://kasei.us/2009/09/sparql/data/data1.rdf> { <data1.rdf> ?p ?o }
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/sparql-results+xml or application/sparql-results+json.
  • Expect true result.

query_content_type_select - query appropriate content type (expect one of: XML, JSON, CSV, TSV)

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-query
	Content-Length: XXX
	
	SELECT (1 AS ?value) {}
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/sparql-results+xml, application/sparql-results+json, text/tab-separated-values, or text/csv.

query_content_type_ask - query appropriate content type (expect one of: XML, JSON)

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-query
	Content-Length: XXX
	
	ASK {}
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/sparql-results+xml or application/sparql-results+json.

query_content_type_describe - query appropriate content type (expect one of: RDF/XML, Turtle)

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-query
	Content-Length: XXX
	
	DESCRIBE <http://example.org/>
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/rdf+xml, application/rdf+json or text/turtle.

query_content_type_construct - query appropriate content type (expect one of: RDF/XML, Turtle)

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-query
	Content-Length: XXX
	
	CONSTRUCT { <s> <p> 1 } WHERE {}
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/rdf+xml, application/rdf+json or text/turtle.

update_dataset_default_graph - update with protocol-specified default graph

	POST /sparql?using-graph-uri=http%3A%2F%2Fkasei.us%2F2009%2F09%2Fsparql%2Fdata%2Fdata1.rdf HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-update
	Content-Length: XXX
	
	PREFIX dc: <http://purl.org/dc/terms/>
	PREFIX foaf: <http://xmlns.com/foaf/0.1/>
	CLEAR ALL ;
	INSERT DATA {
		GRAPH <http://kasei.us/2009/09/sparql/data/data1.rdf> {
			<http://kasei.us/2009/09/sparql/data/data1.rdf> a foaf:Document
		}
	} ;
	INSERT {
		GRAPH <http://example.org/protocol-update-dataset-test/> {
			?s a dc:BibliographicResource
		}
	}
	WHERE {
		?s a foaf:Document
	}
  • Expect 2xx or 3xx response.

followed by

	POST /sparql HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Accept: application/sparql-results+xml
	Content-Type: application/sparql-query
	Content-Length: XXX
	
	ASK {
		GRAPH <http://example.org/protocol-update-dataset-test/> {
			<http://kasei.us/2009/09/sparql/data/data1.rdf> a <http://purl.org/dc/terms/BibliographicResource>
		}
	}
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/sparql-results+xml.
  • Expect true result.

update_dataset_default_graphs - update with protocol-specified default graphs

	POST /sparql?using-graph-uri=http%3A%2F%2Fkasei.us%2F2009%2F09%2Fsparql%2Fdata%2Fdata1.rdf&using-graph-uri=http%3A%2F%2Fkasei.us%2F2009%2F09%2Fsparql%2Fdata%2Fdata2.rdf HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-update
	Content-Length: XXX
	
	PREFIX dc: <http://purl.org/dc/terms/>
	PREFIX foaf: <http://xmlns.com/foaf/0.1/>
	CLEAR ALL ;
	INSERT DATA {
		GRAPH <http://kasei.us/2009/09/sparql/data/data1.rdf> { <http://kasei.us/2009/09/sparql/data/data1.rdf> a foaf:Document }
		GRAPH <http://kasei.us/2009/09/sparql/data/data2.rdf> { <http://kasei.us/2009/09/sparql/data/data2.rdf> a foaf:Document }
		GRAPH <http://kasei.us/2009/09/sparql/data/data3.rdf> { <http://kasei.us/2009/09/sparql/data/data3.rdf> a foaf:Document }
	} ;
	INSERT {
		GRAPH <http://example.org/protocol-update-dataset-graphs-test/> {
			?s a dc:BibliographicResource
		}
	}
	WHERE {
		?s a foaf:Document
	}
  • Expect 2xx or 3xx response.

followed by

	POST /sparql HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Accept: application/sparql-results+xml
	Content-Type: application/sparql-query
	Content-Length: XXX
	
	ASK {
		GRAPH <http://example.org/protocol-update-dataset-test/> {
			<http://kasei.us/2009/09/sparql/data/data1.rdf> a <http://purl.org/dc/terms/BibliographicResource> .
			<http://kasei.us/2009/09/sparql/data/data2.rdf> a <http://purl.org/dc/terms/BibliographicResource> .
		}
		FILTER NOT EXISTS {
			GRAPH <http://example.org/protocol-update-dataset-test/> {
				<http://kasei.us/2009/09/sparql/data/data3.rdf> a <http://purl.org/dc/terms/BibliographicResource> .
			}
		}
	}
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/sparql-results+xml.
  • Expect true result.

update_dataset_named_graphs - update with protocol-specified named graphs

	POST /sparql?using-named-graph-uri=http%3A%2F%2Fkasei.us%2F2009%2F09%2Fsparql%2Fdata%2Fdata1.rdf&using-named-graph-uri=http%3A%2F%2Fkasei.us%2F2009%2F09%2Fsparql%2Fdata%2Fdata2.rdf HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-update
	Content-Length: XXX
	
	PREFIX dc: <http://purl.org/dc/terms/>
	PREFIX foaf: <http://xmlns.com/foaf/0.1/>
	CLEAR ALL ;
	INSERT DATA {
		GRAPH <http://kasei.us/2009/09/sparql/data/data1.rdf> { <http://kasei.us/2009/09/sparql/data/data1.rdf> a foaf:Document }
		GRAPH <http://kasei.us/2009/09/sparql/data/data2.rdf> { <http://kasei.us/2009/09/sparql/data/data2.rdf> a foaf:Document }
		GRAPH <http://kasei.us/2009/09/sparql/data/data3.rdf> { <http://kasei.us/2009/09/sparql/data/data3.rdf> a foaf:Document }
	} ;
	INSERT {
		GRAPH <http://example.org/protocol-update-dataset-graphs-test/> {
			?s a dc:BibliographicResource
		}
	}
	WHERE {
		GRAPH ?g {
			?s a foaf:Document
		}
	}
  • Expect 2xx or 3xx response.

followed by

	POST /sparql HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Accept: application/sparql-results+xml
	Content-Type: application/sparql-query
	Content-Length: XXX
	
	ASK {
		GRAPH <http://example.org/protocol-update-dataset-test/> {
			<http://kasei.us/2009/09/sparql/data/data1.rdf> a <http://purl.org/dc/terms/BibliographicResource> .
			<http://kasei.us/2009/09/sparql/data/data2.rdf> a <http://purl.org/dc/terms/BibliographicResource> .
		}
		FILTER NOT EXISTS {
			GRAPH <http://example.org/protocol-update-dataset-test/> {
				<http://kasei.us/2009/09/sparql/data/data3.rdf> a <http://purl.org/dc/terms/BibliographicResource> .
			}
		}
	}
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/sparql-results+xml.
  • Expect true result.

update_dataset_full - update with protocol-specified dataset (both named and default graphs)

	POST /sparql?using-graph-uri=http%3A%2F%2Fkasei.us%2F2009%2F09%2Fsparql%2Fdata%2Fdata1.rdf&using-named-graph-uri=http%3A%2F%2Fkasei.us%2F2009%2F09%2Fsparql%2Fdata%2Fdata2.rdf HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-update
	Content-Length: XXX
	
	PREFIX dc: <http://purl.org/dc/terms/>
	PREFIX foaf: <http://xmlns.com/foaf/0.1/>
	CLEAR ALL ;
	INSERT DATA {
		GRAPH <http://kasei.us/2009/09/sparql/data/data1.rdf> { <http://kasei.us/2009/09/sparql/data/data1.rdf> a foaf:Document }
		GRAPH <http://kasei.us/2009/09/sparql/data/data2.rdf> { <http://kasei.us/2009/09/sparql/data/data2.rdf> a foaf:Document }
		GRAPH <http://kasei.us/2009/09/sparql/data/data3.rdf> { <http://kasei.us/2009/09/sparql/data/data3.rdf> a foaf:Document }
	} ;
	INSERT {
		GRAPH <http://example.org/protocol-update-dataset-graphs-test/> {
			?s <http://example.org/in> ?in
		}
	}
	WHERE {
		{
			GRAPH ?g { ?s a foaf:Document }
			BIND(?g AS ?in)
		}
		UNION
		{
			?s a foaf:Document .
			BIND("default" AS ?in)
		}
	}
  • Expect 2xx or 3xx response.

followed by

	POST /sparql HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Accept: application/sparql-results+xml
	Content-Type: application/sparql-query
	Content-Length: XXX
	
	ASK {
		GRAPH <http://example.org/protocol-update-dataset-test/> {
			<http://kasei.us/2009/09/sparql/data/data1.rdf> <http://example.org/in> "default" .
			<http://kasei.us/2009/09/sparql/data/data2.rdf> <http://example.org/in> <http://kasei.us/2009/09/sparql/data/data2.rdf> .
		}
		FILTER NOT EXISTS {
			GRAPH <http://example.org/protocol-update-dataset-test/> {
				<http://kasei.us/2009/09/sparql/data/data3.rdf> ?p ?o
			}
		}
	}
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/sparql-results+xml.
  • Expect true result.

update_post_form - update via URL-encoded POST

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/x-www-url-form-urlencoded
	Content-Length: XXX
	
	update=CLEAR%20ALL
  • Expect 2xx or 3xx response.

update_post_direct - update via POST directly

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-update
	Content-Length: XXX
	
	CLEAR ALL
  • Expect 2xx or 3xx response.

update_base_uri - test for service-defined BASE URI ("which MAY be the service endpoint").

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-update
	Content-Length: XXX
	
	CLEAR GRAPH <http://example.org/protocol-base-test/> ;
	INSERT DATA { GRAPH <http://example.org/protocol-base-test/> { <http://example.org/s> <http://example.org/p> <test> } }
  • Expect 2xx or 3xx response.

followed by

	POST /sparql/ HTTP/1.1
	Host: www.example
	User-agent: sparql-client/0.1
	Content-Type: application/sparql-query
	Accept: application/sparql-results+xml
	Content-Length: XXX
	
	SELECT ?o WHERE {
		GRAPH <http://example.org/protocol-base-test/> {
			<http://example.org/s> <http://example.org/p> ?o
		}
	}
  • Expect 2xx or 3xx response.
  • Expect Content-Type of application/sparql-results+xml.
  • Expect one result with ?o bound to an IRI that is not <test>.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment