jmeter_perf 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (275) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +19 -0
  4. data/.standard.yml +4 -0
  5. data/CHANGELOG.md +18 -0
  6. data/DSL.md +235 -0
  7. data/README.md +24 -0
  8. data/Rakefile +12 -0
  9. data/example/Gemfile +39 -0
  10. data/example/Gemfile.lock +232 -0
  11. data/example/README.md +3 -0
  12. data/example/Rakefile +6 -0
  13. data/example/app/controllers/application_controller.rb +2 -0
  14. data/example/app/controllers/test_controller.rb +15 -0
  15. data/example/bin/bundle +109 -0
  16. data/example/bin/docker-entrypoint +8 -0
  17. data/example/bin/rails +4 -0
  18. data/example/bin/rake +4 -0
  19. data/example/bin/setup +33 -0
  20. data/example/config/application.rb +44 -0
  21. data/example/config/boot.rb +3 -0
  22. data/example/config/credentials.yml.enc +1 -0
  23. data/example/config/database.yml +25 -0
  24. data/example/config/environment.rb +5 -0
  25. data/example/config/environments/development.rb +64 -0
  26. data/example/config/environments/production.rb +82 -0
  27. data/example/config/environments/test.rb +61 -0
  28. data/example/config/initializers/cors.rb +16 -0
  29. data/example/config/initializers/filter_parameter_logging.rb +8 -0
  30. data/example/config/initializers/inflections.rb +16 -0
  31. data/example/config/locales/en.yml +31 -0
  32. data/example/config/puma.rb +35 -0
  33. data/example/config/routes.rb +5 -0
  34. data/example/config.ru +7 -0
  35. data/example/fast.log +49 -0
  36. data/example/jmeter.log +28 -0
  37. data/example/lib/tasks/test.rake +40 -0
  38. data/example/log/.keep +0 -0
  39. data/example/public/robots.txt +1 -0
  40. data/example/random.log +49 -0
  41. data/example/slow.log +49 -0
  42. data/example/vendor/.keep +0 -0
  43. data/lib/Rakefile +4 -0
  44. data/lib/jmeter_perf/dsl/access_log_sampler.rb +38 -0
  45. data/lib/jmeter_perf/dsl/aggregate_graph.rb +61 -0
  46. data/lib/jmeter_perf/dsl/aggregate_report.rb +61 -0
  47. data/lib/jmeter_perf/dsl/ajp13_sampler.rb +47 -0
  48. data/lib/jmeter_perf/dsl/assertion_results.rb +61 -0
  49. data/lib/jmeter_perf/dsl/bean_shell_assertion.rb +34 -0
  50. data/lib/jmeter_perf/dsl/bean_shell_listener.rb +34 -0
  51. data/lib/jmeter_perf/dsl/bean_shell_postprocessor.rb +34 -0
  52. data/lib/jmeter_perf/dsl/bean_shell_preprocessor.rb +34 -0
  53. data/lib/jmeter_perf/dsl/bean_shell_sampler.rb +34 -0
  54. data/lib/jmeter_perf/dsl/bean_shell_timer.rb +34 -0
  55. data/lib/jmeter_perf/dsl/bsf_assertion.rb +34 -0
  56. data/lib/jmeter_perf/dsl/bsf_listener.rb +34 -0
  57. data/lib/jmeter_perf/dsl/bsf_postprocessor.rb +34 -0
  58. data/lib/jmeter_perf/dsl/bsf_preprocessor.rb +34 -0
  59. data/lib/jmeter_perf/dsl/bsf_sampler.rb +34 -0
  60. data/lib/jmeter_perf/dsl/bsf_timer.rb +34 -0
  61. data/lib/jmeter_perf/dsl/compare_assertion.rb +33 -0
  62. data/lib/jmeter_perf/dsl/comparison_assertion_visualizer.rb +61 -0
  63. data/lib/jmeter_perf/dsl/constant_throughput_timer.rb +32 -0
  64. data/lib/jmeter_perf/dsl/constant_timer.rb +31 -0
  65. data/lib/jmeter_perf/dsl/counter.rb +37 -0
  66. data/lib/jmeter_perf/dsl/css_jquery_extractor.rb +37 -0
  67. data/lib/jmeter_perf/dsl/csv_data_set_config.rb +39 -0
  68. data/lib/jmeter_perf/dsl/debug_postprocessor.rb +34 -0
  69. data/lib/jmeter_perf/dsl/debug_sampler.rb +33 -0
  70. data/lib/jmeter_perf/dsl/distribution_graphalpha.rb +61 -0
  71. data/lib/jmeter_perf/dsl/duration_assertion.rb +31 -0
  72. data/lib/jmeter_perf/dsl/for_each_controller.rb +33 -0
  73. data/lib/jmeter_perf/dsl/ftp_request.rb +40 -0
  74. data/lib/jmeter_perf/dsl/ftp_request_defaults.rb +38 -0
  75. data/lib/jmeter_perf/dsl/gaussian_random_timer.rb +32 -0
  76. data/lib/jmeter_perf/dsl/generate_summary_results.rb +29 -0
  77. data/lib/jmeter_perf/dsl/graph_results.rb +61 -0
  78. data/lib/jmeter_perf/dsl/html_assertion.rb +36 -0
  79. data/lib/jmeter_perf/dsl/html_link_parser.rb +29 -0
  80. data/lib/jmeter_perf/dsl/html_parameter_mask.rb +38 -0
  81. data/lib/jmeter_perf/dsl/http_authorization_manager.rb +39 -0
  82. data/lib/jmeter_perf/dsl/http_cache_manager.rb +32 -0
  83. data/lib/jmeter_perf/dsl/http_cookie_manager.rb +34 -0
  84. data/lib/jmeter_perf/dsl/http_header_manager.rb +36 -0
  85. data/lib/jmeter_perf/dsl/http_request.rb +47 -0
  86. data/lib/jmeter_perf/dsl/http_request_defaults.rb +53 -0
  87. data/lib/jmeter_perf/dsl/http_url_rewriting_modifier.rb +36 -0
  88. data/lib/jmeter_perf/dsl/if_controller.rb +33 -0
  89. data/lib/jmeter_perf/dsl/include_controller.rb +31 -0
  90. data/lib/jmeter_perf/dsl/j_unit_request.rb +43 -0
  91. data/lib/jmeter_perf/dsl/java_request.rb +75 -0
  92. data/lib/jmeter_perf/dsl/java_request_defaults.rb +75 -0
  93. data/lib/jmeter_perf/dsl/jdbc_connection_configuration.rb +43 -0
  94. data/lib/jmeter_perf/dsl/jdbc_postprocessor.rb +39 -0
  95. data/lib/jmeter_perf/dsl/jdbc_preprocessor.rb +39 -0
  96. data/lib/jmeter_perf/dsl/jdbc_request.rb +39 -0
  97. data/lib/jmeter_perf/dsl/jms_pointto_point.rb +47 -0
  98. data/lib/jmeter_perf/dsl/jms_publisher.rb +49 -0
  99. data/lib/jmeter_perf/dsl/jms_subscriber.rb +41 -0
  100. data/lib/jmeter_perf/dsl/json_path_postprocessor.rb +33 -0
  101. data/lib/jmeter_perf/dsl/jsr223_assertion.rb +35 -0
  102. data/lib/jmeter_perf/dsl/jsr223_listener.rb +35 -0
  103. data/lib/jmeter_perf/dsl/jsr223_postprocessor.rb +35 -0
  104. data/lib/jmeter_perf/dsl/jsr223_preprocessor.rb +35 -0
  105. data/lib/jmeter_perf/dsl/jsr223_sampler.rb +35 -0
  106. data/lib/jmeter_perf/dsl/jsr223_timer.rb +35 -0
  107. data/lib/jmeter_perf/dsl/keystore_configuration.rb +34 -0
  108. data/lib/jmeter_perf/dsl/ldap_extended_request.rb +48 -0
  109. data/lib/jmeter_perf/dsl/ldap_extended_request_defaults.rb +48 -0
  110. data/lib/jmeter_perf/dsl/ldap_request.rb +41 -0
  111. data/lib/jmeter_perf/dsl/ldap_request_defaults.rb +45 -0
  112. data/lib/jmeter_perf/dsl/login_config_element.rb +32 -0
  113. data/lib/jmeter_perf/dsl/loop_controller.rb +32 -0
  114. data/lib/jmeter_perf/dsl/mail_reader_sampler.rb +43 -0
  115. data/lib/jmeter_perf/dsl/mailer_visualizer.rb +70 -0
  116. data/lib/jmeter_perf/dsl/md5_hex_assertion.rb +31 -0
  117. data/lib/jmeter_perf/dsl/module_controller.rb +31 -0
  118. data/lib/jmeter_perf/dsl/monitor_results.rb +61 -0
  119. data/lib/jmeter_perf/dsl/once_only_controller.rb +29 -0
  120. data/lib/jmeter_perf/dsl/os_process_sampler.rb +40 -0
  121. data/lib/jmeter_perf/dsl/poisson_random_timer.rb +32 -0
  122. data/lib/jmeter_perf/dsl/random_controller.rb +31 -0
  123. data/lib/jmeter_perf/dsl/random_order_controller.rb +29 -0
  124. data/lib/jmeter_perf/dsl/random_variable.rb +36 -0
  125. data/lib/jmeter_perf/dsl/recording_controller.rb +29 -0
  126. data/lib/jmeter_perf/dsl/reg_ex_user_parameters.rb +33 -0
  127. data/lib/jmeter_perf/dsl/regular_expression_extractor.rb +38 -0
  128. data/lib/jmeter_perf/dsl/response_assertion.rb +37 -0
  129. data/lib/jmeter_perf/dsl/response_time_graph.rb +61 -0
  130. data/lib/jmeter_perf/dsl/result_status_action_handler.rb +31 -0
  131. data/lib/jmeter_perf/dsl/runtime_controller.rb +31 -0
  132. data/lib/jmeter_perf/dsl/save_responses_to_a_file.rb +35 -0
  133. data/lib/jmeter_perf/dsl/simple_config_element.rb +29 -0
  134. data/lib/jmeter_perf/dsl/simple_controller.rb +29 -0
  135. data/lib/jmeter_perf/dsl/simple_data_writer.rb +61 -0
  136. data/lib/jmeter_perf/dsl/smime_assertion.rb +41 -0
  137. data/lib/jmeter_perf/dsl/smtp_sampler.rb +57 -0
  138. data/lib/jmeter_perf/dsl/soap_xml_rpc_request.rb +39 -0
  139. data/lib/jmeter_perf/dsl/spline_visualizer.rb +61 -0
  140. data/lib/jmeter_perf/dsl/summary_report.rb +61 -0
  141. data/lib/jmeter_perf/dsl/switch_controller.rb +31 -0
  142. data/lib/jmeter_perf/dsl/synchronizing_timer.rb +32 -0
  143. data/lib/jmeter_perf/dsl/tcp_sampler.rb +39 -0
  144. data/lib/jmeter_perf/dsl/tcp_sampler_config.rb +37 -0
  145. data/lib/jmeter_perf/dsl/test_action.rb +33 -0
  146. data/lib/jmeter_perf/dsl/test_fragment.rb +29 -0
  147. data/lib/jmeter_perf/dsl/test_plan.rb +37 -0
  148. data/lib/jmeter_perf/dsl/thread_group.rb +43 -0
  149. data/lib/jmeter_perf/dsl/throughput_controller.rb +38 -0
  150. data/lib/jmeter_perf/dsl/transaction_controller.rb +32 -0
  151. data/lib/jmeter_perf/dsl/uniform_random_timer.rb +32 -0
  152. data/lib/jmeter_perf/dsl/user_defined_variables.rb +39 -0
  153. data/lib/jmeter_perf/dsl/user_parameters.rb +36 -0
  154. data/lib/jmeter_perf/dsl/view_results_in_table.rb +61 -0
  155. data/lib/jmeter_perf/dsl/view_results_tree.rb +61 -0
  156. data/lib/jmeter_perf/dsl/while_controller.rb +31 -0
  157. data/lib/jmeter_perf/dsl/x_path_assertion.rb +37 -0
  158. data/lib/jmeter_perf/dsl/x_path_extractor.rb +37 -0
  159. data/lib/jmeter_perf/dsl/xml_assertion.rb +29 -0
  160. data/lib/jmeter_perf/dsl/xml_schema_assertion.rb +31 -0
  161. data/lib/jmeter_perf/extend/assertions/response_assertion.rb +38 -0
  162. data/lib/jmeter_perf/extend/config_elements/header_manager.rb +13 -0
  163. data/lib/jmeter_perf/extend/config_elements/http_cache_manager.rb +12 -0
  164. data/lib/jmeter_perf/extend/config_elements/http_cookie_manager.rb +39 -0
  165. data/lib/jmeter_perf/extend/config_elements/http_request_defaults.rb +55 -0
  166. data/lib/jmeter_perf/extend/config_elements/user_defined_variables.rb +13 -0
  167. data/lib/jmeter_perf/extend/config_elements/user_parameters.rb +31 -0
  168. data/lib/jmeter_perf/extend/controllers/foreach_controller.rb +31 -0
  169. data/lib/jmeter_perf/extend/controllers/loop_controller.rb +11 -0
  170. data/lib/jmeter_perf/extend/controllers/module_controller.rb +26 -0
  171. data/lib/jmeter_perf/extend/controllers/throughput_controller.rb +15 -0
  172. data/lib/jmeter_perf/extend/controllers/transaction_controller.rb +14 -0
  173. data/lib/jmeter_perf/extend/misc/exists.rb +13 -0
  174. data/lib/jmeter_perf/extend/misc/rsync.rb +24 -0
  175. data/lib/jmeter_perf/extend/misc/uuid.rb +12 -0
  176. data/lib/jmeter_perf/extend/misc/with_helpers.rb +27 -0
  177. data/lib/jmeter_perf/extend/plugins/jmeter_plugins.rb +124 -0
  178. data/lib/jmeter_perf/extend/processors/extract.rb +27 -0
  179. data/lib/jmeter_perf/extend/processors/regular_expression_extractor.rb +27 -0
  180. data/lib/jmeter_perf/extend/samplers/http_request.rb +66 -0
  181. data/lib/jmeter_perf/extend/samplers/jms_pointtopoint.rb +23 -0
  182. data/lib/jmeter_perf/extend/samplers/soapxmlrpc_request.rb +10 -0
  183. data/lib/jmeter_perf/extend/threads/thread_group.rb +19 -0
  184. data/lib/jmeter_perf/extend/timers/constant_throughput_timer.rb +11 -0
  185. data/lib/jmeter_perf/extend/timers/random_timer.rb +14 -0
  186. data/lib/jmeter_perf/helpers/dsl_generator.rb +157 -0
  187. data/lib/jmeter_perf/helpers/fallback_content_proxy.rb +96 -0
  188. data/lib/jmeter_perf/helpers/helper.rb +63 -0
  189. data/lib/jmeter_perf/helpers/parser.rb +143 -0
  190. data/lib/jmeter_perf/helpers/running_statistics.rb +62 -0
  191. data/lib/jmeter_perf/helpers/string.rb +60 -0
  192. data/lib/jmeter_perf/helpers/user-agents.rb +42 -0
  193. data/lib/jmeter_perf/plugins/active_threads_over_time.rb +59 -0
  194. data/lib/jmeter_perf/plugins/composite_graph.rb +77 -0
  195. data/lib/jmeter_perf/plugins/console_status_logger.rb +19 -0
  196. data/lib/jmeter_perf/plugins/dummy_sampler.rb +30 -0
  197. data/lib/jmeter_perf/plugins/jmx_collector.rb +74 -0
  198. data/lib/jmeter_perf/plugins/json_path_assertion.rb +23 -0
  199. data/lib/jmeter_perf/plugins/json_path_extractor.rb +22 -0
  200. data/lib/jmeter_perf/plugins/latencies_over_time.rb +53 -0
  201. data/lib/jmeter_perf/plugins/loadosophia_uploader.rb +66 -0
  202. data/lib/jmeter_perf/plugins/perfmon_collector.rb +87 -0
  203. data/lib/jmeter_perf/plugins/redis_data_set.rb +43 -0
  204. data/lib/jmeter_perf/plugins/response_codes_per_second.rb +53 -0
  205. data/lib/jmeter_perf/plugins/response_times_distribution.rb +53 -0
  206. data/lib/jmeter_perf/plugins/response_times_over_time.rb +53 -0
  207. data/lib/jmeter_perf/plugins/response_times_percentiles.rb +54 -0
  208. data/lib/jmeter_perf/plugins/stepping_thread_group.rb +34 -0
  209. data/lib/jmeter_perf/plugins/transactions_per_second.rb +53 -0
  210. data/lib/jmeter_perf/plugins/ultimate_thread_group.rb +28 -0
  211. data/lib/jmeter_perf/plugins/variable_throughput_timer.rb +35 -0
  212. data/lib/jmeter_perf/report/comparator.rb +258 -0
  213. data/lib/jmeter_perf/report/summary.rb +268 -0
  214. data/lib/jmeter_perf/tasks/dsl.rake +19 -0
  215. data/lib/jmeter_perf/version.rb +5 -0
  216. data/lib/jmeter_perf/views/report_template.html.erb +114 -0
  217. data/lib/jmeter_perf.rb +183 -0
  218. data/lib/specifications/idl.xml +1494 -0
  219. data/sig/jmeter_perf.rbs +195 -0
  220. data/sorbet/config +5 -0
  221. data/sorbet/rbi/annotations/.gitattributes +1 -0
  222. data/sorbet/rbi/annotations/rainbow.rbi +269 -0
  223. data/sorbet/rbi/gems/.gitattributes +1 -0
  224. data/sorbet/rbi/gems/ast@2.4.2.rbi +585 -0
  225. data/sorbet/rbi/gems/bump@0.10.0.rbi +169 -0
  226. data/sorbet/rbi/gems/byebug@11.1.3.rbi +3607 -0
  227. data/sorbet/rbi/gems/coderay@1.1.3.rbi +3427 -0
  228. data/sorbet/rbi/gems/diff-lcs@1.5.1.rbi +1131 -0
  229. data/sorbet/rbi/gems/docile@1.4.1.rbi +377 -0
  230. data/sorbet/rbi/gems/erubi@1.13.0.rbi +150 -0
  231. data/sorbet/rbi/gems/json@2.7.2.rbi +1562 -0
  232. data/sorbet/rbi/gems/language_server-protocol@3.17.0.3.rbi +14238 -0
  233. data/sorbet/rbi/gems/lint_roller@1.1.0.rbi +240 -0
  234. data/sorbet/rbi/gems/method_source@1.1.0.rbi +304 -0
  235. data/sorbet/rbi/gems/netrc@0.11.0.rbi +159 -0
  236. data/sorbet/rbi/gems/nokogiri@1.16.7.rbi +7311 -0
  237. data/sorbet/rbi/gems/parallel@1.26.3.rbi +291 -0
  238. data/sorbet/rbi/gems/parser@3.3.5.0.rbi +5519 -0
  239. data/sorbet/rbi/gems/prism@1.2.0.rbi +39085 -0
  240. data/sorbet/rbi/gems/pry-byebug@3.10.1.rbi +1151 -0
  241. data/sorbet/rbi/gems/pry@0.14.2.rbi +10076 -0
  242. data/sorbet/rbi/gems/racc@1.8.1.rbi +162 -0
  243. data/sorbet/rbi/gems/rainbow@3.1.1.rbi +403 -0
  244. data/sorbet/rbi/gems/rake@13.2.1.rbi +3074 -0
  245. data/sorbet/rbi/gems/rbi@0.2.1.rbi +4535 -0
  246. data/sorbet/rbi/gems/rbtree3@0.7.1.rbi +9 -0
  247. data/sorbet/rbi/gems/regexp_parser@2.9.2.rbi +3772 -0
  248. data/sorbet/rbi/gems/rexml@3.3.8.rbi +4858 -0
  249. data/sorbet/rbi/gems/rspec-core@3.13.1.rbi +11132 -0
  250. data/sorbet/rbi/gems/rspec-expectations@3.13.3.rbi +8183 -0
  251. data/sorbet/rbi/gems/rspec-mocks@3.13.1.rbi +5341 -0
  252. data/sorbet/rbi/gems/rspec-support@3.13.1.rbi +1630 -0
  253. data/sorbet/rbi/gems/rspec@3.13.0.rbi +83 -0
  254. data/sorbet/rbi/gems/rubocop-ast@1.32.3.rbi +7054 -0
  255. data/sorbet/rbi/gems/rubocop-performance@1.21.1.rbi +9 -0
  256. data/sorbet/rbi/gems/rubocop@1.65.1.rbi +58182 -0
  257. data/sorbet/rbi/gems/ruby-progressbar@1.13.0.rbi +1318 -0
  258. data/sorbet/rbi/gems/simplecov-html@0.13.1.rbi +225 -0
  259. data/sorbet/rbi/gems/simplecov@0.22.0.rbi +2149 -0
  260. data/sorbet/rbi/gems/simplecov_json_formatter@0.1.4.rbi +9 -0
  261. data/sorbet/rbi/gems/spoom@1.5.0.rbi +4932 -0
  262. data/sorbet/rbi/gems/standard-custom@1.0.2.rbi +9 -0
  263. data/sorbet/rbi/gems/standard-performance@1.4.0.rbi +9 -0
  264. data/sorbet/rbi/gems/standard@1.40.0.rbi +926 -0
  265. data/sorbet/rbi/gems/tapioca@0.16.3.rbi +3596 -0
  266. data/sorbet/rbi/gems/tdigest@0.2.1.rbi +170 -0
  267. data/sorbet/rbi/gems/thor@1.3.2.rbi +4378 -0
  268. data/sorbet/rbi/gems/unicode-display_width@2.6.0.rbi +66 -0
  269. data/sorbet/rbi/gems/yard-sorbet@0.9.0.rbi +435 -0
  270. data/sorbet/rbi/gems/yard@0.9.37.rbi +18379 -0
  271. data/sorbet/rbi/todo.rbi +31 -0
  272. data/sorbet/tapioca/config.yml +13 -0
  273. data/sorbet/tapioca/require.rb +15 -0
  274. data/tasks/dsl.rake +22 -0
  275. metadata +355 -0
@@ -0,0 +1,157 @@
1
+ require "nokogiri"
2
+ require "pathname"
3
+
4
+ require_relative "string"
5
+
6
+ module JmeterPerf
7
+ module Helpers
8
+ # The DSLGenerator class generates the DSL methods and files
9
+ # for use in JMeter performance testing scripts. It uses a JMeter TestPlan (idl.xml)
10
+ # to generate the methods and files.
11
+ # @see https://github.com/jlurena/jmeter_perf/wiki/3.-Generating-DSL-Methods
12
+ class DSLGenerator
13
+ # Initializes the DSLGenerator.
14
+ # @param dsl_dir [String] Path to the directory where DSL files will be generated.
15
+ # @param idl_xml_path [String] Path to the XML file used for generating methods.
16
+ def initialize(dsl_dir:, idl_xml_path:, document_dsl: true)
17
+ @document_dsl = document_dsl
18
+ @dsl_dir = dsl_dir
19
+ @idl_xml_path = idl_xml_path
20
+ end
21
+
22
+ # Main method to generate DSL files and methods.
23
+ # It parses the XML, generates methods, documents,
24
+ # updates RBS files, and creates individual DSL files.
25
+ # @return [void]
26
+ def generate
27
+ results = parse_xml
28
+ methods = generate_methods(results)
29
+
30
+ write_methods_to_dsl_md(methods) if @document_dsl
31
+ update_rbs(methods) if @document_dsl
32
+ create_dsl_files(results)
33
+ end
34
+
35
+ private
36
+
37
+ # Parses the XML file specified by the `idl_xml_path` parameter.
38
+ # @return [Array<Nokogiri::XML::Node>] Array of XML nodes representing valid elements.
39
+ def parse_xml
40
+ idl_xml = File.open(@idl_xml_path)
41
+ doc = Nokogiri::XML(idl_xml.read.gsub(/\n\s+/, ""))
42
+ results = []
43
+
44
+ doc.traverse do |node|
45
+ if valid_node?(node)
46
+ results << node
47
+ end
48
+ end
49
+
50
+ results
51
+ end
52
+
53
+ # Checks if a given Nokogiri XML node is valid based on specific criteria.
54
+ #
55
+ # A node is considered valid if:
56
+ # - It is not an instance of Nokogiri::XML::Document.
57
+ # - It has an attribute named "testclass".
58
+ # - Its name is not "elementProp".
59
+ #
60
+ # @param node [Nokogiri::XML::Node] The XML node to be validated.
61
+ # @return [Boolean] Returns true if the node is valid, false otherwise.
62
+ def valid_node?(node)
63
+ node.class != Nokogiri::XML::Document &&
64
+ node.attributes["testclass"] &&
65
+ node.name != "elementProp"
66
+ end
67
+
68
+ # Generates methods based on parsed XML results.
69
+ # @param results [Array<Nokogiri::XML::Node>] Parsed XML nodes.
70
+ # @return [Array<Array<String>>] Array of class and method name pairs.
71
+ def generate_methods(results)
72
+ results.map do |element|
73
+ klass = JmeterPerf::Helpers::String.classify(element.attributes["testname"].to_s)
74
+ method = JmeterPerf::Helpers::String.underscore(klass)
75
+ [klass, method]
76
+ end.sort_by(&:first)
77
+ end
78
+
79
+ # Creates individual DSL files based on parsed XML results.
80
+ # @param results [Array<Nokogiri::XML::Node>] Parsed XML nodes.
81
+ # @return [void]
82
+ def create_dsl_files(results)
83
+ FileUtils.rm_rf(@dsl_dir)
84
+ FileUtils.mkdir_p(@dsl_dir)
85
+
86
+ results.each do |element|
87
+ klass = JmeterPerf::Helpers::String.classify(element.attributes["testname"].to_s)
88
+ puts "\tfor Element #{klass}"
89
+ File.write("#{@dsl_dir}/#{JmeterPerf::Helpers::String.underscore(klass)}.rb", <<~EOC)
90
+ module JmeterPerf
91
+ class DSL
92
+ # DSL method synonymous with the JMeter Element #{klass}
93
+ # @param params [Hash] Parameters for the #{klass} element (default: `{}`).
94
+ # @yield block to attach to the #{klass} element
95
+ # @return [JmeterPerf::#{klass}], a subclass of JmeterPerf::DSL that can be chained with other DSL methods.
96
+ # @see https://github.com/jlurena/jmeter_perf/wiki/1.-DSL-Documentation##{klass.downcase}
97
+ def #{JmeterPerf::Helpers::String.underscore(klass)}(params = {}, &)
98
+ node = #{klass}.new(params)
99
+ attach_node(node, &)
100
+ end
101
+
102
+ class #{klass}
103
+ attr_accessor :doc
104
+ include JmeterPerf::Helpers::XmlDocumentUpdater
105
+
106
+ def initialize(params = {})
107
+ testname = params.is_a?(Array) ? "#{klass}" : (params[:name] || "#{klass}")
108
+ @doc = Nokogiri::XML(JmeterPerf::Helpers::String.strip_heredoc(
109
+ <<~EOS
110
+ #{element.to_xml.gsub(/testname=".+?"/, 'testname="#{testname}"').gsub(/^/, " ")}
111
+ EOS
112
+ ))
113
+ update params
114
+ update_at_xpath params if params.is_a?(Hash) && params[:update_at_xpath]
115
+ end
116
+ end
117
+ end
118
+ end
119
+ EOC
120
+ end
121
+ end
122
+
123
+ # Updates the RBS file with method signatures for the DSL methods.
124
+ # @param methods [Array<Array<String>>] Array of class and method name pairs.
125
+ # @return [void]
126
+ def update_rbs(methods)
127
+ file_path = "sig/jmeter_perf.rbs"
128
+ replace_regex = /\s*## AUTOGENERATED - DSL methods RBS(.*?)## AUTOGENERATED - DSL methods RBS/m
129
+ new_content = <<~NEW_CONTENT
130
+ #{methods.map { |klass, method| " def #{method}: (Hash[Symbol, untyped], &block) -> void" }.join("\n")}
131
+ NEW_CONTENT
132
+
133
+ current_content = File.read(file_path)
134
+
135
+ new_file_content = current_content.gsub(replace_regex) do
136
+ "\n ## AUTOGENERATED - DSL methods RBS\n\n#{new_content}\n ## AUTOGENERATED - DSL methods RBS"
137
+ end
138
+
139
+ File.write(file_path, new_file_content)
140
+ end
141
+
142
+ # Writes the list of generated methods to a markdown file.
143
+ # @param methods [Array<Array<String>>] Array of class and method name pairs.
144
+ # @return [void]
145
+ def write_methods_to_dsl_md(methods)
146
+ output = []
147
+ output << "# JmeterPerf::DSL methods"
148
+
149
+ methods.each do |klass, method|
150
+ output << "- #{klass}\n `#{method}`"
151
+ end
152
+
153
+ File.write("DSL.md", output.join("\n"))
154
+ end
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,96 @@
1
+ #
2
+ # This module provides a proxy class that delegates method calls to a primary receiver object,
3
+ # and falls back to a secondary object if the primary does not respond to the method.
4
+ #
5
+ # @example
6
+ # primary = PrimaryClass.new
7
+ # fallback = FallbackClass.new
8
+ # proxy = JmeterPerf::Helpers::FallbackContextProxy.new(primary, fallback)
9
+ # proxy.some_method # Will call `some_method` on primary, or fallback if primary does not respond
10
+ #
11
+ module JmeterPerf::Helpers
12
+ class FallbackContextProxy
13
+ # List of methods that should not be proxied.
14
+ NON_PROXIED_METHODS = [
15
+ :__id__,
16
+ :__send__,
17
+ :!,
18
+ :"!=",
19
+ :==,
20
+ :equal?,
21
+ :instance_eval,
22
+ :instance_variable_get,
23
+ :instance_variable_set,
24
+ :instance_variables,
25
+ :object_id,
26
+ :remove_instance_variable
27
+ ]
28
+
29
+ # List of instance variables that should not be proxied.
30
+ NON_PROXIED_INSTANCE_VARIABLES = [
31
+ :@__fallback__,
32
+ :@__receiver__
33
+ ]
34
+
35
+ # Initializes a new FallbackContextProxy.
36
+ #
37
+ # @param receiver [Object] the primary object to which method calls are delegated.
38
+ # @param fallback [Object] the secondary object to which method calls are delegated if the primary does not respond.
39
+ def initialize(receiver, fallback)
40
+ @__receiver__ = receiver
41
+ @__fallback__ = fallback
42
+ end
43
+
44
+ # Returns the ID of the primary receiver.
45
+ #
46
+ # @return [Object] the ID of the primary receiver.
47
+ def id
48
+ @__receiver__.__send__(:id)
49
+ end
50
+
51
+ # Proxies the `sub` method call to the primary receiver or fallback.
52
+ #
53
+ # @param args [Array] the arguments to pass to the `sub` method.
54
+ # @return [Object] the result of the `sub` method call.
55
+ def sub(...)
56
+ __proxy_method__(:sub, ...)
57
+ end
58
+
59
+ # Returns the instance variables of the proxy, excluding non-proxied instance variables.
60
+ #
61
+ # @return [Array<Symbol>] the instance variables of the proxy.
62
+ def instance_variables
63
+ super.map(&:to_sym) - NON_PROXIED_INSTANCE_VARIABLES
64
+ end
65
+
66
+ # Checks if the proxy responds to a given method.
67
+ #
68
+ # @param name [Symbol] the name of the method.
69
+ # @param include_private [Boolean] whether to include private methods.
70
+ # @return [Boolean] true if the proxy responds to the method, false otherwise.
71
+ def respond_to_missing?(name, include_private)
72
+ __proxy_method__(:respond_to?, name, include_private)
73
+ end
74
+
75
+ # Handles method calls that are not explicitly defined in the proxy.
76
+ #
77
+ # @param method [Symbol] the name of the method.
78
+ # @param args [Array] the arguments to pass to the method.
79
+ # @return [Object] the result of the method call.
80
+ def method_missing(method, ...)
81
+ __proxy_method__(method, ...)
82
+ end
83
+
84
+ # Proxies a method call to the primary receiver or fallback.
85
+ #
86
+ # @param method [Symbol] the name of the method.
87
+ # @param args [Array] the arguments to pass to the method.
88
+ # @return [Object] the result of the method call.
89
+ # @raise [NoMethodError] if neither the primary receiver nor the fallback respond to the method.
90
+ def __proxy_method__(method, ...)
91
+ @__receiver__.__send__(method.to_sym, ...)
92
+ rescue NoMethodError
93
+ @__fallback__.__send__(method.to_sym, ...)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,63 @@
1
+ module JmeterPerf::Helpers
2
+ module XmlDocumentUpdater
3
+ private
4
+
5
+ def update(params)
6
+ params.delete(:name)
7
+ enabled_disabled(params)
8
+ if params.instance_of?(Array)
9
+ update_collection params
10
+ else
11
+ params.each do |name, value|
12
+ node = @doc.children.xpath("//*[contains(@name,\"#{name}\")]")
13
+ if value.instance_of?(Nokogiri::XML::Builder)
14
+ node.first.children = value.doc.at_xpath("//builder").children
15
+ else
16
+ node.first.content = value unless node.empty?
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ def enabled_disabled(params)
23
+ return unless params.is_a?(Hash)
24
+ return unless @doc.children.first.attributes["enabled"]
25
+ @doc.children.first.attributes["enabled"].value = params[:enabled].to_s.empty? ? "true" : "false"
26
+ end
27
+
28
+ def update_at_xpath(params)
29
+ params[:update_at_xpath].each do |fragment|
30
+ if fragment[:xpath]
31
+ @doc.at_xpath(fragment[:xpath]) << fragment[:value]
32
+ else
33
+ fragment.each do |xpath, value|
34
+ @doc.at_xpath(xpath).content = value
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def update_collection(params)
41
+ elements = @doc.at_xpath("//collectionProp/elementProp")
42
+ params.each_with_index do |param, index|
43
+ param.each do |name, value|
44
+ next unless elements&.element_children
45
+ element = elements.element_children.xpath("//*[contains(@name,\"#{name}\")]")
46
+ element.last.content = value
47
+ end
48
+ if index != params.size - 1 && elements
49
+ @doc.at_xpath("//collectionProp") << elements.dup
50
+ end
51
+ end
52
+ end
53
+
54
+ def enabled(params)
55
+ # default to true unless explicitly set to false
56
+ if params.has_key?(:enabled) && params[:enabled] == false
57
+ "false"
58
+ else
59
+ "true"
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,143 @@
1
+ require "uri"
2
+
3
+ module JmeterPerf::Helpers
4
+ module Parser
5
+ private
6
+
7
+ def parse_http_request(params)
8
+ if params[:raw_path]
9
+ params[:path] = params[:url]
10
+ parse_url(params)
11
+ else
12
+ parse_url(params)
13
+ params[:fill_in] ||= {}
14
+ params[:params]&.split("&")&.each do |param|
15
+ name, value = param.split("=")
16
+ params[:fill_in][name] ||= []
17
+ params[:fill_in][name] << value
18
+ end
19
+ end
20
+
21
+ fill_in(params) if params.has_key?(:fill_in)
22
+ raw_body(params) if params.has_key?(:raw_body)
23
+ files(params) if params.has_key?(:files)
24
+ end
25
+
26
+ def parse_url(params)
27
+ return if params[:url].empty?
28
+ if params[:url] =~ /https?:\/\/\$/ || params[:url][0] == "$"
29
+ params[:path] = params[:url] # special case for named expressions
30
+ else
31
+ uri = parse_uri(params[:url])
32
+ params[:port] ||= uri.port unless URI.parse(URI::DEFAULT_PARSER.escape(params[:url])).scheme.nil?
33
+ params[:protocol] ||= uri.scheme unless URI.parse(URI::DEFAULT_PARSER.escape(params[:url])).scheme.nil?
34
+ params[:domain] ||= uri.host
35
+ params[:path] ||= uri.path && URI.decode_www_form_component(uri.path)
36
+ params[:params] ||= uri.query && URI.decode_www_form_component(uri.query)
37
+ end
38
+ params.delete(:url)
39
+ end
40
+
41
+ def parse_uri(uri)
42
+ URI.parse(URI::DEFAULT_PARSER.escape(uri)).scheme.nil? ?
43
+ URI.parse(URI::DEFAULT_PARSER.escape("http://#{uri}")) :
44
+ URI.parse(URI::DEFAULT_PARSER.escape(uri))
45
+ end
46
+
47
+ def fill_in(params)
48
+ params[:update_at_xpath] ||= []
49
+ params[:update_at_xpath] = params[:fill_in]
50
+ .each_with_object(params[:update_at_xpath]) do |(name, values), memo|
51
+ Array(values).each do |value|
52
+ memo.push({
53
+ xpath: "//collectionProp",
54
+ value: Nokogiri::XML(JmeterPerf::Helpers::String.strip_heredoc(
55
+ <<-EOF
56
+ <elementProp name="#{name}" elementType="HTTPArgument">
57
+ <boolProp name="HTTPArgument.always_encode">#{params[:always_encode] ? "true" : false}</boolProp>
58
+ <stringProp name="Argument.value">#{value}</stringProp>
59
+ <stringProp name="Argument.metadata">=</stringProp>
60
+ <boolProp name="HTTPArgument.use_equals">true</boolProp>
61
+ <stringProp name="Argument.name">#{name}</stringProp>
62
+ </elementProp>
63
+ EOF
64
+ )).children
65
+ })
66
+ end
67
+ end
68
+ params.delete(:fill_in)
69
+ end
70
+
71
+ def raw_body(params)
72
+ params[:update_at_xpath] ||= []
73
+ params[:update_at_xpath].push({
74
+ xpath: "//HTTPSamplerProxy",
75
+ value: Nokogiri::XML(JmeterPerf::Helpers::String.strip_heredoc(
76
+ <<-EOF
77
+ <boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
78
+ EOF
79
+ )).children
80
+ })
81
+
82
+ params[:update_at_xpath].push({
83
+ xpath: "//collectionProp",
84
+ value: Nokogiri::XML(JmeterPerf::Helpers::String.strip_heredoc(
85
+ <<-EOF
86
+ <elementProp name="" elementType="HTTPArgument">
87
+ <boolProp name="HTTPArgument.always_encode">false</boolProp>
88
+ <stringProp name="Argument.value">#{params[:raw_body].encode(xml: :text)}</stringProp>
89
+ <stringProp name="Argument.metadata">=</stringProp>
90
+ </elementProp>
91
+ EOF
92
+ )).children
93
+ })
94
+ params.delete(:raw_body)
95
+ end
96
+
97
+ def files(params)
98
+ files = params.delete(:files)
99
+ return if files.empty?
100
+ x = Nokogiri::XML::Builder.new do |b|
101
+ b.elementProp(name: "HTTPsampler.Files", elementType: "HTTPFileArgs") {
102
+ b.collectionProp(name: "HTTPFileArgs.files") {
103
+ files.each do |f|
104
+ b.elementProp(name: f[:path], elementType: "HTTPFileArg") {
105
+ b.stringProp f[:path] || "", name: "File.path"
106
+ b.stringProp f[:paramname] || "", name: "File.paramname"
107
+ b.stringProp f[:mimetype] || "", name: "File.mimetype"
108
+ }
109
+ end
110
+ }
111
+ }
112
+ end
113
+ params[:update_at_xpath] ||= []
114
+ params[:update_at_xpath] << {
115
+ xpath: "//HTTPSamplerProxy",
116
+ value: x.doc.root
117
+ }
118
+ end
119
+
120
+ def parse_test_type(params)
121
+ case params.keys.first.to_s
122
+ when "contains"
123
+ 2
124
+ when "not-contains"
125
+ 6
126
+ when "matches"
127
+ 1
128
+ when "not-matches"
129
+ 5
130
+ when "equals"
131
+ 8
132
+ when "not-equals"
133
+ 12
134
+ when "substring"
135
+ 16
136
+ when "not-substring"
137
+ 20
138
+ else
139
+ 2
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,62 @@
1
+ require "tdigest"
2
+
3
+ module JmeterPerf::Helpers
4
+ # Provides running statistics for a series of numbers, including approximate percentiles and
5
+ # standard deviation.
6
+ #
7
+ # @note This class uses a TDigest data structure to keep statistics "close enough". Accuracy is not guaranteed.
8
+ class RunningStatistisc
9
+ # The marker for when to call the compression function on the TDigest structure.
10
+ COMPRESS_MARKER = 1000
11
+
12
+ # @return [Float] the running average of the numbers added
13
+ attr_reader :avg
14
+
15
+ # Initializes a new instance of RunningStatistisc to calculate running statistics.
16
+ #
17
+ # @return [RunningStatistisc]
18
+ def initialize
19
+ @tdigest = ::TDigest::TDigest.new
20
+ @count = 0
21
+ @avg = 0
22
+ @m2 = 0 # Sum of squares of differences from the avg
23
+ end
24
+
25
+ # Adds a number to the running statistics and updates the average and variance calculations.
26
+ #
27
+ # @param num [Float] the number to add to the running statistics
28
+ # @return [void]
29
+ def add_number(num)
30
+ @tdigest.push(num)
31
+
32
+ @count += 1
33
+ delta = num - @avg
34
+ @avg += delta / @count
35
+ delta2 = num - @avg
36
+ @m2 += delta * delta2
37
+
38
+ # Compress data every 1000 items to maintain memory efficiency
39
+ @tdigest.compress! if @count % COMPRESS_MARKER == 0
40
+ end
41
+
42
+ # Retrieves approximate percentiles for the data set based on the requested percentile values.
43
+ #
44
+ # @param percentiles [Array<Float>] the requested percentiles (e.g., 0.5 for the 50th percentile)
45
+ # @return [Array<Float>] an array of calculated percentiles corresponding to the requested values
46
+ # @example Requesting the 10th, 50th, and 95th percentiles
47
+ # get_percentiles(0.1, 0.5, 0.95) #=> [some_value_for_10th, some_value_for_50th, some_value_for_95th]
48
+ def get_percentiles(*percentiles)
49
+ @tdigest.compress!
50
+ percentiles.map { |percentile| @tdigest.percentile(percentile) }
51
+ end
52
+
53
+ # Calculates the standard deviation of the numbers added so far.
54
+ #
55
+ # @return [Float] the standard deviation, or 0 if fewer than two values have been added
56
+ def standard_deviation
57
+ return 0 if @count < 2
58
+ Math.sqrt(@m2 / (@count - 1))
59
+ end
60
+ alias_method :std, :standard_deviation
61
+ end
62
+ end
@@ -0,0 +1,60 @@
1
+ module JmeterPerf::Helpers
2
+ class String
3
+ class << self
4
+ # Converts a string to CamelCase.
5
+ #
6
+ # @param string [String] the string to be converted.
7
+ # @return [String] the CamelCase version of the string.
8
+ def classify(string)
9
+ camelize(string.gsub(/\s/, "_"))
10
+ end
11
+
12
+ # Converts a string to snake_case.
13
+ #
14
+ # @param string [String] the string to be converted.
15
+ # @return [String] the snake_case version of the string.
16
+ def underscore(string)
17
+ string.gsub("::", "/")
18
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
19
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
20
+ .tr("-", "_")
21
+ .downcase
22
+ end
23
+
24
+ # Converts a string to CamelCase or camelCase.
25
+ #
26
+ # @param str [String] the string to be converted.
27
+ # @param uppercase_first_letter [Boolean, Symbol] whether to capitalize the first letter or not.
28
+ # If `:lower`, the first letter will be lowercase.
29
+ # @return [String] the CamelCase or camelCase version of the string.
30
+ def camelize(str, uppercase_first_letter = true)
31
+ string = str.dup
32
+ # String#camelize takes a symbol (:upper or :lower), so here we also support :lower to keep the methods consistent.
33
+ if !uppercase_first_letter || uppercase_first_letter == :lower
34
+ string = string.sub(/^(?:(?=a)b(?=\b|[A-Z_])|\w)/) { |match| match.downcase! || match }
35
+ elsif string.match?(/\A[a-z\d]*\z/)
36
+ return string.capitalize
37
+ else
38
+ string = string.sub(/^[a-z\d]*/) { |match| match.capitalize || match }
39
+ end
40
+
41
+ string.gsub!(/(?:_|(\/))([a-z\d]*)/i) do
42
+ word = $2
43
+ substituted = word.capitalize! || word
44
+ ($1) ? "_#{substituted}" : substituted
45
+ end
46
+
47
+ string.gsub!(/[^a-zA-Z0-9]/, "")
48
+ string
49
+ end
50
+
51
+ # Strips leading whitespace from each line that is the same as the amount of whitespace on the first line.
52
+ #
53
+ # @param string [String] the string to be stripped of leading whitespace.
54
+ # @return [String] the string with leading whitespace removed.
55
+ def strip_heredoc(string)
56
+ string.gsub(/^#{string[/\A\s*/]}/, "")
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,42 @@
1
+ # This module provides a collection of common user-agent strings for various devices and browsers.
2
+ # It allows retrieval of user-agent strings based on device type.
3
+ module JmeterPerf::Helpers
4
+ module UserAgent
5
+ # A hash containing user-agent strings for common devices and browsers.
6
+ # @return [Hash<Symbol, String>] the user-agent strings for various devices and browsers.
7
+ COMMON_DEVICES = {
8
+ # User-agent string for iPhone
9
+ iphone: "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1",
10
+ # User-agent string for iPod
11
+ ipod: "Mozilla/5.0 (iPod touch; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1",
12
+ # User-agent string for iPad
13
+ ipad: "Mozilla/5.0 (iPad; CPU OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1",
14
+ # User-agent string for Safari on macOS
15
+ safari_osx: "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15",
16
+ # User-agent string for Safari on Windows
17
+ safari_win: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.188",
18
+ # User-agent string for Edge
19
+ edge: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.188",
20
+ # User-agent string for Chrome on macOS
21
+ chrome_osx: "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36",
22
+ # User-agent string for Chrome on Windows
23
+ chrome_win: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36",
24
+ # User-agent string for Firefox on macOS
25
+ ff_osx: "Mozilla/5.0 (Macintosh; Intel Mac OS X 13.0; rv:115.0) Gecko/20100101 Firefox/115.0",
26
+ # User-agent string for Firefox on Windows
27
+ ff_win: "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:115.0) Gecko/20100101 Firefox/115.0",
28
+ # User-agent string for Opera on macOS
29
+ opera_osx: "Mozilla/5.0 (Macintosh; Intel Mac OS X 13.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 OPR/102.0.0.0",
30
+ # User-agent string for Opera on Windows
31
+ opera_win: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 OPR/102.0.0.0"
32
+ }
33
+
34
+ # Retrieves the user-agent string for the specified device.
35
+ #
36
+ # @param device [Symbol] the device type for which to retrieve the user-agent string.
37
+ # @return [String] the user-agent string for the specified device, or the default Chrome on macOS user-agent string if the device is not found.
38
+ def self.string(device)
39
+ COMMON_DEVICES[device] || COMMON_DEVICES[:chrome_osx]
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,59 @@
1
+ module JmeterPerf
2
+ module Plugins
3
+ class ActiveThreadsOverTime
4
+ attr_accessor :doc
5
+ include JmeterPerf::Helpers::XmlDocumentUpdater
6
+ def initialize(params = {})
7
+ testname = params.is_a?(Array) ? "ActiveThreadsOverTime" : (params[:name] || "ActiveThreadsOverTime")
8
+ @doc = Nokogiri::XML(
9
+ JmeterPerf::Helpers::String.strip_heredoc(
10
+ <<-XML
11
+ <kg.apc.jmeter.vizualizers.CorrectedResultCollector guiclass="kg.apc.jmeter.vizualizers.ThreadsStateOverTimeGui" testclass="kg.apc.jmeter.vizualizers.CorrectedResultCollector" testname="#{testname}" enabled="true">
12
+ <boolProp name="ResultCollector.error_logging">false</boolProp>
13
+ <objProp>
14
+ <name>saveConfig</name>
15
+ <value class="SampleSaveConfiguration">
16
+ <time>true</time>
17
+ <latency>true</latency>
18
+ <timestamp>true</timestamp>
19
+ <success>true</success>
20
+ <label>true</label>
21
+ <code>true</code>
22
+ <message>false</message>
23
+ <threadName>true</threadName>
24
+ <dataType>false</dataType>
25
+ <encoding>false</encoding>
26
+ <assertions>false</assertions>
27
+ <subresults>false</subresults>
28
+ <responseData>false</responseData>
29
+ <samplerData>false</samplerData>
30
+ <xml>false</xml>
31
+ <fieldNames>false</fieldNames>
32
+ <responseHeaders>false</responseHeaders>
33
+ <requestHeaders>false</requestHeaders>
34
+ <responseDataOnError>false</responseDataOnError>
35
+ <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>
36
+ <assertionsResultsToSave>0</assertionsResultsToSave>
37
+ <bytes>true</bytes>
38
+ <threadCounts>true</threadCounts>
39
+ <sampleCount>true</sampleCount>
40
+ </value>
41
+ </objProp>
42
+ <stringProp name="filename"></stringProp>
43
+ <longProp name="interval_grouping">500</longProp>
44
+ <boolProp name="graph_aggregated">false</boolProp>
45
+ <stringProp name="include_sample_labels"></stringProp>
46
+ <stringProp name="exclude_sample_labels"></stringProp>
47
+ <stringProp name="start_offset"></stringProp>
48
+ <stringProp name="end_offset"></stringProp>
49
+ <boolProp name="include_checkbox_state">false</boolProp>
50
+ <boolProp name="exclude_checkbox_state">false</boolProp>
51
+ </kg.apc.jmeter.vizualizers.CorrectedResultCollector>
52
+ XML
53
+ )
54
+ )
55
+ update params
56
+ end
57
+ end
58
+ end
59
+ end