All Classes Namespaces Files Functions Pages
flowoutofsequence.tcl
Go to the documentation of this file.
1 ##
2 # @brief Basic namespace for all Excentis Tcl extensions
3 #
4 namespace eval excentis {
5 
6 ##
7 # @brief This namespace holds all ByteBlower-related Tcl extensions, including the ByteBlower higher-layer Tcl API.
8 #
9 # These procedures are developed for higher-level usage of the ByteBlower API.
10 # They are mainly used to simplify running specific Test Scenarios similar to
11 # scenarios you know from the ByteBlower GUI.
12 #
13 namespace eval ByteBlower {
14 
15 ## \file
16 #
17 # @brief Wrapper module for out of sequence detection scenarios that forces the required TX and RX components to be present and returns only out of sequence values.
18 #
19 # @copyright Excentis nv - www.excentis.com
20 #
21 
22 ##
23 # @brief Executes an out of sequence detecting scenario based on a declarative scenario configuration and returns the calculated out of sequence values.
24 #
25 # This method assumes the scenario configuration has certain properties and returns clear error messages when a scenario configuration is malformed.
26 # The scenario configuration requirements are:
27 # @ulist
28 # @ulitem{A flow should either be used for out of sequence detection or for background traffic.}
29 # @ulitem{A background flow may only have one or more TX parts\, but no RX parts.}
30 # @ulitem{An out of sequence flow may only have a single TX part\, which must have the 'outofsequence' option enabled.}
31 # @ulitem{An out of sequence flow may have zero\, one or more RX parts. They must all have a basic out of sequence configured.}
32 # @endulist
33 #
34 # @param scenarioConfig
35 # The scenario configuration as expected by the @apiref{excentis::ByteBlower::ExecuteScenario,ExecuteScenario} function.
36 # See the @ref TclApiHLOverview "higher-layer API overview" for more information.
37 #
38 # @param args
39 # Scenario-level option list in the form of a list of key-value pairs:
40 # @dlist
41 # @dlitem{-return, Defines the output mode. Following output modes are supported:
42 # @dlist
43 # @dlitem{numbers, Number of transmitted\, received frames and frames out of sequence per flow in the scenario.}
44 # @enddlist
45 # @defaultvalue{numbers}
46 # }
47 # @enddlist
48 #
49 # @return
50 # The out of sequence values per are returned based on the value of the @command{return} option.
51 # @dlist
52 # @dlitem{numbers,Simplified nested list structure with out of sequence values:
53 # @ulist
54 # @ulitem{Scenario structure (flows) and flow structures (TX and RX) are maintained.}
55 # @ulitem{The TX return value is one element\, the number of transmitted frames.}
56 # @ulitem{The RX return value is a list of 2 values: the amount of received frames and
57 # the amount of frames out of sequence.}
58 # @endulist
59 # }
60 # @enddlist
61 #
62 proc FlowOutofsequence { scenarioConfig args } {
63  # Default args
64  set outputmode "numbers"
65 
66  # Parsing args
67  foreach { option value } $args {
68  set option [ string tolower $option ]
69  switch -- $option {
70  -return {
71  set outputmode $value
72  }
73  default {
74  error "ByteBlowerHL FlowOutofsequence error: Invalid argument '$option'"
75  }
76  }
77  }
78 
80  set scenarioResult [ ExecuteScenario $scenarioConfig ]
81 
82  if {$outputmode == "numbers"} {
83  return [ x.FlowOutofsequence.Result.Parse.Numbers $scenarioResult ]
84  }
85 }
86 
87 proc x.FlowOutofsequence.ScenarioConfig.Validate { scenarioConfig } {
88 #
89 # This parses and validates the flow list for an out of sequence scenario. This
90 # is needed because a flow out of sequence scenario imposes stricter rules on
91 # the flow configuration then a generic scenario used by 'ExecuteScenario'.
92 #
93 # If the stricter configuration is not met, an error is thrown.
94 #
95 # @arg scenarioConfig
96 # The scenario configuration passed by the user.
97 # @error
98 # Error is thrown if validation of scenario configuration fails
99 #
100 
101  foreach flowConfig $scenarioConfig {
102  set txCount 0
103  set rxCount 0
104  set outofsequenceTxCount 0
105 
106  # Count TX and RX parts
107  foreach {item value} $flowConfig {
108  switch -- $item {
109  -tx {
110  incr txCount
111  set txParamList $value
112  set index [ lsearch $txParamList "-outofsequence" ]
113  if { $index != -1 && [ lindex $txParamList [ expr $index + 1 ] ] == 1 } {
114  incr outofsequenceTxCount
115  }
116  }
117  -rx {
118  incr rxCount
119  # Rx part is validated later
120  }
121  default { error "ByteBlowerHL FlowOutofsequence error: Invalid flow paremter '$item'" }
122  }
123  }; # end parse flow parameters
124 
125  # TX and RX count validation
126  if { $txCount == 0} {
127  error "ByteBlowerHL FlowOutofsequence error: flow must have at least one TX part\n flow configuration: '$flowConfig'"
128  }
129  if { $txCount > 1 && $outofsequenceTxCount > 0} {
130  error "ByteBlowerHL FlowOutofsequence error: flow with an outofsequence-enabled TX part may have no other TX parts\n flow configuration: '$flowConfig'"
131  }
132  if { $outofsequenceTxCount == 0 && $rxCount > 0} {
133  error "ByteBlowerHL FlowOutofsequence error: flow without an outofsequence-enabled TX part may not contain RX parts\n flow configuration: '$flowConfig'"
134  }
135  if { $outofsequenceTxCount == 1 && $rxCount == 0} {
136  error "ByteBlowerHL FlowOutofsequence error: flow with an outofsequence-enabled TX part must have at least one outofsequence-enabled RX part\n flow configuration: '$flowConfig'"
137  }
138 
139  # Validate RX parts
140  foreach {item value} $flowConfig {
141  switch -- $item {
142  -rx {
143  set rxParamList $value
144  set basicOutofsequenceCount 0
145  foreach {option value} $rxParamList {
146  switch -- $option {
147  -outofsequence {
148  incr basicOutofsequenceCount
149  foreach {seqOption seqValue} $value {
150  # if type option is present, it must be 'basic' (basic is also default value)
151  switch -- $seqOption {
152  -type {
153  if { ! [ string equal $seqValue "" ] && ! [ string equal $seqValue basic ] } {
154  error "ByteBlowerHL FlowOutofsequence error: flow RX part may not contain '$seqValue' type out of sequence detector\n flow configuration: '$flowConfig'"
155  }
156  }
157  }
158  }
159  }
160  -trigger {
161  error "ByteBlowerHL FlowOutofsequence error: out of sequence flow RX part may not contain trigger\n flow configuration: '$flowConfig'"
162  }
163  -capture {
164  error "ByteBlowerHL FlowOutofsequence error: out of sequence flow RX part may not contain capture tool\n flow configuration: '$flowConfig'"
165  }
166  -latency {
167  error "ByteBlowerHL FlowOutofsequence error: out of sequence flow RX part may not contain latency detector\n flow configuration: '$flowConfig'"
168  }
169  default {
170  # ignore other parameters, not our task to validate them
171  }
172  }
173  }
174  if { $basicOutofsequenceCount == 0 } {
175  error "ByteBlowerHL FlowOutofsequence error: out of sequence flow RX part must contain an out of sequence detector\n flow configuration: '$flowConfig'"
176  }
177  if { $basicOutofsequenceCount > 1 } {
178  error "ByteBlowerHL FlowOutofsequence error: out of sequence flow RX part must contain exactly one out of sequence detector\n flow configuration: '$flowConfig'"
179  }
180  }
181  }
182  }; # end parse flow configuration
183  }; # end parse scenario configuration
184 }
185 
186 proc x.FlowOutofsequence.Result.Parse.Numbers { scenarioResult } {
187 #
188 # Parse the scenario result for the numbers option. Because of our setup the
189 # scenario result has a specific format.
190 # * The scenario structure is maintained.
191 # * TX parts within a flow are 'Tx.Stream.Counter.Brief.Get' values
192 # * RX parts within a flow are 'Rx.OutOfSequence.Basic.Counters.Get' values
193 #
194 # @param scenarioResult
195 # The normal scenario result returned by ExecuteScenario.
196 # @return
197 # Return information in the format as specified by the 'numbers'
198 # option.
199 #
200 
201  set scenarioNumbersResult [ list ]
202  foreach flowResult $scenarioResult {
203  set flowNumbersResult [ list ]
204  foreach {item value} $flowResult {
205  switch -- $item {
206  -tx {
207  set txCounters $value
208  # Format: 'NrOfFramesSent <value> <FrameOid_1> <value_1> <FrameOid_2> ...'
209  # Required format: '<value>'
210  set txNumbersResult [ lindex $txCounters 1 ]
211  lappend flowNumbersResult "-tx" $txNumbersResult
212  }
213  -rx {
214  if {$value != "NA"} {
215  set rxCounters $value
216  # Format: 'FramesOutOfSequence <outofsequenceValue> NrOfFrames <value>'
217  # Required format: '<value> <outofsequenceValue>' (note: reverse order!)
218  set rxNumbersResult [ list [lindex $rxCounters 3] [lindex $rxCounters 1] ]
219  lappend flowNumbersResult "-rx" $rxNumbersResult
220  } else {
221  lappend flowNumbersResult "-rx" $value
222  }
223  }
224  }
225  }
226  lappend scenarioNumbersResult $flowNumbersResult
227  }
228  return $scenarioNumbersResult
229 }
230 
231 }
232 
233 }