diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f50c298f..290e2cbe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,13 +26,13 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-java@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '11' - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Start from clean state diff --git a/ontology/owl/owl.ttl b/ontology/owl/owl.ttl index 08819462..21d7aace 100644 --- a/ontology/owl/owl.ttl +++ b/ontology/owl/owl.ttl @@ -230,12 +230,12 @@ uco-owl:Disjointedness-C-DT-shape sh:sparql [ a sh:SPARQLConstraint ; rdfs:seeAlso ; - sh:message "An IRI may not be a member of both an owl:Class and owl:Datatype."@en ; + sh:message "An IRI may not be a member of both an owl:Class and rdfs:Datatype."@en ; sh:select """ PREFIX owl: SELECT $this WHERE { - $this a owl:Datatype ; + $this a rdfs:Datatype ; } """ ; ] ; diff --git a/ontology/uco/core/core.ttl b/ontology/uco/core/core.ttl index e061bd54..a9010464 100644 --- a/ontology/uco/core/core.ttl +++ b/ontology/uco/core/core.ttl @@ -121,7 +121,6 @@ core:ContextualCompilation rdfs:comment "A contextual compilation is a grouping of things sharing some context (e.g., a set of network connections observed on a given day, all accounts associated with a given person)."@en ; sh:property [ sh:class core:UcoObject ; - sh:minCount "1"^^xsd:integer ; sh:nodeKind sh:IRI ; sh:path core:object ; ] ; @@ -318,6 +317,19 @@ core:ModusOperandi sh:targetClass core:ModusOperandi ; . +core:ObjectStatusVocab + a rdfs:Datatype ; + rdfs:label "Object Status Vocabulary"@en-US ; + owl:equivalentClass [ + a rdfs:Datatype ; + owl:oneOf ( + "Draft"^^core:ObjectStatusVocab + "Final"^^core:ObjectStatusVocab + "Deprecated"^^core:ObjectStatusVocab + ) ; + ] ; + . + core:Relationship a owl:Class , @@ -378,6 +390,17 @@ core:UcoInherentCharacterizationThing sh:targetClass core:UcoInherentCharacterizationThing ; . +core:UcoInherentCharacterizationThing-disjointWith-UcoObject-shape + a sh:NodeShape ; + sh:message "core:UcoInherentCharacterizationThing and core:UcoObject are disjoint classes. Assigning both types to a single node will be an error in UCO 2.0.0."@en ; + sh:not [ + a sh:NodeShape ; + sh:class core:UcoObject ; + ] ; + sh:severity sh:Warning ; + sh:targetClass core:UcoInherentCharacterizationThing ; + . + core:UcoObject a owl:Class , @@ -441,6 +464,17 @@ core:UcoObject sh:datatype xsd:string ; sh:nodeKind sh:Literal ; sh:path core:tag ; + ] , + [ + sh:datatype core:ObjectStatusVocab ; + sh:in ( + "Draft"^^core:ObjectStatusVocab + "Final"^^core:ObjectStatusVocab + "Deprecated"^^core:ObjectStatusVocab + ) ; + sh:maxCount "1"^^xsd:integer ; + sh:nodeKind sh:Literal ; + sh:path core:objectStatus ; ] ; sh:targetClass core:UcoObject ; @@ -687,6 +721,19 @@ core:objectMarking rdfs:range core:MarkingDefinitionAbstraction ; . +core:objectStatus + a owl:AnnotationProperty ; + rdfs:label "objectStatus"@en ; + rdfs:comment "The current state of formality and acceptance for a UCO object."@en-US ; + rdfs:range core:ObjectStatusVocab ; + . + +core:objectStatus-subjects-shape + a sh:NodeShape ; + sh:class core:UcoObject ; + sh:targetSubjectsOf core:objectStatus ; + . + core:referenceURL a owl:DatatypeProperty ; rdfs:label "referenceURL"@en ; diff --git a/ontology/uco/observable/observable.ttl b/ontology/uco/observable/observable.ttl index 9583efbb..6dc75195 100644 --- a/ontology/uco/observable/observable.ttl +++ b/ontology/uco/observable/observable.ttl @@ -239,6 +239,14 @@ observable:AlternateDataStream rdfs:subClassOf observable:ObservableObject ; rdfs:label "AlternateDataStream"@en ; rdfs:comment "An alternate data stream is data content stored within an NTFS file that is independent of the standard content stream of the file and is hidden from access by default NTFS file viewing mechanisms."@en ; + rdfs:seeAlso [ + a sh:NodeShape ; + rdfs:comment "This anonymous shape is attached with rdfs:seeAlso in order to associate a warning-severity class constraint, that will only be necessary as an independent shape until UCO 2.0.0."@en ; + sh:class observable:FileSystemObject ; + sh:message "In UCO 2.0.0, uco-observable:AlternateDataStream will be a subclass of uco-observable:FileSystemObject. In preparation for UCO 2.0.0, the additional type uco-observable:FileSystemObject should be assigned to this node."@en ; + sh:severity sh:Warning ; + sh:targetClass observable:AlternateDataStream ; + ] ; sh:targetClass observable:AlternateDataStream ; . @@ -2429,6 +2437,14 @@ observable:Disk rdfs:subClassOf observable:ObservableObject ; rdfs:label "Disk"@en ; rdfs:comment "A disk is a storage mechanism where data is recorded by various electronic, magnetic, optical, or mechanical changes to a surface layer of one or more rotating disks."@en ; + rdfs:seeAlso [ + a sh:NodeShape ; + rdfs:comment "This anonymous shape is attached with rdfs:seeAlso in order to associate a warning-severity class constraint, that will only be necessary as an independent shape until UCO 2.0.0."@en ; + sh:class observable:StorageMedium ; + sh:message "In UCO 2.0.0, uco-observable:Disk will be a subclass of uco-observable:StorageMedium. In preparation for UCO 2.0.0, the additional type uco-observable:StorageMedium should be assigned to this node."@en ; + sh:severity sh:Warning ; + sh:targetClass observable:Disk ; + ] ; sh:targetClass observable:Disk ; . @@ -5056,6 +5072,20 @@ observable:ObservableRelationship ; rdfs:label "ObservableRelationship"@en ; rdfs:comment "An observable relationship is a grouping of characteristics unique to an assertion of an association between two observable objects."@en ; + sh:property + [ + sh:class observable:Observable ; + sh:message "The source on an ObservableRelationship is expected to be typed as an Observable, and the noted value node is not. This will be an error in UCO 2.0.0."@en ; + sh:path core:source ; + sh:severity sh:Warning ; + ] , + [ + sh:class observable:Observable ; + sh:message "The target on an ObservableRelationship is expected to be typed as an Observable, and the noted value node is not. This will be an error in UCO 2.0.0."@en ; + sh:path core:target ; + sh:severity sh:Warning ; + ] + ; sh:targetClass observable:ObservableRelationship ; . diff --git a/ontology/uco/types/types.ttl b/ontology/uco/types/types.ttl index ad91bedb..2f646d9f 100644 --- a/ontology/uco/types/types.ttl +++ b/ontology/uco/types/types.ttl @@ -59,16 +59,47 @@ types:Dictionary ; rdfs:subClassOf core:UcoInherentCharacterizationThing ; rdfs:label "Dictionary"@en ; - rdfs:comment "A dictionary is list of (term/key, value) pairs with each term/key existing no more than once."@en ; + rdfs:comment "A dictionary is list of (term/key, value) pairs with each term/key having an expectation to exist no more than once. types:Dictionary alone does not validate this expectation, but validation is available. For use cases where this expectation must be validated, the subclass types:ProperDictionary should be used instead of types:Dictionary. For instances where this expectation has been found to be violated, the subclass types:ImproperDictionary should be used instead of types:Dictionary."@en ; sh:property [ sh:class types:DictionaryEntry ; - sh:minCount "1"^^xsd:integer ; sh:nodeKind sh:IRI ; sh:path types:entry ; ] ; sh:targetClass types:Dictionary ; . +types:Dictionary-keyUniqueness-shape + a sh:NodeShape ; + sh:description "This shape is separated from the types:Dictionary class-shape in order to associate a warning-severity SPARQL-based shape."@en ; + sh:severity sh:Warning ; + sh:sparql [ + a sh:SPARQLConstraint ; + sh:message "A key in a dictionary should appear no more than once. The value literal does. Please consider using the types:ImproperDictionary class and types:repeatsKey property."@en ; + sh:select """ + PREFIX types: + SELECT $this ?value + WHERE { + $this + types:entry/types:key ?value ; + . + FILTER NOT EXISTS { + $this + a types:ImproperDictionary ; + . + } + FILTER NOT EXISTS { + $this + a types:ProperDictionary ; + . + } + } + GROUP BY ?value + HAVING (COUNT(?value) > 1) + """ ; + ] ; + sh:targetClass types:Dictionary ; + . + types:DictionaryEntry a owl:Class , @@ -167,11 +198,64 @@ types:Identifier rdfs:comment "An identifier is a string conformant to the specified UUID-based format for UCO object identifiers."@en ; . +types:ImproperDictionary + a + owl:Class , + sh:NodeShape + ; + rdfs:subClassOf types:Dictionary ; + rdfs:label "ImproperDictionary"@en ; + owl:disjointWith types:ProperDictionary ; + sh:property [ + sh:datatype xsd:string ; + sh:nodeKind sh:Literal ; + sh:path types:repeatsKey ; + ] ; + sh:targetClass types:ImproperDictionary ; + . + +types:ImproperDictionary-disjointWith-ProperDictionary-shape + a sh:NodeShape ; + sh:message "types:ImproperDictionary and types:ProperDictionary are disjoint classes."@en ; + sh:not [ + a sh:NodeShape ; + sh:class types:ProperDictionary ; + ] ; + sh:targetClass types:ImproperDictionary ; + . + types:NativeFormatString a rdfs:Datatype ; rdfs:comment "Specifies data in its native format of some external language. The data may be encoded in Base64 per [RFC4648]. Data encoded in Base64 must be denoted as such using the encoded property."@en ; . +types:ProperDictionary + a + owl:Class , + sh:NodeShape + ; + rdfs:subClassOf types:Dictionary ; + rdfs:label "ProperDictionary"@en ; + rdfs:comment "A proper dictionary is list of (term/key, value) pairs with each term/key existing no more than once."@en ; + owl:disjointWith types:ImproperDictionary ; + sh:sparql [ + a sh:SPARQLConstraint ; + sh:message "A key in a proper dictionary can appear no more than once."@en ; + sh:select """ + PREFIX types: + SELECT $this ?value + WHERE { + $this + types:entry/types:key ?value ; + . + } + GROUP BY ?value + HAVING (COUNT(?value) > 1) + """ ; + ] ; + sh:targetClass types:ProperDictionary ; + . + types:StructuredText a rdfs:Datatype ; rdfs:comment "Expresses string-based data in some information structuring format (e.g., HTML5)."@en ; @@ -195,6 +279,17 @@ types:Thread ] ; . +types:Thread-disjointWith-co-List-shape + a sh:NodeShape ; + sh:message "types:Thread and co:List are disjoint classes. Assigning both types to a single node will be an error in UCO 2.0.0."@en ; + sh:not [ + a sh:NodeShape ; + sh:class co:List ; + ] ; + sh:severity sh:Warning ; + sh:targetClass types:Thread ; + . + types:ThreadItem a owl:Class , @@ -213,6 +308,17 @@ types:ThreadItem ] ; . +types:ThreadItem-disjointWith-co-ListItem-shape + a sh:NodeShape ; + sh:message "types:ThreadItem and co:ListItem are disjoint classes. Assigning both types to a single node will be an error in UCO 2.0.0."@en ; + sh:not [ + a sh:NodeShape ; + sh:class co:ListItem ; + ] ; + sh:severity sh:Warning ; + sh:targetClass types:ThreadItem ; + . + types:entry a owl:ObjectProperty ; rdfs:label "entry"@en ; @@ -247,6 +353,20 @@ types:key rdfs:range xsd:string ; . +types:repeatsKey + a owl:DatatypeProperty ; + rdfs:label "repeatsKey"@en ; + rdfs:comment "A key found to be repeated in multiple dictionary entries within one dictionary."@en ; + rdfs:domain types:ImproperDictionary ; + rdfs:range xsd:string ; + . + +types:repeatsKey-subjects-shape + a sh:NodeShape ; + sh:class types:ImproperDictionary ; + sh:targetSubjectsOf types:repeatsKey ; + . + types:threadNextItem a owl:ObjectProperty ; rdfs:subPropertyOf types:threadSuccessor ; diff --git a/ontology/uco/vocabulary/vocabulary.ttl b/ontology/uco/vocabulary/vocabulary.ttl index d13c89e7..2e013aa7 100644 --- a/ontology/uco/vocabulary/vocabulary.ttl +++ b/ontology/uco/vocabulary/vocabulary.ttl @@ -17,7 +17,6 @@ vocabulary:AccountTypeVocab rdfs:label "Account Type Vocabulary"@en-US ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "ldap"^^vocabulary:AccountTypeVocab "nis"^^vocabulary:AccountTypeVocab @@ -37,7 +36,6 @@ vocabulary:ActionArgumentNameVocab rdfs:comment "Defines an open-vocabulary for common arguments of cyber actions."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "APC Address"^^vocabulary:ActionArgumentNameVocab "APC Mode"^^vocabulary:ActionArgumentNameVocab @@ -100,7 +98,6 @@ vocabulary:ActionNameVocab rdfs:comment "Defines an open-vocabulary of common specific cyber action names."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "Accept Socket Connection"^^vocabulary:ActionNameVocab "Add Connection to Network Share"^^vocabulary:ActionNameVocab @@ -293,7 +290,6 @@ vocabulary:ActionRelationshipTypeVocab rdfs:comment "Defines an open-vocabulary for capturing types of relationships between actions."@en-US ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "Dependent_On"^^vocabulary:ActionRelationshipTypeVocab "Equivalent_To"^^vocabulary:ActionRelationshipTypeVocab @@ -312,7 +308,6 @@ vocabulary:ActionStatusTypeVocab rdfs:comment "Defines an open-vocabulary of action status types."@en-US ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "Complete/Finish"^^vocabulary:ActionStatusTypeVocab "Error"^^vocabulary:ActionStatusTypeVocab @@ -331,7 +326,6 @@ vocabulary:ActionTypeVocab rdfs:comment "Defines an open-vocabulary of common general action types."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "Accept"^^vocabulary:ActionTypeVocab "Access"^^vocabulary:ActionTypeVocab @@ -454,7 +448,6 @@ vocabulary:BitnessVocab rdfs:comment "Defines an open-vocabulary of word sizes that define classes of operating systems."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "32"^^vocabulary:BitnessVocab "64"^^vocabulary:BitnessVocab @@ -468,7 +461,6 @@ vocabulary:CharacterEncodingVocab rdfs:comment "Defines an open-vocabulary of character encodings."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "ASCII"^^vocabulary:CharacterEncodingVocab "UTF-16"^^vocabulary:CharacterEncodingVocab @@ -493,7 +485,6 @@ vocabulary:ContactAddressScopeVocab rdfs:comment "Defines an open-vocabulary of scopes for address entries of digital contacts."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "home"^^vocabulary:ContactAddressScopeVocab "work"^^vocabulary:ContactAddressScopeVocab @@ -508,7 +499,6 @@ vocabulary:ContactEmailScopeVocab rdfs:comment "Defines an open-vocabulary of scopes for email entries of digital contacts."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "home"^^vocabulary:ContactEmailScopeVocab "work"^^vocabulary:ContactEmailScopeVocab @@ -524,7 +514,6 @@ vocabulary:ContactPhoneScopeVocab rdfs:comment "Defines an open-vocabulary of scopes for phone entries of digital contacts."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "home"^^vocabulary:ContactPhoneScopeVocab "work"^^vocabulary:ContactPhoneScopeVocab @@ -544,7 +533,6 @@ vocabulary:ContactSIPScopeVocab rdfs:comment "Defines an open-vocabulary of scopes for Session Initiation Protocol (SIP) entries of digital contacts."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "home"^^vocabulary:ContactSIPScopeVocab "work"^^vocabulary:ContactSIPScopeVocab @@ -559,7 +547,6 @@ vocabulary:ContactURLScopeVocab rdfs:comment "Defines an open-vocabulary of scopes for URL entries of digital contacts."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "home"^^vocabulary:ContactURLScopeVocab "work"^^vocabulary:ContactURLScopeVocab @@ -575,7 +562,6 @@ vocabulary:DiskTypeVocab rdfs:comment "Defines an open-vocabulary of disk types."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "CDRom"^^vocabulary:DiskTypeVocab "Fixed"^^vocabulary:DiskTypeVocab @@ -592,7 +578,6 @@ vocabulary:EndiannessTypeVocab rdfs:comment "Defines an open-vocabulary of byte ordering methods."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "Big-endian"^^vocabulary:EndiannessTypeVocab "Little-endian"^^vocabulary:EndiannessTypeVocab @@ -607,7 +592,6 @@ vocabulary:HashNameVocab rdfs:comment "Defines an open-vocabulary of hashing algorithm names."@en-US ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "MD5"^^vocabulary:HashNameVocab "MD6"^^vocabulary:HashNameVocab @@ -631,7 +615,6 @@ vocabulary:LibraryTypeVocab rdfs:comment "Defines an open-vocabulary of library types."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "Dynamic"^^vocabulary:LibraryTypeVocab "Other"^^vocabulary:LibraryTypeVocab @@ -648,7 +631,6 @@ vocabulary:MemoryBlockTypeVocab rdfs:comment "Defines an open-vocabulary of types of memory blocks."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "Bit-mapped"^^vocabulary:MemoryBlockTypeVocab "Byte-mapped"^^vocabulary:MemoryBlockTypeVocab @@ -665,7 +647,6 @@ vocabulary:ObservableObjectRelationshipVocab rdfs:comment "Defines an open-vocabulary of inter-observable object relationships."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "Allocated"^^vocabulary:ObservableObjectRelationshipVocab "Allocated_By"^^vocabulary:ObservableObjectRelationshipVocab @@ -816,7 +797,6 @@ vocabulary:ObservableObjectStateVocab rdfs:comment "Defines an open-vocabulary of observable object states."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "Active"^^vocabulary:ObservableObjectStateVocab "Closed"^^vocabulary:ObservableObjectStateVocab @@ -838,7 +818,6 @@ vocabulary:PartitionTypeVocab rdfs:comment "Defines an open-vocabulary of partition types. See http://www.win.tue.nl/~aeb/partitions/partition_types-1.html for more information about the various partition types."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "PARTITION_ENTRY_UNUSED"^^vocabulary:PartitionTypeVocab "PARTITION_EXTENDED"^^vocabulary:PartitionTypeVocab @@ -869,7 +848,6 @@ vocabulary:ProcessorArchVocab rdfs:comment "Defines an open-vocabulary of computer processor architectures."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "ARM"^^vocabulary:ProcessorArchVocab "Alpha"^^vocabulary:ProcessorArchVocab @@ -893,7 +871,6 @@ vocabulary:RecoveredObjectStatusVocab rdfs:comment "Defines the vocabulary for Recovered Object status of data."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "recovered"^^vocabulary:RecoveredObjectStatusVocab "partially recovered"^^vocabulary:RecoveredObjectStatusVocab @@ -909,7 +886,6 @@ vocabulary:RegionalRegistryTypeVocab rdfs:comment "Defines an open-vocabulary of Regional Internet Registries (RIRs) names, represented via their respective acronyms."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "APNIC"^^vocabulary:RegionalRegistryTypeVocab "ARIN"^^vocabulary:RegionalRegistryTypeVocab @@ -925,7 +901,6 @@ vocabulary:RegistryDatatypeVocab rdfs:label "Registry Datatype Vocabulary"@en-US ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "reg_binary"^^vocabulary:RegistryDatatypeVocab "reg_dword"^^vocabulary:RegistryDatatypeVocab @@ -950,7 +925,6 @@ vocabulary:SIMFormVocab rdfs:comment "Defines an open-vocabulary of common SIM card form factors."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "Full-size SIM"^^vocabulary:SIMFormVocab "Micro SIM"^^vocabulary:SIMFormVocab @@ -965,7 +939,6 @@ vocabulary:SIMTypeVocab rdfs:comment "Defines an open-vocabulary of common SIM card types."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "SIM"^^vocabulary:SIMTypeVocab "UICC"^^vocabulary:SIMTypeVocab @@ -980,7 +953,6 @@ vocabulary:TaskActionTypeVocab rdfs:comment "Defines an open-vocabulary of task action types. See also: http://msdn.microsoft.com/en-us/library/windows/desktop/aa380596(v=vs.85).aspx."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "TASK_ACTION_COM_HANDLER"^^vocabulary:TaskActionTypeVocab "TASK_ACTION_EXEC"^^vocabulary:TaskActionTypeVocab @@ -996,7 +968,6 @@ vocabulary:TaskFlagVocab rdfs:comment "Defines an open-vocabulary of the run flags for a task scheduler task. See also: http://msdn.microsoft.com/en-us/library/windows/desktop/aa381283(v=vs.85).aspx See Also: http://msdn.microsoft.com/en-us/library/microsoft.office.excel.server.addins.computecluster.taskscheduler.taskflags(v=office.12).aspx."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "TASK_FLAG_DELETE_WHEN_DONE"^^vocabulary:TaskFlagVocab "TASK_FLAG_DISABLED"^^vocabulary:TaskFlagVocab @@ -1021,7 +992,6 @@ vocabulary:TaskPriorityVocab rdfs:comment "Defines an open-vocabulary of the priority levels of task scheduler tasks. See also: http://msdn.microsoft.com/en-us/library/windows/desktop/aa383512(v=vs.85).aspx."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "ABOVE_NORMAL_PRIORITY_CLASS"^^vocabulary:TaskPriorityVocab "BELOW_NORMAL_PRIORITY_CLASS"^^vocabulary:TaskPriorityVocab @@ -1039,7 +1009,6 @@ vocabulary:TaskStatusVocab rdfs:comment "Defines an open-vocabulary of the possible statuses of a scheduled task. See also: http://msdn.microsoft.com/en-us/library/windows/desktop/aa383604(v=vs.85).aspx See also: http://msdn.microsoft.com/en-us/library/windows/desktop/aa381263(v=vs.85).aspx See also: http://msdn.microsoft.com/en-us/library/windows/desktop/aa381833(v=vs.85).aspx See also: http://msdn.microsoft.com/en-us/library/windows/desktop/aa383617(v=vs.85).aspx."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "SCHED_E_ACCOUNT_DBASE_CORRUPT"^^vocabulary:TaskStatusVocab "SCHED_E_ACCOUNT_INFORMATION_NOT_SET"^^vocabulary:TaskStatusVocab @@ -1075,7 +1044,6 @@ vocabulary:ThreadRunningStatusVocab rdfs:comment "Defines an open-vocabulary of the various states that a thread may be in before, during, or after execution. See http://msdn.microsoft.com/en-us/library/system.diagnostics.threadstate(v=vs.110).aspx."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "Initialized"^^vocabulary:ThreadRunningStatusVocab "Ready"^^vocabulary:ThreadRunningStatusVocab @@ -1095,7 +1063,6 @@ vocabulary:TimestampPrecisionVocab rdfs:comment "Defines an open-vocabulary of timestamp precision granularities."@en-US ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "day"^^vocabulary:TimestampPrecisionVocab "hour"^^vocabulary:TimestampPrecisionVocab @@ -1113,7 +1080,6 @@ vocabulary:TrendVocab rdfs:comment "Defines an open-vocabulary of trend values."@en-US ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "Decreasing"^^vocabulary:TrendVocab "Increasing"^^vocabulary:TrendVocab @@ -1127,7 +1093,6 @@ vocabulary:TriggerFrequencyVocab rdfs:comment "Defines an open-vocabulary of the frequency types that a trigger may use. See also: http://msdn.microsoft.com/en-us/library/windows/desktop/aa383620(v=vs.85).aspx and http://msdn.microsoft.com/en-us/library/windows/desktop/aa383987(v=vs.85).aspx."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "TASK_EVENT_TRIGGER_AT_LOGON"^^vocabulary:TriggerFrequencyVocab "TASK_EVENT_TRIGGER_AT_SYSTEMSTART"^^vocabulary:TriggerFrequencyVocab @@ -1147,7 +1112,6 @@ vocabulary:TriggerTypeVocab rdfs:comment "Defines an open-vocabulary of the types of triggers associated with a task."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "TASK_TRIGGER_BOOT"^^vocabulary:TriggerTypeVocab "TASK_TRIGGER_EVENT"^^vocabulary:TriggerTypeVocab @@ -1166,7 +1130,6 @@ vocabulary:URLTransitionTypeVocab rdfs:comment "Defines an open-vocabulary of types of URL transitions."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "link"^^vocabulary:URLTransitionTypeVocab "typed"^^vocabulary:URLTransitionTypeVocab @@ -1189,7 +1152,6 @@ vocabulary:UnixProcessStateVocab rdfs:comment "Defines an open-vocabulary of Unix process states"@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "Dead"^^vocabulary:UnixProcessStateVocab "InterruptibleSleep"^^vocabulary:UnixProcessStateVocab @@ -1208,7 +1170,6 @@ vocabulary:WhoisContactTypeVocab rdfs:comment "Defines an open-vocabulary of types of registrar contacts listed in a whois entry."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "ADMIN"^^vocabulary:WhoisContactTypeVocab "BILLING"^^vocabulary:WhoisContactTypeVocab @@ -1223,7 +1184,6 @@ vocabulary:WhoisDNSSECTypeVocab rdfs:comment "Defines an open-vocabulary of acceptable values for the DNSSEC field in a Whois entry."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "Signed"^^vocabulary:WhoisDNSSECTypeVocab "Unsigned"^^vocabulary:WhoisDNSSECTypeVocab @@ -1237,7 +1197,6 @@ vocabulary:WhoisStatusTypeVocab rdfs:comment "Defines an open-vocabulary of all valid statuses for a domain within a whois entry."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "ADD_PERIOD"^^vocabulary:WhoisStatusTypeVocab "AUTO_RENEW_PERIOD"^^vocabulary:WhoisStatusTypeVocab @@ -1268,7 +1227,6 @@ vocabulary:WindowsDriveTypeVocab rdfs:comment "Defines an open-vocabulary of possible drive types, as enumerated by the WINAPI GetDriveType function: http://msdn.microsoft.com/en-us/library/windows/desktop/aa364939(v=vs.85).aspx."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "DRIVE_CDROM"^^vocabulary:WindowsDriveTypeVocab "DRIVE_FIXED"^^vocabulary:WindowsDriveTypeVocab @@ -1287,7 +1245,6 @@ vocabulary:WindowsVolumeAttributeVocab rdfs:comment "Defines an open-vocabulary of attributes that may be returned by the diskpart attributes command: http://technet.microsoft.com/en-us/library/cc766465(v=ws.10).aspx."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "Hidden"^^vocabulary:WindowsVolumeAttributeVocab "NoDefaultDriveLetter"^^vocabulary:WindowsVolumeAttributeVocab @@ -1303,7 +1260,6 @@ vocabulary:WirelessNetworkSecurityModeVocab rdfs:comment "Defines an open-vocabulary of security modes that may be configured for wireless network connections."@en ; owl:equivalentClass [ a rdfs:Datatype ; - owl:onDatatype xsd:string ; owl:oneOf ( "None"^^vocabulary:WirelessNetworkSecurityModeVocab "WEP"^^vocabulary:WirelessNetworkSecurityModeVocab diff --git a/tests/examples/Makefile b/tests/examples/Makefile index 91e6098a..eaef6963 100644 --- a/tests/examples/Makefile +++ b/tests/examples/Makefile @@ -21,12 +21,16 @@ all: \ action_inheritance_PASS_validation.ttl \ action_inheritance_XFAIL_validation.ttl \ action_result_PASS_validation.ttl \ + alternate_data_stream_PASS_validation.ttl \ co_PASS_validation.ttl \ co_XFAIL_validation.ttl \ configuration_setting_PASS_validation.ttl \ configuration_setting_XFAIL_validation.ttl \ database_records_PASS_validation.ttl \ database_records_XFAIL_validation.ttl \ + dictionary_PASS_validation.ttl \ + dictionary_XFAIL_validation.ttl \ + disjointedness_PASS_validation.ttl \ event_XFAIL_validation.ttl \ file_url_PASS_validation.ttl \ has_facet_inverse_functional_PASS_validation.ttl \ @@ -37,6 +41,8 @@ all: \ location_XFAIL_validation.ttl \ message_thread_PASS_validation.ttl \ message_thread_XFAIL_validation.ttl \ + object_status_PASS_validation.ttl \ + object_status_XFAIL_validation.ttl \ observable_creation_time_PASS_validation.ttl \ owl_axiom_PASS_validation.ttl \ owl_axiom_XFAIL_validation.ttl \ @@ -94,12 +100,16 @@ check: \ action_inheritance_PASS_validation.ttl \ action_inheritance_XFAIL_validation.ttl \ action_result_PASS_validation.ttl \ + alternate_data_stream_PASS_validation.ttl \ co_PASS_validation.ttl \ co_XFAIL_validation.ttl \ configuration_setting_PASS_validation.ttl \ configuration_setting_XFAIL_validation.ttl \ database_records_PASS_validation.ttl \ database_records_XFAIL_validation.ttl \ + dictionary_PASS_validation.ttl \ + dictionary_XFAIL_validation.ttl \ + disjointedness_PASS_validation.ttl \ event_XFAIL_validation.ttl \ file_url_PASS_validation.ttl \ has_facet_inverse_functional_PASS_validation.ttl \ @@ -110,6 +120,8 @@ check: \ location_XFAIL_validation.ttl \ message_thread_PASS_validation.ttl \ message_thread_XFAIL_validation.ttl \ + object_status_PASS_validation.ttl \ + object_status_XFAIL_validation.ttl \ observable_creation_time_PASS_validation.ttl \ owl_axiom_PASS_validation.ttl \ owl_axiom_XFAIL_validation.ttl \ diff --git a/tests/examples/README.md b/tests/examples/README.md index 4b00de91..03abedd1 100644 --- a/tests/examples/README.md +++ b/tests/examples/README.md @@ -9,6 +9,32 @@ Two instance data files are currently in the directory: SHACL validation results are stored in corresponding files named `..._validation.ttl`, to present the current state of validation conditions. +## Design of the Dictionary tests + +The `Dictionary` objects in the `dictionary_*.json` files cover these combinations of asserted type (proper dictionary, improper dictionary, or the generic parent class), whether a dictionary entry key is repeated in the data, and whether the `repeatsKey` property is asserted. (P/X denotes whether the instance is a PASS or XFAIL test case.) + +| uuid | P/X | Dictionary type | Key repeats | repeatsKey asserted | +| --- | --- | --- | --- | --- | +| `3bb38b3e` | P | `Dictionary` | no | no | +| `e6dc9c2e` | X | `Dictionary` | no | yes | +| `e9adf6c1` | P | `Dictionary` | yes | no | +| `34ac0c49` | X | `Dictionary` | yes | yes | +| `cbc1c80d` | P | `ImproperDictionary` | no | no | +| `7fa3ea45` | P | `ImproperDictionary` | no | yes | +| `14e28425` | P | `ImproperDictionary` | yes | no | +| `a8e5e8e1` | P | `ImproperDictionary` | yes | yes | +| `eaded28e` | P | `ProperDictionary` | no | no | +| `8114819f` | X | `ProperDictionary` | no | yes | +| `b2baf8af` | X | `ProperDictionary` | yes | no | +| `f5ae2e6a` | X | `ProperDictionary` | yes | yes | + +Other miscellaneous tests are added without full combinatoric review: + +* `kb:ProperDictionary-f5ae2e6a-9b10-46f3-8441-30aada36aa1b` also demonstrates an XFAIL case where a key-value *pair* is repeated. +* `kb:ImproperDictionary-7fa3ea45-6426-4ad3-bb5f-7559e07adeb4` also demonstrates a PASS case where `repeatsKey`'s value is not in the supplied dictionary. +* `kb:Dictionary-5bc55661-4808-48e6-9e02-80a153eee5d3` demonstrates an XFAIL case where the disjoint `Dictionary` subtypes are both asserted. + + ## Design of the Relationship tests The `Relationship` objects in the `relationship_*.json` files include a numbering scheme in their identifiers, (object class)-(lexical value)-(datatype). These track the following matrix of test cases: diff --git a/tests/examples/alternate_data_stream_PASS.json b/tests/examples/alternate_data_stream_PASS.json new file mode 100644 index 00000000..e6abd5bb --- /dev/null +++ b/tests/examples/alternate_data_stream_PASS.json @@ -0,0 +1,21 @@ +{ + "@context": { + "kb": "http://example.org/kb/", + "observable": "https://ontology.unifiedcyberontology.org/uco/observable/", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#" + }, + "@graph": [ + { + "@id": "kb:AlternateDataStream-07b3c41a-080c-4916-8375-c18148763e13", + "@type": "observable:AlternateDataStream", + "rdfs:comment": "This node should trigger a sh:Warning from not being a observable:FileSystemObject" + }, + { + "@id": "kb:AlternateDataStream-b2d4968b-4490-4b44-a56b-832058834454", + "@type": [ + "observable:AlternateDataStream", + "observable:FileSystemObject" + ] + } + ] +} diff --git a/tests/examples/alternate_data_stream_PASS_validation.ttl b/tests/examples/alternate_data_stream_PASS_validation.ttl new file mode 100644 index 00000000..d13a07eb --- /dev/null +++ b/tests/examples/alternate_data_stream_PASS_validation.ttl @@ -0,0 +1,28 @@ +@prefix observable: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . + +[] + a sh:ValidationReport ; + sh:conforms "true"^^xsd:boolean ; + sh:result [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "In UCO 2.0.0, uco-observable:AlternateDataStream will be a subclass of uco-observable:FileSystemObject. In preparation for UCO 2.0.0, the additional type uco-observable:FileSystemObject should be assigned to this node."@en ; + sh:resultSeverity sh:Warning ; + sh:sourceConstraintComponent sh:ClassConstraintComponent ; + sh:sourceShape [ + a sh:NodeShape ; + rdfs:comment "This anonymous shape is attached with rdfs:seeAlso in order to associate a warning-severity class constraint, that will only be necessary as an independent shape until UCO 2.0.0."@en ; + sh:class observable:FileSystemObject ; + sh:message "In UCO 2.0.0, uco-observable:AlternateDataStream will be a subclass of uco-observable:FileSystemObject. In preparation for UCO 2.0.0, the additional type uco-observable:FileSystemObject should be assigned to this node."@en ; + sh:severity sh:Warning ; + sh:targetClass observable:AlternateDataStream ; + ] ; + sh:value ; + ] ; + . + diff --git a/tests/examples/co_XFAIL_validation.ttl b/tests/examples/co_XFAIL_validation.ttl index e243322f..9888889d 100644 --- a/tests/examples/co_XFAIL_validation.ttl +++ b/tests/examples/co_XFAIL_validation.ttl @@ -78,7 +78,7 @@ [ a sh:ValidationResult ; sh:focusNode ; - sh:resultMessage 'Node kb:list-item-4361eb9c-a1c2-40e7-ba83-92802554392a conforms to shape [ rdf:type sh:PropertyShape ; sh:class co:Item ; sh:description Literal("This shape encodes in SHACL that the range of co:itemContent is the complement of co:Item.", lang=en) ; sh:path co:itemContent ]' ; + sh:resultMessage 'Node kb:list-item-4361eb9c-a1c2-40e7-ba83-92802554392a must not conform to shape [ rdf:type sh:PropertyShape ; sh:class co:Item ; sh:description Literal("This shape encodes in SHACL that the range of co:itemContent is the complement of co:Item.", lang=en) ; sh:path co:itemContent ]' ; sh:resultSeverity sh:Violation ; sh:sourceConstraintComponent sh:NotConstraintComponent ; sh:sourceShape uco-co:itemContent-subjects-shape ; diff --git a/tests/examples/configuration_setting_XFAIL_validation.ttl b/tests/examples/configuration_setting_XFAIL_validation.ttl index fdd76c5b..866e84ae 100644 --- a/tests/examples/configuration_setting_XFAIL_validation.ttl +++ b/tests/examples/configuration_setting_XFAIL_validation.ttl @@ -13,7 +13,7 @@ [ a sh:ValidationResult ; sh:focusNode ; - sh:resultMessage 'Node kb:configuration-entry-5f0fc3ea-e763-4b6d-997a-be0d1ceffc8c does not conform to exactly one shape in [ sh:property [ sh:maxCount Literal("0", datatype=xsd:integer) ; sh:path configuration:itemObject ], [ sh:maxCount Literal("0", datatype=xsd:integer) ; sh:path configuration:itemValue ] ] , [ sh:property [ sh:minCount Literal("1", datatype=xsd:integer) ; sh:path configuration:itemObject ] ] , [ sh:property [ sh:minCount Literal("1", datatype=xsd:integer) ; sh:path configuration:itemValue ] ]' ; + sh:resultMessage 'Node kb:configuration-entry-5f0fc3ea-e763-4b6d-997a-be0d1ceffc8c must conform to exactly one shape in [ sh:property [ sh:maxCount Literal("0", datatype=xsd:integer) ; sh:path configuration:itemObject ], [ sh:maxCount Literal("0", datatype=xsd:integer) ; sh:path configuration:itemValue ] ] , [ sh:property [ sh:minCount Literal("1", datatype=xsd:integer) ; sh:path configuration:itemObject ] ] , [ sh:property [ sh:minCount Literal("1", datatype=xsd:integer) ; sh:path configuration:itemValue ] ]' ; sh:resultSeverity sh:Violation ; sh:sourceConstraintComponent sh:XoneConstraintComponent ; sh:sourceShape configuration:ConfigurationEntry ; diff --git a/tests/examples/database_records_XFAIL_validation.ttl b/tests/examples/database_records_XFAIL_validation.ttl index 2e76cf72..30d9ec99 100644 --- a/tests/examples/database_records_XFAIL_validation.ttl +++ b/tests/examples/database_records_XFAIL_validation.ttl @@ -12,7 +12,7 @@ [ a sh:ValidationResult ; sh:focusNode ; - sh:resultMessage 'Node kb:table-field-facet-37182dba-4dbd-4b97-b49e-8038b7fbfd29 does not conform to exactly one shape in [ rdf:type sh:NodeShape ; sh:property [ sh:hasValue Literal("false" = False, datatype=xsd:boolean) ; sh:path observable:recordFieldIsNull ] ] , [ rdf:type sh:NodeShape ; sh:property [ sh:hasValue Literal("true" = True, datatype=xsd:boolean) ; sh:path observable:recordFieldIsNull ], [ sh:maxCount Literal("0", datatype=xsd:integer) ; sh:path observable:recordFieldValue ] ] , [ rdf:type sh:NodeShape ; sh:property [ sh:maxCount Literal("0", datatype=xsd:integer) ; sh:path observable:recordFieldIsNull ] ]' ; + sh:resultMessage 'Node kb:table-field-facet-37182dba-4dbd-4b97-b49e-8038b7fbfd29 must conform to exactly one shape in [ rdf:type sh:NodeShape ; sh:property [ sh:hasValue Literal("false" = False, datatype=xsd:boolean) ; sh:path observable:recordFieldIsNull ] ] , [ rdf:type sh:NodeShape ; sh:property [ sh:hasValue Literal("true" = True, datatype=xsd:boolean) ; sh:path observable:recordFieldIsNull ], [ sh:maxCount Literal("0", datatype=xsd:integer) ; sh:path observable:recordFieldValue ] ] , [ rdf:type sh:NodeShape ; sh:property [ sh:maxCount Literal("0", datatype=xsd:integer) ; sh:path observable:recordFieldIsNull ] ]' ; sh:resultSeverity sh:Violation ; sh:sourceConstraintComponent sh:XoneConstraintComponent ; sh:sourceShape observable:TableFieldFacet ; @@ -35,7 +35,7 @@ [ a sh:ValidationResult ; sh:focusNode ; - sh:resultMessage 'Node kb:table-field-facet-46aafb6e-0be4-4412-a938-16c4b5ae5314 does not conform to exactly one shape in [ rdf:type sh:NodeShape ; sh:property [ sh:hasValue Literal("false" = False, datatype=xsd:boolean) ; sh:path observable:recordFieldIsNull ] ] , [ rdf:type sh:NodeShape ; sh:property [ sh:hasValue Literal("true" = True, datatype=xsd:boolean) ; sh:path observable:recordFieldIsNull ], [ sh:maxCount Literal("0", datatype=xsd:integer) ; sh:path observable:recordFieldValue ] ] , [ rdf:type sh:NodeShape ; sh:property [ sh:maxCount Literal("0", datatype=xsd:integer) ; sh:path observable:recordFieldIsNull ] ]' ; + sh:resultMessage 'Node kb:table-field-facet-46aafb6e-0be4-4412-a938-16c4b5ae5314 must conform to exactly one shape in [ rdf:type sh:NodeShape ; sh:property [ sh:hasValue Literal("false" = False, datatype=xsd:boolean) ; sh:path observable:recordFieldIsNull ] ] , [ rdf:type sh:NodeShape ; sh:property [ sh:hasValue Literal("true" = True, datatype=xsd:boolean) ; sh:path observable:recordFieldIsNull ], [ sh:maxCount Literal("0", datatype=xsd:integer) ; sh:path observable:recordFieldValue ] ] , [ rdf:type sh:NodeShape ; sh:property [ sh:maxCount Literal("0", datatype=xsd:integer) ; sh:path observable:recordFieldIsNull ] ]' ; sh:resultSeverity sh:Violation ; sh:sourceConstraintComponent sh:XoneConstraintComponent ; sh:sourceShape observable:TableFieldFacet ; diff --git a/tests/examples/dictionary_PASS.json b/tests/examples/dictionary_PASS.json new file mode 100644 index 00000000..31e1aab8 --- /dev/null +++ b/tests/examples/dictionary_PASS.json @@ -0,0 +1,125 @@ +{ + "@context": { + "kb": "http://example.org/kb/", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + "types": "https://ontology.unifiedcyberontology.org/uco/types/" + }, + "@graph": [ + { + "@id": "kb:Dictionary-3bb38b3e-d47a-43c8-8a77-afc0e6655ce1", + "@type": "types:Dictionary", + "types:entry": [ + { + "@id": "kb:DictionaryEntry-b8a01d49-53c1-440f-a2d5-618b58801d37", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "1" + }, + { + "@id": "kb:DictionaryEntry-6cac6c2c-5d4e-45f5-b784-c029c9f9fb6d", + "@type": "types:DictionaryEntry", + "types:key": "y", + "types:value": "2" + } + ] + }, + { + "@id": "kb:ProperDictionary-eaded28e-0bf8-4df1-aee8-84d22c09702c", + "@type": "types:ProperDictionary", + "types:entry": [ + { + "@id": "kb:DictionaryEntry-314212eb-39c4-4bf3-be3a-f07c38f0eae8", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "1" + }, + { + "@id": "kb:DictionaryEntry-9ec24a1a-7e99-41c9-ba7d-9d23f11babb4", + "@type": "types:DictionaryEntry", + "types:key": "y", + "types:value": "2" + } + ] + }, + { + "@id": "kb:ImproperDictionary-a8e5e8e1-b3de-4ac4-99dd-e36f96beea4d", + "@type": "types:ImproperDictionary", + "types:repeatsKey": "x", + "types:entry": [ + { + "@id": "kb:DictionaryEntry-55786f64-534d-4e8c-8a64-616f708ea4d3", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "1" + }, + { + "@id": "kb:DictionaryEntry-d1a83c3d-cbe6-40b0-bb26-3527c47a01d8", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "2" + } + ] + }, + { + "@id": "kb:Dictionary-e9adf6c1-0287-4290-95a9-c94a128d7ff6", + "@type": "types:Dictionary", + "rdfs:comment": "This dictionary, not being typed as a ProperDictionary, will not trigger a warning from having two entries keyed with value 'x'.", + "types:entry": [ + { + "@id": "kb:DictionaryEntry-20431f00-64a3-4c0f-94a4-1eb09f8a6b6a", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "1" + }, + { + "@id": "kb:DictionaryEntry-f187ee7f-12fb-4580-966d-47bf1afd4975", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "1" + } + ] + }, + { + "@id": "kb:ImproperDictionary-7fa3ea45-6426-4ad3-bb5f-7559e07adeb4", + "@type": "types:ImproperDictionary", + "repeatsKey": "z" + }, + { + "@id": "kb:ImproperDictionary-14e28425-00c1-4f11-b2ed-21390fc0749a", + "@type": "types:ImproperDictionary", + "types:entry": [ + { + "@id": "kb:DictionaryEntry-09f23642-389b-4553-b5be-283a6160f534", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "1" + }, + { + "@id": "kb:DictionaryEntry-7a84a0d6-d1cd-4291-afb4-c834d611898d", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "2" + } + ] + }, + { + "@id": "kb:ImproperDictionary-cbc1c80d-1bad-4947-8459-c53ff61e8bfa", + "@type": "types:ImproperDictionary", + "rdfs:comment": "This improper dictionary has no repeated key or assertion of a repeated key. This should not trigger a data error, because the information in the graph could merely be incomplete.", + "types:entry": [ + { + "@id": "kb:DictionaryEntry-ca1910ab-fa26-402a-86bb-229f490dd89a", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "1" + }, + { + "@id": "kb:DictionaryEntry-2a13e674-5e95-4a7a-9fac-c90417dcd97c", + "@type": "types:DictionaryEntry", + "types:key": "y", + "types:value": "2" + } + ] + } + ] +} diff --git a/tests/examples/dictionary_PASS_validation.ttl b/tests/examples/dictionary_PASS_validation.ttl new file mode 100644 index 00000000..f563abc0 --- /dev/null +++ b/tests/examples/dictionary_PASS_validation.ttl @@ -0,0 +1,46 @@ +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix types: . +@prefix xsd: . + +[] + a sh:ValidationReport ; + sh:conforms "true"^^xsd:boolean ; + sh:result [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "A key in a dictionary should appear no more than once. The value literal does. Please consider using the types:ImproperDictionary class and types:repeatsKey property." ; + sh:resultSeverity sh:Warning ; + sh:sourceConstraint [ + a sh:SPARQLConstraint ; + sh:message "A key in a dictionary should appear no more than once. The value literal does. Please consider using the types:ImproperDictionary class and types:repeatsKey property."@en ; + sh:select """ + PREFIX types: + SELECT $this ?value + WHERE { + $this + types:entry/types:key ?value ; + . + FILTER NOT EXISTS { + $this + a types:ImproperDictionary ; + . + } + FILTER NOT EXISTS { + $this + a types:ProperDictionary ; + . + } + } + GROUP BY ?value + HAVING (COUNT(?value) > 1) + """ ; + ] ; + sh:sourceConstraintComponent sh:SPARQLConstraintComponent ; + sh:sourceShape types:Dictionary-keyUniqueness-shape ; + sh:value "x" ; + ] ; + . + diff --git a/tests/examples/dictionary_XFAIL.json b/tests/examples/dictionary_XFAIL.json new file mode 100644 index 00000000..dd2a4567 --- /dev/null +++ b/tests/examples/dictionary_XFAIL.json @@ -0,0 +1,122 @@ +{ + "@context": { + "kb": "http://example.org/kb/", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + "types": "https://ontology.unifiedcyberontology.org/uco/types/" + }, + "@graph": [ + { + "@id": "kb:Dictionary-5bc55661-4808-48e6-9e02-80a153eee5d3", + "@type": [ + "types:ImproperDictionary", + "types:ProperDictionary" + ], + "rdfs:comment": "This dictionary will trigger an error from being typed as both disjoint subclasses of types:Dictionary.", + "types:entry": { + "@id": "kb:DictionaryEntry-fa139d6e-2b4d-49e5-8c7d-3cfc635d56e0", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "1" + } + }, + { + "@id": "kb:Dictionary-34ac0c49-1042-49c0-8fd6-c42a810e58da", + "@type": "types:Dictionary", + "rdfs:comment": "This dictionary will trigger an error from using repeatsKey while not also typing itself as a types:ImproperDictionary.", + "types:repeatsKey": "x", + "types:entry": [ + { + "@id": "kb:DictionaryEntry-322b718b-3869-48a3-a7bf-d97d5463563b", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "1" + }, + { + "@id": "kb:DictionaryEntry-e51c7808-7fcb-423a-95e6-dcb431a3bade", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "2" + } + ] + }, + { + "@id": "kb:ProperDictionary-b2baf8af-3d5d-4c4e-b442-49befefd147e", + "@type": "types:ProperDictionary", + "rdfs:comment": "This dictionary will trigger an error from having two entries keyed with value 'x'.", + "types:entry": [ + { + "@id": "kb:DictionaryEntry-203a8596-1439-4065-a99f-daf4d530bed7", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "1" + }, + { + "@id": "kb:DictionaryEntry-40b9d75d-6a11-4a8f-9951-e96e2c1fe683", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "2" + } + ] + }, + { + "@id": "kb:ProperDictionary-8114819f-d3c8-4e29-9e31-295d771f9db2", + "@type": "types:ProperDictionary", + "rdfs:comment": "This proper dictionary will trigger an error from using repeatsKey while not being an ImproperDictionary.", + "types:repeatsKey": "x", + "types:entry": [ + { + "@id": "kb:DictionaryEntry-1311a664-fce3-4174-ace1-539ac6d54a5f", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "1" + }, + { + "@id": "kb:DictionaryEntry-8b149881-5adc-4020-b46f-2be1c60bab83", + "@type": "types:DictionaryEntry", + "types:key": "y", + "types:value": "2" + } + ] + }, + { + "@id": "kb:ProperDictionary-f5ae2e6a-9b10-46f3-8441-30aada36aa1b", + "@type": "types:ProperDictionary", + "rdfs:comment": "This dictionary will trigger an error from having two entries keyed with value 'x'.", + "types:repeatsKey": "x", + "types:entry": [ + { + "@id": "kb:DictionaryEntry-0274c19c-89b9-42b6-a87e-f671cbd2c731", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "1" + }, + { + "@id": "kb:DictionaryEntry-de108ec2-8ddd-4201-8267-5a04035ba88e", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "1" + } + ] + }, + { + "@id": "kb:Dictionary-e6dc9c2e-25bc-422f-8ae8-8457e29f5fde", + "@type": "types:Dictionary", + "rdfs:comment": "This dictionary will trigger an error from using repeatsKey while not also typing itself as a types:ImproperDictionary.", + "types:repeatsKey": "x", + "types:entry": [ + { + "@id": "kb:DictionaryEntry-02edb446-1ad5-41ef-8877-fbee912189e7", + "@type": "types:DictionaryEntry", + "types:key": "x", + "types:value": "1" + }, + { + "@id": "kb:DictionaryEntry-147908bb-ebba-42e8-854d-72352dc903a1", + "@type": "types:DictionaryEntry", + "types:key": "y", + "types:value": "2" + } + ] + } + ] +} diff --git a/tests/examples/dictionary_XFAIL_validation.ttl b/tests/examples/dictionary_XFAIL_validation.ttl new file mode 100644 index 00000000..f15a7580 --- /dev/null +++ b/tests/examples/dictionary_XFAIL_validation.ttl @@ -0,0 +1,141 @@ +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix types: . +@prefix xsd: . + +[] + a sh:ValidationReport ; + sh:conforms "false"^^xsd:boolean ; + sh:result + [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "A key in a dictionary should appear no more than once. The value literal does. Please consider using the types:ImproperDictionary class and types:repeatsKey property." ; + sh:resultSeverity sh:Warning ; + sh:sourceConstraint [ + a sh:SPARQLConstraint ; + sh:message "A key in a dictionary should appear no more than once. The value literal does. Please consider using the types:ImproperDictionary class and types:repeatsKey property."@en ; + sh:select """ + PREFIX types: + SELECT $this ?value + WHERE { + $this + types:entry/types:key ?value ; + . + FILTER NOT EXISTS { + $this + a types:ImproperDictionary ; + . + } + FILTER NOT EXISTS { + $this + a types:ProperDictionary ; + . + } + } + GROUP BY ?value + HAVING (COUNT(?value) > 1) + """ ; + ] ; + sh:sourceConstraintComponent sh:SPARQLConstraintComponent ; + sh:sourceShape types:Dictionary-keyUniqueness-shape ; + sh:value "x" ; + ] , + [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "Value does not have class types:ImproperDictionary" ; + sh:resultSeverity sh:Violation ; + sh:sourceConstraintComponent sh:ClassConstraintComponent ; + sh:sourceShape types:repeatsKey-subjects-shape ; + sh:value ; + ] , + [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "types:ImproperDictionary and types:ProperDictionary are disjoint classes."@en ; + sh:resultSeverity sh:Violation ; + sh:sourceConstraintComponent sh:NotConstraintComponent ; + sh:sourceShape types:ImproperDictionary-disjointWith-ProperDictionary-shape ; + sh:value ; + ] , + [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "Value does not have class types:ImproperDictionary" ; + sh:resultSeverity sh:Violation ; + sh:sourceConstraintComponent sh:ClassConstraintComponent ; + sh:sourceShape types:repeatsKey-subjects-shape ; + sh:value ; + ] , + [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "Value does not have class types:ImproperDictionary" ; + sh:resultSeverity sh:Violation ; + sh:sourceConstraintComponent sh:ClassConstraintComponent ; + sh:sourceShape types:repeatsKey-subjects-shape ; + sh:value ; + ] , + [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "A key in a proper dictionary can appear no more than once." ; + sh:resultSeverity sh:Violation ; + sh:sourceConstraint [ + a sh:SPARQLConstraint ; + sh:message "A key in a proper dictionary can appear no more than once."@en ; + sh:select """ + PREFIX types: + SELECT $this ?value + WHERE { + $this + types:entry/types:key ?value ; + . + } + GROUP BY ?value + HAVING (COUNT(?value) > 1) + """ ; + ] ; + sh:sourceConstraintComponent sh:SPARQLConstraintComponent ; + sh:sourceShape types:ProperDictionary ; + sh:value "x" ; + ] , + [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "A key in a proper dictionary can appear no more than once." ; + sh:resultSeverity sh:Violation ; + sh:sourceConstraint [ + a sh:SPARQLConstraint ; + sh:message "A key in a proper dictionary can appear no more than once."@en ; + sh:select """ + PREFIX types: + SELECT $this ?value + WHERE { + $this + types:entry/types:key ?value ; + . + } + GROUP BY ?value + HAVING (COUNT(?value) > 1) + """ ; + ] ; + sh:sourceConstraintComponent sh:SPARQLConstraintComponent ; + sh:sourceShape types:ProperDictionary ; + sh:value "x" ; + ] , + [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "Value does not have class types:ImproperDictionary" ; + sh:resultSeverity sh:Violation ; + sh:sourceConstraintComponent sh:ClassConstraintComponent ; + sh:sourceShape types:repeatsKey-subjects-shape ; + sh:value ; + ] + ; + . + diff --git a/tests/examples/disjointedness_PASS.json b/tests/examples/disjointedness_PASS.json new file mode 100644 index 00000000..227775a6 --- /dev/null +++ b/tests/examples/disjointedness_PASS.json @@ -0,0 +1,18 @@ +{ + "@context": { + "kb": "http://example.org/kb/", + "core": "https://ontology.unifiedcyberontology.org/uco/core/", + "observable": "https://ontology.unifiedcyberontology.org/uco/observable/", + "xsd": "http://www.w3.org/2001/XMLSchema#" + }, + "@graph": [ + { + "@id": "kb:File-33a25932-3a1a-4828-a90f-d31818b495ce", + "@type": [ + "observable:File", + "observable:FileFacet" + ], + "rdfs:comment": "This node will trigger a violation in UCO 2.0.0 for designating itself a File and FileFacet, which are disjoint due to File being a (eventual) subclass of UcoObject, and FileFacet being a (eventual) subclass of UcoInherentCharacterizationThing." + } + ] +} diff --git a/tests/examples/disjointedness_PASS_validation.ttl b/tests/examples/disjointedness_PASS_validation.ttl new file mode 100644 index 00000000..02ba4683 --- /dev/null +++ b/tests/examples/disjointedness_PASS_validation.ttl @@ -0,0 +1,21 @@ +@prefix core: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . + +[] + a sh:ValidationReport ; + sh:conforms "true"^^xsd:boolean ; + sh:result [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "core:UcoInherentCharacterizationThing and core:UcoObject are disjoint classes. Assigning both types to a single node will be an error in UCO 2.0.0."@en ; + sh:resultSeverity sh:Warning ; + sh:sourceConstraintComponent sh:NotConstraintComponent ; + sh:sourceShape core:UcoInherentCharacterizationThing-disjointWith-UcoObject-shape ; + sh:value ; + ] ; + . + diff --git a/tests/examples/hash_XFAIL_validation.ttl b/tests/examples/hash_XFAIL_validation.ttl index e05552df..ea350416 100644 --- a/tests/examples/hash_XFAIL_validation.ttl +++ b/tests/examples/hash_XFAIL_validation.ttl @@ -78,7 +78,7 @@ [ a sh:ValidationResult ; sh:focusNode ; - sh:resultMessage 'Node Literal("1", datatype=xsd:integer) does not conform to one or more shapes in [ sh:datatype vocabulary:HashNameVocab ] , [ sh:datatype xsd:string ]' ; + sh:resultMessage 'Node Literal("1", datatype=xsd:integer) must conform to one or more shapes in [ sh:datatype vocabulary:HashNameVocab ] , [ sh:datatype xsd:string ]' ; sh:resultPath types:hashMethod ; sh:resultSeverity sh:Violation ; sh:sourceConstraintComponent sh:OrConstraintComponent ; diff --git a/tests/examples/object_status_PASS.json b/tests/examples/object_status_PASS.json new file mode 100644 index 00000000..2d10dc40 --- /dev/null +++ b/tests/examples/object_status_PASS.json @@ -0,0 +1,16 @@ +{ + "@context": { + "core": "https://ontology.unifiedcyberontology.org/uco/core/", + "kb": "http://example.org/kb/" + }, + "@graph": [ + { + "@id": "kb:UcoObject-f86c567d-374a-4873-b9bc-a746ca2bf360", + "@type": "core:UcoObject", + "core:objectStatus": { + "@type": "core:ObjectStatusVocab", + "@value": "Draft" + } + } + ] +} diff --git a/tests/examples/object_status_PASS_validation.ttl b/tests/examples/object_status_PASS_validation.ttl new file mode 100644 index 00000000..33496ff0 --- /dev/null +++ b/tests/examples/object_status_PASS_validation.ttl @@ -0,0 +1,11 @@ +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . + +[] + a sh:ValidationReport ; + sh:conforms "true"^^xsd:boolean ; + . + diff --git a/tests/examples/object_status_XFAIL.json b/tests/examples/object_status_XFAIL.json new file mode 100644 index 00000000..b827c238 --- /dev/null +++ b/tests/examples/object_status_XFAIL.json @@ -0,0 +1,26 @@ +{ + "@context": { + "core": "https://ontology.unifiedcyberontology.org/uco/core/", + "kb": "http://example.org/kb/", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#" + }, + "@graph": [ + { + "@id": "kb:UcoObject-6ae2b245-a8cd-45dc-9f40-5b2738879351", + "@type": "core:UcoObject", + "rdfs:comment": "This will trigger an error from using a value outside of the required vocabulary.", + "core:objectStatus": "Initial draft" + }, + { + "@id": "kb:File-c9c36379-8eca-4a85-887c-b51f7721edfd", + "@type": "observable:File", + "core:hasFacet": { + "@id": "kb:ArchiveFileFacet-5884ca1c-2f5e-4e66-bdc6-7d48606f9fbc", + "@type": "observable:ArchiveFileFacet", + "rdfs:comment": "This will trigger an error from using objectStatus on a non-UcoObject thing.", + "core:objectStatus": "Draft", + "observable:archiveType": "Currently-unknown compressing-and-encrypting type seen multiple places, further research needed" + } + } + ] +} diff --git a/tests/examples/object_status_XFAIL_validation.ttl b/tests/examples/object_status_XFAIL_validation.ttl new file mode 100644 index 00000000..819bbf85 --- /dev/null +++ b/tests/examples/object_status_XFAIL_validation.ttl @@ -0,0 +1,63 @@ +@prefix core: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . + +[] + a sh:ValidationReport ; + sh:conforms "false"^^xsd:boolean ; + sh:result + [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "Value does not have class core:UcoObject" ; + sh:resultSeverity sh:Violation ; + sh:sourceConstraintComponent sh:ClassConstraintComponent ; + sh:sourceShape core:objectStatus-subjects-shape ; + sh:value ; + ] , + [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "Value Literal(\"Initial draft\") not in list ['Literal(\"Draft\", datatype=core:ObjectStatusVocab)', 'Literal(\"Final\", datatype=core:ObjectStatusVocab)', 'Literal(\"Deprecated\", datatype=core:ObjectStatusVocab)']" ; + sh:resultPath core:objectStatus ; + sh:resultSeverity sh:Violation ; + sh:sourceConstraintComponent sh:InConstraintComponent ; + sh:sourceShape [ + sh:datatype core:ObjectStatusVocab ; + sh:in ( + "Draft"^^core:ObjectStatusVocab + "Final"^^core:ObjectStatusVocab + "Deprecated"^^core:ObjectStatusVocab + ) ; + sh:maxCount "1"^^xsd:integer ; + sh:nodeKind sh:Literal ; + sh:path core:objectStatus ; + ] ; + sh:value "Initial draft" ; + ] , + [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "Value is not Literal with datatype core:ObjectStatusVocab" ; + sh:resultPath core:objectStatus ; + sh:resultSeverity sh:Violation ; + sh:sourceConstraintComponent sh:DatatypeConstraintComponent ; + sh:sourceShape [ + sh:datatype core:ObjectStatusVocab ; + sh:in ( + "Draft"^^core:ObjectStatusVocab + "Final"^^core:ObjectStatusVocab + "Deprecated"^^core:ObjectStatusVocab + ) ; + sh:maxCount "1"^^xsd:integer ; + sh:nodeKind sh:Literal ; + sh:path core:objectStatus ; + ] ; + sh:value "Initial draft" ; + ] + ; + . + diff --git a/tests/examples/rdf_list_XFAIL_validation.ttl b/tests/examples/rdf_list_XFAIL_validation.ttl index 65ab509a..d8646eda 100644 --- a/tests/examples/rdf_list_XFAIL_validation.ttl +++ b/tests/examples/rdf_list_XFAIL_validation.ttl @@ -14,7 +14,7 @@ sh:detail [ a sh:ValidationResult ; sh:focusNode ; - sh:resultMessage 'Node kb:list-1 does not conform to exactly one shape in [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] , [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:path [ sh:oneOrMorePath rdf:rest ] ; sh:xone ( [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:maxCount Literal("1", datatype=xsd:integer) ; sh:minCount Literal("1", datatype=xsd:integer) ; sh:path rdf:first ] ] ) ] ]' ; + sh:resultMessage 'Node kb:list-1 must conform to exactly one shape in [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] , [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:path [ sh:oneOrMorePath rdf:rest ] ; sh:xone ( [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:maxCount Literal("1", datatype=xsd:integer) ; sh:minCount Literal("1", datatype=xsd:integer) ; sh:path rdf:first ] ] ) ] ]' ; sh:resultSeverity sh:Violation ; sh:sourceConstraintComponent sh:XoneConstraintComponent ; sh:sourceShape uco-owl:Sequence-shape ; @@ -40,7 +40,7 @@ sh:detail [ a sh:ValidationResult ; sh:focusNode ; - sh:resultMessage 'Node ex:someDatatypeProperty does not conform to exactly one shape in [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] , [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:path [ sh:oneOrMorePath rdf:rest ] ; sh:xone ( [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:maxCount Literal("1", datatype=xsd:integer) ; sh:minCount Literal("1", datatype=xsd:integer) ; sh:path rdf:first ] ] ) ] ]' ; + sh:resultMessage 'Node ex:someDatatypeProperty must conform to exactly one shape in [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] , [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:path [ sh:oneOrMorePath rdf:rest ] ; sh:xone ( [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:maxCount Literal("1", datatype=xsd:integer) ; sh:minCount Literal("1", datatype=xsd:integer) ; sh:path rdf:first ] ] ) ] ]' ; sh:resultSeverity sh:Violation ; sh:sourceConstraintComponent sh:XoneConstraintComponent ; sh:sourceShape uco-owl:Sequence-shape ; @@ -66,7 +66,7 @@ ) ; - sh:resultMessage 'Node ( kb:concept-7 kb:concept-8 ) does not conform to exactly one shape in [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] , [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:path [ sh:oneOrMorePath rdf:rest ] ; sh:xone ( [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:maxCount Literal("1", datatype=xsd:integer) ; sh:minCount Literal("1", datatype=xsd:integer) ; sh:path rdf:first ] ] ) ] ]' ; + sh:resultMessage 'Node ( kb:concept-7 kb:concept-8 ) must conform to exactly one shape in [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] , [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:path [ sh:oneOrMorePath rdf:rest ] ; sh:xone ( [ rdf:type sh:NodeShape ; sh:hasValue rdf:nil ] [ rdf:type sh:NodeShape ; sh:nodeKind sh:BlankNode ; sh:property [ rdf:type sh:PropertyShape ; sh:maxCount Literal("1", datatype=xsd:integer) ; sh:minCount Literal("1", datatype=xsd:integer) ; sh:path rdf:first ] ] ) ] ]' ; sh:resultSeverity sh:Violation ; sh:sourceConstraintComponent sh:XoneConstraintComponent ; sh:sourceShape uco-owl:Sequence-shape ; diff --git a/tests/examples/test_validation.py b/tests/examples/test_validation.py index 7eb6ef4b..33c5e06a 100644 --- a/tests/examples/test_validation.py +++ b/tests/examples/test_validation.py @@ -179,6 +179,15 @@ def test_action_result_PASS_validation() -> None: g = load_validation_graph("action_result_PASS_validation.ttl", True) assert isinstance(g, rdflib.Graph) +def test_alternate_data_stream_PASS_validation() -> None: + confirm_validation_results( + "alternate_data_stream_PASS_validation.ttl", + True, + expected_focus_node_severities={ + ("http://example.org/kb/AlternateDataStream-07b3c41a-080c-4916-8375-c18148763e13", str(NS_SH.Warning)), + } + ) + def test_configuration_setting_PASS_validation() -> None: g = load_validation_graph("configuration_setting_PASS_validation.ttl", True) assert isinstance(g, rdflib.Graph) @@ -209,6 +218,39 @@ def test_database_records_XFAIL() -> None: } ) +def test_dictionary_PASS() -> None: + confirm_validation_results( + "dictionary_PASS_validation.ttl", + True, + expected_focus_node_severities={ + ("http://example.org/kb/Dictionary-e9adf6c1-0287-4290-95a9-c94a128d7ff6", str(NS_SH.Warning)), + } + ) + +def test_dictionary_XFAIL() -> None: + confirm_validation_results( + "dictionary_XFAIL_validation.ttl", + False, + expected_focus_node_severities={ + ("http://example.org/kb/Dictionary-5bc55661-4808-48e6-9e02-80a153eee5d3", str(NS_SH.Violation)), + ("http://example.org/kb/Dictionary-e6dc9c2e-25bc-422f-8ae8-8457e29f5fde", str(NS_SH.Violation)), + ("http://example.org/kb/Dictionary-34ac0c49-1042-49c0-8fd6-c42a810e58da", str(NS_SH.Warning)), + ("http://example.org/kb/Dictionary-34ac0c49-1042-49c0-8fd6-c42a810e58da", str(NS_SH.Violation)), + ("http://example.org/kb/ProperDictionary-8114819f-d3c8-4e29-9e31-295d771f9db2", str(NS_SH.Violation)), + ("http://example.org/kb/ProperDictionary-b2baf8af-3d5d-4c4e-b442-49befefd147e", str(NS_SH.Violation)), + ("http://example.org/kb/ProperDictionary-f5ae2e6a-9b10-46f3-8441-30aada36aa1b", str(NS_SH.Violation)), + } + ) + +def test_disjointedness_PASS() -> None: + confirm_validation_results( + "disjointedness_PASS_validation.ttl", + True, + expected_focus_node_severities={ + ("http://example.org/kb/File-33a25932-3a1a-4828-a90f-d31818b495ce", str(NS_SH.Warning)), + } + ) + def test_event_XFAIL() -> None: confirm_validation_results( "event_XFAIL_validation.ttl", @@ -385,6 +427,28 @@ def test_message_thread_PASS_validation() -> None: def test_message_thread_XFAIL_validation() -> None: confirm_validation_results("message_thread_XFAIL_validation.ttl", False) +def test_object_status_PASS() -> None: + confirm_validation_results( + "object_status_PASS_validation.ttl", + True, + ) + +def test_object_status_XFAIL() -> None: + confirm_validation_results( + "object_status_XFAIL_validation.ttl", + False, + expected_focus_node_severities={ + ( + "http://example.org/kb/UcoObject-6ae2b245-a8cd-45dc-9f40-5b2738879351", + str(NS_SH.Violation) + ), + ( + "http://example.org/kb/ArchiveFileFacet-5884ca1c-2f5e-4e66-bdc6-7d48606f9fbc", + str(NS_SH.Violation) + ), + } + ) + def test_observable_creation_time_PASS() -> None: confirm_validation_results( "observable_creation_time_PASS_validation.ttl", diff --git a/tests/examples/thread_XFAIL_validation.ttl b/tests/examples/thread_XFAIL_validation.ttl index 8991af7f..7e86377f 100644 --- a/tests/examples/thread_XFAIL_validation.ttl +++ b/tests/examples/thread_XFAIL_validation.ttl @@ -48,7 +48,7 @@ [ a sh:ValidationResult ; sh:focusNode ; - sh:resultMessage 'Node kb:thread-item-2bd09467-d413-4a03-af5d-f0e428f7d987 conforms to shape [ rdf:type sh:PropertyShape ; sh:class co:Item ; sh:description Literal("This shape encodes in SHACL that the range of co:itemContent is the complement of co:Item.", lang=en) ; sh:path co:itemContent ]' ; + sh:resultMessage 'Node kb:thread-item-2bd09467-d413-4a03-af5d-f0e428f7d987 must not conform to shape [ rdf:type sh:PropertyShape ; sh:class co:Item ; sh:description Literal("This shape encodes in SHACL that the range of co:itemContent is the complement of co:Item.", lang=en) ; sh:path co:itemContent ]' ; sh:resultSeverity sh:Violation ; sh:sourceConstraintComponent sh:NotConstraintComponent ; sh:sourceShape uco-co:itemContent-subjects-shape ;