Test automation checkpoint (#1)

* Test REQ-WA103-QO1 working, added assert handling for cases with HTTP Client exceptions
* Added additional test support methods for testing specific OData versions, also reset for local state.
* Assert stepdef cleanup.
* Added support for asserting response codes, like 400s, for a specific OData version
* Added support for arithmetic integer comparisons.
* Updated resoscript variables and added further test support.
* Added Integer Comparison Tests (through REQ-WA103-QO11)
* rebuilt for Java 1.8 and cleaned up some of the logging and int compare tests
* Updated Dockerfile, generic.resoscript, and removed assertions from the runRESOScript action. Gradle should be used for assertion testing. See README.
This commit is contained in:
Joshua Darnell 2020-02-26 18:49:41 -08:00 committed by GitHub
parent cffb8bf9e2
commit 97722ba86c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 504 additions and 269 deletions

View File

@ -4,7 +4,7 @@ WORKDIR /home/gradle/project
ADD . ./
RUN gradle copyJarToOut
RUN gradle jar
RUN ls
@ -13,7 +13,7 @@ FROM alpine:latest
RUN apk add --update bash ca-certificates openjdk8-jre-base nss && \
rm -rf /var/cache/apk/*
COPY --from=builder /home/gradle/project/out/web-api-commander.jar ./
COPY --from=builder /home/gradle/project/build/libs/web-api-commander.jar ./
ENTRYPOINT ["java","-jar","/web-api-commander.jar"]
CMD ["--help"]

View File

@ -296,7 +296,6 @@ The XML DTD for this schema is as follows:
<!ELEMENT Requests (Request)*>
<!ELEMENT Request (#PCDATA)*>
<!ATTLIST Request
AssertResponseCode CDATA #IMPLIED
Capability CDATA #REQUIRED
MetallicLevel CDATA #REQUIRED
OutputFile CDATA #REQUIRED
@ -492,4 +491,4 @@ Please contact [josh@reso.org](mailto:josh@reso.org) with any questions, bug rep
* Support for authentication options in addition to Bearer tokens (Client Credentials in beta, please email for more info).
* Parallel fetch for replication
* Job Scheduling
* Excel export
* Excel export

Binary file not shown.

View File

@ -25,9 +25,8 @@
Name CDATA #REQUIRED
Value CDATA #REQUIRED>
<!ELEMENT Requests (Request)*>
<!ELEMENT Request (Assertions)*>
<!ELEMENT Request (#PCDATA)*>
<!ATTLIST Request
AssertResponseCode CDATA #IMPLIED
Capability CDATA #REQUIRED
MetallicLevel CDATA #REQUIRED
OutputFile CDATA #REQUIRED
@ -35,12 +34,6 @@
TestDescription CDATA #REQUIRED
Url CDATA #REQUIRED
WebAPIReference CDATA #REQUIRED>
<!ELEMENT Assertions (AssertPresent|AssertBinaryOpComparison)*>
<!ELEMENT AssertPresent (#PCDATA)>
<!ELEMENT AssertBinaryOpComparison (LVal|Op|RVal)*>
<!ELEMENT LVal (#PCDATA)>
<!ELEMENT Op (#PCDATA)>
<!ELEMENT RVal (#PCDATA)>
]>
<OutputScript>
@ -89,7 +82,7 @@
<!-- REQUIRED: OData $select list - adapt this for your system and then adjust the remaining queries accordingly -->
<Parameter Name="SelectList" Value="ListingKey,BedroomsTotal,StreetName,PropertyType,ModificationTimestamp" />
<!-- REQUIRED: Substitute key name from your EndpointMetadata here, either ListingKey or ListingKeyNumeric,
<!-- REQUIRED: Substitute key name from your EndpointMetadata here, either ListingKey or ListingKeyInteger,
which requires rewriting some of the queries that follow... -->
<Parameter Name="UniqueID" Value="ListingKey" />
@ -100,14 +93,14 @@
<Parameter Name="TopCount" Value="5" />
<Parameter Name="SortCount" Value="20" />
<!-- Numeric Field for eq, ne, gt, ge, lt, le testing -->
<!-- Integer Field for eq, ne, gt, ge, lt, le testing -->
<!-- Type="Edm.Int16" or Type="Edm.Int32" or Type="Edm.Int64" for non-lookup fields -->
<Parameter Name="FilterNumericField" Value="BedroomsTotal" />
<Parameter Name="FilterNumericValueLow" Value="9" />
<Parameter Name="FilterNumericValueHigh" Value="15" />
<Parameter Name="FilterNumericNotFound" Value="-1" />
<Parameter Name="FilterIntegerField" Value="BedroomsTotal" />
<Parameter Name="FilterIntegerValueLow" Value="9" />
<Parameter Name="FilterIntegerValueHigh" Value="15" />
<Parameter Name="FilterIntegerNotFound" Value="-1" />
<!-- Numeric Field for "not" testing -->
<!-- Integer Field for "not" testing -->
<Parameter Name="FilterNotField" Value="BedroomsTotal" />
<Parameter Name="FilterNotValue" Value="-1" />
@ -126,11 +119,11 @@
<Parameter Name="ExpandField" Value="ListAgent" />
<!-- For Geo-spatial Testing -->
<Parameter Name="GeospatialLatitudeField" Value="Latitude" />
<Parameter Name="GeospatialLongitudeField" Value="Longitude" />
<Parameter Name="GeospatialField" Value="Coordinates" />
<Parameter Name="GeospatialValue" Value="REQUIRED: YOUR COORDINATES GO HERE in 'Longitude Latitude' format" /> <!-- "Longitude Latitude" -->
<Parameter Name="GeospatialDistanceValue" Value="100" />
<Parameter Name="GeoSpatialLatitudeField" Value="Latitude" />
<Parameter Name="GeoSpatialLongitudeField" Value="Longitude" />
<Parameter Name="GeoSpatialField" Value="Coordinates" />
<Parameter Name="GeoSpatialValue" Value="REQUIRED: YOUR COORDINATES GO HERE in 'Longitude Latitude' format" /> <!-- "Longitude Latitude" -->
<Parameter Name="GeoSpatialDistanceValue" Value="100" />
<!--String Fields for testing -->
<!-- Type="Edm.String" -->
@ -184,220 +177,192 @@
<!-- NOTE: for this test, we always assume that /$metadata is relative to the Web API Service Root, referred to as WebAPIURI here -->
<Request
TestDescription="Metadata Endpoint"
RequirementId="REQ-WA103-END3"
RequirementId="REQ-WA103-END3.metadata"
MetallicLevel="Core"
Capability="Core Support"
Capability="Core"
WebAPIReference=""
OutputFile="REQ-WA103-END3_Metadata.xml"
OutputFile="REQ-WA103-END3.metadata.xml"
Url="*ClientSettings_WebAPIURI*/$metadata?$format=application/xml"
/>
<Request
TestDescription="Data System"
RequirementId="REQ-WA103-END2"
RequirementId="REQ-WA103-END2.datasystem"
MetallicLevel="Core"
Capability="Core Support"
WebAPIReference=""
OutputFile="REQ-WA103-END2_DataSystem.json"
OutputFile="REQ-WA103-END2.datasystem.json"
Url="*Parameter_EndpointDataSystem*"
/>
<Request
TestDescription="Field names are case sensitive when used in the $select, $filter, and $orderby parameters. Case sensitivity is tested against the values defined in the resource metadata. Case sensitivity MUST be supported."
RequirementId="REQ-WA103-Q1"
MetallicLevel="Core"
Capability="Core Support"
WebAPIReference=""
OutputFile="REQ-WA103-Q1.json"
Url=""
AssertResponseCode="400"
/>
<!-- TODO: verify AssertResponseCode -->
<Request
TestDescription="Servers MAY reject queries that are too complex to accept/handle. Servers MUST generate an appropriate error response and gracefully deny the request."
RequirementId="REQ-WA103-Q2"
MetallicLevel="Core"
Capability="Query functions"
WebAPIReference=""
OutputFile="REQ-WA103-Q2.json"
Url="*Parameter_QueryTooComplexUri*"
AssertResponseCode="20211"
/>
<Request
TestDescription="Search Parameters: Search by UniqueID"
RequirementId="REQ-WA103-QR1"
TestDescription="Search Parameters: Select UniqueID"
RequirementId="REQ-WA103-QR1.select.uniqueId"
MetallicLevel="Core"
Capability="Query functions"
WebAPIReference="2.4.1"
OutputFile="REQ-WA103-QR1.json"
OutputFile="REQ-WA103-QR1.select.uniqueId.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*(*Parameter_UniqueIDValue*)?$select=*Parameter_UniqueID*"
AssertResponseCode="200"
/>
<Request
TestDescription="Query Support: $select"
RequirementId="REQ-WA103-QR3"
RequirementId="REQ-WA103-QR3.select"
MetallicLevel="Core"
Capability="Query functions"
WebAPIReference="2.4.2"
OutputFile="REQ-WA103-QR3.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterNumericField* gt *Parameter_FilterNumericValueLow**Parameter_RequiredParameters*"
OutputFile="REQ-WA103-QR3.select.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterIntegerField* gt *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*"
/>
<Request
TestDescription="Query Support: $top"
RequirementId="REQ-WA103-QR4"
RequirementId="REQ-WA103-QR4.top"
MetallicLevel="Core"
Capability="Client paging ($top, $skip)"
WebAPIReference="2.4.2"
OutputFile="REQ-WA103-QR4.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterNumericField* gt *Parameter_FilterNumericValueLow**Parameter_RequiredParameters*"
OutputFile="REQ-WA103-QR4.top.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterIntegerField* gt *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*"
/>
<Request
TestDescription="Query Support: $skip"
RequirementId="REQ-WA103-QR5"
RequirementId="REQ-WA103-QR5.skip"
MetallicLevel="Core"
Capability="Client pageability ($top, $skip)"
WebAPIReference="2.4.2"
OutputFile="REQ-WA103-QR5.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterNumericField* gt *Parameter_FilterNumericValueLow**Parameter_RequiredParameters*"
OutputFile="REQ-WA103-QR5.skip.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterIntegerField* gt *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*"
/>
<Request
TestDescription="Query Support: $filter"
RequirementId="REQ-WA103-QO1"
TestDescription="Query Support: $select case-sensitivity. Expect 400 response on OData 4.0"
RequirementId="REQ-WA103-QO1.select.case"
MetallicLevel="Core"
Capability="Filterability ($filter)"
Capability="Core"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO1-1_Select_Case.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$SeLeCt=*Parameter_SelectList*&amp;$filter=*Parameter_FilterNumericField* eq *Parameter_FilterNumericValueLow**Parameter_RequiredParameters*"
AssertResponseCode="400"
OutputFile="REQ-WA103-QO1.select.case.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$SeLeCt=*Parameter_SelectList*&amp;$filter=*Parameter_FilterIntegerField* eq *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*"
/>
<Request
TestDescription="Query Support: $filter (2)"
RequirementId="REQ-WA103-QO1"
TestDescription="Query Support: $filter case-sensitivity. Expect 400 response on OData 4.0"
RequirementId="REQ-WA103-QO1.filter.case"
MetallicLevel="Core"
Capability="Filterability ($filter)"
Capability="Core"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO1-2_Filter_Case.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$FiLtEr=*Parameter_FilterNumericField* eq *Parameter_FilterNumericValueLow**Parameter_RequiredParameters*"
AssertResponseCode="400"
OutputFile="REQ-WA103-QO1.filter.case.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$FiLtEr=*Parameter_FilterIntegerField* eq *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*"
/>
<Request
TestDescription="Query Support: $filter (3)"
RequirementId="REQ-WA103-QO1"
TestDescription="Query Support: $orderby asc case-sensitivity. Expect 400 response on OData 4.0"
RequirementId="REQ-WA103-QO1.orderby.asc.case"
MetallicLevel="Core"
Capability="Filterability ($filter)"
Capability="Core"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO1-3a_OrderByAsc_Case.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_SortCount*&amp;$select=*Parameter_FilterNumericField*&amp;$filter=*Parameter_FilterNumericField* gt *Parameter_FilterNumericValueLow**Parameter_RequiredParameters*&amp;$OrDeRbY=*Parameter_FilterNumericField* asc"
AssertResponseCode="400"
OutputFile="REQ-WA103-QO1.orderby.asc.case.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_SortCount*&amp;$select=*Parameter_FilterIntegerField*&amp;$filter=*Parameter_FilterIntegerField* gt *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*&amp;$OrDeRbY=*Parameter_FilterIntegerField* asc"
/>
<Request
TestDescription="Query Support: $filter (4)"
RequirementId="REQ-WA103-QO1"
TestDescription="Query Support: $orderby desc case-sensitivity. Expect 400 response on OData 4.0"
RequirementId="REQ-WA103-QO1.orderby.desc.case"
MetallicLevel="Core"
Capability="Filterability ($filter)"
Capability="Core"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO1-3b_OrderByDesc_Case.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_SortCount*&amp;$select=*Parameter_FilterNumericField*&amp;$filter=*Parameter_FilterNumericField* gt *Parameter_FilterNumericValueLow**Parameter_RequiredParameters*&amp;$oRdErBy=*Parameter_FilterNumericField* desc"
AssertResponseCode="400"
OutputFile="REQ-WA103-QO1.orderby.desc.case.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_SortCount*&amp;$select=*Parameter_FilterIntegerField*&amp;$filter=*Parameter_FilterIntegerField* gt *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*&amp;$oRdErBy=*Parameter_FilterIntegerField* desc"
/>
<Request
TestDescription="Query Support: $filter - Comparison: eq (equal)"
RequirementId="REQ-WA103-QO2"
TestDescription="Query Support: $filter - Integer Comparison: eq (equal)"
RequirementId="REQ-WA103-QO2.filter.int.compare.eq"
MetallicLevel="Core"
Capability="Filterability ($filter)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO2_filter_eq.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterNumericField* eq *Parameter_FilterNumericValueLow**Parameter_RequiredParameters*"
OutputFile="REQ-WA103-QO2.filter.int.compare.eq.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterIntegerField* eq *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*"
/>
<Request
TestDescription="Query Support: $filter - Comparison: ne (not equal)"
RequirementId="REQ-WA103-QO3"
TestDescription="Query Support: $filter - Integer Comparison: ne (not equal)"
RequirementId="REQ-WA103-QO3.filter.int.compare.ne"
MetallicLevel="Core"
Capability="Filterability ($filter)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO3_filter_ne.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterNumericField* ne *Parameter_FilterNumericValueLow**Parameter_RequiredParameters*"
OutputFile="REQ-WA103-QO3.filter.int.compare.ne.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterIntegerField* ne *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*"
/>
<Request
TestDescription="Query Support: $filter - Comparison: gt (greater than)"
RequirementId="REQ-WA103-QO4"
TestDescription="Query Support: $filter - Integer Comparison: gt (greater than)"
RequirementId="REQ-WA103-QO4.filter.int.compare.gt"
MetallicLevel="Core"
Capability="Filterability ($filter)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO4_filter_gt.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterNumericField* gt *Parameter_FilterNumericValueLow**Parameter_RequiredParameters*"
OutputFile="REQ-WA103-QO4.filter.int.compare.gt.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterIntegerField* gt *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*"
/>
<Request
TestDescription="Query Support: $filter - Comparison: ge (greater or equal)"
RequirementId="REQ-WA103-QO5"
TestDescription="Query Support: $filter - Integer Comparison: ge (greater or equal)"
RequirementId="REQ-WA103-QO5.filter.int.compare.ge"
MetallicLevel="Core"
Capability="Filterability ($filter)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO5_filter_ge.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterNumericField* ge *Parameter_FilterNumericValueLow**Parameter_RequiredParameters*"
OutputFile="REQ-WA103-QO5.filter.int.compare.ge.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterIntegerField* ge *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*"
/>
<Request
TestDescription="Query Support: $filter - Comparison: lt (less than)"
RequirementId="REQ-WA103-QO6"
TestDescription="Query Support: $filter - Integer Comparison: lt (less than)"
RequirementId="REQ-WA103-QO6.filter.int.compare.lt"
MetallicLevel="Core"
Capability="Filterability ($filter)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO6_filter_lt.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterNumericField* lt *Parameter_FilterNumericValueLow**Parameter_RequiredParameters*"
OutputFile="REQ-WA103-QO6.filter.int.compare.lt.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterIntegerField* lt *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*"
/>
<Request
TestDescription="Query Support: $filter - Comparison: le (less or equal)"
RequirementId="REQ-WA103-QO7"
TestDescription="Query Support: $filter - Integer Comparison: le (less or equal)"
RequirementId="REQ-WA103-QO7.filter.int.compare.le"
MetallicLevel="Core"
Capability="Filterability ($filter)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO7_filter_le.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterNumericField* le *Parameter_FilterNumericValueLow**Parameter_RequiredParameters*"
OutputFile="REQ-WA103-QO7.filter.int.compare.le.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterIntegerField* le *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*"
/>
<Request
TestDescription="Query Support: $filter - Logical: and"
RequirementId="REQ-WA103-QO9"
TestDescription="Query Support: $filter - Integer Comparison: and"
RequirementId="REQ-WA103-QO9.filter.int.compare.and"
MetallicLevel="Core"
Capability="Filterability ($filter)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO9_filter_and.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterNumericField* gt *Parameter_FilterNumericValueLow* and *Parameter_FilterNumericField* lt *Parameter_FilterNumericValueHigh**Parameter_RequiredParameters*"
OutputFile="REQ-WA103-QO9.filter.int.compare.and.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterIntegerField* gt *Parameter_FilterIntegerValueLow* and *Parameter_FilterIntegerField* lt *Parameter_FilterIntegerValueHigh**Parameter_RequiredParameters*"
/>
<Request
TestDescription="Query Support: $filter - Logical: or"
RequirementId="REQ-WA103-QO10"
TestDescription="Query Support: $filter - Integer Comparison: or"
RequirementId="REQ-WA103-QO10.filter.int.compare.or"
MetallicLevel="Core"
Capability="Filterability ($filter)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO10_filter_or.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterNumericField* gt *Parameter_FilterNumericValueHigh* or *Parameter_FilterNumericField* lt *Parameter_FilterNumericValueLow**Parameter_RequiredParameters*"
OutputFile="REQ-WA103-QO10.filter.int.compare.or.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=*Parameter_FilterIntegerField* gt *Parameter_FilterIntegerValueHigh* or *Parameter_FilterIntegerField* lt *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*"
/>
<Request
TestDescription="Query Support: $filter - Logical: not"
RequirementId="REQ-WA103-QO11"
TestDescription="Query Support: $filter - Integer: not operator"
RequirementId="REQ-WA103-QO11.filter.int.compare.not.operator"
MetallicLevel="Core"
Capability="Filterability ($filter)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO11_filter_not.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=not (*Parameter_FilterNotField* le *Parameter_FilterNotValue*)*Parameter_RequiredParameters*"
OutputFile="REQ-WA103-QO11.filter.int.compare.not.operator.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=not(*Parameter_FilterNotField* le *Parameter_FilterNotValue*)*Parameter_RequiredParameters*"
/>
<Request
@ -444,7 +409,7 @@
TestDescription="Support Annotations"
RequirementId="REQ-WA103-QM6"
MetallicLevel="Bronze"
Capability="Core Support"
Capability="Core"
WebAPIReference="2.4.8"
OutputFile="REQ-WA103-QM6.json"
Url=""
@ -497,7 +462,7 @@
Capability="Sortability ($orderby)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO28_OrderByAscFiltered.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_SortCount*&amp;$select=*Parameter_FilterNumericField*,*Parameter_TimestampField*&amp;$orderby=*Parameter_TimestampField* asc&amp;$filter=*Parameter_FilterNumericField* gt *Parameter_FilterNumericValueLow**Parameter_RequiredParameters*"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_SortCount*&amp;$select=*Parameter_FilterIntegerField*,*Parameter_TimestampField*&amp;$orderby=*Parameter_TimestampField* asc&amp;$filter=*Parameter_FilterIntegerField* gt *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*"
/>
<Request
@ -507,7 +472,7 @@
Capability="Sortability ($orderby)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO28_OrderByAscNoFilter.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_SortCount*&amp;$select=*Parameter_FilterNumericField*,*Parameter_TimestampField*&amp;$orderby=*Parameter_TimestampField* asc"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_SortCount*&amp;$select=*Parameter_FilterIntegerField*,*Parameter_TimestampField*&amp;$orderby=*Parameter_TimestampField* asc"
/>
<Request
@ -517,7 +482,7 @@
Capability="Sortability ($orderby)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO28_OrderByDescFiltered.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_SortCount*&amp;$select=*Parameter_FilterNumericField*,*Parameter_TimestampField*&amp;$orderby=*Parameter_TimestampField* desc&amp;$filter=*Parameter_FilterNumericField* gt *Parameter_FilterNumericValueLow**Parameter_RequiredParameters*"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_SortCount*&amp;$select=*Parameter_FilterIntegerField*,*Parameter_TimestampField*&amp;$orderby=*Parameter_TimestampField* desc&amp;$filter=*Parameter_FilterIntegerField* gt *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*"
/>
<Request
@ -527,7 +492,7 @@
Capability="Sortability ($orderby)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO28_OrderByDescNoFilter.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_SortCount*&amp;$select=*Parameter_FilterNumericField*,*Parameter_TimestampField*&amp;$orderby=*Parameter_TimestampField* desc"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_SortCount*&amp;$select=*Parameter_FilterIntegerField*,*Parameter_TimestampField*&amp;$orderby=*Parameter_TimestampField* desc"
/>
<Request
@ -701,23 +666,23 @@
/>
<Request
TestDescription="Support Geospatial Search Implementation"
TestDescription="Support GeoSpatial Search Implementation"
RequirementId="REQ-WA103-QM5"
MetallicLevel="Platinum"
Capability="Query functions"
WebAPIReference="2.4.7"
OutputFile="REQ-WA103-QM5_GeospatialLongLat_PointGeo.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=geo.distance(*Parameter_GeospatialField*, geography'POINT(*Parameter_GeospatialValue*)') le *Parameter_GeospatialDistanceValue*"
OutputFile="REQ-WA103-QM5_GeoSpatialLongLat_PointGeo.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=geo.distance(*Parameter_GeoSpatialField*, geography'POINT(*Parameter_GeoSpatialValue*)') le *Parameter_GeoSpatialDistanceValue*"
/>
<Request
TestDescription="Support Geospatial Search Implementation"
TestDescription="Support GeoSpatial Search Implementation"
RequirementId="REQ-WA103-QM5"
MetallicLevel="Platinum"
Capability="Query functions"
WebAPIReference="2.4.7"
OutputFile="REQ-WA103-QM5_GeospatialLongLat_LatGT1_PointGeo.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=geo.distance(*Parameter_GeospatialField*, geography'POINT(*Parameter_GeospatialValue*)') le *Parameter_GeospatialDistanceValue* and *Parameter_GeospatialLatitudeField* gt 1"
OutputFile="REQ-WA103-QM5_GeoSpatialLongLat_LatGT1_PointGeo.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=geo.distance(*Parameter_GeoSpatialField*, geography'POINT(*Parameter_GeoSpatialValue*)') le *Parameter_GeoSpatialDistanceValue* and *Parameter_GeoSpatialLatitudeField* gt 1"
/>
<Request
@ -727,7 +692,7 @@
Capability="Filterability ($filter)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO12_Grouping.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=(*Parameter_FilterNumericField* eq *Parameter_FilterNumericValueLow*) and (*Parameter_FilterNumericField* le *Parameter_FilterNumericValueHigh* and *Parameter_FilterNumericField* ge *Parameter_FilterNumericValueLow*)*Parameter_RequiredParameters*"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&amp;$select=*Parameter_SelectList*&amp;$filter=(*Parameter_FilterIntegerField* eq *Parameter_FilterIntegerValueLow*) and (*Parameter_FilterIntegerField* le *Parameter_FilterIntegerValueHigh* and *Parameter_FilterIntegerField* ge *Parameter_FilterIntegerValueLow*)*Parameter_RequiredParameters*"
/>
<Request
@ -784,7 +749,7 @@
TestDescription="Service Endpoint"
RequirementId="REQ-WA103-END1"
MetallicLevel="Core"
Capability="Core Support"
Capability="Core"
WebAPIReference=""
OutputFile="REQ-WA103-END1_Service.json"
Url="*ClientSettings_WebAPIURI*/"
@ -793,58 +758,53 @@
<!-- RESPONSE CODE SUPPORT -->
<Request
TestDescription="Assert 200 OK Request"
TestDescription="200 OK Request"
RequirementId="REQ-WA103-RC3"
MetallicLevel="Core"
Capability="Core Support"
Capability="Core"
WebAPIReference="2.5.2"
OutputFile="REQ-WA103-RC05_200OKRequest.json"
Url="ClientSettings_WebAPIURI*/*Parameter_200_OK*"
AssertResponseCode="200"
/>
<Request
TestDescription="Assert 400 Bad Request"
TestDescription="400 Bad Request"
RequirementId="REQ-WA103-RC5"
MetallicLevel="Core"
Capability="Core Support"
Capability="Core"
WebAPIReference="2.5.2"
OutputFile="REQ-WA103-RC05_400BadRequest.json"
Url="ClientSettings_WebAPIURI*/*Parameter_400BadRequest*"
AssertResponseCode="400"
/>
<Request
TestDescription="Assert 403 Forbidden Request"
TestDescription="403 Forbidden Request"
RequirementId="REQ-WA103-RC06"
MetallicLevel="Core"
Capability="Core Support"
Capability="Core"
WebAPIReference="2.5.2"
OutputFile="REQ-WA103-RC06_403Forbidden_Generic.json"
Url="ClientSettings_WebAPIURI*/*Parameter_403Forbidden*"
AssertResponseCode="403"
/>
<Request
TestDescription="Assert 404 Not Found Request"
TestDescription="404 Not Found Request"
RequirementId="REQ-WA103-RC07"
MetallicLevel="Core"
Capability="Core Support"
Capability="Core"
WebAPIReference="2.5.2"
OutputFile="REQ-WA103-RC07_404NotFound.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_404NotFound*"
AssertResponseCode="404"
/>
<Request
TestDescription="Assert 501 Not Implemented Request"
TestDescription="501 Not Implemented Request"
RequirementId="REQ-WA103-RC11"
MetallicLevel="Core"
Capability="Core Support"
Capability="Core"
WebAPIReference="2.5.2"
OutputFile="REQ-WA103-RC11_501NotImplemented.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_501NotImplemented*"
AssertResponseCode="501"
/>
</Requests>

View File

@ -7,47 +7,145 @@ Feature: Web API Server 1.0.2 Certification
And Client Settings and Parameters were read from the file
And an OData client was successfully created from the given RESOScript
@REQ-WA103-END3 @core @x.y.z @core-support-endorsement
Scenario: REQ-WA103-END3 - CORE - Request and Validate Server Metadata
When a GET request is made to the resolved Url in "REQ-WA103-END3"
@REQ-WA103-END3 @core @x.y.z @core-endorsement
Scenario: Request and Validate Server Metadata
When a GET request is made to the resolved Url in "REQ-WA103-END3.metadata"
Then the server responds with a status code of 200
And the response is valid XML
And the metadata returned is valid
@REQ-WA103-END2 @core @x.y.z @core-support-endorsement
Scenario: REQ-WA103-END2 - CORE - Data System Endpoint test
When a GET request is made to the resolved Url in "REQ-WA103-END2"
@REQ-WA103-END2 @core @x.y.z @core-endorsement
Scenario: Data System Endpoint test
When a GET request is made to the resolved Url in "REQ-WA103-END2.datasystem"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And the results match the expected DataSystem JSON schema
@REQ-WA103-QR1 @core @2.4.1 @query-functions-endorsement
Scenario: REQ-WA103-QR1 - CORE - Search Parameters: Search by UniqueID
When a GET request is made to the resolved Url in "REQ-WA103-QR1"
Scenario: Search Parameters: Select UniqueID
When a GET request is made to the resolved Url in "REQ-WA103-QR1.select.uniqueId"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has singleton results in the "Parameter_UniqueID" field
And the provided "Parameter_UniqueIDValue" is returned in the "Parameter_UniqueID" field
@REQ-WA103-QR3 @core @2.4.2 @query-functions-endorsement
Scenario: REQ-WA103-QR3 - CORE - Query Support: $select
When a GET request is made to the resolved Url in "REQ-WA103-QR3"
Scenario: Query Support: $select
When a GET request is made to the resolved Url in "REQ-WA103-QR3.select"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And data are present in fields contained within "Parameter_SelectList"
@REQ-WA103-QR4 @core @2.4.2 @client-paging-endorsement
Scenario: REQ-WA103-QR4 - CORE - Query Support: $top
When a GET request is made to the resolved Url in "REQ-WA103-QR4"
Scenario: Query Support: $top
When a GET request is made to the resolved Url in "REQ-WA103-QR4.top"
Then the server responds with a status code of 200
And the response is valid JSON
And the results contain at most "Parameter_TopCount" records
And the response has results
And the number of results is less than or equal to "Parameter_TopCount"
@REQ-WA103-QR5 @core @2.4.2 @query-support
Scenario: REQ-WA103-QR5 - CORE - Query Support: $skip
When a GET request is made to the resolved Url in "REQ-WA103-QR5"
@REQ-WA103-QR5 @core @2.4.2 @query-support-endorsement
Scenario: Query Support: $skip
When a GET request is made to the resolved Url in "REQ-WA103-QR5.skip"
Then the server responds with a status code of 200
And the response is valid JSON
And a GET request is made to the resolved Url in "REQ-WA103-QR5" with $skip="Parameter_TopCount"
And the response has results
And a GET request is made to the resolved Url in "REQ-WA103-QR5.skip" with $skip="Parameter_TopCount"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And data in the "Parameter_UniqueId" fields are different in the second request than in the first
@REQ-WA103-QO1 @REQ-WA103-QO1.select @core @2.4.4 @core-endorsement @OData-4.0
Scenario: Query Support: $select case-sensitivity for OData 4.0
When a GET request is made to the resolved Url in "REQ-WA103-QO1.select.case"
Then the server responds with a status code of 400 if the server headers report OData version "4.0"
@REQ-WA103-QO1 @REQ-WA103-QO1.filter @core @2.4.4 @core-endorsement @OData-4.0
Scenario: Query Support: $filter case-sensitivity for OData 4.0
When a GET request is made to the resolved Url in "REQ-WA103-QO1.filter.case"
Then the server responds with a status code of 400 if the server headers report OData version "4.0"
@REQ-WA103-QO1 @REQ-WA103-QO1.orderby.asc.case @core @2.4.4 @core-endorsement @OData-4.0
Scenario: Query Support: $orderby asc case-sensitivity for OData 4.0
When a GET request is made to the resolved Url in "REQ-WA103-QO1.orderby.asc.case"
Then the server responds with a status code of 400 if the server headers report OData version "4.0"
@REQ-WA103-QO1 @REQ-WA103-QO1.orderby.desc.case @core @2.4.4 @core-endorsement @OData-4.0
Scenario: Query Support: $orderby desc case-sensitivity for OData 4.0
When a GET request is made to the resolved Url in "REQ-WA103-QO1.orderby.desc.case"
Then the server responds with a status code of 400 if the server headers report OData version "4.0"
@REQ-WA103-QO2 @core @2.4.4 @filterability-endorsement
Scenario: Query Support: $filter - Integer Comparison: eq
When a GET request is made to the resolved Url in "REQ-WA103-QO2.filter.int.compare.eq"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And Integer data in "Parameter_FilterIntegerField" "eq" "Parameter_FilterIntegerValueLow"
@REQ-WA103-QO3 @core @2.4.4 @filterability-endorsement
Scenario: Query Support: $filter - Integer Comparison: ne
When a GET request is made to the resolved Url in "REQ-WA103-QO3.filter.int.compare.ne"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And Integer data in "Parameter_FilterIntegerField" "ne" "Parameter_FilterIntegerValueLow"
@REQ-WA103-QO4 @core @2.4.4 @filterability-endorsement
Scenario: Query Support: $filter - Integer Comparison: gt
When a GET request is made to the resolved Url in "REQ-WA103-QO4.filter.int.compare.gt"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And Integer data in "Parameter_FilterIntegerField" "gt" "Parameter_FilterIntegerValueLow"
@REQ-WA103-QO5 @core @2.4.4 @filterability-endorsement
Scenario: Query Support: $filter - Integer Comparison: ge
When a GET request is made to the resolved Url in "REQ-WA103-QO5.filter.int.compare.ge"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And Integer data in "Parameter_FilterIntegerField" "ge" "Parameter_FilterIntegerValueLow"
@REQ-WA103-QO6 @core @2.4.4 @filterability-endorsement
Scenario: Query Support: $filter - Integer Comparison: lt
When a GET request is made to the resolved Url in "REQ-WA103-QO6.filter.int.compare.lt"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And Integer data in "Parameter_FilterIntegerField" "lt" "Parameter_FilterIntegerValueLow"
@REQ-WA103-QO7 @core @2.4.4 @filterability-endorsement
Scenario: Query Support: $filter - Integer Comparison: le
When a GET request is made to the resolved Url in "REQ-WA103-QO7.filter.int.compare.le"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And Integer data in "Parameter_FilterIntegerField" "le" "Parameter_FilterIntegerValueLow"
@REQ-WA103-QO9 @core @2.4.4 @filterability-endorsement
Scenario: Query Support: $filter - Integer Comparison: and
When a GET request is made to the resolved Url in "REQ-WA103-QO9.filter.int.compare.and"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And Integer data in "Parameter_FilterIntegerField" "gt" "Parameter_FilterIntegerValueLow" "and" "lt" "Parameter_FilterIntegerValueHigh"
@REQ-WA103-QO10 @core @2.4.4 @filterability-endorsement
Scenario: Query Support: $filter - Integer Comparison: or
When a GET request is made to the resolved Url in "REQ-WA103-QO10.filter.int.compare.or"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And Integer data in "Parameter_FilterIntegerField" "gt" "Parameter_FilterIntegerValueLow" "or" "lt" "Parameter_FilterIntegerValueHigh"
@REQ-WA103-QO11 @core @2.4.4 @filterability-endorsement
Scenario: Query Support: $filter - Integer Comparison: not() (operator)
When a GET request is made to the resolved Url in "REQ-WA103-QO11.filter.int.compare.not.operator"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And Integer data in "Parameter_FilterNotField" "ne" "Parameter_FilterNotValue"

View File

@ -1,13 +1,14 @@
package org.reso.certification.stepdefs;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.cucumber.java8.En;
import io.restassured.response.Response;
import io.restassured.response.ValidatableResponse;
import io.restassured.specification.RequestSpecification;
import org.apache.http.Header;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.olingo.client.api.communication.ODataClientErrorException;
import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
import org.apache.olingo.client.api.communication.response.ODataRawResponse;
import org.apache.olingo.client.api.edm.xml.XMLMetadata;
@ -23,8 +24,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import static io.restassured.path.json.JsonPath.from;
import static org.junit.Assert.*;
@ -40,23 +43,83 @@ public class WebAPIServer_1_0_2 implements En {
private String serviceRoot, bearerToken, clientId, clientSecret, authorizationUri, tokenUri, redirectUri, scope;
private String pathToRESOScript;
private static final String JSON_VALUE_PATH = "value";
//container to hold retrieved metadata for later comparisons
private static AtomicReference<XMLMetadata> xmlMetadata = new AtomicReference<>();
public WebAPIServer_1_0_2() {
//TODO: split into separate test files and parallelize to remove the need for Atomic "globals"
AtomicReference<Commander> commander = new AtomicReference<>();
AtomicReference<ODataRawResponse> oDataRawResponse = new AtomicReference<>();
AtomicReference<Request> request = new AtomicReference<>();
AtomicReference<Integer> responseCode = new AtomicReference<>();
AtomicReference<String> responseData = new AtomicReference<>();
AtomicReference<String> initialResponseData = new AtomicReference<>(); //used if two result sets need to be compared
AtomicReference<ODataRawRequest> rawRequest = new AtomicReference<>();
//container to hold retrieved metadata for later comparisons
AtomicReference<XMLMetadata> xmlMetadata = new AtomicReference<>();
AtomicReference<ODataClientErrorException> oDataClientErrorException = new AtomicReference<>();
AtomicReference<Boolean> oDataClientErrorExceptionHandled = new AtomicReference<>();
AtomicReference<String> serverODataHeaderVersion = new AtomicReference<>();
AtomicReference<Boolean> testAppliesToServerODataHeaderVersion = new AtomicReference<>();
final String HEADER_ODATA_VERSION = "OData-Version";
/*
* Instance Utility Methods - must precede usage
*/
/*
* Resets the local instance state used during test time. TODO: refactor into collection of AtomicReference<T>
*/
Runnable resetState = () -> {
commander.set(null);
oDataRawResponse.set(null);
request.set(null);
responseCode.set(null);
responseData.set(null);
initialResponseData.set(null);
rawRequest.set(null);
oDataClientErrorException.set(null);
serverODataHeaderVersion.set(null);
oDataClientErrorExceptionHandled.set(false);
testAppliesToServerODataHeaderVersion.set(false);
};
/*
* Executes HTTP GET request and sets the expected local variables.
* Handles exceptions and sets response codes.
*/
Function<URI, Void> executeGetRequest = (URI requestUri) -> {
LOG.info("Request URI: " + requestUri);
try {
rawRequest.set(commander.get().getClient().getRetrieveRequestFactory().getRawRequest(requestUri));
oDataRawResponse.set(rawRequest.get().execute());
responseData.set(convertInputStreamToString(oDataRawResponse.get().getRawResponse()));
serverODataHeaderVersion.set(oDataRawResponse.get().getHeader(HEADER_ODATA_VERSION).toString());
LOG.info("Request succeeded..." + responseData.get().getBytes().length + " bytes received.");
} catch (ODataClientErrorException cex) {
LOG.debug("OData Client Error Exception caught. Check subsequent test output for asserted conditions...");
oDataClientErrorException.set(cex);
serverODataHeaderVersion.set(Utils.getHeaderData(HEADER_ODATA_VERSION, cex.getHeaderInfo()));
responseCode.set(cex.getStatusLine().getStatusCode());
oDataClientErrorExceptionHandled.set(true);
}
return null;
};
/*
* Background
*/
Given("^a RESOScript file was provided$", () -> {
/* NOTE: this item is the first step in the Background */
//Reset ALL local state variables prior to each run.
resetState.run();
if (pathToRESOScript == null) {
pathToRESOScript = System.getProperty("pathToRESOScript");
}
@ -156,7 +219,7 @@ public class WebAPIServer_1_0_2 implements En {
AtomicInteger numResults = new AtomicInteger();
//iterate over the items and count the number of fields with data to determine whether there are data present
from(responseData.get()).getList("value", HashMap.class).forEach(item -> {
from(responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
if (item != null) {
numResults.getAndIncrement();
fieldList.forEach(field -> {
@ -180,7 +243,7 @@ public class WebAPIServer_1_0_2 implements En {
* $top=*Parameter_TopCount*
*/
And("^the results contain at most \"([^\"]*)\" records$", (String parameterTopCount) -> {
List<String> items = from(responseData.get()).getList("value");
List<String> items = from(responseData.get()).getList(JSON_VALUE_PATH);
AtomicInteger numResults = new AtomicInteger(items.size());
int topCount = Integer.parseInt(Utils.resolveValue(parameterTopCount, settings));
@ -204,19 +267,18 @@ public class WebAPIServer_1_0_2 implements En {
//TODO: convert to OData filter factory
URI requestUri = Commander.prepareURI(Settings.resolveParameters(settings.getRequests().get(requirementId), settings).getUrl() + "&$skip=" + skipCount);
LOG.info("Request URI: " + (requestUri != null ? requestUri.toString() : ""));
rawRequest.set(commander.get().getClient().getRetrieveRequestFactory().getRawRequest(requestUri));
oDataRawResponse.set(rawRequest.get().execute());
responseData.set(convertInputStreamToString(oDataRawResponse.get().getRawResponse()));
executeGetRequest.apply(requestUri);
});
And("^data in the \"([^\"]*)\" fields are different in the second request than in the first$", (String parameterUniqueId) -> {
ObjectMapper mapper = new ObjectMapper();
JsonNode n1 = mapper.readTree(initialResponseData.get());
JsonNode n2 = mapper.readTree(responseData.get());
List<Object> l1 = from(initialResponseData.get()).getList(JSON_VALUE_PATH);
List<Object> l2 = from(responseData.get()).getList(JSON_VALUE_PATH);
assertFalse(n1.equals(n2));
assertFalse(l1.containsAll(l2));
});
//==================================================================================================================
// Common Methods
//==================================================================================================================
@ -226,51 +288,19 @@ public class WebAPIServer_1_0_2 implements En {
*/
When("^a GET request is made to the resolved Url in \"([^\"]*)\"$", (String requirementId) -> {
URI requestUri = Commander.prepareURI(Settings.resolveParameters(settings.getRequests().get(requirementId), settings).getUrl());
LOG.info("Request URI: " + requestUri);
rawRequest.set(commander.get().getClient().getRetrieveRequestFactory().getRawRequest(requestUri));
oDataRawResponse.set(rawRequest.get().execute());
responseData.set(convertInputStreamToString(oDataRawResponse.get().getRawResponse()));
LOG.info("Request succeeded..." + responseData.get().getBytes().length + " bytes received.");
});
/*
* GET request by requirementId with an additional Uri fragment for the base Uri
*/
When("^a GET request is made to the resolved Url in \"([^\"]*)\" with \"([^\"]*)\"$", (String requirementId, String parameterTopCount) -> {
request.set(Settings.resolveParameters(settings.getRequests().get(requirementId), settings));
LOG.info("Request URL: " + request.get().getUrl());
rawRequest.set(commander.get().getClient().getRetrieveRequestFactory().getRawRequest(Commander.prepareURI(request.get().getUrl())));
oDataRawResponse.set(rawRequest.get().execute());
responseData.set(convertInputStreamToString(oDataRawResponse.get().getRawResponse()));
LOG.info("Request succeeded..." + responseData.get().getBytes().length + " bytes received.");
executeGetRequest.apply(requestUri);
});
/*
* Assert response code
*/
Then("^the server responds with a status code of (\\d+)$", (Integer code) -> {
int responseCode = oDataRawResponse.get().getStatusCode();
LOG.info("Response code is: " + responseCode);
assertEquals(code.intValue(), responseCode);
});
Then("^the server responds with a status code of (\\d+)$", (Integer assertedResponseCode) -> {
responseCode.set(oDataClientErrorException.get() != null
? oDataClientErrorException.get().getStatusLine().getStatusCode()
: oDataRawResponse.get().getStatusCode());
/*
* Assert greater than: lValFromItem > rValFromSetting
*
* TODO: add general op expression parameter rather than creating individual comparators
*/
And("^data in \"([^\"]*)\" are greater than \"([^\"]*)\"$", (String lValFromItem, String rValFromSetting) -> {
from(responseData.get()).getList("value", HashMap.class).forEach(item -> {
Integer lVal = new Integer(item.get(Utils.resolveValue(lValFromItem, settings)).toString()),
rVal = new Integer(Utils.resolveValue(rValFromSetting, settings));
assertTrue( lVal > rVal );
});
LOG.info("Asserted Response Code: " + assertedResponseCode + ", " + "Server Response Code: " + responseCode);
assertEquals(responseCode.get().intValue(), assertedResponseCode.intValue());
});
/*
@ -291,12 +321,183 @@ public class WebAPIServer_1_0_2 implements En {
LOG.info("Response is valid JSON!");
});
/*
* Assert OData version
*/
And("^the server reports OData version \"([^\"]*)\"$", (String assertODataVersion) -> {
LOG.info("Asserted version: " + assertODataVersion + ", Reported OData Version: " + serverODataHeaderVersion.get()); ;
assertEquals(serverODataHeaderVersion.get(), assertODataVersion);
});
/*
* Assert HTTP Response Code given asserted OData version
*
* TODO: make a general Header assertion function
*/
Then("^the server responds with a status code of (\\d+) if the server headers report OData version \"([^\"]*)\"$",
(Integer assertedHttpResponseCode, String assertedODataVersion) -> {
boolean versionsMatch = responseCode.get().intValue() == assertedHttpResponseCode.intValue(),
responseCodesMatch = serverODataHeaderVersion.get().equals(assertedODataVersion);
if (versionsMatch) {
assertTrue(responseCodesMatch);
}
});
/*
* Compares field data (LHS) to a given parameter value (RHS). The operator is passed as a string,
* and is used to select among the supported comparisons.
*/
And("^Integer data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String parameterFieldName, String op, String parameterAssertedValue) -> {
LOG.info("Parameter_FieldName: " + parameterFieldName + ", op: " + op + ", Parameter_Value: " + parameterAssertedValue);
String fieldName = Utils.resolveValue(parameterFieldName, settings);
int assertedValue = Integer.parseInt(Utils.resolveValue(parameterAssertedValue, settings));
//subsequent value comparisons are and-ed together while iterating over the list of items, so init to true
AtomicBoolean result = new AtomicBoolean(true);
AtomicReference<Integer> fieldValue = new AtomicReference<>();
//iterate through response data and ensure that with data, the statement fieldName "op" assertValue is true
from(responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
fieldValue.set(Integer.parseInt(item.get(fieldName).toString()));
result.set(result.get() && Utils.compare(fieldValue.get(), op, assertedValue));
LOG.info("Compare: " + fieldValue.get() + " " + op + " " + assertedValue + " is " + result.get());
});
assertTrue(result.get());
});
/*
* True if response has results, meaning value.length > 0
*/
And("^the response has results$", () -> {
int count = from(responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).size();
LOG.info("Results count is: " + count);
assertTrue(count > 0);
});
/*
* True if data are present in the response
*/
And("^the response has singleton results in the \"([^\"]*)\" field$", (String parameterFieldName) -> {
String value = Utils.resolveValue(parameterFieldName, settings);
boolean isPresent = from(responseData.get()).get() != null && value != null;
LOG.info("Response value is: " + value);
LOG.info("IsPresent: " + isPresent);
assertTrue(isPresent);
});
/*
* True if results count less than or equal to limit
*/
And("^the number of results is less than or equal to \"([^\"]*)\"$", (String limitField) -> {
int count = from(responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).size(),
limit = Integer.parseInt(Utils.resolveValue(limitField, settings));
LOG.info("Results count is: " + count + ", Limit is: " + limit);
assertTrue(count <= limit);
});
/*
* True if data in the lhs expression and rhs expressions pass the AND or OR condition given in andOrOp
*/
And("^Integer data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String parameterFieldName, String opLhs, String parameterAssertedLhsValue, String andOrOp, String opRhs, String parameterAssertedRhsValue) -> {
String fieldName = Utils.resolveValue(parameterFieldName, settings);
Integer assertedLhsValue = Integer.parseInt(Utils.resolveValue(parameterAssertedLhsValue, settings)),
assertedRhsValue = Integer.parseInt(Utils.resolveValue(parameterAssertedRhsValue, settings));
String op = andOrOp.toLowerCase();
boolean isAndOp = op.contains(Operators.AND);
//these should default to true when And and false when Or for the purpose of boolean comparisons
AtomicBoolean lhsResult = new AtomicBoolean(isAndOp);
AtomicBoolean rhsResult = new AtomicBoolean(isAndOp);
AtomicBoolean itemResult = new AtomicBoolean(isAndOp);
AtomicReference<Integer> lhsValue = new AtomicReference<>(),
rhsValue = new AtomicReference<>();
//iterate through response data and ensure that with data, the statement fieldName "op" assertValue is true
from(responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
lhsValue.set(Integer.parseInt(item.get(fieldName).toString()));
rhsValue.set(Integer.parseInt(item.get(fieldName).toString()));
LOG.info("Checking LHS");
lhsResult.set(Utils.compare(lhsValue.get(), opLhs, assertedLhsValue));
LOG.info("Checking RHS");
rhsResult.set(Utils.compare(rhsValue.get(), opRhs, assertedRhsValue));
if (op.contentEquals(Operators.AND)) {
itemResult.set(lhsResult.get() && rhsResult.get());
LOG.info("assertTrue: " + lhsResult.get() + " AND " + rhsResult.get() + " ==> " + itemResult.get());
assertTrue(itemResult.get());
} else if (op.contentEquals(Operators.OR)) {
itemResult.set(lhsResult.get() || rhsResult.get());
LOG.info("assertTrue: " + lhsResult.get() + " OR " + rhsResult.get() + " ==> " + itemResult.get());
assertTrue(itemResult.get());
}
});
});
}
/**
* Contains the list of supported operators for use in query expressions.
*/
private static class Operators {
private static final String
AND = "and",
OR = "or",
NE = "ne",
EQ = "eq",
GREATER_THAN = "gt",
GREATER_THAN_OR_EQUAL = "ge",
LESS_THAN = "lt",
LESS_THAN_OR_EQUAL = "le";
}
private static class Utils {
/**
* Returns true if each item in the list is true
* @param lhs left hand value
* @param op a binary operator for use in comparsions
* @param rhs right hand value
* @return true if lhs op rhs produces true, false otherwise
*/
private static boolean compare(Integer lhs, String op, Integer rhs) {
boolean result = false;
switch (op) {
case Operators.EQ:
result = lhs.equals(rhs);
break;
case Operators.NE:
result = !lhs.equals(rhs);
break;
case Operators.GREATER_THAN:
result = lhs > rhs;
break;
case Operators.GREATER_THAN_OR_EQUAL:
result = lhs >= rhs;
break;
case Operators.LESS_THAN:
result = lhs < rhs;
break;
case Operators.LESS_THAN_OR_EQUAL:
result = lhs <= rhs;
break;
}
LOG.info("Compare: " + lhs + " " + op + " " + rhs + " ==> " + result);
return result;
}
/**
* Tests the given string to see if it's valid JSON
* @param jsonString
* @param jsonString the JSON string to test the validity of
* @return true if valid, false otherwise. Throws {@link IOException}
*/
private static boolean isValidJson(String jsonString) {
@ -334,16 +535,16 @@ public class WebAPIServer_1_0_2 implements En {
private static String getResponseData(ODataRawResponse oDataRawResponse) {
return convertInputStreamToString(oDataRawResponse.getRawResponse());
}
}
/**
* These are now passed dynamically but we may want to verify the choices. Leave in for now.
*/
private static class REQUESTS {
private static class WEB_API_1_0_2 {
private static final String REQ_WA_103_END_3 = "REQ-WA103-END3";
private static final String REQ_WA_103_QR_3 = "REQ-WA103-QR3";
private static final String REQ_WA103_END2 = "REQ-WA103-END2";
private static String getHeaderData(String key, Header[] headers) {
String data = null;
for(Header header : headers) {
if (header.getName().toLowerCase().contains(key.toLowerCase())) {
data = header.getValue();
}
}
return data;
}
}

View File

@ -170,12 +170,12 @@ public class App {
//TODO: create dynamic JUnit (or similar) test runner
LOG.info(SMALL_DIVIDER);
LOG.info("Assertion: #" + (i + 1));
LOG.info("Request: #" + (i + 1));
LOG.info(SMALL_DIVIDER);
LOG.info("Assertion Name: " + request.getName());
LOG.info("Request Name: " + request.getName());
//TODO: function-ize the property test
LOG.info("Assertion Description: " + (request.getTestDescription().length() > 0 ? request.getTestDescription() : "Not Specified"));
LOG.info("Description: " + (request.getTestDescription().length() > 0 ? request.getTestDescription() : "Not Specified"));
LOG.info("Requirement Id: " + (request.getRequirementId().length() > 0 ? request.getRequirementId() : "Not Specified"));
LOG.info("Metallic Level: " + (request.getMetallicLevel().length() > 0 ? request.getMetallicLevel() : "Not Specified"));
LOG.info("Capability: " + (request.getCapability().length() > 0 ? request.getCapability() : "Not Specified"));
@ -200,6 +200,8 @@ public class App {
if (responseCode == HttpStatus.SC_OK) {
STATS.updateRequest(request, Request.Status.SUCCEEDED);
} else {
STATS.updateRequest(request, Request.Status.FAILED);
}
if (request.getOutputFile().toLowerCase().contains(EDMX_EXTENSION.toLowerCase())) {
@ -210,16 +212,9 @@ public class App {
LOG.error("Error: Invalid metadata retrieved. Cannot continue!!");
System.exit(NOT_OK);
}
} else if (responseCode != null && request.getAssertResponseCode() != null) {
if (responseCode == Integer.parseInt(request.getAssertResponseCode())) {
LOG.info("Assert Response Code " + request.getAssertResponseCode() + " passed!");
} else {
LOG.error("Request " + request.getName() + " Failed!");
STATS.updateRequest(request, Request.Status.FAILED);
}
}
} else {
LOG.info("Request " + request.getRequirementId() + " has an empty URL. Skipping...");
STATS.updateRequest(request, Request.Status.SKIPPED);
}
} catch (Exception ex) {
@ -228,10 +223,6 @@ public class App {
LOG.error("Stack trace:");
Arrays.stream(ex.getStackTrace()).forEach(stackTraceElement -> LOG.error(stackTraceElement.toString()));
} finally {
if (request != null && STATS.getRequests().size() > 0) {
LOG.info("Request " + STATS.getRequests().get(request).getStatus().toString().toLowerCase() + "!");
}
if (resolvedUrl != null && resolvedUrl.length() > 0) {
LOG.info("Elapsed Time: " + String.format("%.2f", (STATS.getRequests().get(request).getElapsedTimeMillis() / 1000.0)) + "s");
}
@ -443,7 +434,7 @@ public class App {
numIncomplete = stats.getRequestCount(Request.Status.STARTED);
reportBuilder.append("\n\n" + DIVIDER);
reportBuilder.append("\nAssertion Statistics");
reportBuilder.append("\nRequest Statistics");
reportBuilder.append("\n" + DIVIDER);
reportBuilder.append(generateTotalsReport(stats.totalRequestCount(), numSucceeded, numFailed, numSkipped, numIncomplete));
@ -462,7 +453,7 @@ public class App {
numSkipped = stats.filterByMetallicCertification(metallicKey, stats.filterByStatus(Request.Status.SKIPPED)).size();
numIncomplete = stats.filterByMetallicCertification(metallicKey, stats.filterByStatus(Request.Status.STARTED)).size();
reportBuilder.append("\n\n").append(metallicKey).append(numSucceeded > 0 && numSucceeded == (requestCount - numSkipped) ? " - REQUESTS SUCCEEDED!" : "");
reportBuilder.append("\n\n").append(metallicKey).append(numSucceeded > 0 && numSucceeded == (requestCount - numSkipped) ? " - ALL REQUESTS SUCCEEDED!" : "");
reportBuilder.append(generateTotalsReport(requestCount, numSucceeded, numFailed, numSkipped, numIncomplete));
}
@ -477,7 +468,7 @@ public class App {
numSkipped = stats.filterByCapability(capabilityKey, stats.filterByStatus(Request.Status.SKIPPED)).size();
numIncomplete = stats.filterByCapability(capabilityKey, stats.filterByStatus(Request.Status.STARTED)).size();
reportBuilder.append("\n\n").append(capabilityKey).append(numSucceeded > 0 && numSucceeded == (requestCount - numSkipped) ? " - REQUESTS SUCCEEDED!" : "");
reportBuilder.append("\n\n").append(capabilityKey).append(numSucceeded > 0 && numSucceeded == (requestCount - numSkipped) ? " - ALL REQUESTS SUCCEEDED!" : "");
reportBuilder.append(generateTotalsReport(requestCount, numSucceeded, numFailed, numSkipped, numIncomplete));
}
reportBuilder.append("\n" + DIVIDER + "\n");

View File

@ -24,7 +24,6 @@ public class Request {
private String metallicLevel;
private String capability;
private String webApiReference;
private String assertResponseCode;
private Request request;
private Status status;
@ -41,7 +40,7 @@ public class Request {
* @param url
*/
public Request(String requirementId, String outputFile, String url, String testDescription, String metallicLevel,
String capability, String webApiReference, String assertResponseCode) {
String capability, String webApiReference) {
//TODO: add Builder
setRequirementId(requirementId);
@ -51,7 +50,6 @@ public class Request {
setMetallicLevel(metallicLevel);
setCapability(capability);
setWebApiReference(webApiReference);
setAssertResponseCode(assertResponseCode);
}
@ -123,8 +121,7 @@ public class Request {
String expression = "/OutputScript/" + REQUESTS_KEY + "/node()";
NodeList nodes = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
Node node;
String name, outputFile, url, testDescription, requirementId, metallicLevel, capability, webApiReference,
assertResponseCode;
String name, outputFile, url, testDescription, requirementId, metallicLevel, capability, webApiReference;
Request request;
for (int i = 0; i < nodes.getLength(); i++) {
@ -138,9 +135,8 @@ public class Request {
metallicLevel = safeGetNamedItem(FIELDS.METALLIC_LEVEL, node);
capability = safeGetNamedItem(FIELDS.CAPABILITY, node);
webApiReference = safeGetNamedItem(FIELDS.WEB_API_REFERENCE, node);
assertResponseCode = safeGetNamedItem(FIELDS.ASSERT_RESPONSE_CODE, node);
request = new Request(requirementId, outputFile, url, testDescription, metallicLevel, capability, webApiReference, assertResponseCode);
request = new Request(requirementId, outputFile, url, testDescription, metallicLevel, capability, webApiReference);
name = safeGetNamedItem(FIELDS.NAME, node);
request.setName(name == null ? outputFile : name);
@ -249,14 +245,6 @@ public class Request {
this.webApiReference = webApiReference;
}
public String getAssertResponseCode() {
return assertResponseCode;
}
public void setAssertResponseCode(String assertResponseCode) {
this.assertResponseCode = assertResponseCode;
}
private static final class FIELDS {
static final String NAME = "Name";
static final String OUTPUT_FILE = "OutputFile";
@ -266,6 +254,5 @@ public class Request {
static final String METALLIC_LEVEL = "MetallicLevel";
static final String CAPABILITY = "Capability";
static final String WEB_API_REFERENCE = "WebAPIReference";
static final String ASSERT_RESPONSE_CODE = "AssertResponseCode";
}
}

View File

@ -59,7 +59,7 @@ public class Settings {
public static Request resolveParameters(Request request, Settings settings) {
//calls to resolve nested parameters
return new Request(request.getRequirementId(), request.getOutputFile(), resolveParametersString(request.getUrl(), settings), request.getTestDescription(),
request.getMetallicLevel(), request.getCapability(), request.getWebApiReference(), request.getAssertResponseCode());
request.getMetallicLevel(), request.getCapability(), request.getWebApiReference());
}
/**

View File

@ -6,8 +6,7 @@ package org.reso.commander;
import org.junit.Test;
public class AppTest {
@Test public void testAppHasAGreeting() {
App classUnderTest = new App();
//assertNotNull("app should have a greeting", classUnderTest.getGreeting());
@Test public void testParameterDeserialization() {
//TODO
}
}