732e938da1f972b387708ed23c9794c1a73dd60c
[anna.git] / example / diameter / launcher / resources / HELP.md
1 # OVERVIEW
2
3 The ADML (*ANNA Diameter MultiHost Launcher*) process is a multi-host node with client and server capabilities as well as balancer (proxy) features. It could be used as diameter server (i.e. to simulate PCRF nodes, OCS systems, etc.), as diameter client (GGSNs, DPIs, etc.), and balancer systems to provide failover to external round-robin launchers. Also, auxiliary encoder/decoder/loader function could be deployed to reinterpret certain external flow and send it to another process.
4
5 The *ANNA::diameter_comm* built-in module provides a great set of characteristics as multiple connections on both server and client side, definition for multiple-server entities (and not only two as standard establish as minimum), separate statistics analyzer per each resource, automatic CER/CEA and DWR/DWA generation, expiration control and many more features.
6
7 The ADML process can easily configure a many origin-host nodes as needed, which will have own endpoints. You should avoid loop configurations (client and server for that client) because automatic forwarding, is implemented and this would get in a never ending cycle when a request is sent.
8
9 Process traces are dump on \"launcher.trace\" and could have any trace level (POSIX levels), usually 'debug' or 'warning'. See ANNA documentation for more details.
10
11 As any other ANNA process, context dump could be retrieved sending SIGUSR1 signal:
12    kill -10 <pid>
13     or
14    kill -s SIGUSR1 <pid>
15     and then
16    vi /var/tmp/anna.context.<pid>
17
18 A complete xml report will show all the context information (counters, alarms, statistics, handlers, diameter stacks, etc.), and a powerful log module could dump all the events processed and flow information. Statistics could be analized at context dump and optionally written to disk as sample files (useful for graphs and spreadsheet reports) with all the measurements.
19
20 Also SIGUSR2 is handled for management purposes. We will talk later about this.
21
22
23 COMMAND LINE
24 ============
25
26 Start the launcher process without arguments in order to see all the startup configuration posibilities, many of which could be modified on the air through the management interface (we will talk later about this great feature). There is only one mandatory parameter which is the services definition: --services <services xml file>. You must follow the dtd schema to build a valid services xml file. Some basic examples are:
27
28 Client configuration:
29
30 > <services>
31 >   <!-- Stacks -->
32 >   <stack id=\"0\" dictionary=\"dictionary.xml\"/>
33 >
34 >   <!-- Nodes -->
35 >   <node originHost=\"ADML-client\" applicationId=\"0\" entity=\"localhost:3868\"/>
36 > </services>
37
38 Server configuration:
39
40 > <services>
41 >   <!-- Stacks -->
42 >   <stack id=\"0\" dictionary=\"dictionary.xml\"/>
43 >
44 >   <!-- Nodes -->
45 >   <node originHost=\"ADML-server\" applicationId=\"0\" diameterServer=\"localhost:3868\"/>
46 > </services>
47
48 If you act as a proxy or a translation agent, you need to combine both former setups, and probably will need to program the answers to be replied through the operations interface. To balance the traffic at your client side you shall use '--balance' and '--sessionBasedModelsClientSocketSelection' arguments in order to define the balancing behaviour. To make hybrid setups you only must mix the nodes:
49
50 Client and server configuration:
51
52 > <services>
53 >   <!-- Stacks -->
54 >   <stack id=\"16777236\" dictionary=\"dictionary_Rx.xml\"/>
55 >   <stack id=\"16777238\" dictionary=\"dictionary_Gx.xml\"/>
56 >   <stack id=\"0\" dictionary=\"dictionary_base.xml\"/>
57 >
58 >   <!-- Nodes -->
59 >   <node originHost=\"ADML-Rx-client\" applicationId=\"16777236\" entity=\"localhost:3868\" cer=\"cer_Rx.xml\"/>
60 >   <node originHost=\"ADML-Gx-client\" applicationId=\"16777238\" entity=\"localhost:3868\" cer=\"cer_Gx.xml\"/>
61 > </services>
62
63 The process builds automatically CER and DWR messages as a client, but you could specify your own as shown in the hybrid former example. Note that the base protocol stack must be registered because the configuration corresponds to a multistack process which change the stack using the application-id processed (0 in the case of base protocol messages: CER, CEA, DWR, DWA, DPR, DPA).
64
65 DYNAMIC OPERATIONS
66 ==================
67
68 ADML supports several operations which could be recognized via SIGUSR2 caugh or HTTP interface:
69
70 ## SIGUSR2 caugh
71
72 Requires the creation of the task(s) file which will be read at signal event:
73
74 >    echo \"<operation>\" > "; result += getSignalUSR2InputFile();
75 >     then
76 >    kill -12 <pid>
77 >     or
78 >    kill -s SIGUSR2 <pid>
79 >     and then see the results:
80 >    cat "; result += getSignalUSR2OutputFile();
81
82    (this file is ended with EOF final line, useful managing huge batch files to ensure the job completion)
83
84 You could place more than one line (task) in the input file. Output reports will be appended in that case over the output file. Take into account that all the content of the task file will be executed sinchronously by the process. If you are planning traffic load, better use the asynchronous http interface.
85
86 An operation is specified by mean a string containing the operation name and needed arguments separated by pipes. These are the available commands:
87
88 ### Node management
89
90 **node[|<name>]**
91
92 Selects a context working node by mean a registered name (origin-host).
93 All the subsequent operations will be forced to work with this node, which makes possible some rare scenarios like sending unexpected messages on remote peers. This is also useful for some operations in order to restrict the scope of action (statistics, communication visibility, etc.).
94
95 Empty parameter will show the current configuration.
96
97 **node-auto**
98
99 Returns to the default behaviour (smart node selection).
100 Depending on the operation, this could imply a global action scope, affecting to all the registered hosts.
101 This should be the normal configuration. Take into account that if you fix the working node, this could affect to things like test programming: communication resources will override those which would be inferred from programmed messages Origin-Host avps.
102
103 ### Parsing operations
104
105 **code|<source_file>|<target_file>**
106
107 Encodes source file (pathfile) into target file (pathfile).
108
109 **decode|<source_file>|<target_file>**
110
111 Decodes source file (pathfile) into target file (pathfile).
112
113 **loadxml|<source_file>**
114
115 Reinterpret xml source file (pathfile).
116
117 ### Hot changes
118
119 **services[|<source file>]**
120
121 Adds and starts the services specified in the xml file provided. If missing, the file 'services.xml' will be used. This is used to load new nodes once the ADML is started, regardless if command line '--services' parameter was used or not. Those services which are not correctly loaded will be ignored to keep the process alive.
122 If you need to load services as deltas, you must firstly load the diameter base dictionary with stack id 0, because all the nodes will use this dictionary to encode/decode base protocol messages managed by the communication engine.
123
124 **diameterServerSessions|<integer>**
125
126 Updates the maximum number of accepted connections to diameter server socket.
127
128 **change-dir[|directory]**
129
130 Changes the execution point which could be fine to ease some file system interaction tasks. Be care about some requirements (for example if you have a user defined counters directory as relative path this must exists from the new execution directory). If nothing provided, initial working directory will be restored.
131
132 ### Client sessions visibility
133
134 <action: **hide**, **show**, **hidden**, **shown**>|<address>:<port>|<socket>
135
136 *Actions*: hide, show (update state) and hidden, shown (query state).
137 Acts over a client session for messages delivery (except CER/A, DWR/A, DPR/A).
138 If missing server (first parameter) all applications sockets will be affected.
139 If missing socket (second parameter) for specific server, all its sockets will be affected.
140
141 All application client sessions are shown on startup, but standard delivery only use primary server ones except if fails. Balance configuration use all the allowed sockets. You could also use command line 'sessionBasedModelsClientSocketSelection' to force traffic flow over certain client sessions, but for this, hide/show feature seems easier.
142
143 ### Snapshots
144
145 **collect**
146
147 Reset statistics and counters to start a new test stage of performance measurement. Context data can be written at '/var/tmp/anna.context.<pid>' by mean 'kill -10 <pid>' or sending operation 'context|[target file]'. This operation applies over all the registered host nodes except if one specific working node has been set.
148
149 **context[|<target file>]**
150
151 Application context could also be written by mean this operation (not only through SIGUSR1). If optional path file is missing, default '/var/tmp/anna.context.<pid>' will be used.
152
153 **forceCountersRecord**
154
155 Forces dump to file the current counters of the process.
156
157 **log-statistics-samples|<list>**
158
159 Log statistics samples for the provided comma-separated concept id list, over './sample.<concept id>.csv' files. For example: "1,2" will log concepts 1 and 2. Reserved words "all"/"none" activates/deactivates all registered statistics concept identifiers. That ids are shown at context dump.
160
161 **show-oam**
162
163 Dumps current counters of the process. This is also done at process context dump.
164
165 **show-stats**
166
167 Dumps statistics of the process. This is also done at process context dump.
168
169 ### Flow operations
170
171 **sendxml2e|<source_file>**
172
173 Sends xml source file (pathfile) through configured entity.
174
175 **sendxml2c|<source_file>**
176
177 Sends xml source file (pathfile) to client.
178
179 **answerxml2e[|source_file]**
180
181 Answer xml source file (pathfile) for incoming request with same code from entity.
182 The answer is stored in a FIFO queue for a specific message code, then there are as many queues as different message codes have been programmed.
183
184 **answerxml2c[|source_file]**
185
186 Answer xml source file (pathfile) for incoming request with same code from client. The answer is stored in a FIFO queue for a specific message code, then there are as many queues as different message codes have been programmed.
187
188 **answerxml<2e/2c>**
189
190 List programmed answers (to entity/client) if no parameter provided.
191
192 **answerxml<2e/2c>|dump**
193
194 Write programmed answers (to entity/client) to file 'programmed_answer.<message code>.<sequence>', where 'sequence' is the order of the answer in each FIFO code-queue of programmed answers.
195
196 **answerxml<2e/2c>|clear**
197
198 Clear programmed answers (to entity/client).
199
200 **answerxml<2e/2c>|exhaust**
201
202 Disable the corresponding queue rotation, which is the default behaviour.
203
204 **answerxml<2e/2c>|rotate**
205
206 Enable the corresponding queue rotation, useful in performance tests. Rotation consists in add again to the queue, each element retrieved for answering.
207
208 Send operations are available using hexadecimal content (hex formatted files) which also allow to test
209 special scenarios (protocol errors):
210
211 **sendhex2e|<source_file>**
212
213 Sends hex source file (pathfile) through configured entity.
214
215 **sendhex2c|<source_file>**
216
217 Sends hex source file (pathfile) to client.
218
219 Answer programming in hexadecimal is not really neccessary (you could use send primitives) and also is intended to be used with decoded messages in order to replace things like hop by hop, end to end, subscriber id, session id, etc. Anyway you could use 'decode' operation and then program the xml created.
220
221 If a request is received, answer map (built with 'answerxml<2e/2c>' operations) will be checked to find a corresponding programmed answer to be replied(*). If no ocurrence is found, or answer message was received, the message is forwarded to the other side (entity or client), or nothing but trace when no peer at that side is configured. Answer to client have sense when diameter server socket is configured, answer to entity have sense when entity does.
222
223 In the most complete situation (process with both client and server side) there are internally two maps with N FIFO queues, one for each different message code within programmed answers. One map is for answers towards the client, and the other is to react entity requests. Then in each one we could program different answers corresponding to different request codes received.
224
225 (*) sequence values (hop-by-hop and end-to-end), Session-Id and Subscription-Id avps, are mirrored to the peer which sent the request. If user wants to test a specific answer without changing it, use 'sendxml<2e/2c>/sendhex<2e/2c>' operations better than programming.
226
227 Balance ('--balance' command line parameter) could be used to forward server socket receptions through entity servers by mean a round-robin algorithm. Both diameter server socket and entity targets should have been configured, that is to say: launcher acts as client and server. If no balance is used, an standard delivery is performed: first primary entity server, secondary when fails, etc.
228
229 ### Processing types (log tags)
230
231 Used as log file extensions (when '--splitLog' is provided on command line) and context preffixes on log
232  details when unique log file is dumped:
233
234 | MULTIPLEXOR IDENTIFIER | Description                                                  |
235 | ---------------------- | ------------------------------------------------------------ |
236 | [sent2e/send2eError]   | Send to entity (success/error)                               |
237 | [sent2c/send2cError]   | Send to client (success/error)                               |
238 | [fwd2e/fwd2eError]     | Forward to entity a reception from client (success/error)    |
239 | [fwd2c/fwd2cError]     | Forward to client a reception from entity (success/error)    |
240 | [recvfc]               | Reception from client                                        |
241 | [recvfe]               | Reception from entity                                        |
242 | [req2c-expired]        | A request sent to client has been expired                    |
243 | [req2e-expired]        | A request sent to entity has been expired                    |
244 | [recvfc-ans-unknown]   | Reception from client of an unknown answer (probably former [req2c-expired] has been logged) |
245 | [recvfe-ans-unknown]   | Reception from entity of an unknown answer (probably former [req2e-expired] has been logged) |
246 | [retry]                | Request retransmission                                       |
247
248 ### Burst test
249
250 In order to simplify user experience, burst category operations are only allowed in single host node
251  configuration. Indeed, you could send messages with unmatched Origin-Host, and no warning is shown.
252 All the operations are performed through the unique host: if you need to use more interfaces, you may
253  launch different ADML instances. Is nonsense to allow burst in a multi-host configured ADML, because
254  this feature is not able to coordinate the messages.
255
256 **burst|<action>[|parameter]**
257
258 Used for performance testing, we first program diameter requests messages in order to launch them from client side to the configured diameter entity. We could start the burst with an initial load (non-asynchronous sending), after this, a new request will be sent per answer received or expired context. There are 10 actions: clear, load, start, push, pop, stop, repeat, send, goto and look.
259
260 | OPERATION                    | DESCRIPTION                                                  |
261 | ---------------------------- | ------------------------------------------------------------ |
262 | burst\|clear                 | Clears all loaded burst messages.                            |
263 | burst\|load\|<source_file>   | Loads the next diameter message into launcher burst.         |
264 | burst\|start\|<initial load> | Starts (or restarts if already in progress) the message sending with a certain initial load. |
265 | burst\|push\|<load amount>   | Sends specific non-aynchronous load.                         |
266 | burst\|pop\|<release amount> | Skip send burst messages in order to reduce over-the-air requests. Popping all OTA requests implies burst stop because no more answer will arrive to the process. Burst output file (--burstLog command line parameter) shows popped messages with crosses (x). Each cross represents one received answer for which no new request is sent. |
267 | burst\|stop\|                | Stops the burst cycle. You can resume pushing 1 load amount. |
268 | burst\|repeat[\|[yes]\|no]   | Restarts the burst launch when finish. If initial load or push load amount is greater than burst list size, they will be limited when the list is processed except when repeat mode is enabled. |
269 | burst\|send\|<amount>        | Sends messages from burst list. The main difference with start/push operations is that burst won't be awaken. Externally we could control sending time (no request will be sent for answers). |
270 | burst\|goto\|<order>         | Updates current burst pointer position.                      |
271 | burst\|look[\|order]         | Show programmed burst message for order provided, current when missing. |
272
273 ### Advanced testing (FSM, finite state machine)
274
275 Burst mode only allows single interface interaction. For multiple interface (origin-host) coordination, you could use the advanced test cases programming:
276
277    **test|<id>|<command>[|parameters]**
278
279 Adds a new step to the test case with provided identifier. If provided identifier is not registered yet, a new test case will be created with that value and the step will be added as the first. For a specific 'id', the steps are stored in order as they are programmed. Check possible runtime exceptions when adding a new step because those which fail, will be ignored/skipped during test case programming giving an incomplete sequence invalid for the testing purpose.
280
281 <id>: integer number, normally monotonically increased for each test case. Some external script/procedure shall clone a test case template in order to build a collection of independent and coherent test cases (normally same type) with different context values (Session-Id, Subscriber-Id, etc.).
282
283 <command>: commands to be executed for the test id provided. Each command programmed constitutes a test case 'step', numbered from 1 to N, with an exception for 'description' which is used to describe the test case:
284
285
286
287 > **description|<description>**
288 >
289 > Sets a test case description. Test cases by default are constructed with description 'Testcase_<id>'.
290 >
291 > **ip-limit[|amount]**
292 >
293 > In-progress limit of test cases controlled from this test. No new test cases will be launched over this value (test manager tick work will be ignored). Zero-value is equivalent to stop the clock tick, -1 is used to specify 'no limit' which is the default. For missing amount, value of 1 is applied.
294 >
295 > **timeout|<msecs>**
296 >
297 > Sets an asynchronous timer to restrict the maximum timeout until last test step. Normally, this command is invoked in the first step, anyway it measures the time from the execution point whatever it is. The expiration will abort the test if still running. One or more timeouts could be programmed (not usual), but the more restrict will apply.
298 > It is highly recommended to program a initial timeout step, or the test case could be eternally in-progress.
299 >
300 > **sendxml2e|<source_file>[|<step number>]**
301 > Sends xml source file (pathfile) to entity (it would be a 'forward' event if it came through local server endpoint).
302 > Take into account that the xml message is encoded just on call. The xml file is not longer needed neither interpreted in case of modification, after calling this command. The step number should be provided for answers to indicate the 'wait for request' corresponding step. If you miss this reference, the sequence information (hop-by-hop, end-to-end) will be sent as they are in the answer xml message (realize the difficulty of predicting these information). Be sure to refer to a 'wait for request' step. Conditions like 'regexp' (as we will see later) are not verified.
303 > In the case of requests, the step number is used to force the copy of Session-Id value from the referred step.
304 >
305 > **sendxml2c|<source_file>[|<step number>]**
306 > Sends xml source file (pathfile) to client (it would be a 'forward' event if it came through remote server endpoint). Same commented for 'sendxml2e' regarding the step number.
307 >
308 > **delay|<msecs>**
309 >
310 > Blocking step until the time lapse expires. Useful to give some cadence control and time schedule for a specific case. A value of 0 could be used as a dummy step.
311 >
312 > **sh-command|<script>**
313 >
314 > External execution for script/executable via shell through a dedicated thread, providing the command and parameters. You could use dynamic variables ##<tag> to have more flexibility:
315 > Test pool cycle id: ##cycleid##
316 > Test case id: ##testcaseid##
317 > Test step id: ##teststepid##
318 >
319 > For example, your command could be something like this:
320 >
321 > > insert_sql_##testcaseid##.sh -db dbname --verbose > /tmp/cycle-##cycleid##.testcase-##testcaseid##.teststep-##teststepid##.out
322 >
323 >
324 >
325 > Try to redirect stdout and stderr to avoid ADML output contamination with the possible outputs from the scripts. You could also put your job in background although sh-command will return 0-value immediately.
326 >
327 > **wait<fe/fc>-hex|<source_file>[|strict]**
328 > Wait condition, from entity (waitfe-hex) or client (waitfc-hex) to match the hexadecimal representation for received messages against source file (hex format). Fix mode must be enabled to avoid unexpected matching behaviour. Specify 'strict' to use the hex content 'as is'.
329 > If not, the hex content will be understood as whole message and then, borders will be added (^<content>$) and sequence information bypassed even for diameter answers.
330 >
331 > **wait<fe/fc>-xml|<source_file>[|strict]**
332 > Wait condition from entity (waitfe-xml) or client (waitfc-xml) to match the serialized xml content for received messages against source file (xml representation). Fix mode must be enabled to avoid unexpected matching behaviour. If you need a strict matching you must add parameter 'strict', if not, regexp is built ignoring sequence information (hop-by-hop-id=\"[0-9]+\" end-to-end-id=\"[0-9]+\") and Origin-State-Id value.
333 >
334 > **wait<fe/fc>|<condition>**
335 >
336 > Blocking step until condition is fulfilled. The message could received from entity (waitfe) or from client (waitfc). CPU cost is lower than former 'wait<fe/fc>-<xml|hex>' variants.
337 >
338 > > <condition>:
339 > >
340 > > Optional parameters which must be fulfilled to continue through the next step. Any received message over diameter interfaces will be evaluated against the corresponding test case starting from the current step until the first one whose condition is fulfilled. If no condition is fulfilled the event will be classified as 'uncovered' (normally a test case bad configuration, or perhaps a real unexpected message).
341 > >
342 > > How to answer: a wait condition for a request will store the incoming message which fulfills that condition. This message is useful together with the peer connection source in a further send step configured with the corresponding response. You could also insert a delay between wait and send steps to be more realistic (processing time simulation in a specific ADML host node).
343 > > Always, a response send step will get the needed information from the most recent wait step finding in reverse order (note that some race conditions could happen if your condition is not specific enough).
344 > >
345 > > Condition format is: **[code]|[bitR]|[hopByHop]|[applicationId]|[sessionId]|[resultCode]|[msisdn]|[imsi]|[serviceContextId]**
346 > >
347 > > *code*: integer number
348 > > *bitR*: 1 (request), 0 (answer)
349 > > *hopByHop*: integer number or request send step reference: #<step number>
350 > >
351 > > Using the hash reference, you would indicate a specific wait condition for answers. The step number provided must correspond to any of the previous send commands (sendxml2e/sendxml2c) configured for a request.
352 > > This 'hop-by-hop' variant eases the wait condition for answers in the safest way.
353 > >
354 > > *applicationId*: integer number
355 > > *sessionId*: string
356 > > *resultCode*: integer number
357 > > *msisdn*: string
358 > > *imsi*: string
359 > > *serviceContextId*: string
360 > >
361 > > Take into account these rules, useful in general:
362 > >
363 > > - Be as much specific as possible defining conditions to avoid ambiguity sending messages out of context due to race conditions. Although you could program several times similar conditions, some risky practices will throw a warning trace (if you repeat the same condition within the same test case).
364 > > - Adding a ResultCode and/or HopByHop to the condition are only valid waiting answers.
365 > > - Requests hop-by-hop values must be different for all the test case requests.
366 > > RFC says that a hop by hop must be unique for a specific connection, something that could be difficult to manage if we have multiple available connections from client side endpoint (entity or local server), even if we would have only one connection but several host interfaces. It is enough to configure different hop-by-hop values within each test case, because on reception, the Session-Id is used to identify that test case.
367
368 ####  Programming example:
369
370 *Basic Rx/Gx scenary: PCEF (Gx) - PCRF - AF (Rx)*
371
372 test|1|timeout|5000
373 test|1|sendxml2e|CCR-I.xml
374 test|1|waitfe|272|0|||SGx|2001
375 test|1|sendxml2e|AAR-flows.xml
376 test|1|waitfe|265|0|||SRx|2001
377 test|1|waitfe|258|1|||SGx
378 test|1|sendxml2e|RAA-install.xml|6
379 test|1|sendxml2e|CCR-T.xml
380 test|1|waitfe|272|0|H1||SGx|2001
381 test|1|waitfe|258|1|||SGx
382 test|1|sendxml2e|RAA-remove.xml|10
383
384
385
386 - Step 1: whole time requirement is 5 seconds
387 - Step 2: imagine this xml uses the Session-Id 'SGx'
388 - Step 3: waits the CCA for the CCR-I with Result-Code = DIAMETER_SUCCESS
389 - Step 4: imagine this xml uses the Session-Id 'SRx'
390 - Step 5: waits the AAA for the AAR-flows with Result-Code = DIAMETER_SUCCESS
391 - Step 6: waits the RAR (install policies) from the PCRF server
392 - Step 7: sends the response for the RAR
393 - Step 8: termination of the Gx session, imagine this xml puts hop-by-hop 'H1'
394 - Step 9: waits the CCA for the CCR-T with Result-Code = DIAMETER_SUCCESS and hop-by-hop 'H1'
395 - Step 10: waits the RAR (remove policies) from the PCRF server
396 - Step 11: sends the response for the RAR
397
398
399
400 **Notes**:
401
402 We added an additional condition in step 9: the hop-by-hop. When we program the corresponding source request (CCR-T), we configured the value 'H1' for the hop-by-hop. This is an 'application value' because the real hop-by-hop transported through the client connection is managed by the diameter stack. But when returned, the transaction pool resolve the original value. This feature is necessary to ease the implementation of certain diameter agents (proxies for example). In our case, we could format the hop-by-hop values within the request templates with total freedom to improve the programmed conditions.
403
404 In the case of 'waiting for requests' is not such easy. Indeed, steps 6 and 10 will write a warning because they are the same condition. We know that we are not going to have any problem because such events are blocking-protected regarding logic-dependent messages (CCR-T), and race condition is absolutely strange in this case.
405
406 You could speed up the test case moving forward steps like 3 & 5, understood as non-strict requirements to continue testing. Anyway, remember that test cases should be as real as possible, and that there are many ways to increase the load rate as we will see in next section (test cases execution).
407
408 Other simplifications: the steps 3, 5 and 9 can be replaced by
409
410 test|1|waitfe||0|#2
411 test|1|waitfe||0|#4
412 test|1|waitfe||0|#8
413
414 which means that hop-by-hop must be retrieved from steps 2, 4 and 8 respectively, and the expected message shall be an answer. Normally you will add other conditions, for example a DIAMETER_SUCCESS result (adding 2001 as Result-Code).
415
416 #### Test cases execution:
417
418 **test|ttps|<amount>**
419
420 Starts/resume the provided number of test ticks per second (ttps). The ADML starts with the event trigger system suspended, and this operation is neccessary to begin those cases which need this time event (internal triggering). Some other test cases could be started through external events (first test case event could be programmed to wait specific message), but is not usual this external mode and neither usual to mix triggering types. Normally, you will pause/stop new test launchs providing 0 as ttps value, and also you could dynamically modify the load rate updating that value. If a test case has N messages then 'ttps * N' will be the virtual number of messages managed per second when no bottleneck exists.
421
422 Provide 0 in order to stop the timer triggering.
423
424 The timer manager resolution currently harcoded allows a maximum  of 50 events per second. To reach greater rates ADML will join synchronously the needed number of new time-triggered test cases per a single event, writting a warning-level trace to advice about the risk of burst sendings and recommend launching multiple instances to achieve such load with a lower rate per instance.
425
426 **test|next[|<sync-amount>]**
427
428 Forces the execution of the next test case(s) without waiting for test manager tick.
429 Provide an integer value for 'sync-amount' to send a burst synchronous amount of the next programmed test cases (1 by default). This event works regardless the timer tick function, but it is normally used with the test manager tick stopped.
430
431 **test|ip-limit[|amount]**
432
433 In-progress limit of test cases established from global context. This value will be overwritten if used at test case level when the corresponding test step is executed.
434 Anyway, the meaning is the same in both contexts. But now, when the amount is missing, the limit and current amount of in-progress test cases will be shown.
435
436 **test|goto|<id>**
437
438 Updates current test pointer position. Take into account, that 'test|next' will execute the next test case, not the one pointed with *goto*.
439
440 **test|run|<id>**
441
442 Run the test case selected.
443
444 **test|look[|id]**
445
446 Show programmed test case for id provided, current 'in-process' test case when missing.
447 Test cases reports are not dumped on process context (too many information in general).
448 The report contains context information in every moment: this operation acts as a snapshot.
449
450 **test|state[|id]**
451
452 Get test case state for id provided, current 'in-process' test case when missing.
453
454 **test|interact|amount[|id]**
455
456 Makes interactive a specific test case id. The amount is the margin of execution steps to be done. Normally, we will execute 'test|interact|0[|<test case id>]', which means that the test case is selected to be interactive, but no step is executed. Then you have to interact with positive amounts (usually 1), executing the provided number of steps if they are ready and fulfill the needed conditions. The value of 0, implies no execution steps margin, which could be useful to 'freeze' a test in the middle of its execution.
457 You could also provide -1 to make it non-interactive resuming it from the current step.
458 By default, current test case id is selected for interaction.
459
460 **test|reset|<[soft]/hard>[|id]**
461
462 Reset the test case for id provided, all the tests when missing. It could be hard/soft:
463
464 - hard: you probably may need to stop the load rate before. This operation initializes all test cases regardless their states.
465 - soft: only for finished cases (those with 'Success' or 'Failed' states). It does not affect to test cases with 'InProgress' state.
466
467 **test|repeats|<amount>**
468
469 Restarts the whole programmed test list when finished the amount number of times (repeats forever if value -1 is provided). This is disabled by default (amount = 0): testing trigger system will enter suspended state until new ttps operation is received and a soft reset has been done before. Test cases state & data will be reset (when achieved again), but general statistics and counters will continue measuring until reset with 'collect' operation.
470
471 **test|auto-reset|<soft|hard>**
472
473 When cycling, current test cases can be soft or hard reset. If no timeout has been configured for the test case, hard reset could prevent stuck on the next cycle for those test cases still in progress.
474
475 **test|initialized**
476
477 Shows the number of initialized test cases. Zero-value means that everything was processed or not initiated yet.
478
479 **test|finished**
480
481 Shows the number of finished (successful or failed) test cases.
482
483 **test|clear**
484
485 Clears all the programmed test cases and stop testing (if in progress).
486
487 **test|junit**
488
489 Shows the junit report in the moment of execution.
490
491 **test|summary-counts**
492
493 Test manager counts report. Counts by state and prints total verdict.
494
495 **test|summary-states**
496
497 Test manager states report.
498
499 **test|summary**
500
501 Test manager general report (number of test cases, counts by state, global configuration, forced in-progress limitation, reports visibility, etc.). Be careful when you have reports enabled because the programmed test cases dumps could be heavy (anyway you could enable the dumps separately, for any of the possible states: Initialized, InProgress, Failed, Success).
502
503 **test|report|<initialized/in-progress/failed/success/[all]/none>[|[yes]|no]**
504
505 Enables/disables report generation for a certain test case state: initialized, in-progress, failed or success (also 'all' and 'none' reserved words could be used). This applies to report summary (former described operation) and automatic dumps during testing where only failed or successful states will appear: every time a test case is finished its xml representation will be dump on a file under the execution directory (or the one configured in process command-line 'tmDir') with the name: 'cycle-<cycle id>.testcase-<test case id>.xml'.
506
507 By default, all the states are disabled to avoid IO overload. In most of cases not all the tests are going to fail then you could enable only such failed dumps. Anyway you could set the reports visibility to fit your needs in a given situation
508
509 **test|report-hex[|[yes]|no]**
510
511 Reports could include the diameter messages in hexadecimal format. Disabled by default.
512
513 **test|dump-stdout[|[yes]|no]**
514
515 Test manager information is dumped into stdout.
516
517 ### Dynamic procedure
518
519 **dynamic[|args]**
520
521 This launch an internal operation implemented in 'Procedure' class. Its default implementation does nothing, but you could create a dynamic library 'libanna_launcherDynamic.so' and replace the one in this project. One interesting application consists in the use of the diameter API and event operation to create a set of libraries as the testing framework.
522 To execute each test case, the ADML process would be executed with a specific library path. But the main use would be the stress programming to achieve a great amount of cloned (even mixed) tests without using the management operation interface by mean http or signals: a single call to 'dynamic' would be enough to start a cascade of internally implemented operations.
523 This operation accepts a generic string argument (piped or not, as you desire and depending on your procedure implementation).
524
525 This operation requires advanced programming and knowlegde of ANNA Diameter stack and testing framework, to take advantage of all the possibilities.
526
527
528 # HTTP Interface
529
530 Most of the operations described above can be used through the optional HTTP1.1 interface. You only have
531  to define the http server at the command line with something like: '--httpServer localhost:8000'.
532 REST API specification.
533
534 **We will describe briefly the supported *GET* & *POST* operations, but you could extend the explanation from SIGUSR2 interface description above**.
535
536 Implemented status codes: *200* (ok), *400* (bad request) and *405* (method not allowed).
537
538 ## GET
539
540 > curl -v --request GET localhost:8000<uri>
541
542 You could also expose the service as HTTP2 server through *nginx* working as reverse proxy (*anna-adml-http* image is built in this way although internally provides HTTP operations script only for 1.1). Then you could use HTTP2 clients like *nghttp*:
543
544 > nghttp -v -H ":method: GET" "<uri>"
545
546
547
548 ### Snapshots
549
550 #### GET /show-oam
551
552 Retrieve oam xml report (will be *base64-encoded* at response).
553
554 **Response body**:
555
556 ```
557 {
558     "result":"<true or false>",
559     "response":"<error description or base64-encoded xml report>"
560 }
561 ```
562
563 #### GET /show-stats
564
565 Retrieve statistics xml report (will be *base64-encoded* at response).
566
567 **Response body**:
568
569 ```
570 {
571     "result":"<true or false>",
572     "response":"<error description or base64-encoded xml report>"
573 }
574 ```
575
576
577
578 ## POST
579
580 > curl -v --request POST -H "Content-Type: application/json" localhost:8000<uri> -d@test.json
581
582 You could also expose the service as HTTP2 server through *nginx* working as reverse proxy (*anna-adml-http* image is built in this way although internally provides HTTP operations script only for 1.1). Then you could use HTTP2 clients like *nghttp*:
583
584 > nghttp -v -H ":method: POST" -d test.json "<uri>"
585
586
587
588 **Important note:** Anna Suite work natively with xml. Although REST API supports diameter messages (*diameterJson* fields) and services configuration (*servicesJson* fields) in *json* format, these messages are not validated directly with a *json schema*. Instead, the *json* object are converted to *xml*  at ADML and the resulting xml representations are validates against *dtd* schemas:
589
590 Schema for diameter messages: [here](../../../../include/anna/diameter/codec/message.dtd).
591
592 Schema for configuration services: [here](./services_examples/services.dtd).
593
594 There are lots of examples for *xml diameter messages and xml services* (normally deployed with *ADML* at `./xml_examples` and `./services_examples`), then you could transform them to the *json format* accepted by the REST API easily, for example using *xmltodict* python module:
595
596 ```
597 #!/usr/bin/python3
598 import xmltodict
599 import json
600 import sys
601
602 try:
603   file = sys.argv[1]
604 except:
605   print("Usage: " + sys.argv[0] + " <diameter xml file>")
606   sys.exit(1)
607
608 try:
609   with open(file, 'r') as myfile:
610     xml = myfile.read()
611 except:
612   print("ERROR reading '" + file + "'")
613   sys.exit(1)
614
615 # although default attribute prefix is '@', anyway we will
616 # force the value just in case xmltodict implementation
617 # changes. The anna::core::functions::json2xml helper,
618 # assumes this prefix in order to work properly.
619 my_dict=xmltodict.parse(xml, attr_prefix='@')
620 json_data=json.dumps(my_dict, indent=3, sort_keys=True)
621 print(json_data)
622 ```
623
624 **Former script is packaged** together with REST API component tests under `./diameterJsonHelper/xml2json.py`.
625
626 Native example for *AA-Request* diameter message:
627
628 ```
629 <message version="1" name="AA-Request" p-bit="yes" application-id="16777236" hop-by-hop-id="0" end-to-end-id="0">
630    <avp name="Session-Id" data="test1;afNodeHostname.nodeHostRealm.com;1;8033450"/>
631    <avp name="Auth-Application-Id" data="16777236"/>
632    <avp name="Origin-Host" data="afHost.afRealm.com"/>
633    <avp name="Origin-Realm" data="afRealm.com"/>
634    <avp name="Destination-Realm" data="operatorRealm.com"/>
635    <avp name="Destination-Host" data="ownHostId.operatorRealm.com"/>
636    <avp name="AF-Application-Identifier" hex-data="313232"/>
637    <avp name="Media-Component-Description">
638       <avp name="Media-Component-Number" data="0"/>
639       <avp name="AF-Application-Identifier" hex-data="313232"/>
640       <avp name="Max-Requested-Bandwidth-UL" data="127"/>
641       <avp name="Max-Requested-Bandwidth-DL" data="133"/>
642       <avp name="Flow-Status" data="2" alias="ENABLED"/>
643       <avp name="Reservation-Priority" data="0" alias="DEFAULT"/>
644    </avp>
645    <avp name="Service-Info-Status" data="0" alias="FINAL_SERVICE_INFORMATION"/>
646    <avp name="Subscription-Id">
647       <avp name="Subscription-Id-Type" data="0" alias="END_USER_E164"/>
648       <avp name="Subscription-Id-Data" data="626037099"/>
649    </avp>
650    <avp name="Framed-IP-Address" hex-data="3139322e3136382e302e31"/>
651    <avp name="Called-Station-Id" hex-data="5741502e4d4f564953544152"/>
652 </message>
653
654 ```
655
656 Corresponding content in *json* format:
657
658 ```
659 {
660    "message": {
661       "@application-id": "16777236",
662       "@end-to-end-id": "0",
663       "@hop-by-hop-id": "0",
664       "@name": "AA-Request",
665       "@p-bit": "yes",
666       "@version": "1",
667       "avp": [
668          {
669             "@data": "test1;afNodeHostname.nodeHostRealm.com;1;8033450",
670             "@name": "Session-Id"
671          },
672          {
673             "@data": "16777236",
674             "@name": "Auth-Application-Id"
675          },
676          {
677             "@data": "afHost.afRealm.com",
678             "@name": "Origin-Host"
679          },
680          {
681             "@data": "afRealm.com",
682             "@name": "Origin-Realm"
683          },
684          {
685             "@data": "operatorRealm.com",
686             "@name": "Destination-Realm"
687          },
688          {
689             "@data": "ownHostId.operatorRealm.com",
690             "@name": "Destination-Host"
691          },
692          {
693             "@hex-data": "313232",
694             "@name": "AF-Application-Identifier"
695          },
696          {
697             "@name": "Media-Component-Description",
698             "avp": [
699                {
700                   "@data": "0",
701                   "@name": "Media-Component-Number"
702                },
703                {
704                   "@hex-data": "313232",
705                   "@name": "AF-Application-Identifier"
706                },
707                {
708                   "@data": "127",
709                   "@name": "Max-Requested-Bandwidth-UL"
710                },
711                {
712                   "@data": "133",
713                   "@name": "Max-Requested-Bandwidth-DL"
714                },
715                {
716                   "@alias": "ENABLED",
717                   "@data": "2",
718                   "@name": "Flow-Status"
719                },
720                {
721                   "@alias": "DEFAULT",
722                   "@data": "0",
723                   "@name": "Reservation-Priority"
724                }
725             ]
726          },
727          {
728             "@alias": "FINAL_SERVICE_INFORMATION",
729             "@data": "0",
730             "@name": "Service-Info-Status"
731          },
732          {
733             "@name": "Subscription-Id",
734             "avp": [
735                {
736                   "@alias": "END_USER_E164",
737                   "@data": "0",
738                   "@name": "Subscription-Id-Type"
739                },
740                {
741                   "@data": "626037099",
742                   "@name": "Subscription-Id-Data"
743                }
744             ]
745          },
746          {
747             "@hex-data": "3139322e3136382e302e31",
748             "@name": "Framed-IP-Address"
749          },
750          {
751             "@hex-data": "5741502e4d4f564953544152",
752             "@name": "Called-Station-Id"
753          }
754       ]
755    }
756 }
757 ```
758
759 Native example for a services configuration example:
760
761 ```
762 <services>
763   <!--
764   Stacks
765
766   * Monostack: you could select any id value, normally 0.
767   * Multistack: use the application id for the id value.
768                 This eases codec engine selection for
769                 processed messages.
770   -->
771   <stack id="0" dictionary="dictionary.xml" fixMode="Always" ignoreFlagsOnValidation="yes"/>
772
773   <!--
774   Nodes
775
776   * Client example:
777
778   <node originHost="<origin host>" applicationId="<application id>"
779         entity="<addr1:port1[,addr2:port2]...[,addrN:portN]>"
780         cer="<cer xml file>" answersTimeout="300000" dumpLog="yes"/>
781
782   * Server example:
783
784   <node originHost="<origin host>" applicationId="<application id>"
785         diameterServer="<addr:port>" diameterServerSessions="10"
786         cea="<cea xml file>" answersTimeout="300000" dumpLog="yes"/>
787   -->
788   <node originHost="afHost.afRealm.com" applicationId="0" entity="localhost:3868"/>
789   <node originHost="ownHostId.operatorRealm.com" applicationId="0"
790         diameterServer="localhost:3868" diameterServerSessions="1"/>
791
792 </services>
793 ```
794
795 And the converted *json* equivalent:
796
797 ```
798 {
799    "services": {
800       "node": [
801          {
802             "@applicationId": "0",
803             "@entity": "localhost:3868",
804             "@originHost": "afHost.afRealm.com"
805          },
806          {
807             "@applicationId": "0",
808             "@diameterServer": "localhost:3868",
809             "@diameterServerSessions": "1",
810             "@originHost": "ownHostId.operatorRealm.com"
811          }
812       ],
813       "stack": {
814          "@dictionary": "dictionary.xml",
815          "@fixMode": "Always",
816          "@id": "0",
817          "@ignoreFlagsOnValidation": "yes"
818       }
819    }
820 }
821 ```
822
823
824
825 **Note that the '@' character is mandatory to indicate attribute keys, and it is necessary to complete the *"json to xml"* conversion successfully at ADML REST Server endpoint.**
826
827
828
829 ### Node management
830
831 #### POST /node
832
833 Selects a context working node by mean a registered name (origin-host). If empty, current node information is retrieved.
834
835 **Request body**:
836
837 ```
838 {
839     "name":"[node name]"
840 }
841 ```
842
843 **Response body**:
844
845 ```
846 {
847     "result":"<true or false>",
848     "response":"<error description or base64-encoded xml information>"
849 }
850 ```
851
852 #### POST /node-auto
853
854 Smart node selection.
855
856 **Request body**: none
857
858 **Response body**:
859
860 ```
861 {
862     "result":"<true or false>",
863     "response":"<response>"
864 }
865 ```
866
867 ### Parsing operations
868
869 #### POST /code
870
871 Encodes a diameter json into hexadecimal representation.
872
873 **Request body**:
874
875 ```
876 {
877     "diameterJson":<diameter message json object>
878 }
879 ```
880
881 **Response body**:
882
883 ```
884 {
885     "result":"<true or false>",
886     "response":"<error description or diameter hex>"
887 }
888 ```
889
890 #### POST /decode
891
892 Decodes an hexadecimal string (no spaces, no colons, i.e.: `01000150c0...`), into diameter xml (*base64-encoded*).
893
894 **Request body**:
895
896 ```
897 {
898     "diameterHex":"<hex string>"
899 }
900 ```
901
902 **Response body**:
903
904 ```
905 {
906     "result":"<true or false>",
907     "response":"<error description or base64-encoded xml diameter message>"
908 }
909 ```
910
911 #### POST /loadmsg
912
913 Reinterprets diameter json into xml (*base64-encoded*).
914
915 **Request body**:
916
917 ```
918 {
919     "diameterJson":<diameter message json object>
920 }
921 ```
922
923 **Response body**:
924
925 ```
926 {
927     "result":"<true or false>",
928     "response":"<error description or base64-encoded xml diameter message>"
929 }
930 ```
931
932 ### Hot changes
933
934 #### POST /services
935
936 Referred files (*dictionaries, cer, cea, etc.*) shall be accesible for ADML and are not provided in this operation.
937
938 **Request body**:
939
940 ```
941 {
942     "servicesJson":<services json object>
943 }
944 ```
945
946 **Response body**:
947
948 ```
949 {
950     "result":"<true or false>",
951     "response":"<response>"
952 }
953 ```
954
955 #### POST /diameterServerSessions
956
957 Updates diameter server sessions to be accepted.
958
959 **Request body**:
960
961 ```
962 {
963     "sessions":<sessions (integer)>
964 }
965 ```
966
967 **Response body**:
968
969 ```
970 {
971     "result":"<true or false>",
972     "response":"<response>"
973 }
974 ```
975
976 #### POST /change-dir
977
978 Updates ADML working directory.
979
980 **Request body**:
981
982 ```
983 {
984     "directory":"<directory path or empty to restore initial working directory>"
985 }
986 ```
987
988 **Response body**:
989
990 ```
991 {
992     "result":"<true or false>",
993     "response":"<response>"
994 }
995 ```
996
997 ### Client sessions visibility
998
999 #### POST /visibility
1000
1001 **Request body**:
1002
1003 ```
1004 {
1005     "action":"<hide|show|hidden|shown>"
1006     [, "addressPort":"<address:port>"]
1007     [, "socket":<socket id (integer)>]
1008 }
1009 ```
1010
1011 **Response body**:
1012
1013 ```
1014 {
1015     "result":"<true or false>",
1016     "response":"<response>"
1017 }
1018 ```
1019
1020 ### Snapshots
1021
1022 #### POST /collect
1023
1024 Reset statistics and counters.
1025
1026 **Request body**: none
1027
1028 **Response body**:
1029
1030 ```
1031 {
1032     "result":"<true or false>",
1033     "response":"<response>"
1034 }
1035 ```
1036
1037 #### POST /context
1038
1039 Dump ADML context at file path provided. If empty (or field missing), default path is selected. Context information is not retrieved in the response, so, file is related to ADML execution context.
1040
1041 **Request body**:
1042
1043 ```
1044 {
1045     ["targetFile":"[file path]"]
1046 }
1047 ```
1048
1049 **Response body**:
1050
1051 ```
1052 {
1053     "result":"<true or false>",
1054     "response":"<response>"
1055 }
1056 ```
1057
1058 #### POST /forceCountersRecord
1059
1060 Forces dump to file the current counters of the process.
1061
1062 **Request body**: none
1063
1064 **Response body**:
1065
1066 ```
1067 {
1068     "result":"<true or false>",
1069     "response":"<response>"
1070 }
1071 ```
1072
1073 #### POST /log-statistics-samples
1074
1075 Set the statistics concepts to be logged. To know the concept indentifiers registered, get the ADML context information.
1076
1077 **Request body**:
1078
1079 ```
1080 {
1081     ["list":"<comma-separated list|[all]|none>"]
1082 }
1083 ```
1084
1085 **Response body**:
1086
1087 ```
1088 {
1089     "result":"<true or false>",
1090     "response":"<response>"
1091 }
1092 ```
1093
1094 ### Flow operations
1095
1096 #### POST /sendmsg2e
1097
1098 Sends diameter json message **to**(2) the connected **entity**(e).
1099
1100 **Request body**:
1101
1102 ```
1103 {
1104     "diameterJson":<diameter message json object>
1105 }
1106 ```
1107
1108 **Response body**:
1109
1110 ```
1111 {
1112     "result":"<true or false>",
1113     "response":"<response>"
1114 }
1115 ```
1116
1117 #### POST /sendmsg2c
1118
1119 Sends diameter json message **to**(2) the connected **client**(c).
1120
1121 **Request body**:
1122
1123 ```
1124 {
1125     "diameterJson":<diameter message json object>
1126 }
1127 ```
1128
1129 **Response body**:
1130
1131 ```
1132 {
1133     "result":"<true or false>",
1134     "response":"<response>"
1135 }
1136 ```
1137
1138 #### POST /answermsg2e
1139
1140 Answers diameter json message **to**(2) the connected **entity**(e).
1141
1142 Mocking FIFO queue based in message code.
1143
1144 **Request body**:
1145
1146 ```
1147 {
1148     "diameterJson":<diameter message json object>
1149 }
1150 ```
1151
1152 or
1153
1154 ```
1155 {
1156     "action":"[action: <[list]|dump|clear|exhaust|rotate>]"
1157 }
1158 ```
1159
1160 **Response body**:
1161
1162 ```
1163 {
1164     "result":"<true or false>",
1165     "response":"<response or base64-encoded output for 'list' action>"
1166 }
1167 ```
1168
1169 #### POST /answermsg2c
1170
1171 Answers diameter json message **to**(2) the connected **client**(c).
1172
1173 Mocking FIFO queue based in message code.
1174
1175 **Request body**:
1176
1177 ```
1178 {
1179     "diameterJson":<diameter message json object>
1180 }
1181 ```
1182
1183 or
1184
1185 ```
1186 {
1187     "action":"[action: <[list]|dump|clear|exhaust|rotate>]"
1188 }
1189 ```
1190
1191 **Response body**:
1192
1193 ```
1194 {
1195     "result":"<true or false>",
1196     "response":"<response or base64-encoded output for 'list' action>"
1197 }
1198 ```
1199
1200 #### POST /sendhex2e
1201
1202 Sends diameter expressed in hexadecimal string (no spaces, no colons, i.e.: `01000150c0...`), **to**(2) the connected **entity**(e).
1203
1204 **Request body**:
1205
1206 ```
1207 {
1208     "diameterHex":"<hex string>"
1209 }
1210 ```
1211
1212 **Response body**:
1213
1214 ```
1215 {
1216     "result":"<true or false>",
1217     "response":"<response>"
1218 }
1219 ```
1220
1221 #### POST /sendhex2c
1222
1223 Sends diameter expressed in hexadecimal string (no spaces, no colons, i.e.: `01000150c0...`), **to**(2) the connected **client**(c).
1224
1225 **Request body**:
1226
1227 ```
1228 {
1229     "diameterHex":"<hex string>"
1230 }
1231 ```
1232
1233 **Response body**:
1234
1235 ```
1236 {
1237     "result":"<true or false>",
1238     "response":"<response>"
1239 }
1240 ```
1241
1242 ### FSM testing
1243
1244 ADML implements a bulting *Finite State Machine* to plan testing flows with a great flexibility.
1245
1246 #### POST /testid-description
1247
1248 **Request body**:
1249
1250 ```
1251 {
1252     "description":"<description (string)>"
1253 }
1254 ```
1255
1256 **Response body**:
1257
1258 ```
1259 {
1260     "result":"<true or false>",
1261     "response":"<response>"
1262 }
1263 ```
1264
1265 #### POST /testid-ip-limit
1266
1267 In-Progress limit is the maximum number of tests which can be executed in parallel.
1268 This operation allows a specific test to set this global pool behaviour.
1269
1270 Zero-value is equivalent to stop the clock (no tests will be executed).
1271
1272 Value '-1' means 'no limit' (full parallel). Be careful with resources consumption.
1273
1274 **Request body**:
1275
1276 ```
1277 {
1278     "amount":[amount (integer, 1 by default: execution in sequence)]
1279 }
1280 ```
1281
1282 **Response body**:
1283
1284 ```
1285 {
1286     "result":"<true or false>",
1287     "response":"<response>"
1288 }
1289 ```
1290
1291 #### POST /testid-timeout
1292
1293 **Request body**:
1294
1295 ```
1296 {
1297     "msecs":<milliseconds (integer)>
1298 }
1299 ```
1300
1301 **Response body**:
1302
1303 ```
1304 {
1305     "result":"<true or false>",
1306     "response":"<response>"
1307 }
1308 ```
1309
1310 #### POST /testid-sendmsg2e
1311
1312 **Request body**:
1313
1314 ```
1315 {
1316     "diameterJson":<diameter message json object>
1317     [,"stepNumber":[amount (integer, -1 no step associated)]]
1318 }
1319 ```
1320
1321 **Response body**:
1322
1323 ```
1324 {
1325     "result":"<true or false>",
1326     "response":"<response>"
1327 }
1328 ```
1329
1330 #### POST /testid-sendmsg2c
1331
1332 **Request body**:
1333
1334 ```
1335 {
1336     "diameterJson":<diameter message json object>
1337     [,"stepNumber":[amount (integer, -1 no step associated)]]
1338 }
1339 ```
1340
1341 **Response body**:
1342
1343 ```
1344 {
1345     "result":"<true or false>",
1346     "response":"<response>"
1347 }
1348 ```
1349
1350 #### POST /testid-delay
1351
1352 **Request body**:
1353
1354 ```
1355 {
1356     "msecs":<milliseconds (integer)>
1357 }
1358 ```
1359
1360 **Response body**:
1361
1362 ```
1363 {
1364     "result":"<true or false>",
1365     "response":"<response>"
1366 }
1367 ```
1368
1369 #### POST /testid-sh-command
1370
1371 **Request body**:
1372
1373 ```
1374 {
1375     "script":"<script>"
1376 }
1377 ```
1378
1379 **Response body**:
1380
1381 ```
1382 {
1383     "result":"<true or false>",
1384     "response":"<response>"
1385 }
1386 ```
1387
1388 #### POST /testid-waitfe-hex
1389
1390 **Request body**:
1391
1392 ```
1393 {
1394     "hex":"<hex string>"
1395     [,"strict":"[<true|[false]>]"]]
1396 }
1397 ```
1398
1399 **Response body**:
1400
1401 ```
1402 {
1403     "result":"<true or false>",
1404     "response":"<response>"
1405 }
1406 ```
1407
1408 #### POST /testid-waitfc-hex
1409
1410 **Request body**:
1411
1412 ```
1413 {
1414     "hex":"<hex string>"
1415     [,"strict":"[<true|[false]>]"]]
1416 }
1417 ```
1418
1419 **Response body**:
1420
1421 ```
1422 {
1423     "result":"<true or false>",
1424     "response":"<response>"
1425 }
1426 ```
1427
1428 #### POST /testid-waitfe-msg
1429
1430 **Request body**:
1431
1432 ```
1433 {
1434     "diameterJson":<diameter message json object>
1435     [,"strict":"[<true|[false]>]"]]
1436 }
1437 ```
1438
1439 **Response body**:
1440
1441 ```
1442 {
1443     "result":"<true or false>",
1444     "response":"<response>"
1445 }
1446 ```
1447
1448 #### POST /testid-waitfc-msg
1449
1450 **Request body**:
1451
1452 ```
1453 {
1454     "diameterJson":<diameter message json object>
1455     [,"strict":"[<true|[false]>]"]]
1456 }
1457 ```
1458
1459 **Response body**:
1460
1461 ```
1462 {
1463     "result":"<true or false>",
1464     "response":"<response>"
1465 }
1466 ```
1467
1468 #### POST /testid-waitfe
1469
1470 **Request body**:
1471
1472 ```
1473 {
1474     "condition": {
1475       "code":"[(integer)]",
1476       "bitR":"[(1|0)]",
1477       "hopByHop":"[(integer)]",
1478       "applicationId":"[(integer)]",
1479       "sessionId":"[session id]",
1480       "resultCode":"[(integer)]",
1481       "msisdn":"[msisdn]",
1482       "imsi":"[imsi]",
1483       "serviceContextId":"[service context id]"
1484     }
1485 }
1486 ```
1487
1488 **Response body**:
1489
1490 ```
1491 {
1492     "result":"<true or false>",
1493     "response":"<response>"
1494 }
1495 ```
1496
1497 #### POST /testid-waitfc
1498
1499 **Request body**:
1500
1501 ```
1502 {
1503     "condition": {
1504       "code":"[(integer)]",
1505       "bitR":"[(1|0)]",
1506       "hopByHop":"[(integer)]",
1507       "applicationId":"[(integer)]",
1508       "sessionId":"[session id]",
1509       "resultCode":"[(integer)]",
1510       "msisdn":"[msisdn]",
1511       "imsi":"[imsi]",
1512       "serviceContextId":"[service context id]"
1513     }
1514 }
1515 ```
1516
1517 **Response body**:
1518
1519 ```
1520 {
1521     "result":"<true or false>",
1522     "response":"<response>"
1523 }
1524 ```
1525
1526 ### FSM TESTING EXECUTION ACTIONS
1527
1528 #### POST /test-ttps
1529
1530 **Request body**:
1531
1532 ```
1533 {
1534     "amount":<amount (integer)>
1535 }
1536 ```
1537
1538 **Response body**:
1539
1540 ```
1541 {
1542     "result":"<true or false>",
1543     "response":"<response>"
1544 }
1545 ```
1546
1547 #### POST /test-next
1548
1549 **Request body**:
1550
1551 ```
1552 {
1553     ["syncAmount":[amount (integer: 1 by default)]]
1554 }
1555 ```
1556
1557 **Response body**:
1558
1559 ```
1560 {
1561     "result":"<true or false>",
1562     "response":"<response>"
1563 }
1564 ```
1565
1566 #### POST /test-ip-limit
1567
1568 Global operation (also at test identifier level is accessible).
1569
1570 Zero-value is equivalent to stop the clock (no tests will be executed).
1571
1572 Value '-1' means 'no limit' (full parallel). Be careful with resources consumption.
1573
1574 Defaults to '-2' (no '-1' which is default for *testid-ip-limit* version), which wil show the current pool *ip-limit* and also the number of test cases which are *in progress*.
1575
1576 **Request body**:
1577
1578 ```
1579 {
1580     ["amount":[amount (integer, shows current ip-limit and in-progress test cases amount, by default (-2))]]
1581 }
1582 ```
1583
1584 **Response body**:
1585
1586 ```
1587 {
1588     "result":"<true or false>",
1589     "response":"<response>"
1590 }
1591 ```
1592
1593 #### POST /test-goto
1594
1595 **Request body**:
1596
1597 ```
1598 {
1599     "id":<test identifier>
1600 }
1601 ```
1602
1603 **Response body**:
1604
1605 ```
1606 {
1607     "result":"<true or false>",
1608     "response":"<response>"
1609 }
1610 ```
1611
1612 #### POST /test-run
1613
1614 **Request body**:
1615
1616 ```
1617 {
1618     "id":<test identifier>
1619 }
1620 ```
1621
1622 **Response body**:
1623
1624 ```
1625 {
1626     "result":"<true or false>",
1627     "response":"<response>"
1628 }
1629 ```
1630
1631 #### POST /test-look
1632
1633 **Request body**:
1634
1635 ```
1636 {
1637      ["id":[test identifier (integer: current by default (-1))]]
1638 }
1639 ```
1640
1641 **Response body**:
1642
1643 ```
1644 {
1645     "result":"<true or false>",
1646     "response":"<base64-encoded output>"
1647 }
1648 ```
1649
1650 #### POST /test-state
1651
1652 **Request body**:
1653
1654 ```
1655 {
1656      ["id":[test identifier (integer: current by default (-1))]]
1657 }
1658 ```
1659
1660 **Response body**:
1661
1662 ```
1663 {
1664     "result":"<true: if state is 'Success' or false>",
1665     "response":"<response>"
1666 }
1667 ```
1668
1669 #### POST /test-interact
1670
1671 Makes interactive a specific test case id. The amount of 0, implies no execution steps margin, which could be useful to 'freeze' a test in the middle of its execution. Value -1 makes it non-interactive resuming it from the current step.
1672
1673 **Request body**:
1674
1675 ```
1676 {
1677      "amount":<amount (integer)>
1678      [,"id":[test identifier (integer: current by default (-1))]]
1679 }
1680 ```
1681
1682 **Response body**:
1683
1684 ```
1685 {
1686     "result":"<true or false>",
1687     "response":"<response>"
1688 }
1689 ```
1690
1691 #### POST /test-reset
1692
1693 **Request body**:
1694
1695 ```
1696 {
1697      ["type":"<[soft]|hard>"]
1698      [,"id":[test identifier (integer: apply to all the tests (-1))]]
1699 }
1700 ```
1701
1702 **Response body**:
1703
1704 ```
1705 {
1706     "result":"<true or false>",
1707     "response":"<response>"
1708 }
1709 ```
1710
1711 #### POST /test-repeats
1712
1713 **Request body**:
1714
1715 ```
1716 {
1717      "amount":<amount (integer)>
1718 }
1719 ```
1720
1721 **Response body**:
1722
1723 ```
1724 {
1725     "result":"<true or false>",
1726     "response":"<response>"
1727 }
1728 ```
1729
1730 #### POST /test-auto-reset
1731
1732 **Request body**:
1733
1734 ```
1735 {
1736      "type":"<soft|hard>"
1737 }
1738 ```
1739
1740 **Response body**:
1741
1742 ```
1743 {
1744     "result":"<true or false>",
1745     "response":"<response>"
1746 }
1747 ```
1748
1749 #### POST /test-initialized
1750
1751 **Request body**: none
1752
1753 **Response body**:
1754
1755 ```
1756 {
1757     "result":"<true or false>",
1758     "response":"<response>"
1759 }
1760 ```
1761
1762 #### POST /test-finished
1763
1764 **Request body**: none
1765
1766 **Response body**:
1767
1768 ```
1769 {
1770     "result":"<true or false>",
1771     "response":"<response>"
1772 }
1773 ```
1774
1775 #### POST /test-clear
1776
1777 **Request body**: none
1778
1779 **Response body**:
1780
1781 ```
1782 {
1783     "result":"<true or false>",
1784     "response":"<response>"
1785 }
1786 ```
1787
1788 #### POST /test-junit
1789
1790 As it could be very large, it will be dumped on provided target directory, '*/tmp/junit.xml*' by default.
1791
1792 **Request body**:
1793
1794 ```
1795 {
1796     ["targetFile":"<file path>"]
1797 }
1798 ```
1799
1800 **Response body**:
1801
1802 ```
1803 {
1804     "result":"<true or false>",
1805     "response":"<response>"
1806 }
1807 ```
1808
1809 #### POST /test-summary-counts
1810
1811 **Request body**: none
1812
1813 **Response body**:
1814
1815 ```
1816 {
1817     "result":"<true or false>",
1818     "response":"<base64-encoded output>"
1819 }
1820 ```
1821
1822 #### POST /test-summary-states
1823
1824 **Request body**: none
1825
1826 **Response body**:
1827
1828 ```
1829 {
1830     "result":"<true or false>",
1831     "response":"<base64-encoded output>"
1832 }
1833 ```
1834
1835 #### POST /test-summary
1836
1837 **Request body**: none
1838
1839 **Response body**:
1840
1841 ```
1842 {
1843     "result":"<true or false>",
1844     "response":"<base64-encoded output>"
1845 }
1846 ```
1847
1848 #### POST /test-report
1849
1850 **Request body**:
1851
1852 ```
1853 {
1854     ["state":"[<initialized|in-progress|failed|success|[all]|none>]"]
1855     [,"action":"[<[enable]|disable>]"]
1856 }
1857 ```
1858
1859 **Response body**:
1860
1861 ```
1862 {
1863     "result":"<true or false>",
1864     "response":"<response>"
1865 }
1866 ```
1867
1868 #### POST /test-report-hex
1869
1870 **Request body**:
1871
1872 ```
1873 {
1874     ["action":"[<[enable]|disable>]"]
1875 }
1876 ```
1877
1878 **Response body**:
1879
1880 ```
1881 {
1882     "result":"<true or false>",
1883     "response":"<response>"
1884 }
1885 ```
1886
1887 #### POST /test-dump_stdout
1888
1889 **Request body**:
1890
1891 ```
1892 {
1893     ["action":"[<[enable]|disable>]"]
1894 }
1895 ```
1896
1897 **Response body**:
1898
1899 ```
1900 {
1901     "result":"<true or false>",
1902     "response":"<response>"
1903 }
1904 ```
1905
1906 ### DYNAMIC PROCEDURE
1907
1908 Used for system test. Arguments are determined by the way in a specific dynamic library is designed/documented.
1909
1910 #### POST /dynamic
1911
1912 **Request body**:
1913
1914 ```
1915 {
1916     "dynamic": <diameter arguments json object>
1917 }
1918 ```
1919
1920 **Response body**:
1921
1922 ```
1923 {
1924     "result":"<true or false>",
1925     "response":"<response>"
1926 }
1927 ```
1928