There are many testing tools available that support testing REST APIs. On this page two approaches to testing are demonstrated by testing the PingPong API.

Testing Ping Pong APU with Metaswitch Scenario Simulator

The Scenario Simulator is a testing tool which simulates network traffic — for testing network elements and services. You define your test cases with scenario definition files, which describe the message flows between network elements. The scenario simulator can play one or more roles when you run the scenario.

Note The REST API Framework Demonstration uses the scenario simulator.

The following scenario file describes a call-flow where the client sends a Ping (api=SS-ClientApiToTest, scenario=SS-ClientApiTestScenarioToRun) request to a server. The expected response is a 200 OK, with a response body of Pong!.

scenario sim file
ping-request  [description "Triggers the example service with a pingpong api POST rest request."]  (FORMAT 1.0) {
   (ROLES) {
    RESTCLIENT  [description "client to the unified rest ra"] ;
    UNIFIEDREST  [description "rhino with a unified rest ra installed and activated"] ;
  }
   (DIALOGS) {
    RESTCLIENT-UNIFIEDREST  [description "rest/http interactions"]  (ROLE_A RESTCLIENT, ROLE_B UNIFIEDREST, SCHEMA http, VERSION 1.0c) {
      applicationContext "HTTP/1.1";
    }
  }
   (TABLES) ;
  POST  (DIALOG RESTCLIENT-UNIFIEDREST, DIRECTION A_TO_B) {
    Request-URI {
      Encoded "/pingpong/ping";
    }
    headers {
      Content-Length  (AUTO) ;
      Content-Type "application/json";
      Host "localhost:8000";
    }
    Message-Body {
      application_json_UTF-8 {
        Object {
          Name-Value {
            Name "api";
            Value {
              Primitive {
                String "SS-ClientApiToTest";
              }
            }
          }
          Name-Value {
            Name "scenario";
            Value {
              Primitive {
                String "SS-ClientApiTestScenarioToRun";
              }
            }
          }
        }
      }
    }
  }
  200  (DIALOG RESTCLIENT-UNIFIEDREST, DIRECTION B_TO_A) {
    headers {
      Content-Length  (AUTO) ;
      Date  (AUTO) ;
    }
    Message-Body {
      text_plain_UTF-8 "Pong!";
    }
  }
}
Tip View the scenario file with the Scenario Editor.

The scenario simulator can be used interactively to run scenarios.

running the scenario sim
~/work/unified-rest-ra-sdk/sim$ ~/scenario-sim/scenario-simulator.sh -f setup-restclient.commands 1
Starting JVM...
Processing commands from file at setup-restclient.commands
Processing command: set-endpoint-address rest-client-http-endpoint localhost:8181
Processing command: create-local-endpoint rest-client-http-endpoint http -propsfile setup-restclient.properties
Initializing local endpoint "rest-client-http-endpoint" ...
Local endpoint initialized.
Processing command: bind-role RESTCLIENT rest-client-http-endpoint
Processing command: set-endpoint-address unified-rest-http-endpoint localhost:8000
Processing command: bind-role UNIFIEDREST unified-rest-http-endpoint
Finished reading commands from file
Ready to start

Please type commands... (type "help" <ENTER> for command help)
> load-scenario ping-request.scen 2
Playing role "RESTCLIENT" in initiating scenario "ping-request" with dialogs [RESTCLIENT-UNIFIEDREST]
> run-session ping-request 3
Send -->  POST to unified-rest-http-endpoint
Recv <--  200 OK from unified-rest-http-endpoint
Outcome of "ping-request" session: Matched scenario definition "ping-request"
>
  1. Start the scenario simulator. The argument is a file of commands to run on startup that defines all the roles involved in the scenario.

  2. Load a scenario to run

  3. Run the scenario and observe the results. The scenario simaulor plays the role of the client and sends a POST request to the server (the example-rest-ra in Rhino). The server (the service running in Rhino) sends a 200 OK response. This response matches the expected response in this scenario, so the test passes.

Tip
The scenario sim setup commands file used in this test
set-endpoint-address rest-client-http-endpoint localhost:8181 1
create-local-endpoint rest-client-http-endpoint http -propsfile setup-restclient.properties
bind-role RESTCLIENT rest-client-http-endpoint 2

set-endpoint-address unified-rest-http-endpoint localhost:8000 3
bind-role UNIFIEDREST unified-rest-http-endpoint 4
  1. The endpoint of the client

  2. The ROLE in the scenario that corresponds to the client (the simulator will play this role)

  3. The endpoint of the server

  4. The ROLE in the scenario that corresponds to the server (the example-rest-ra in Rhino)

Here is a snippet of the Rhino logs showing what happened on the server.

rhino logs
[example_rest_ra.controller] incomingHttpRequest: id=HttpRequestId[incoming,6,3], request=FullHttpRequest[POST http://localhost:8000/pingpong/ping] 1

[example_rest_ra.controller] Select an API suitable for: '/pingpong/ping' 2
[example_rest_ra] startActivity: HttpActivity[nodeID=101,requestId=HttpRequestId[incoming,6,3]]

[example_rest_ra] selectApiRestRATypeProvider('/pingpong') = 'PingpongApiServerPluginRATypeProvider@6a3877a1' 3

[example_rest_ra] fireEvent: ah=HttpActivity[nodeID=101,requestId=HttpRequestId[incoming,6,3]], eventID=EventTypeID[name=PingRequest,vendor=ExampleCo,version=1.0], event=PingRequest[pingContext=PingContext { api: SS-ClientApiToTest, scenario: SS-ClientApiTestScenarioToRun }], address=null, flags=96 4

[example-rest-api-sbb] sbbCreate 5
[example-rest-api-sbb] sbbPostCreate
[example-pingpong-api-sbbpart] SBB part created

[example-pingpong-api-sbbpart] Received: PingRequest[pingContext=PingContext { api: SS-ClientApiToTest, scenario: SS-ClientApiTestScenarioToRun }] 6
[example-pingpong-api-sbbpart] Ping! PingRequest[pingContext=PingContext { api: SS-ClientApiToTest, scenario: SS-ClientApiTestScenarioToRun }]

[example-rest-api-sbb] Triggering: api=SS-ClientApiToTest, scenario=SS-ClientApiTestScenarioToRun 7

[example_rest_ra] sendResponse: Event: SEND_REST_RESPONSE, Type: REST_Response, API: PINGPONG, Operation: Ping, Content: 8
[example-rest-api-sbb] sbbStore

[example_rest_ra] eventProcessingSuccessful: ah=HttpActivity[nodeID=101,requestId=HttpRequestId[incoming,6,3]], eventID=EventTypeID[name=PingRequest,vendor=ExampleCo,version=1.0], event=PingRequest[pingContext=PingContext { api: SS-ClientApiToTest, scenario: SS-ClientApiTestScenarioToRun }], address=null, flags=256 9

[example-rest-api-sbb] sbbRemove 10
  1. The example-rest-ra receives the POST REST request

  2. The example-rest-ra determines which API should process this new request

  3. …​ It is the PingpongApiServerPluginRATypeProvider

  4. The example-rest-ra creates, and fires an event to Rhino for processing by a service

  5. example-rest-api-sbb (the root sbb of the example service) and example-pingpong-api-sbbpart are instantiated

  6. The example-pingpong-api-sbbpart instance receives the PingRequest event.

  7. …​ and triggers the example-rest-api-sbb, which logs some details about the Ping request.

  8. The example-pingpong-api-sbbpart sends a 200 OK response

  9. Rhino notifies the example-rest-ra that the PingRequest event has been processed by a service.

  10. Rhino cleans up the example-rest-api-sbb instance

Testing Ping Pong API the with Swagger Inspector

In the following screenshot, Swagger Inspector is used to trigger the example service running in Rhino. In this case, the Swagger Inspector is playing the role of the client.

pingpong swagger inspector
Using swagger inspector

Here is a snippet of the Rhino logs showing what happened on the server.

rhino logs
[example-rest-api-sbb] sbbCreate 1
[example-rest-api-sbb] sbbPostCreate
[example-pingpong-api-sbbpart] SBB part created
[example-pingpong-api-sbbpart] Received: PingRequest[pingContext=PingContext { api: ClientApiToTest, scenario: ClientApiScenario }] 2
[example-pingpong-api-sbbpart] Ping! PingRequest[pingContext=PingContext { api: ClientApiToTest, scenario: ClientApiScenario }]
[example-rest-api-sbb] Triggering: api=ClientApiToTest, scenario=ClientApiScenario 3
[example-rest-api-sbb] sbbStore
[example-rest-api-sbb] sbbRemove 4
  1. example-rest-api-sbb (the root sbb of the example service) and example-pingpong-api-sbbpart are instantiated

  2. The example-pingpong-api-sbbpart instance receives the PingRequest event.

  3. …​ and triggers the example-rest-api-sbb, which logs some details about the Ping request.

  4. Rhino cleans up the example-rest-api-sbb instance

Testing Pet Store API with the Swagger Inspector

In the following screenshot, Swagger Inspector is used to trigger the example service running in Rhino. In this case, the Swagger Inspector is playing the role of the client.

petstore list pets 1
Listing the Pets in the Pet Store
petstore create pet
Add a new Pet to the Store
rhino logs - listing the pets in the store
 [trace.example-rest-api-sbb] sbbCreate
 [trace.example-rest-api-sbb] sbbPostCreate
 [trace.example-petstore-api-sbbpart] SBB part created
 [trace.example-pingpong-api-sbbpart] SBB part created
 [trace.example-petstore-api-sbbpart] Received: CreatePetRequest[pet=Pet { id: 10, name: Ploppy }]
 [trace.example-petstore-api-sbbpart] Added pet: Pet { id: 10, name: Ploppy }
 [trace.example-rest-api-sbb] sbbStore
 [trace.example-rest-api-sbb] sbbRemove
petstore list pets 2
Listing the updated Pets in the Pet Store
rhino logs - listing the pets in the store
[trace.example-rest-api-sbb] sbbCreate
[trace.example-rest-api-sbb] sbbPostCreate
[trace.example-petstore-api-sbbpart] SBB part created
[trace.example-pingpong-api-sbbpart] SBB part created
[trace.example-petstore-api-sbbpart] Received: ListPetsRequest[]
[trace.example-petstore-api-sbbpart] Listing Pets: [Pet { id: 1, name: Stripey }, Pet { id: 2, name: Splodge }, Pet { id: 3, name: Simba }, Pet { id: 10, name: Ploppy }]
[trace.example-rest-api-sbb] sbbStore
[trace.example-rest-api-sbb] sbbRemove
petstore list unknown pet
Find an unknown Pet in the Store
rhino logs - listing the pets in the store
[trace.example-rest-api-sbb] sbbCreate
[trace.example-rest-api-sbb] sbbPostCreate
[trace.example-petstore-api-sbbpart] SBB part created
[trace.example-pingpong-api-sbbpart] SBB part created
[trace.example-petstore-api-sbbpart] Received: ShowPetByIdRequest[petId=5]
[trace.example-petstore-api-sbbpart] Show pet with id: 5 = null
[trace.example-rest-api-sbb] sbbStore
[trace.example-rest-api-sbb] sbbRemove
petstore list pet 10
Find a Pet in the Store
rhino logs - listing the pets in the store
[trace.example-rest-api-sbb] sbbCreate
[trace.example-rest-api-sbb] sbbPostCreate
[trace.example-petstore-api-sbbpart] SBB part created
[trace.example-pingpong-api-sbbpart] SBB part created
[trace.example-petstore-api-sbbpart] Received: ShowPetByIdRequest[petId=10]
[trace.example-rest-api-sbb] sbbStore
[trace.example-rest-api-sbb] sbbRemove
Previous page Next page