69f0615c9065e0d18649df8be8da4fa3479ddbe8
[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 **context[|<target file>]**
129
130 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.
131
132 **collect**
133
134 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.
135
136 **forceCountersRecord**
137
138 Forces dump to file the current counters of the process.
139
140 **log-statistics-samples|<list>**
141
142 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.
143
144 **change-dir[|directory]**
145
146 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.
147
148 **show-oam**
149
150 Dumps current counters of the process. This is also done at process context dump.
151
152 **show-stats**
153
154 Dumps statistics of the process. This is also done at process context dump.
155
156 **visibility|<action>|<address>:<port>**
157
158 *Actions*: hide, show (update state) and hidden, shown (query state).
159 Acts over a client session for messages delivery (except CER/A, DWR/A, DPR/A).
160 If missing server (first parameter) all applications sockets will be affected.
161 If missing socket (second parameter) for specific server, all its sockets will be affected.
162
163 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.
164
165 ### Flow operations
166
167 **sendxml2e|<source_file>**
168
169 Sends xml source file (pathfile) through configured entity.
170
171 **sendxml2c|<source_file>**
172
173 Sends xml source file (pathfile) to client.
174
175 **answerxml2e[|source_file]**
176
177 Answer xml source file (pathfile) for incoming request with same code from entity.
178 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.
179
180 **answerxml2c[|source_file]**
181
182 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.
183
184 **answerxml<2e/2c>**
185
186 List programmed answers (to entity/client) if no parameter provided.
187
188 **answerxml<2e/2c>|dump**
189
190 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.
191
192 **answerxml<2e/2c>|clear**
193
194 Clear programmed answers (to entity/client).
195
196 **answerxml<2e/2c>|exhaust**
197
198 Disable the corresponding queue rotation, which is the default behaviour.
199
200 **answerxml<2e/2c>|rotate**
201
202 Enable the corresponding queue rotation, useful in performance tests. Rotation consists in add again to the queue, each element retrieved for answering.
203
204 Send operations are available using hexadecimal content (hex formatted files) which also allow to test
205 special scenarios (protocol errors):
206
207 **sendhex2e|<source_file>**
208
209 Sends hex source file (pathfile) through configured entity.
210
211 **sendhex2c|<source_file>**
212
213 Sends hex source file (pathfile) to client.
214
215 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.
216
217 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.
218
219 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.
220
221 (*) 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.
222
223 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.
224
225 ### Processing types (log tags)
226
227 Used as log file extensions (when '--splitLog' is provided on command line) and context preffixes on log
228  details when unique log file is dumped:
229
230 | MULTIPLEXOR IDENTIFIER | Description                                                  |
231 | ---------------------- | ------------------------------------------------------------ |
232 | [sent2e/send2eError]   | Send to entity (success/error)                               |
233 | [sent2c/send2cError]   | Send to client (success/error)                               |
234 | [fwd2e/fwd2eError]     | Forward to entity a reception from client (success/error)    |
235 | [fwd2c/fwd2cError]     | Forward to client a reception from entity (success/error)    |
236 | [recvfc]               | Reception from client                                        |
237 | [recvfe]               | Reception from entity                                        |
238 | [req2c-expired]        | A request sent to client has been expired                    |
239 | [req2e-expired]        | A request sent to entity has been expired                    |
240 | [recvfc-ans-unknown]   | Reception from client of an unknown answer (probably former [req2c-expired] has been logged) |
241 | [recvfe-ans-unknown]   | Reception from entity of an unknown answer (probably former [req2e-expired] has been logged) |
242 | [retry]                | Request retransmission                                       |
243
244 ### Burst test
245
246 In order to simplify user experience, burst category operations are only allowed in single host node
247  configuration. Indeed, you could send messages with unmatched Origin-Host, and no warning is shown.
248 All the operations are performed through the unique host: if you need to use more interfaces, you may
249  launch different ADML instances. Is nonsense to allow burst in a multi-host configured ADML, because
250  this feature is not able to coordinate the messages.
251
252 **burst|<action>[|parameter]**
253
254 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.
255
256 | OPERATION                    | DESCRIPTION                                                  |
257 | ---------------------------- | ------------------------------------------------------------ |
258 | burst\|clear                 | Clears all loaded burst messages.                            |
259 | burst\|load\|<source_file>   | Loads the next diameter message into launcher burst.         |
260 | burst\|start\|<initial load> | Starts (or restarts if already in progress) the message sending with a certain initial load. |
261 | burst\|push\|<load amount>   | Sends specific non-aynchronous load.                         |
262 | 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. |
263 | burst\|stop\|                | Stops the burst cycle. You can resume pushing 1 load amount. |
264 | 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. |
265 | 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). |
266 | burst\|goto\|<order>         | Updates current burst pointer position.                      |
267 | burst\|look[\|order]         | Show programmed burst message for order provided, current when missing. |
268
269 ### Advanced testing (FSM, finite state machine)
270
271 Burst mode only allows single interface interaction. For multiple interface (origin-host) coordination, you could use the advanced test cases programming:
272
273    **test|<id>|<command>[|parameters]**
274
275 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.
276
277 <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.).
278
279 <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:
280
281
282
283 > **description|<description>**
284 >
285 > Sets a test case description. Test cases by default are constructed with description 'Testcase_<id>'.
286 >
287 > **ip-limit[|amount]**
288 >
289 > 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.
290 >
291 > **timeout|<msecs>**
292 >
293 > 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.
294 > It is highly recommended to program a initial timeout step, or the test case could be eternally in-progress.
295 >
296 > **sendxml2e|<source_file>[|<step number>]**
297 > Sends xml source file (pathfile) to entity (it would be a 'forward' event if it came through local server endpoint).
298 > 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.
299 > In the case of requests, the step number is used to force the copy of Session-Id value from the referred step.
300 >
301 > **sendxml2c|<source_file>[|<step number>]**
302 > 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.
303 >
304 > **delay|<msecs>**
305 >
306 > 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.
307 >
308 > **sh-command|<script>**
309 >
310 > 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:
311 > Test pool cycle id: ##cycleid##
312 > Test case id: ##testcaseid##
313 > Test step id: ##teststepid##
314 >
315 > For example, your command could be something like this:
316 >
317 > > insert_sql_##testcaseid##.sh -db dbname --verbose > /tmp/cycle-##cycleid##.testcase-##testcaseid##.teststep-##teststepid##.out
318 >
319 >
320 >
321 > 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.
322 >
323 > **wait<fe/fc>-hex|<source_file>[|strict]**
324 > 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'.
325 > 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.
326 >
327 > **wait<fe/fc>-xml|<source_file>[|strict]**
328 > 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. All LF codes will be internally removed when comparison is executed in order to ease xml content configuration.
329 >
330 > **wait<fe/fc>|<condition>**
331 >
332 > 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.
333 >
334 > > <condition>:
335 > >
336 > > 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).
337 > >
338 > > 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).
339 > > 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).
340 > >
341 > > Condition format is: **[code]|[bitR]|[hopByHop]|[applicationId]|[sessionId]|[resultCode]|[msisdn]|[imsi]|[serviceContextId]**
342 > >
343 > > *code*: integer number
344 > > *bitR*: 1 (request), 0 (answer)
345 > > *hopByHop*: integer number or request send step reference: #<step number>
346 > >
347 > > 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.
348 > > This 'hop-by-hop' variant eases the wait condition for answers in the safest way.
349 > >
350 > > *applicationId*: integer number
351 > > *sessionId*: string
352 > > *resultCode*: integer number
353 > > *msisdn*: string
354 > > *imsi*: string
355 > > *serviceContextId*: string
356 > >
357 > > Take into account these rules, useful in general:
358 > >
359 > > - 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).
360 > > - Adding a ResultCode and/or HopByHop to the condition are only valid waiting answers.
361 > > - Requests hop-by-hop values must be different for all the test case requests.
362 > > 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.
363
364 ####  Programming example:
365
366 *Basic Rx/Gx scenary: PCEF (Gx) - PCRF - AF (Rx)*
367
368 test|1|timeout|5000
369 test|1|sendxml2e|CCR-I.xml
370 test|1|waitfe|272|0|||SGx|2001
371 test|1|sendxml2e|AAR-flows.xml
372 test|1|waitfe|265|0|||SRx|2001
373 test|1|waitfe|258|1|||SGx
374 test|1|sendxml2e|RAA-install.xml|6
375 test|1|sendxml2e|CCR-T.xml
376 test|1|waitfe|272|0|H1||SGx|2001
377 test|1|waitfe|258|1|||SGx
378 test|1|sendxml2e|RAA-remove.xml|10
379
380
381
382 - Step 1: whole time requirement is 5 seconds
383 - Step 2: imagine this xml uses the Session-Id 'SGx'
384 - Step 3: waits the CCA for the CCR-I with Result-Code = DIAMETER_SUCCESS
385 - Step 4: imagine this xml uses the Session-Id 'SRx'
386 - Step 5: waits the AAA for the AAR-flows with Result-Code = DIAMETER_SUCCESS
387 - Step 6: waits the RAR (install policies) from the PCRF server
388 - Step 7: sends the response for the RAR
389 - Step 8: termination of the Gx session, imagine this xml puts hop-by-hop 'H1'
390 - Step 9: waits the CCA for the CCR-T with Result-Code = DIAMETER_SUCCESS and hop-by-hop 'H1'
391 - Step 10: waits the RAR (remove policies) from the PCRF server
392 - Step 11: sends the response for the RAR
393
394
395
396 **Notes**:
397
398 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.
399
400 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.
401
402 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).
403
404 Other simplifications: the steps 3, 5 and 9 can be replaced by
405
406 test|1|waitfe||0|#2
407 test|1|waitfe||0|#4
408 test|1|waitfe||0|#8
409
410 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).
411
412 #### Test cases execution:
413
414 **test|ttps|<amount>**
415
416 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.
417
418 Provide 0 in order to stop the timer triggering.
419
420 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.
421
422 **test|next[|<sync-amount>]**
423
424 Forces the execution of the next test case(s) without waiting for test manager tick.
425 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.
426
427 **test|ip-limit[|amount]**
428
429 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.
430 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.
431
432 **test|goto|<id>**
433
434 Updates current test pointer position. Take into account, that 'test|next' will execute the next test case, not the one pointed with *goto*.
435
436 **test|run|<id>**
437
438 Run the test case selected.
439
440 **test|look[|id]**
441
442 Show programmed test case for id provided, current 'in-process' test case when missing.
443 Test cases reports are not dumped on process context (too many information in general).
444 The report contains context information in every moment: this operation acts as a snapshot.
445
446 **test|state[|id]**
447
448 Get test case state for id provided, current 'in-process' test case when missing.
449
450 **test|interact|amount[|id]**
451
452 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.
453 You could also provide -1 to make it non-interactive resuming it from the current step.
454 By default, current test case id is selected for interaction.
455
456 **test|reset|<[soft]/hard>[|id]**
457
458 Reset the test case for id provided, all the tests when missing. It could be hard/soft:
459
460 - hard: you probably may need to stop the load rate before. This operation initializes all test cases regardless their states.
461 - soft: only for finished cases (those with 'Success' or 'Failed' states). It does not affect to test cases with 'InProgress' state.
462
463 **test|repeats|<amount>**
464
465 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.
466
467 **test|auto-reset|<soft|hard>**
468
469 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.
470
471 **test|initialized**
472
473 Shows the number of initialized test cases. Zero-value means that everything was processed or not initiated yet.
474
475 **test|finished**
476
477 Shows the number of finished (successful or failed) test cases.
478
479 **test|clear**
480
481 Clears all the programmed test cases and stop testing (if in progress).
482
483 **test|junit**
484
485 Shows the junit report in the moment of execution.
486
487 **test|summary-counts**
488
489 Test manager counts report. Counts by state and prints total verdict.
490
491 **test|summary-states**
492
493 Test manager states report.
494
495 **test|summary**
496
497 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).
498
499 **test|report|<initialized/in-progress/failed/success/[all]/none>[|[yes]|no]**
500
501 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'.
502
503 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
504
505 **test|report-hex[|[yes]|no]**
506
507 Reports could include the diameter messages in hexadecimal format. Disabled by default.
508
509 **test|dump-stdout[|[yes]|no]**
510
511 Test manager information is dumped into stdout.
512
513 ### Dynamic procedure
514
515 **dynamic[|args]**
516
517 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.
518 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.
519 This operation accepts a generic string argument (piped or not, as you desire and depending on your procedure implementation).
520
521 This operation requires advanced programming and knowlegde of ANNA Diameter stack and testing framework, to take advantage of all the possibilities.
522
523
524 # HTTP Interface
525
526 All the operations described above can be used through the optional HTTP interface. You only have
527  to define the http server at the command line with something like: '--httpServer localhost:8000'.
528 REST API specification:
529
530 ## GET
531
532 > curl -v --request GET localhost:8000<uri>
533
534 HTTP2 is not served, so, you should use *nginx* reverse proxy or similar, to pass HTTP1 requests to the server, allowing the external use of HTTP2 clients like *nghttp*:
535
536 > nghttp -v -H ":method: GET" "<uri>"
537
538 ### GET /xxxx
539
540
541
542 ## POST
543
544 > curl -v --request POST -H "Content-Type: application/json" localhost:8000<uri> -d@test.json
545
546 HTTP2 is not served, so, you should use *nginx* reverse proxy or similar, to pass HTTP1 requests to the server, allowing the external use of HTTP2 clients like *nghttp*:
547
548 > nghttp -v -H ":method: POST" -d test.json "<uri>"