summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Helma <helma@in-silico.ch>2012-03-08 15:23:43 +0000
committerChristoph Helma <helma@in-silico.ch>2012-03-08 15:23:43 +0000
commit63fcd8f8feed58af4b1e1ff0e5fdaa09791c9596 (patch)
tree97103c785013abd8fe2b3798f73ebec4bcb9e885
parent2f6d5c75fc1fece5fc10cc7c45ad59cf6b820d64 (diff)
improved integration of error reports, call stack added as errorDetails
-rw-r--r--lib/error.rb147
-rw-r--r--lib/opentox-client.rb16
-rw-r--r--lib/opentox.rb118
-rw-r--r--lib/overwrite.rb55
-rw-r--r--lib/rest-client-wrapper.rb122
-rw-r--r--lib/task.rb37
-rw-r--r--test/dataset.rb44
-rw-r--r--test/error.rb2
-rw-r--r--test/feature.rb4
-rw-r--r--test/task.rb6
10 files changed, 236 insertions, 315 deletions
diff --git a/lib/error.rb b/lib/error.rb
index 2033c1e..0ab2c73 100644
--- a/lib/error.rb
+++ b/lib/error.rb
@@ -1,24 +1,27 @@
require 'open4'
-# adding additional fields to Exception class to format errors according to OT-API
+# add additional fields to Exception class to format errors according to OT-API
class RuntimeError
- attr_accessor :report, :http_code
- def initialize message
+ attr_accessor :http_code, :uri
+ def initialize message, uri=nil
super message
- self.set_backtrace message.backtrace if message.is_a? Exception
+ @uri = uri
@http_code ||= 500
- puts self.class
- @report = OpenTox::ErrorReport.create self
- $logger.error "\n"+@report.to_turtle
+ $logger.error "\n"+self.report.to_turtle
+ end
+
+ def report
+ # TODO: remove kludge for old task services
+ OpenTox::ErrorReport.new(@http_code, self)
end
end
module OpenTox
class Error < RuntimeError
- def initialize code, message
+ def initialize code, message, uri=nil
@http_code = code
- super message
+ super message, uri
end
end
@@ -35,15 +38,16 @@ module OpenTox
}.each do |klass,code|
# create error classes
c = Class.new Error do
- define_method :initialize do |message|
- super code, message
+ define_method :initialize do |message, uri=nil|
+ super code, message, uri
end
end
OpenTox.const_set klass,c
# define global methods for raising errors, eg. bad_request_error
Object.send(:define_method, klass.underscore.to_sym) do |message|
- raise c.new message
+ defined?(@uri) ? uri = @uri : uri=nil
+ raise c, message, uri
end
end
@@ -53,61 +57,41 @@ module OpenTox
def initialize request, response, message
@request = request
@response = response
- super 502, message
+ super 502, message, request.url
end
end
+ # TODO: create reports directly from errors, requires modified task service
class ErrorReport
-
- attr_accessor :rdf # RDF Graph
- attr_accessor :http_code # TODO: remove when task service is fixed
-
- def initialize
- @rdf = RDF::Graph.new
- end
-
- # creates a error report object, from an ruby-exception object
- # @param [Exception] error
- def self.create error
- report = ErrorReport.new
- subject = RDF::Node.new
- report.rdf << [subject, RDF.type, RDF::OT.ErrorReport]
- message = error.message
- errorDetails = ""
- if error.respond_to? :request
- report.rdf << [subject, RDF::OT.actor, error.request.url ]
- errorDetails += "REST paramenters:\n#{error.request.args.inspect}"
- end
- error.respond_to?(:http_code) ? statusCode = error.http_code : statusCode = 500
- puts error.inspect
- if error.respond_to? :response
- statusCode = error.response.code if error.response
- message = error.response.body
- end
- statusCode = error.http_code if error.respond_to? :http_code
- report.rdf << [subject, RDF::OT.statusCode, statusCode ]
- report.rdf << [subject, RDF::OT.errorCode, error.class.to_s ]
- # TODO: remove kludge for old task services
- report.http_code = statusCode
- report.rdf << [subject, RDF::OT.message , message ]
- errorDetails += "\nBacktrace:\n" + error.backtrace.short_backtrace if error.respond_to?(:backtrace) and error.backtrace
- report.rdf << [subject, RDF::OT.errorDetails, errorDetails ]
- # TODO Error cause
- #report.rdf << [subject, OT.errorCause, error.report] if error.respond_to?(:report) and !error.report.empty?
- report
+ def initialize http_code, error
+ @http_code = http_code
+ #@report = report#.to_yaml
+ @report = {}
+ @report[RDF::OT.actor] = error.uri
+ @report[RDF::OT.message] = error.message
+ @report[RDF::OT.statusCode] = @http_code
+ @report[RDF::OT.errorCode] = error.class.to_s
+ @report[RDF::OT.errorDetails] = caller.collect{|line| line unless line =~ /#{File.dirname(__FILE__)}/}.compact.join("\n")
+ @report[RDF::OT.errorDetails] += "REST paramenters:\n#{error.request.args.inspect}" if defined? error.request
+ @report[RDF::OT.message] += "\n" + error.response.body if defined? error.response
+ # TODO fix Error cause
+ #report[RDF::OT.errorCause] = @report if defined?(@report)
end
- def actor=(uri)
- # TODO: test actor assignement (in opentox-server)
- subject = RDF::Query.execute(@rdf) do
- pattern [:subject, RDF.type, RDF::OT.ErrorReport]
- end.limit(1).select(:subject)
- @rdf << [subject, RDF::OT.actor, uri]
- end
-
# define to_ and self.from_ methods for various rdf formats
- [:rdfxml,:ntriples,:turtle].each do |format|
+ RDF_FORMATS.each do |format|
+
+ send :define_method, "to_#{format}".to_sym do
+ rdf = RDF::Writer.for(format).buffer do |writer|
+ subject = RDF::Node.new
+ @report.each do |predicate,object|
+ writer << [subject, predicate, object] if object
+ end
+ end
+ rdf
+ end
+=begin
define_singleton_method "from_#{format}".to_sym do |rdf|
report = ErrorReport.new
RDF::Reader.for(format).new(rdf) do |reader|
@@ -115,50 +99,7 @@ module OpenTox
end
report
end
-
- send :define_method, "to_#{format}".to_sym do
- rdfxml = RDF::Writer.for(format).buffer do |writer|
- @rdf.each{|statement| writer << statement}
- end
- rdfxml
- end
- end
-
- end
-end
-
-# overwrite backtick operator to catch system errors
-module Kernel
-
- # Override raises an error if _cmd_ returns a non-zero exit status.
- # Returns stdout if _cmd_ succeeds. Note that these are simply concatenated; STDERR is not inline.
- def ` cmd
- stdout, stderr = ''
- status = Open4::popen4(cmd) do |pid, stdin_stream, stdout_stream, stderr_stream|
- stdout = stdout_stream.read
- stderr = stderr_stream.read
- end
- raise stderr.strip if !status.success?
- return stdout
- rescue Exception
- internal_server_error $!
- end
-
- alias_method :system!, :system
-
- def system cmd
- `#{cmd}`
- return true
- end
-end
-
-class Array
- def short_backtrace
- short = []
- each do |c|
- break if c =~ /sinatra\/base/
- short << c
+=end
end
- short.join("\n")
end
end
diff --git a/lib/opentox-client.rb b/lib/opentox-client.rb
index a587aa5..7d9329d 100644
--- a/lib/opentox-client.rb
+++ b/lib/opentox-client.rb
@@ -6,6 +6,22 @@ require "rest-client"
require 'uri'
require 'yaml'
require 'logger'
+
+# define constants and global variables
+#TODO: switch services to 1.2
+RDF::OT = RDF::Vocabulary.new 'http://www.opentox.org/api/1.2#'
+RDF::OT1 = RDF::Vocabulary.new 'http://www.opentox.org/api/1.1#'
+RDF::OTA = RDF::Vocabulary.new 'http://www.opentox.org/algorithmTypes.owl#'
+
+#CLASSES = ["Compound", "Feature", "Dataset", "Algorithm", "Model", "Validation", "Task", "ErrorReport", "Investigation"]
+CLASSES = ["Compound", "Feature", "Dataset", "Algorithm", "Model", "Validation", "Task", "Investigation"]
+RDF_FORMATS = [:rdfxml,:ntriples,:turtle]
+$default_rdf = "application/rdf+xml"
+
+# Regular expressions for parsing classification data
+TRUE_REGEXP = /^(true|active|1|1.0|tox|activating|carcinogen|mutagenic)$/i
+FALSE_REGEXP = /^(false|inactive|0|0.0|low tox|deactivating|non-carcinogen|non-mutagenic)$/i
+
require File.join(File.dirname(__FILE__),"overwrite.rb")
require File.join(File.dirname(__FILE__),"error.rb")
require File.join(File.dirname(__FILE__),"rest-client-wrapper.rb")
diff --git a/lib/opentox.rb b/lib/opentox.rb
index 9ba64bd..342b04e 100644
--- a/lib/opentox.rb
+++ b/lib/opentox.rb
@@ -1,52 +1,73 @@
-#TODO: switch services to 1.2
-RDF::OT = RDF::Vocabulary.new 'http://www.opentox.org/api/1.2#'
-RDF::OT1 = RDF::Vocabulary.new 'http://www.opentox.org/api/1.1#'
-RDF::OTA = RDF::Vocabulary.new 'http://www.opentox.org/algorithmTypes.owl#'
-
-SERVICES = ["Compound", "Feature", "Dataset", "Algorithm", "Model", "Validation", "Task", "Investigation"]
-
-# Regular expressions for parsing classification data
-TRUE_REGEXP = /^(true|active|1|1.0|tox|activating|carcinogen|mutagenic)$/i
-FALSE_REGEXP = /^(false|inactive|0|0.0|low tox|deactivating|non-carcinogen|non-mutagenic)$/i
-
# defaults to stderr, may be changed to file output (e.g in opentox-service)
$logger = OTLogger.new(STDERR)
$logger.level = Logger::DEBUG
module OpenTox
- attr_accessor :subjectid, :uri, :response
- attr_writer :metadata
+ attr_accessor :uri, :subjectid, :rdf, :response
+ # Ruby interface
+
+ # Create a new OpenTox object (does not load data from service)
+ # @param [optional,String] URI
+ # @param [optional,String] subjectid
+ # @return [OpenTox] OpenTox object
def initialize uri=nil, subjectid=nil
- @uri = uri.chomp
+ @uri = uri.to_s.chomp
@subjectid = subjectid
+ @rdf = RDF::Graph.new
end
- # Ruby interface
+ # Load metadata from service
+ def pull
+ kind_of?(OpenTox::Dataset) ? uri = File.join(@uri,"metadata") : uri = @uri
+ # TODO generic method for all formats
+ parse_rdfxml RestClientWrapper.get(uri,{},{:accept => $default_rdf, :subjectid => @subjectid})
+ end
- def metadata reload=true
- if reload or @metadata.empty?
- @metadata = {}
- kind_of?(OpenTox::Dataset) ? uri = File.join(@uri,"metadata") : uri = @uri
- RDF::Reader.for(:rdfxml).new( RestClientWrapper.get(uri) ) do |reader|
- reader.each_statement do |statement|
- @metadata[statement.predicate] = statement.object if statement.subject == @uri
- end
- end
+ # Get object metadata
+ # @return [Hash] Metadata
+ def metadata
+ pull if @rdf.empty?
+ metadata = {}
+ @rdf.query([RDF::URI.new(@uri),nil,nil]).collect do |statement|
+ metadata[statement.predicate] ||= []
+ metadata[statement.predicate] << statement.object
end
- @metadata
+ metadata
+ end
+
+ # Get metadata values
+ # @param [RDF] Key from RDF Vocabularies
+ # @return [Array] Values for supplied key
+ def [](key)
+ pull if @rdf.empty?
+ @rdf.query([RDF::URI.new(@uri),key,nil]).collect{|statement| statement.object}
end
+ # Save object at service
def save
- post self.to_rdfxml, { :content_type => 'application/rdf+xml'}
+ #TODO: dynamic assignment
+ post self.to_rdfxml, { :content_type => $default_rdf}
end
- def to_rdfxml
- rdf = RDF::Writer.for(:rdfxml).buffer do |writer|
- @metadata.each { |p,o| writer << RDF::Statement.new(RDF::URI.new(@uri), p, o) }
+ RDF_FORMATS.each do |format|
+
+ # rdf parse methods for all formats e.g. parse_rdfxml
+ send :define_method, "parse_#{format}".to_sym do |rdf|
+ @rdf = RDF::Graph.new
+ RDF::Reader.for(format).new(rdf) do |reader|
+ reader.each_statement{ |statement| @rdf << statement }
+ end
+ end
+
+ # rdf serialization methods for all formats e.g. to_rdfxml
+ send :define_method, "to_#{format}".to_sym do
+ rdf = RDF::Writer.for(format).buffer do |writer|
+ @rdf.each{|statement| writer << statement}
+ end
+ rdf
end
- rdf
end
# REST API
@@ -70,32 +91,49 @@ module OpenTox
def delete headers={}
headers[:subjectid] ||= @subjectid
- @response = RestClientWrapper.delete(@uri.to_s,nil,nil,headers)
+ @response = RestClientWrapper.delete(@uri.to_s,nil,headers)
end
# class methods
module ClassMethods
+ def all service_uri, subjectid=nil
+ uris = RestClientWrapper.get(service_uri, {}, :accept => 'text/uri-list').split("\n").compact
+ uris.collect{|uri| URI.task?(service_uri) ? from_uri(uri, subjectid, false) : from_uri(uri, subjectid)}
+ end
+
def create service_uri, subjectid=nil
- uri = RestClientWrapper.post(service_uri, {}, :subjectid => subjectid).chomp
- subjectid ? eval("#{self}.new(\"#{uri}\", #{subjectid})") : eval("#{self}.new(\"#{uri}\")")
+ uri = RestClientWrapper.post(service_uri, {}, {:accept => 'text/uri-list', :subjectid => subjectid})
+ URI.task?(service_uri) ? from_uri(uri, subjectid, false) : from_uri(uri, subjectid)
end
def from_file service_uri, filename, subjectid=nil
file = File.new filename
- uri = RestClientWrapper.post(service_uri, {:file => file}, {:subjectid => subjectid, :content_type => file.mime_type, :accept => "text/uri-list"})
- puts uri
+ from_uri RestClientWrapper.post(service_uri, {:file => file}, {:subjectid => subjectid, :content_type => file.mime_type, :accept => "text/uri-list"}), subjectid
end
- def all service_uri, subjectid=nil
- uris = RestClientWrapper.get(service_uri, {}, :accept => 'text/uri-list').split("\n").compact
- uris.collect{|uri| subjectid ? eval("#{self}.new(\"#{uri}\", #{subjectid})") : eval("#{self}.new(\"#{uri}\")")}
- end
+ private
+ def from_uri uri, subjectid=nil, wait=true
+
+ uri.chomp!
+ # TODO add waiting task
+ if URI.task? uri and wait
+ t = OpenTox::Task.new(uri)
+ t.wait
+ uri = t.resultURI
+ end
+ # guess class from uri, this is potentially unsafe, but polling metadata from large uri lists is way too slow (and not all service provide RDF.type in their metadata)
+ result = CLASSES.collect{|s| s if uri =~ /#{s.downcase}/}.compact
+ internal_server_error "Cannot determine class from URI: '#{uri}.\nCandidate classes are #{result.inspect}" unless result.size == 1
+ klass = result.first
+ # initialize with/without subjectid
+ subjectid ? eval("#{self}.new(\"#{uri}\", #{subjectid})") : eval("#{self}.new(\"#{uri}\")")
+ end
end
# create default OpenTox classes
- SERVICES.each do |klass|
+ CLASSES.each do |klass|
c = Class.new do
include OpenTox
extend OpenTox::ClassMethods
diff --git a/lib/overwrite.rb b/lib/overwrite.rb
index c7a1d43..7b6cb4f 100644
--- a/lib/overwrite.rb
+++ b/lib/overwrite.rb
@@ -10,6 +10,10 @@ end
module URI
+ def self.compound? uri
+ uri =~ /compound/ and URI.valid? uri
+ end
+
def self.task? uri
uri =~ /task/ and URI.valid? uri
end
@@ -23,8 +27,8 @@ module URI
end
def self.accessible? uri, subjectid=nil
- if URI.task? uri
- # just ry to get a response, valid tasks may return codes > 400
+ if URI.task? uri or URI.compound? uri
+ # just try to get a response, valid tasks may return codes > 400
Net::HTTP.get_response(URI.parse(uri))
true
else
@@ -41,23 +45,46 @@ module URI
false
end
- def self.to_object uri, wait=true
+end
- # TODO add waiting task
- if task? uri and wait
- t = OpenTox::Task.new(uri)
- t.wait
- uri = t.resultURI
- end
+class File
+ def mime_type
+ `file -ib #{self.path}`.chomp
+ end
+end
- klass =
- subjectid ? eval("#{self}.new(\"#{uri}\", #{subjectid})") : eval("#{self}.new(\"#{uri}\")")
+# overwrite backtick operator to catch system errors
+module Kernel
+
+ # Override raises an error if _cmd_ returns a non-zero exit status.
+ # Returns stdout if _cmd_ succeeds. Note that these are simply concatenated; STDERR is not inline.
+ def ` cmd
+ stdout, stderr = ''
+ status = Open4::popen4(cmd) do |pid, stdin_stream, stdout_stream, stderr_stream|
+ stdout = stdout_stream.read
+ stderr = stderr_stream.read
+ end
+ raise stderr.strip if !status.success?
+ return stdout
+ rescue Exception
+ internal_server_error $!
end
+ alias_method :system!, :system
+
+ def system cmd
+ `#{cmd}`
+ return true
+ end
end
-class File
- def mime_type
- `file -ib #{self.path}`.chomp
+class Array
+ def short_backtrace
+ short = []
+ each do |c|
+ break if c =~ /sinatra\/base/
+ short << c
+ end
+ short.join("\n")
end
end
diff --git a/lib/rest-client-wrapper.rb b/lib/rest-client-wrapper.rb
index e594729..c9e6bbb 100644
--- a/lib/rest-client-wrapper.rb
+++ b/lib/rest-client-wrapper.rb
@@ -10,21 +10,10 @@ module OpenTox
# @param [String] destination URI
# @param [optional,Hash|String] Payload data posted to the service
# @param [optional,Hash] Headers with params like :accept, :content_type, :subjectid
- # @param [optional,OpenTox::Task] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
- # @param [wait,Boolean] Set to false to NOT wait for task if result is a task
# @return [RestClient::Response] REST call response
[:head,:get,:post,:put,:delete].each do |method|
- define_singleton_method method do |uri,payload={},headers={},waiting_task=nil, wait=true|
-
- # create request
- args={}
- args[:method] = method
- args[:url] = uri
- args[:timeout] = 600
- args[:payload] = payload
- headers.each{ |k,v| headers.delete(k) if v==nil } if headers #remove keys with empty values, as this can cause problems
- args[:headers] = headers
+ define_singleton_method method do |uri,payload={},headers={}|
# check input
bad_request_error "Invalid URI: '#{uri}'" unless URI.valid? uri
@@ -34,106 +23,25 @@ module OpenTox
[:accept,:content_type,:subjectid].each do |header|
bad_request_error "#{header} should be submitted in the headers" if payload and payload.is_a?(Hash) and payload[header]
end
- #bad_request_error "waiting_task is not 'nil', OpenTox::SubTask or OpenTox::Task: #{waiting_task.class}" unless waiting_task.nil? or waiting_task.is_a?(OpenTox::Task) or waiting_task.is_a?(OpenTox::SubTask)
+
+ # create request
+ args={}
+ args[:method] = method
+ args[:url] = uri
+ args[:timeout] = 600
+ args[:payload] = payload
+ headers.each{ |k,v| headers.delete(k) if v==nil } if headers #remove keys with empty values, as this can cause problems
+ args[:headers] = headers
# perform request
@request = RestClient::Request.new(args)
- #begin
- # do not throw RestClient exceptions in order to create a @response object (needed for error reports) in every case
- @response = @request.execute { |response, request, result| return response }
- # ignore error codes from Task services (may return error codes >= 400 according to API, which causes exceptions in RestClient and RDF::Reader)
- raise OpenTox::RestCallError.new @request, @response, "Response code is #{@response.code}." unless @response.code < 400 or URI.task? uri
- #return @response if @response.code==200 or !wait
-
- # wait for task
- #while @response.code==201 or @response.code==202
- #@response = wait_for_task(@response, uri, waiting_task)
- #end
- @response
-
- #rescue
- #rest_error $!.message
- #end
- end
- end
-
-=begin
- def wait_for_task( response, base_uri, waiting_task=nil )
-
- task = nil
- case @response.headers[:content_type]
- when /application\/rdf\+xml/
- # TODO: task uri from rdf
- #task = OpenTox::Task.from_rdfxml(@response)
- #task = OpenTox::Task.from_rdfxml(@response)
- when /text\/uri-list/
- rest_error "Uri list has more than one entry, should be a single task" if @response.split("\n").size > 1 #if uri list contains more then one uri, its not a task
- task = OpenTox::Task.new(@response.to_s.chomp) if URI.available? @response.to_s
- else
- rest_error "Unknown content-type for task : '"+@response.headers[:content_type].to_s+"'"+" base-uri: "+base_uri.to_s+" content: "+@response[0..200].to_s
+ # do not throw RestClient exceptions in order to create a @response object (needed for error reports) in every case
+ @response = @request.execute { |response, request, result| return response }
+ # ignore error codes from Task services (may return error codes >= 400 according to API, which causes exceptions in RestClient and RDF::Reader)
+ raise OpenTox::RestCallError.new @request, @response, "Response code is #{@response.code}." unless @response.code < 400 or URI.task? uri
+ @response
end
-
- task.wait waiting_task
- unless task.completed? # maybe task was cancelled / error
- if task.errorReport
- received_error task.errorReport, task.http_code, nil, {:rest_uri => task.uri, :rest_code => task.http_code}
- else
- rest_error "Status of task '"+task.uri.to_s+"' is no longer running (hasStatus is '"+task.status+
- "'), but it is neither completed nor has an errorReport"
- end
- end
- @response
- end
-
- def self.rest_error message
- puts message
- raise OpenTox::RestCallError.new @request, @response, message
end
- def self.received_error( body, code, content_type=nil, params=nil )
-
- # try to parse body TODO
- body.is_a?(OpenTox::ErrorReport) ? report = body : report = OpenTox::ErrorReport.from_rdf(body)
- rest_call_error "REST call returned error: '"+body.to_s+"'" unless report
- # parsing sucessfull
- # raise RestCallError with parsed report as error cause
- err = OpenTox::RestCallError.new(@request, @response, "REST call subsequent error")
- err.errorCause = report
- raise err
- end
-=end
-=begin
- def self.received_error( body, code, content_type=nil, params=nil )
-
- # try to parse body
- report = nil
- #report = OpenTox::ErrorReport.from_rdf(body)
- if body.is_a?(OpenTox::ErrorReport)
- report = body
- else
- case content_type
- when /yaml/
- report = YAML.load(body)
- when /rdf/
- report = OpenTox::ErrorReport.from_rdf(body)
- end
- end
-
- unless report
- # parsing was not successfull
- # raise 'plain' RestCallError
- err = OpenTox::RestCallError.new("REST call returned error: '"+body.to_s+"'")
- err.rest_params = params
- raise err
- else
- # parsing sucessfull
- # raise RestCallError with parsed report as error cause
- err = OpenTox::RestCallError.new("REST call subsequent error")
- err.errorCause = report
- err.rest_params = params
- raise err
- end
- end
-=end
end
end
diff --git a/lib/task.rb b/lib/task.rb
index 3a52dee..0562dc7 100644
--- a/lib/task.rb
+++ b/lib/task.rb
@@ -15,13 +15,11 @@ module OpenTox
pid = fork do
begin
result_uri = yield
- if URI.accessible?(result_uri)
- task.completed result_uri
- else
- not_found_error "\"#{result_uri}\" is not a valid result URI"
- end
+ task.completed result_uri
rescue
- task.error $!
+ RestClientWrapper.put(File.join(task.uri,'Error'),{:errorReport => $!.report.to_yaml})
+ task.kill
+ #raise $!
end
end
Process.detach(pid)
@@ -49,11 +47,13 @@ module OpenTox
end
def description
- metadata[RDF::DC.description]
+ pull
+ self.[](RDF::DC.description).uniq.first
end
def creator
- metadata[RDF::DC.creator]
+ pull
+ self.[](RDF::DC.creator).uniq.first
end
def cancel
@@ -66,16 +66,6 @@ module OpenTox
RestClientWrapper.put(File.join(@uri,'Completed'),{:resultURI => uri})
end
- def error error
- # TODO: switch task service to rdf
- #RestClientWrapper.put(File.join(@uri,'Error'),{:errorReport => error.report.to_rdfxml})
- # create report for non-runtime errors
- error.respond_to?(:reporti) ? report = error.report : report = OpenTox::ErrorReport.create(error)
- RestClientWrapper.put(File.join(@uri,'Error'),{:errorReport => report.to_yaml})
- kill
- raise error
- end
-
# waits for a task, unless time exceeds or state is no longer running
# @param [optional,Numeric] dur seconds pausing before checking again for completion
def wait(dur=0.3)
@@ -114,12 +104,11 @@ module OpenTox
res = RestClientWrapper.put(File.join(@uri,method.sub(/=/,'')),{})
super unless res.code == 200
else
- response = metadata[RDF::OT[method]].to_s
- response = metadata[RDF::OT1[method]].to_s if response.empty? # API 1.1 compatibility
- if response.empty?
- not_found_error "No #{method} metadata for #{@uri} "
- end
- return response
+ pull
+ response = self.[](RDF::OT[method])
+ response = self.[](RDF::OT1[method]) if response.empty? # API 1.1 compatibility
+ internal_server_error "No #{method} metadata for #{@uri} " if response.empty?
+ return response.uniq.first.to_s
end
rescue OpenTox::Error
raise $!
diff --git a/test/dataset.rb b/test/dataset.rb
index 13012bd..d2c8d57 100644
--- a/test/dataset.rb
+++ b/test/dataset.rb
@@ -4,43 +4,39 @@ require File.join File.dirname(__FILE__),'..','lib','opentox-client.rb'
class DatasetTest < Test::Unit::TestCase
-=begin
- def test_post_get_delete
- service_uri = "http://ot-dev.in-silico.ch/dataset"
- dataset = OpenTox::Dataset.create service_uri
- assert_match /#{service_uri}/, dataset.uri.to_s
- puts dataset.uri
- puts dataset.class
- puts dataset.to_yaml
- metadata = dataset.metadata
- puts dataset.class
- assert_equal RDF::OT.Dataset, metadata[RDF.type]
- assert_equal dataset.uri, metadata[RDF::XSD.anyURI]
- dataset.delete
- end
def test_all
datasets = OpenTox::Dataset.all "http://ot-dev.in-silico.ch/dataset"
assert_equal OpenTox::Dataset, datasets.first.class
end
- def test_create
- d = OpenTox::Dataset.create "http://ot-dev.in-silico.ch/dataset"
+ def test_create_empty
+ service_uri = "http://ot-dev.in-silico.ch/dataset"
+ d = OpenTox::Dataset.create service_uri
assert_equal OpenTox::Dataset, d.class
- puts d.delete
- assert_raise OpenTox::NotFoundError do
- puts d.get(:accept => 'application/x-yaml')
- end
+ assert_match /#{service_uri}/, d.uri.to_s
+ d.delete
end
-=end
def test_create_from_file
- d = OpenTox::Dataset.from_file "http://ot-dev.in-silico.ch/dataset", "data/EPAFHM.mini.csv"
+ d = OpenTox::Dataset.from_file "http://ot-dev.in-silico.ch/dataset", File.join(File.dirname(__FILE__),"data","EPAFHM.mini.csv")
assert_equal OpenTox::Dataset, d.class
- puts d.inspect
-
+ d.delete
+ assert_raise OpenTox::NotFoundError do
+ d.get
+ end
end
+
=begin
+ def test_metadata
+ d = OpenTox::Dataset.from_file "http://ot-dev.in-silico.ch/dataset", "data/EPAFHM.mini.csv"
+ assert_equal OpenTox::Dataset, d.class
+ # TODO fix metadata retrieval
+ metadata = d.metadata
+ assert_equal RDF::OT.Dataset, metadata[RDF.type]
+ assert_equal dataset.uri, metadata[RDF::XSD.anyURI]
+ d.delete
+ end
def test_save
d = OpenTox::Dataset.create "http://ot-dev.in-silico.ch/dataset"
d.metadata
diff --git a/test/error.rb b/test/error.rb
index af5db52..d736620 100644
--- a/test/error.rb
+++ b/test/error.rb
@@ -6,7 +6,7 @@ class ErrorTest < Test::Unit::TestCase
def test_bad_request
object = OpenTox::Feature.new "http://this-is-a/fantasy/url"
- assert_raise OpenTox::BadRequestError do
+ assert_raise OpenTox::NotFoundError do
response = object.get
end
end
diff --git a/test/feature.rb b/test/feature.rb
index 1308e77..01c2206 100644
--- a/test/feature.rb
+++ b/test/feature.rb
@@ -16,7 +16,9 @@ class FeatureTest < Test::Unit::TestCase
def test_feature
@features.each do |uri|
f = OpenTox::Feature.new(uri)
- assert_equal RDF::OT1.Feature, f.metadata[RDF.type]
+ assert_equal [RDF::OT1.TUM_CDK_nAtom], f[RDF::OWL.sameAs]
+ assert_equal RDF::OT1.TUM_CDK_nAtom, f.metadata[RDF::OWL.sameAs].first
+ assert_equal [RDF::OT1.Feature,RDF::OT1.NumericFeature].sort, f[RDF.type].sort
end
end
diff --git a/test/task.rb b/test/task.rb
index 932d5c9..adbba12 100644
--- a/test/task.rb
+++ b/test/task.rb
@@ -10,12 +10,14 @@ TASK_SERVICE_URI = "http://ot-dev.in-silico.ch/task"
class TaskTest < Test::Unit::TestCase
+=begin
+=end
def test_all
all = OpenTox::Task.all(TASK_SERVICE_URI)
assert_equal Array, all.class
t = all.last
assert_equal OpenTox::Task, t.class
- assert_equal RDF::OT1.Task, t.metadata[RDF.type]
+ assert_equal RDF::OT1.Task, t[RDF.type].first
end
def test_create_and_complete
@@ -77,5 +79,7 @@ class TaskTest < Test::Unit::TestCase
assert task.error?
assert_equal "Error", task.hasStatus
end
+=begin
+=end
end