cutedriver-driver 2.0.0.20210120164037

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +16 -0
  3. data/bin/start_app_perf +200 -0
  4. data/bin/tdriver-devtools +3 -0
  5. data/config/sut_parameters.rb +52 -0
  6. data/config/sut_setup.rb +32 -0
  7. data/config/sut_teardown.rb +32 -0
  8. data/config/tdriver_custom_error_recovery.rb +83 -0
  9. data/ext/extconf.rb +70 -0
  10. data/ext/native_extensions.c +315 -0
  11. data/lib/matti.rb +25 -0
  12. data/lib/tdriver-devtools/behaviour/old/xml/example/flick-example.rb +120 -0
  13. data/lib/tdriver-devtools/behaviour/old/xml/example/impl.rb_invalid +194 -0
  14. data/lib/tdriver-devtools/behaviour/old/xml/generate_behaviour_xml.rb +95 -0
  15. data/lib/tdriver-devtools/behaviour/old/xml/lib/tdriver_generator.rb +722 -0
  16. data/lib/tdriver-devtools/behaviour/old/xml/qdoc_generator.rb +321 -0
  17. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.method.template +43 -0
  18. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.module.template +54 -0
  19. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.argument.template +7 -0
  20. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.argument_type.template +7 -0
  21. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.exception.template +5 -0
  22. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.howto.line.template +2 -0
  23. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.howto.template +5 -0
  24. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.method.template +23 -0
  25. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.template +14 -0
  26. data/lib/tdriver-devtools/behaviour/old/xml/update +3 -0
  27. data/lib/tdriver-devtools/behaviour/xml/generate.rb +88 -0
  28. data/lib/tdriver-devtools/behaviour/xml/rdoc_behaviour_xml_generator.rb +1945 -0
  29. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.argument.default.template +1 -0
  30. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.argument.template +3 -0
  31. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.argument_type.template +4 -0
  32. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.exception.template +4 -0
  33. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.arguments.template +4 -0
  34. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.deprecated.template +3 -0
  35. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.exceptions.template +3 -0
  36. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.info.template +1 -0
  37. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.returns.template +3 -0
  38. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.tables.template +3 -0
  39. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.template +12 -0
  40. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.returns.template +5 -0
  41. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.table.item.template +1 -0
  42. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.table.row.template +2 -0
  43. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.table.template +8 -0
  44. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.template +14 -0
  45. data/lib/tdriver-devtools/doc/behaviour_xml/QtExampleGestureBehaviour.xml +138 -0
  46. data/lib/tdriver-devtools/doc/behaviour_xml/created.rid +1 -0
  47. data/lib/tdriver-devtools/doc/behaviour_xml/tdriver.hash +1 -0
  48. data/lib/tdriver-devtools/doc/feature_xml/qt_widget_hold.feature.xml +9 -0
  49. data/lib/tdriver-devtools/doc/feature_xml/qt_widget_tap.feature.xml +9 -0
  50. data/lib/tdriver-devtools/doc/generate.rb +917 -0
  51. data/lib/tdriver-devtools/doc/update +1 -0
  52. data/lib/tdriver-devtools/doc/xslt/html.rb +7 -0
  53. data/lib/tdriver-devtools/doc/xslt/template.xsl +2170 -0
  54. data/lib/tdriver-devtools/doc/xslt/update +3 -0
  55. data/lib/tdriver-devtools/plugin/placeholder.txt +1 -0
  56. data/lib/tdriver-devtools/tdriver-devtools.rb +404 -0
  57. data/lib/tdriver-devtools/tests/feature_tests/example/behaviour_example.rb +100 -0
  58. data/lib/tdriver-devtools/tests/feature_tests/generate.rb +82 -0
  59. data/lib/tdriver-devtools/tests/feature_tests/lib/custom_rdoc_generator.rb +468 -0
  60. data/lib/tdriver-devtools/tests/feature_tests/templates/feature_attribute.template +5 -0
  61. data/lib/tdriver-devtools/tests/feature_tests/templates/feature_method.template +5 -0
  62. data/lib/tdriver-devtools/tests/feature_tests/templates/scenario_attribute.template +5 -0
  63. data/lib/tdriver-devtools/tests/feature_tests/templates/scenario_method.template +5 -0
  64. data/lib/tdriver-devtools/tests/feature_tests/update +3 -0
  65. data/lib/tdriver.rb +23 -0
  66. data/lib/tdriver/base/behaviour/abstract.rb +29 -0
  67. data/lib/tdriver/base/behaviour/behaviours/object_abstract.rb +107 -0
  68. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_composition.rb +99 -0
  69. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_description.rb +278 -0
  70. data/lib/tdriver/base/behaviour/behaviours/object_composition.rb +119 -0
  71. data/lib/tdriver/base/behaviour/factory.rb +495 -0
  72. data/lib/tdriver/base/behaviour/loader.rb +46 -0
  73. data/lib/tdriver/base/command_data/command_data.rb +51 -0
  74. data/lib/tdriver/base/command_data/loader.rb +29 -0
  75. data/lib/tdriver/base/controller/abstraction.rb +56 -0
  76. data/lib/tdriver/base/controller/loader.rb +21 -0
  77. data/lib/tdriver/base/errors.rb +134 -0
  78. data/lib/tdriver/base/loader.rb +47 -0
  79. data/lib/tdriver/base/state_object.rb +373 -0
  80. data/lib/tdriver/base/sut/adapter.rb +54 -0
  81. data/lib/tdriver/base/sut/controller.rb +151 -0
  82. data/lib/tdriver/base/sut/factory.rb +339 -0
  83. data/lib/tdriver/base/sut/generic/behaviours/agent.rb +77 -0
  84. data/lib/tdriver/base/sut/generic/behaviours/application.rb +427 -0
  85. data/lib/tdriver/base/sut/generic/behaviours/controller.rb +67 -0
  86. data/lib/tdriver/base/sut/generic/behaviours/find.rb +107 -0
  87. data/lib/tdriver/base/sut/generic/behaviours/flash_behaviour.rb +337 -0
  88. data/lib/tdriver/base/sut/generic/behaviours/sut.rb +1888 -0
  89. data/lib/tdriver/base/sut/generic/behaviours/switchbox_behaviour.rb +210 -0
  90. data/lib/tdriver/base/sut/generic/behaviours/verification.rb +222 -0
  91. data/lib/tdriver/base/sut/generic/commands/agent.rb +43 -0
  92. data/lib/tdriver/base/sut/generic/commands/application.rb +274 -0
  93. data/lib/tdriver/base/sut/generic/commands/fixture.rb +47 -0
  94. data/lib/tdriver/base/sut/generic/commands/key_sequence.rb +94 -0
  95. data/lib/tdriver/base/sut/generic/commands/screen_capture.rb +64 -0
  96. data/lib/tdriver/base/sut/generic/plugin.rb +97 -0
  97. data/lib/tdriver/base/sut/loader.rb +35 -0
  98. data/lib/tdriver/base/sut/sut.rb +98 -0
  99. data/lib/tdriver/base/test_object/abstract.rb +208 -0
  100. data/lib/tdriver/base/test_object/adapter.rb +740 -0
  101. data/lib/tdriver/base/test_object/behaviours/syncronization.rb +144 -0
  102. data/lib/tdriver/base/test_object/behaviours/test_object.rb +1047 -0
  103. data/lib/tdriver/base/test_object/cache.rb +134 -0
  104. data/lib/tdriver/base/test_object/factory.rb +684 -0
  105. data/lib/tdriver/base/test_object/loader.rb +51 -0
  106. data/lib/tdriver/base/test_object/verification.rb +178 -0
  107. data/lib/tdriver/base/test_object/xml/abstraction.rb +63 -0
  108. data/lib/tdriver/base/test_object/xml/adapter.rb +773 -0
  109. data/lib/tdriver/env.rb +21 -0
  110. data/lib/tdriver/loader.rb +57 -0
  111. data/lib/tdriver/matti.rb +35 -0
  112. data/lib/tdriver/report/error_recovery/tdriver_custom_error_recovery.rb +83 -0
  113. data/lib/tdriver/report/error_recovery/tdriver_error_recovery.rb +168 -0
  114. data/lib/tdriver/report/error_recovery/tdriver_error_recovery_settings.rb +106 -0
  115. data/lib/tdriver/report/report.rb +61 -0
  116. data/lib/tdriver/report/report_api.rb +348 -0
  117. data/lib/tdriver/report/report_combine.rb +86 -0
  118. data/lib/tdriver/report/report_crash_file_capture.rb +178 -0
  119. data/lib/tdriver/report/report_creator.rb +665 -0
  120. data/lib/tdriver/report/report_cucumber.rb +158 -0
  121. data/lib/tdriver/report/report_cucumber_listener.rb +184 -0
  122. data/lib/tdriver/report/report_cucumber_reporter.rb +181 -0
  123. data/lib/tdriver/report/report_data_presentation.rb +156 -0
  124. data/lib/tdriver/report/report_data_table.rb +64 -0
  125. data/lib/tdriver/report/report_execution_statistics.rb +400 -0
  126. data/lib/tdriver/report/report_file_capture.rb +159 -0
  127. data/lib/tdriver/report/report_graph_generator.rb +59 -0
  128. data/lib/tdriver/report/report_grouping.rb +541 -0
  129. data/lib/tdriver/report/report_javascript.rb +199 -0
  130. data/lib/tdriver/report/report_junit_xml.rb +147 -0
  131. data/lib/tdriver/report/report_rspec.rb +108 -0
  132. data/lib/tdriver/report/report_test_case_run.rb +725 -0
  133. data/lib/tdriver/report/report_test_run.rb +1476 -0
  134. data/lib/tdriver/report/report_test_unit.rb +223 -0
  135. data/lib/tdriver/report/report_writer.rb +1621 -0
  136. data/lib/tdriver/tdriver.rb +209 -0
  137. data/lib/tdriver/util/agent/loader.rb +22 -0
  138. data/lib/tdriver/util/agent/service.rb +107 -0
  139. data/lib/tdriver/util/common/array.rb +39 -0
  140. data/lib/tdriver/util/common/boolean.rb +48 -0
  141. data/lib/tdriver/util/common/crc16.rb +149 -0
  142. data/lib/tdriver/util/common/environment.rb +154 -0
  143. data/lib/tdriver/util/common/error.rb +40 -0
  144. data/lib/tdriver/util/common/exception.rb +53 -0
  145. data/lib/tdriver/util/common/exceptions.rb +12 -0
  146. data/lib/tdriver/util/common/file.rb +328 -0
  147. data/lib/tdriver/util/common/gem.rb +109 -0
  148. data/lib/tdriver/util/common/hash.rb +288 -0
  149. data/lib/tdriver/util/common/kernel.rb +253 -0
  150. data/lib/tdriver/util/common/loader.rb +47 -0
  151. data/lib/tdriver/util/common/numeric.rb +159 -0
  152. data/lib/tdriver/util/common/object.rb +159 -0
  153. data/lib/tdriver/util/common/retryable.rb +179 -0
  154. data/lib/tdriver/util/common/stackable.rb +185 -0
  155. data/lib/tdriver/util/common/string.rb +174 -0
  156. data/lib/tdriver/util/database/access.rb +240 -0
  157. data/lib/tdriver/util/database/connection.rb +44 -0
  158. data/lib/tdriver/util/database/error.rb +34 -0
  159. data/lib/tdriver/util/database/loader.rb +28 -0
  160. data/lib/tdriver/util/filters/attribute_filter.rb +121 -0
  161. data/lib/tdriver/util/filters/loader.rb +29 -0
  162. data/lib/tdriver/util/fixture/loader.rb +22 -0
  163. data/lib/tdriver/util/fixture/service.rb +211 -0
  164. data/lib/tdriver/util/hooking/hooking.rb +477 -0
  165. data/lib/tdriver/util/keymap/keymap.rb +81 -0
  166. data/lib/tdriver/util/loader.rb +80 -0
  167. data/lib/tdriver/util/localisation/error.rb +31 -0
  168. data/lib/tdriver/util/localisation/loader.rb +25 -0
  169. data/lib/tdriver/util/localisation/localisation.rb +762 -0
  170. data/lib/tdriver/util/logger/loader.rb +22 -0
  171. data/lib/tdriver/util/logger/logger.rb +591 -0
  172. data/lib/tdriver/util/operator_data/error.rb +29 -0
  173. data/lib/tdriver/util/operator_data/loader.rb +27 -0
  174. data/lib/tdriver/util/operator_data/operator_data.rb +93 -0
  175. data/lib/tdriver/util/other/config.rb +221 -0
  176. data/lib/tdriver/util/parameter/error.rb +48 -0
  177. data/lib/tdriver/util/parameter/loader.rb +25 -0
  178. data/lib/tdriver/util/parameter/parameter.rb +1161 -0
  179. data/lib/tdriver/util/plugin/abstract.rb +61 -0
  180. data/lib/tdriver/util/plugin/error.rb +0 -0
  181. data/lib/tdriver/util/plugin/loader.rb +28 -0
  182. data/lib/tdriver/util/plugin/service.rb +319 -0
  183. data/lib/tdriver/util/recorder/loader.rb +25 -0
  184. data/lib/tdriver/util/recorder/recorder.rb +72 -0
  185. data/lib/tdriver/util/recorder/scripter.rb +294 -0
  186. data/lib/tdriver/util/statistics/statistics.rb +89 -0
  187. data/lib/tdriver/util/user_data/error.rb +28 -0
  188. data/lib/tdriver/util/user_data/loader.rb +25 -0
  189. data/lib/tdriver/util/user_data/user_data.rb +104 -0
  190. data/lib/tdriver/util/video/camera.rb +67 -0
  191. data/lib/tdriver/util/video/camera_linux.rb +153 -0
  192. data/lib/tdriver/util/video/camera_windows.rb +174 -0
  193. data/lib/tdriver/util/video/loader.rb +31 -0
  194. data/lib/tdriver/util/video/video_utils.rb +139 -0
  195. data/lib/tdriver/util/xml/abstraction.rb +117 -0
  196. data/lib/tdriver/util/xml/attribute.rb +32 -0
  197. data/lib/tdriver/util/xml/builder.rb +53 -0
  198. data/lib/tdriver/util/xml/comment.rb +32 -0
  199. data/lib/tdriver/util/xml/document.rb +32 -0
  200. data/lib/tdriver/util/xml/element.rb +32 -0
  201. data/lib/tdriver/util/xml/error.rb +46 -0
  202. data/lib/tdriver/util/xml/loader.rb +62 -0
  203. data/lib/tdriver/util/xml/nil_node.rb +95 -0
  204. data/lib/tdriver/util/xml/nodeset.rb +32 -0
  205. data/lib/tdriver/util/xml/parsers/libxml/libxml.rb +140 -0
  206. data/lib/tdriver/util/xml/parsers/loader.rb +21 -0
  207. data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +167 -0
  208. data/lib/tdriver/util/xml/parsers/nokogiri/attribute.rb +66 -0
  209. data/lib/tdriver/util/xml/parsers/nokogiri/builder.rb +64 -0
  210. data/lib/tdriver/util/xml/parsers/nokogiri/comment.rb +39 -0
  211. data/lib/tdriver/util/xml/parsers/nokogiri/document.rb +66 -0
  212. data/lib/tdriver/util/xml/parsers/nokogiri/element.rb +39 -0
  213. data/lib/tdriver/util/xml/parsers/nokogiri/loader.rb +58 -0
  214. data/lib/tdriver/util/xml/parsers/nokogiri/node.rb +212 -0
  215. data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +237 -0
  216. data/lib/tdriver/util/xml/parsers/nokogiri/text.rb +39 -0
  217. data/lib/tdriver/util/xml/text.rb +32 -0
  218. data/lib/tdriver/util/xml/xml.rb +332 -0
  219. data/lib/tdriver/verify/verify.rb +2398 -0
  220. data/lib/tdriver/version.rb +21 -0
  221. data/xml/behaviours/generic.xml +530 -0
  222. data/xml/defaults/generic.xml +11 -0
  223. data/xml/defaults/sut_generic.xml +8 -0
  224. data/xml/parameters/tdriver_parameters.xml +23 -0
  225. data/xml/templates/generic.xml +292 -0
  226. metadata +324 -0
@@ -0,0 +1,1161 @@
1
+ ############################################################################
2
+ ##
3
+ ## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4
+ ## All rights reserved.
5
+ ## Contact: Nokia Corporation (testabilitydriver@nokia.com)
6
+ ##
7
+ ## This file is part of Testability Driver.
8
+ ##
9
+ ## If you have questions regarding the use of this file, please contact
10
+ ## Nokia at testabilitydriver@nokia.com .
11
+ ##
12
+ ## This library is free software; you can redistribute it and/or
13
+ ## modify it under the terms of the GNU Lesser General Public
14
+ ## License version 2.1 as published by the Free Software Foundation
15
+ ## and appearing in the file LICENSE.LGPL included in the packaging
16
+ ## of this file.
17
+ ##
18
+ ############################################################################
19
+
20
+ module TDriver
21
+
22
+ class ParameterUserAPI
23
+
24
+ class << self
25
+
26
+ def new
27
+
28
+ warn_caller "$1:$2 warning: #{ to_s } is static class; unable initialize new instance of it"
29
+
30
+ nil
31
+
32
+ end
33
+
34
+ # TODO: document me
35
+ def []=( key, value )
36
+
37
+ $parameters[ key ] = value
38
+
39
+ end
40
+
41
+ # TODO: document me
42
+ def []( *args )
43
+
44
+ $parameters[ *args ]
45
+
46
+ end
47
+
48
+ # TODO: document me
49
+ def fetch( *args, &block )
50
+
51
+ $parameters.fetch( *args, &block )
52
+
53
+ end
54
+
55
+ # TODO: document me
56
+ def files
57
+
58
+ $parameters.files
59
+
60
+ end
61
+
62
+ # TODO: document me
63
+ def clear
64
+
65
+ $parameters.clear
66
+
67
+ end
68
+
69
+ # TODO: document me
70
+ def load_xml( filename )
71
+
72
+ $parameters.parse_file( filename )
73
+
74
+ end
75
+
76
+ # TODO: document me
77
+ def reset( *keys )
78
+
79
+ $parameters.reset
80
+
81
+ end
82
+
83
+ # TODO: document me
84
+ def inspect
85
+
86
+ $parameters.inspect
87
+
88
+ end
89
+
90
+ # TODO: document me
91
+ def to_s
92
+
93
+ $parameters.to_s
94
+
95
+ end
96
+
97
+ # TODO: document me
98
+ def keys
99
+
100
+ $parameters.keys
101
+
102
+ end
103
+
104
+ # TODO: document me
105
+ def values
106
+
107
+ $parameters.values
108
+
109
+ end
110
+
111
+ # TODO: document me
112
+ def configured_suts
113
+
114
+ $parameters.configured_suts
115
+
116
+ end
117
+
118
+ end # self
119
+
120
+ TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
121
+
122
+ end # ParameterUserAPI
123
+
124
+ class ParameterHash < Hash
125
+
126
+ # TODO: document me
127
+ def []( key, *default, &block )
128
+
129
+ $last_parameter = fetch( key ){
130
+
131
+ if default.empty?
132
+
133
+ raise MobyUtil::ParameterNotFoundError, "Parameter #{ key.inspect } not found" unless block_given?
134
+
135
+ # yield with key if block given
136
+ yield key
137
+
138
+ else
139
+
140
+ raise ArgumentError, "Only one default value allowed for parameter (#{ default.join(', ') })" unless default.size == 1
141
+
142
+ #result = default.first
143
+
144
+ #result.kind_of?( Hash ) ? convert_hash( result ) : result
145
+
146
+ convert_hash( default.first )
147
+
148
+
149
+ end
150
+
151
+ }
152
+
153
+ end
154
+
155
+ # TODO: document me
156
+ def []=( key, value )
157
+
158
+ raise MobyUtil::ParameterNotFoundError, 'Parameter key nil is not valid' unless key
159
+
160
+ super key, convert_hash( value ) # value.kind_of?( Hash ) ? convert_hash( value ) : value
161
+
162
+ end
163
+
164
+ # TODO: document me
165
+ def apply_template( name )
166
+
167
+ recursive_merge!(
168
+ TDriver::Parameter.templates.fetch( name.to_s ){
169
+
170
+ raise MobyUtil::TemplateNotFoundError, "Template #{ name.inspect } not found"
171
+
172
+ }
173
+ )
174
+
175
+ end
176
+
177
+ # for backwards compatibility
178
+ def kind_of?( klass )
179
+
180
+ if klass == MobyUtil::ParameterHash
181
+
182
+ warn_caller '$1:$2 warning: deprecated class MobyUtil::ParameterHash, use TDriver::ParameterHash instead'
183
+
184
+ true
185
+
186
+ else
187
+
188
+ super klass
189
+
190
+ end
191
+
192
+ end
193
+
194
+ private
195
+
196
+ # TODO: document me
197
+ def convert_hash( value )
198
+
199
+ value.kind_of?( Hash ) ? ParameterHash[ value.collect{ | key, value | [ key, value.kind_of?( Hash ) ? convert_hash( value ) : value ] } ] : value
200
+
201
+ #value.class == Hash ? ParameterHash[ value.collect{ | key, value | [ key, value.class == Hash ? convert_hash( value ) : value ] } ] : value
202
+
203
+ end
204
+
205
+ TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
206
+
207
+ end # ParameterHash
208
+
209
+ class Parameter
210
+
211
+ # singleton and private methods
212
+ class << self
213
+
214
+ def new
215
+
216
+ warn_caller "$1:$2 warning: #{ to_s } is static class; unable initialize new instance of it"
217
+
218
+ nil
219
+
220
+ end
221
+
222
+ # TODO: document me
223
+ def init
224
+
225
+ # initialize only once
226
+ return if defined?( @initalized )
227
+
228
+ # retrieve platform name
229
+ @platform = MobyUtil::EnvironmentHelper.platform
230
+
231
+ # detect is posix platform
232
+ @is_posix = MobyUtil::EnvironmentHelper.posix?
233
+
234
+ # retrieve parameter filenames from command line arguments
235
+ parse_command_line_arguments
236
+
237
+ # reset templates and parameters
238
+ reset_hashes
239
+
240
+ # indicates that class is already initialized - templates and parameters will not reset
241
+ @initialized = true
242
+
243
+ end
244
+
245
+ private
246
+
247
+ def parse_command_line_arguments
248
+
249
+ # reset command line argument files list
250
+ @command_line_argument_files = []
251
+
252
+ capture_elements = false
253
+
254
+ ARGV.each_with_index do | value, index |
255
+
256
+ value = value.to_s
257
+
258
+ case value
259
+
260
+ when '--tdriver_parameters', '--matti_parameters'
261
+
262
+ warn "warning: #{ value } is deprecated, use -tdriver_parameters instead" if value == '--matti_parameters'
263
+
264
+ # capture following xml filenames
265
+ capture_elements = true
266
+
267
+ # mark element to be removed
268
+ ARGV[ index ] = nil
269
+
270
+ else
271
+
272
+ # process the string if capturing arguments
273
+ if capture_elements
274
+
275
+ # stop capturing if is a option (e.g. --version)
276
+ if [ '-' ].include?( value[ 0 ].chr )
277
+
278
+ capture_elements = false
279
+
280
+ # add argument to parameters list if meets the regexp and capture_element is true
281
+ elsif /\.xml$/i.match( value )
282
+
283
+ # expand filename
284
+ value = File.expand_path( value )
285
+
286
+ # raise exception if given file does not found
287
+ raise MobyUtil::FileNotFoundError, "User defined TDriver parameters file #{ value } does not exist" unless File.exist?( value )
288
+
289
+ # add file to command line arguments files
290
+ @command_line_argument_files << value
291
+
292
+ # mark element to be removed
293
+ ARGV[ index ] = nil
294
+
295
+ end # if
296
+
297
+ end # else
298
+
299
+ end # case
300
+
301
+ end # each_with_index
302
+
303
+ # raise exception if "--tdriver_parameters" option found but no filenames defined
304
+ if capture_elements && @command_line_argument_files.empty?
305
+
306
+ raise ArgumentError, 'TDriver parameters command line argument given without a filename'
307
+
308
+ end
309
+
310
+ # remove nil elements from array
311
+ ARGV.compact!
312
+
313
+ # return collected filenames
314
+ @command_line_argument_files
315
+
316
+ end
317
+
318
+ # TODO: document me
319
+ def initialize_class
320
+
321
+ # initialize only once
322
+ return if defined?( @parameters )
323
+
324
+ # class variables not used; read below article:
325
+ # http://www.oreillynet.com/ruby/blog/2007/01/nubygems_dont_use_class_variab_1.html
326
+
327
+ # parameters container
328
+ @parameters = ParameterHash.new
329
+
330
+ # templates container
331
+ @templates = ParameterHash.new
332
+
333
+ # platform enum
334
+ @platform = nil
335
+
336
+ # determine if platform is type of posix
337
+ @is_posix = nil
338
+
339
+ # list of loaded SUT's
340
+ @sut_list = []
341
+
342
+ # list of loaded parameter filenames
343
+ @parameter_files = []
344
+
345
+ # list of loaded template filenames
346
+ @template_files = []
347
+
348
+ # files defined in command line arguments
349
+ @command_line_argument_files = []
350
+
351
+ # templates cache
352
+ @cache = {}
353
+
354
+ end
355
+
356
+ # TODO: document me
357
+ def load_default_parameters
358
+
359
+ # collect all templates
360
+ Dir.glob( MobyUtil::FileHelper.expand_path( 'defaults/*.xml' ) ).each { | filename |
361
+
362
+ file_content = load_file( filename )
363
+
364
+ MobyUtil::XML.parse_string( file_content ).xpath( '*' ).each{ | element |
365
+
366
+ # merge new hash to parameters hash
367
+ @parameters.recursive_merge!(
368
+
369
+ # parse element and convert it to hash
370
+ process_element( element )
371
+
372
+ )
373
+
374
+ }
375
+
376
+ # add file to loaded parameter files list
377
+ @parameter_files << filename
378
+
379
+ }
380
+
381
+ end
382
+
383
+ # TODO: document me
384
+ def load_file( filename )
385
+
386
+ filename = MobyUtil::FileHelper.expand_path( filename )
387
+
388
+ begin
389
+
390
+ MobyUtil::FileHelper.get_file( filename )
391
+
392
+ rescue MobyUtil::EmptyFilenameError
393
+
394
+ raise $!, 'Unable to load parameters XML file due to filename is empty or nil'
395
+
396
+ rescue MobyUtil::FileNotFoundError
397
+
398
+ raise
399
+
400
+ rescue IOError
401
+
402
+ raise $!, "Error occured while loading xml file. Reason: #{ $!.message }"
403
+
404
+ rescue
405
+
406
+ raise MobyUtil::ParameterFileParseError, "Error occured while parsing parameters xml file #{ filename }\nDescription: #{ $!.message }"
407
+
408
+ end
409
+
410
+ end
411
+
412
+ # TODO: document me
413
+ def process_element( xml )
414
+
415
+ # calculate xml hash
416
+ xml_hash = xml.to_s.hash
417
+
418
+ return @cache[ xml_hash ] if @cache.has_key?( xml_hash )
419
+
420
+ # default results
421
+ results = ParameterHash.new
422
+
423
+ # go through each element in xml
424
+ xml.xpath( "*" ).each{ | element |
425
+
426
+ # retrieve element attributes as hash
427
+ attributes = element.attributes
428
+
429
+ # default value
430
+ value = attributes[ 'value' ]
431
+
432
+ # generic posix value - overwrites attribute["value"] if found
433
+ value = attributes[ 'posix' ] unless attributes[ 'posix' ].nil? if @is_posix
434
+
435
+ # platform specific value - overwrites existing value
436
+ value = attributes[ @platform.to_s ] unless attributes[ @platform.to_s ].nil?
437
+
438
+ # retrieve name attribute
439
+ name = attributes[ 'name' ]
440
+
441
+ case element.name
442
+
443
+ when 'include'
444
+
445
+ directory = MobyUtil::FileHelper.expand_path( attributes[ 'directory' ] )
446
+
447
+ files_pattern = Regexp.new( attributes[ 'files' ] )
448
+
449
+ =begin
450
+ pattern_flags = attributes[ 'flags' ].to_s.each_char.inject( 0 ){ | flags, char |
451
+
452
+ case char
453
+
454
+ when /m/i
455
+
456
+ flags += Regexp::MULTILINE
457
+
458
+ when /i/i
459
+
460
+ flags += Regexp::IGNORECASE
461
+
462
+ when /x/i
463
+
464
+ flags += Regexp::EXTENDED
465
+
466
+ else
467
+
468
+ raise ArgumentError, "Invalid regular expression pattern flag #{ char.inspect } (expected: 'm', 'i' or 'x')"
469
+
470
+ end
471
+
472
+ }
473
+ =end
474
+
475
+ value = ParameterHash.new
476
+
477
+ included_files = []
478
+
479
+ # iterate each found file from given directory
480
+ Dir.glob( File.join( directory, '*' ) ).each do | file |
481
+
482
+ # and merge content of the file if filename matches with given files pattern
483
+ if File.basename( file ) =~ files_pattern
484
+
485
+ value.merge!( process_file( file, false ) )
486
+
487
+ included_files << file
488
+
489
+ end
490
+
491
+ end
492
+
493
+ # merge included values to results
494
+ results.merge!( value )
495
+
496
+ # store included files to :included_files value
497
+ name = "included_files"
498
+
499
+ # append to :included files value
500
+ value = ( results[ name.to_sym, [] ].concat( included_files ) ).compact.uniq
501
+
502
+ when 'keymap'
503
+
504
+ # use element name as parameter name ("keymap")
505
+ name = element.name
506
+
507
+ # read xml file from given location if defined - otherwise pass content as is
508
+ if attributes[ 'xml_file' ]
509
+
510
+ # merge hash values (value type of hash)
511
+ value = process_file( attributes[ 'xml_file' ] )
512
+
513
+ else
514
+
515
+ # use element content as value
516
+ value = process_element( element )
517
+
518
+ end
519
+
520
+ # retrieve environment attribute from xml
521
+ env = attributes[ 'env' ].to_s
522
+
523
+ # set environment to 'default' unless defined in xml element
524
+ env = 'default' if env.empty?
525
+
526
+ # store keymap as hash
527
+ value = { env.to_sym => value, :all => value, :default_keymap => env.to_sym }
528
+
529
+ when 'fixture'
530
+
531
+ name.not_blank( "No name defined for fixture \"#{ element.to_s }\"", SyntaxError )
532
+
533
+ value = {
534
+
535
+ :plugin => attributes[ 'plugin' ].not_blank( "No name defined for fixture with value #{ name }", SyntaxError ),
536
+
537
+ :env => attributes[ 'env' ]
538
+
539
+ }
540
+
541
+ when 'parameter'
542
+
543
+ # verify that name attribute is defined
544
+ name.not_blank( "No name defined for parameter with value #{ value }", SyntaxError )
545
+
546
+ # return value as is
547
+ #value.not_nil( "No value defined for parameter with name #{ name }", SyntaxError )
548
+
549
+ value = '' if value.nil?
550
+
551
+ when 'method'
552
+
553
+ # verify that name attribute is defined
554
+ name.not_blank( "No name defined for parameter with value #{ value }", SyntaxError )
555
+
556
+ # return value as is
557
+ #value.not_nil( "No value defined for parameter with name #{ name }", SyntaxError )
558
+
559
+ value = attributes[ 'args' ]
560
+
561
+ when 'sut'
562
+
563
+ # use id as parameter name
564
+ name = attributes[ 'id' ]
565
+
566
+ # verify that name attribute is defined
567
+ name.not_blank( "No name defined for SUT \"#{ element.to_s }\"", SyntaxError )
568
+
569
+ # add SUT to found sut list
570
+ @sut_list << name unless @sut_list.include?( name )
571
+
572
+ # retrieve names of used templates
573
+ templates = attributes[ 'template' ]
574
+
575
+ # empty value by default
576
+ value = ParameterHash.new
577
+
578
+ unless templates.blank?
579
+
580
+ # retrieve each defined template
581
+ templates.split( ';' ).each{ | template |
582
+
583
+ # merge template with current value hash
584
+ value.recursive_merge!(
585
+
586
+ # retrieve template
587
+ get_template( template )
588
+
589
+ )
590
+
591
+ }
592
+
593
+ end
594
+
595
+ # merge sut content with template values
596
+ value.recursive_merge!( process_element( element ) )
597
+
598
+ else
599
+
600
+ # use element name as parameter name (e.g. fixture, keymap etc)
601
+ name = element.name
602
+
603
+ # read xml file from given location if defined - otherwise pass content as is
604
+ if attributes[ 'xml_file' ]
605
+
606
+ # merge hash values (value type of hash)
607
+ value = process_file( attributes[ 'xml_file' ] )
608
+
609
+ else
610
+
611
+ # use element content as value
612
+ value = process_element( element )
613
+
614
+ end
615
+
616
+ end
617
+
618
+ # store values to parameters
619
+ results[ name.to_sym ] = value
620
+
621
+ }
622
+
623
+ # store to cache and return hash as result
624
+ @cache[ xml_hash ] = results
625
+
626
+ end
627
+
628
+ # TODO: document me
629
+ def parse_template( name )
630
+
631
+ template = @templates[ name ]
632
+
633
+ unless template.kind_of?( Hash )
634
+
635
+ result = ParameterHash.new
636
+
637
+ # retrieve each inherited template
638
+ template[ 'inherits' ].to_s.split(";").each{ | inherited_template |
639
+
640
+ result.recursive_merge!(
641
+
642
+ parse_template( inherited_template )
643
+
644
+ )
645
+
646
+ }
647
+
648
+ # merge template content with inherited templates and store to templates hash table
649
+ @templates[ name ] = result.recursive_merge!(
650
+
651
+ process_element( template )
652
+
653
+ )
654
+
655
+ else
656
+
657
+ # template is already parsed, pass template hash as is
658
+ template
659
+
660
+ end
661
+
662
+ end
663
+
664
+ # TODO: document me
665
+ def load_templates
666
+
667
+ # collect all templates
668
+ Dir.glob( MobyUtil::FileHelper.expand_path( 'templates/*.xml' ) ).each { | filename |
669
+
670
+ unless @template_files.include?( filename )
671
+
672
+ # read file content
673
+ file_content = load_file( filename )
674
+
675
+ MobyUtil::XML.parse_string( file_content ).root.xpath( 'template' ).each{ | template |
676
+
677
+ # store template element to hash
678
+ @templates[ template[ 'name' ] ] = template
679
+
680
+ }
681
+
682
+ # add file to loaded templates files list
683
+ @template_files << filename
684
+
685
+ end
686
+
687
+ }
688
+
689
+ # parse templates hash; convert elements to hash
690
+ @templates.each_pair{ | name, template |
691
+
692
+ # convert element to hash
693
+ parse_template( name )
694
+
695
+ }
696
+
697
+ end
698
+
699
+ # TODO: document me
700
+ def get_template( name )
701
+
702
+ @templates.fetch( name ){
703
+
704
+ # return empty hash if template not found
705
+ ParameterHash.new
706
+
707
+ }
708
+
709
+ end
710
+
711
+ # TODO: document me
712
+ def reset_hashes( options = {} )
713
+
714
+ # default options
715
+ options.default_values(
716
+
717
+ :reset_templates => true,
718
+ :reset_parameters => true,
719
+
720
+ :load_default_parameters => true,
721
+ :load_user_parameters => true,
722
+ :load_command_line_parameters => true
723
+
724
+ )
725
+
726
+ # empty parameters hash
727
+ if options[ :reset_parameters ] == true
728
+
729
+ @parameter_files.clear
730
+
731
+ @parameters.clear
732
+
733
+ end
734
+
735
+ if options[ :reset_templates ] == true
736
+
737
+ @template_files.clear
738
+
739
+ # empty templates hash
740
+ @templates.clear
741
+
742
+ # load parameter templates
743
+ load_templates
744
+
745
+ end
746
+
747
+ # apply global parameters to root level (e.g. TDriver::Parameter[ :logging_outputter_enabled ])
748
+ @parameters.recursive_merge!(
749
+
750
+ get_template( 'global' )
751
+
752
+ )
753
+
754
+ # load and apply default parameter values
755
+ load_default_parameters if options[ :load_default_parameters ] == true
756
+
757
+ # load main parameter configuraion file
758
+ load_parameters_file( 'tdriver_parameters.xml' ) if options[ :load_user_parameters ] == true
759
+
760
+ if options[ :load_command_line_parameters ] == true
761
+
762
+ @command_line_argument_files.each{ | filename |
763
+
764
+ load_parameters_file( filename )
765
+
766
+ }
767
+
768
+ end
769
+
770
+ end
771
+
772
+ # TODO: document me
773
+ def process_file( filename, root = true )
774
+
775
+ begin
776
+
777
+ # load content from file
778
+ file_content = load_file( filename )
779
+
780
+ # parse file content and retrieve root element
781
+ root_element = MobyUtil::XML.parse_string( file_content ) #.root
782
+
783
+ root_element = root_element.root if root == true
784
+
785
+ # parse root element
786
+ process_element( root_element )
787
+
788
+ rescue MobyUtil::FileNotFoundError
789
+
790
+ raise $!, "Parameters file #{ MobyUtil::FileHelper.expand_path( filename ) } does not exist"
791
+
792
+ rescue
793
+
794
+ raise MobyUtil::ParameterFileParseError, "Error occured while parsing parameters XML file #{ filename }. Reason: #{ $!.message } (#{ $!.class })"
795
+
796
+ end
797
+
798
+ end
799
+
800
+ def process_string( source )
801
+
802
+ begin
803
+
804
+ # parse file content and retrieve root element
805
+ root_element = MobyUtil::XML.parse_string( source ).root
806
+
807
+ # parse root element
808
+ process_element( root_element )
809
+
810
+ rescue
811
+
812
+ raise MobyUtil::ParameterXmlParseError, "Error occured while parsing parameters XML string. Reason: #{ $!.message } (#{ $!.class })"
813
+
814
+ end
815
+
816
+ end
817
+
818
+ def load_parameters_file( filename )
819
+
820
+ filename = MobyUtil::FileHelper.expand_path( filename )
821
+
822
+ unless @parameter_files.include?( filename )
823
+
824
+ begin
825
+
826
+ @parameters.recursive_merge!(
827
+
828
+ process_file( filename )
829
+
830
+ )
831
+
832
+ rescue MobyUtil::FileNotFoundError
833
+
834
+ raise $!, "Parameters file #{ filename } does not exist"
835
+
836
+ end
837
+
838
+ # add file to loaded parameter files list
839
+ @parameter_files << filename
840
+
841
+ end # unless
842
+
843
+ end # def
844
+
845
+ end # self
846
+
847
+ class << self
848
+
849
+ # TODO: document me
850
+ def parse_file( filename, reset_parameters = false )
851
+
852
+ # check argument type for filename
853
+ filename.check_type [ String ], 'wrong argument type $1 for filename argument (expected $2)'
854
+
855
+ # check argument type for filename
856
+ reset_parameters.check_type [ TrueClass, FalseClass ], 'wrong argument type $1 for reset_parameters boolean argument (expected $2)'
857
+
858
+ # reset parameter hash if requested
859
+ @parameters.clear if reset_parameters == true
860
+
861
+ # load and parse given file
862
+ load_parameters_file( filename )
863
+
864
+ end
865
+
866
+ # TODO: document me
867
+ def parse_string( source, merge_hashes = true )
868
+
869
+ # check argument type for source
870
+ source.check_type [ String ], 'wrong argument type $1 for source XML argument (expected $2)'
871
+
872
+ # check argument type for merge_hashes
873
+ merge_hashes.check_type [ TrueClass, FalseClass ], 'wrong argument type $1 for merge_hashes argument (expected $2)'
874
+
875
+ # process xml string, returns hash as result
876
+ hash = process_string( source )
877
+
878
+ if merge_hashes
879
+
880
+ @parameters.recursive_merge!( hash )
881
+
882
+ else
883
+
884
+ @parameters.merge!( hash )
885
+
886
+ end
887
+
888
+ end
889
+
890
+ # TODO: document me
891
+ def clear
892
+
893
+ @parameter_files.clear
894
+
895
+ @parameters.clear
896
+
897
+ end
898
+
899
+ # TODO: document me
900
+ def files
901
+
902
+ # return loaded parameter files list
903
+ @parameter_files
904
+
905
+ end
906
+
907
+ # TODO: document me
908
+ def template_files
909
+
910
+ # return loaded parameter files list
911
+ @template_files
912
+
913
+ end
914
+
915
+ # TODO: document me
916
+ def has_template?( name )
917
+
918
+ @templates.has_key?( name.to_s )
919
+
920
+ end
921
+
922
+ # TODO: document me
923
+ def apply_template( name )
924
+
925
+ @parameters.recursive_merge!(
926
+ @templates.fetch( name.to_s ){
927
+ raise MobyUtil::TemplateNotFoundError, "Template #{ name.inspect } not found"
928
+ }
929
+ )
930
+
931
+ end
932
+
933
+ # TODO: document me
934
+ def has_key?( key )
935
+
936
+ @parameters.has_key?( key )
937
+
938
+ end
939
+
940
+ # TODO: document me
941
+ def has_value?( key )
942
+
943
+ @parameters.has_value?( key )
944
+
945
+ end
946
+
947
+ # TODO: document me
948
+ def keys
949
+
950
+ @parameters.keys
951
+
952
+ end
953
+
954
+ # TODO: document me
955
+ def values
956
+
957
+ @parameters.values
958
+
959
+ end
960
+
961
+ # TODO: document me
962
+ def []( key, *default )
963
+
964
+ @parameters[ key, *default ]
965
+
966
+ end
967
+
968
+ # TODO: document me
969
+ def []=( key, value )
970
+
971
+ @parameters[ key ] = value
972
+
973
+ end
974
+
975
+ # TODO: document me
976
+ def fetch( key, *default, &block )
977
+
978
+ @parameters.__send__( :[], key, *default, &block )
979
+
980
+ end
981
+
982
+ # TODO: document me
983
+ def if_found( key, &block )
984
+
985
+ @parameters.__send__( :if_found, key, &block )
986
+
987
+ end
988
+
989
+ # TODO: document me
990
+ def delete( key )
991
+
992
+ @parameters.delete( key )
993
+
994
+ end
995
+
996
+ # TODO: document me
997
+ def inspect
998
+
999
+ @parameters.inspect
1000
+
1001
+ end
1002
+
1003
+ # TODO: document me
1004
+ def templates
1005
+
1006
+ @templates
1007
+
1008
+ end
1009
+
1010
+ def parameters
1011
+
1012
+ warn "warning: deprecated method #{ self.name }##{ __method__ }; please use #{ self.name }#hash instead"
1013
+
1014
+ hash
1015
+
1016
+ end
1017
+
1018
+ def hash
1019
+
1020
+ @parameters
1021
+
1022
+ end
1023
+
1024
+ # TODO: document me
1025
+ def reset
1026
+
1027
+ reset_hashes
1028
+
1029
+ end
1030
+
1031
+ # TODO: document me
1032
+ def configured_suts
1033
+
1034
+ @sut_list
1035
+
1036
+ end
1037
+
1038
+ # deprecated methods
1039
+ def reset_parameters
1040
+
1041
+ warn "warning: deprecated method #{ self.name }##{ __method__ }; please use #{ self.name }#reset instead"
1042
+
1043
+ reset
1044
+
1045
+ end
1046
+
1047
+ # load parameter xml files
1048
+ def load_parameters_xml( filename, reset = false )
1049
+
1050
+ warn "warning: deprecated method #{ self.name }##{ __method__ }; please use #{ self.name }#parse_file instead"
1051
+
1052
+ parse_file( filename, reset )
1053
+
1054
+ end
1055
+
1056
+ end
1057
+
1058
+ TDriver::Hooking.hook_methods( self ) if defined?( TDriver::Hooking )
1059
+
1060
+ # initialize parameters class
1061
+ initialize_class
1062
+
1063
+ end # Parameter
1064
+
1065
+ end
1066
+
1067
+ module MobyUtil
1068
+
1069
+ class ParameterHash
1070
+
1071
+ class << self
1072
+
1073
+ def new
1074
+
1075
+ warn_caller "$1:$2 warning: #{ to_s } is deprecated; use TDriver::ParameterHash instead"
1076
+
1077
+ TDriver::ParameterHash.new
1078
+
1079
+ end
1080
+
1081
+ end # self
1082
+
1083
+ end # ParameterHash
1084
+
1085
+ class Parameter
1086
+
1087
+ class << self
1088
+
1089
+ undef :inspect if respond_to?( :inspect )
1090
+
1091
+ def new
1092
+
1093
+ warn_caller "$1:$2 warning: #{ to_s } is static class; unable initialize new instance of it"
1094
+
1095
+ nil
1096
+
1097
+ end
1098
+
1099
+ def method_missing( id, *args )
1100
+
1101
+ warn_caller "$1:$2 warning: deprecated method; use TDriver::Parameter##{ id.to_s } instead of MobyUtil::Parameter##{ id.to_s }"
1102
+
1103
+ TDriver::Parameter.__send__( id, *args )
1104
+
1105
+ end
1106
+
1107
+ # TODO: document me
1108
+ def instance
1109
+
1110
+ warn_caller "$1:$2 warning: deprecated method #{ self.name }##{ __method__ }; please use #{ self.name } class static methods instead"
1111
+
1112
+ TDriver::Parameter
1113
+
1114
+ end
1115
+
1116
+ end # self
1117
+
1118
+ end # Parameter
1119
+
1120
+ class ParameterUserAPI
1121
+
1122
+ class << self
1123
+
1124
+ undef :inspect if respond_to?( :inspect )
1125
+
1126
+ def new
1127
+
1128
+ warn_caller "$1:$2 warning: #{ to_s } is static class; unable initialize new instance of it"
1129
+
1130
+ nil
1131
+
1132
+ end
1133
+
1134
+ def method_missing( id, *args )
1135
+
1136
+ warn_caller "$1:$2 warning: deprecated method; use TDriver::ParameterUserAPI##{ id.to_s } instead of MobyUtil::ParameterUserAPI##{ id.to_s }"
1137
+
1138
+ TDriver::ParameterUserAPI.__send__( id, *args )
1139
+
1140
+ end
1141
+
1142
+ # TODO: document me
1143
+ def instance
1144
+
1145
+ warn_caller "$1:$2 warning: deprecated method #{ self.name }##{ __method__ }; please use #{ self.name } class static methods instead"
1146
+
1147
+ TDriver::ParameterUserAPI
1148
+
1149
+ end
1150
+
1151
+ end # self
1152
+
1153
+ end # ParameterUserAPI
1154
+
1155
+ end # MobyUtil
1156
+
1157
+ # set global variable pointing to parameter class
1158
+ $parameters = TDriver::Parameter #MobyUtil::Parameter
1159
+
1160
+ # set global variable pointing to parameter API class
1161
+ $parameters_api = TDriver::ParameterUserAPI