cloud-toaster 1.1.2

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 (515) hide show
  1. checksums.yaml +15 -0
  2. data/LICENSE +202 -0
  3. data/README.md +54 -0
  4. data/Rakefile +51 -0
  5. data/VERSION +1 -0
  6. data/bin/strace-4.8_patched/strace-i686 +0 -0
  7. data/bin/strace-4.8_patched/strace-x86_64 +0 -0
  8. data/bin/toaster +74 -0
  9. data/chef/cookbooks/chef-solo-search/CHANGELOG +16 -0
  10. data/chef/cookbooks/chef-solo-search/Gemfile +8 -0
  11. data/chef/cookbooks/chef-solo-search/LICENSE +202 -0
  12. data/chef/cookbooks/chef-solo-search/NOTICE +18 -0
  13. data/chef/cookbooks/chef-solo-search/README.md +143 -0
  14. data/chef/cookbooks/chef-solo-search/Rakefile +10 -0
  15. data/chef/cookbooks/chef-solo-search/libraries/search/overrides.rb +100 -0
  16. data/chef/cookbooks/chef-solo-search/libraries/search/parser.rb +222 -0
  17. data/chef/cookbooks/chef-solo-search/libraries/search.rb +75 -0
  18. data/chef/cookbooks/chef-solo-search/libraries/vendor/chef/solr_query/lucene.treetop +150 -0
  19. data/chef/cookbooks/chef-solo-search/libraries/vendor/chef/solr_query/lucene_nodes.rb +285 -0
  20. data/chef/cookbooks/chef-solo-search/libraries/vendor/chef/solr_query/query_transform.rb +65 -0
  21. data/chef/cookbooks/chef-solo-search/metadata.rb +11 -0
  22. data/chef/cookbooks/chef-solo-search/recipes/default.rb +3 -0
  23. data/chef/cookbooks/chef-solo-search/tests/data/data_bags/node/alpha.json +10 -0
  24. data/chef/cookbooks/chef-solo-search/tests/data/data_bags/node/beta.json +10 -0
  25. data/chef/cookbooks/chef-solo-search/tests/data/data_bags/node/without_json_class.json +7 -0
  26. data/chef/cookbooks/chef-solo-search/tests/data/data_bags/users/jerry.json +8 -0
  27. data/chef/cookbooks/chef-solo-search/tests/data/data_bags/users/lea.json +10 -0
  28. data/chef/cookbooks/chef-solo-search/tests/data/data_bags/users/mike.json +13 -0
  29. data/chef/cookbooks/chef-solo-search/tests/data/data_bags/users/tom.json +10 -0
  30. data/chef/cookbooks/chef-solo-search/tests/gemfiles/Gemfile.10 +4 -0
  31. data/chef/cookbooks/chef-solo-search/tests/gemfiles/Gemfile.11 +5 -0
  32. data/chef/cookbooks/chef-solo-search/tests/test_data_bags.rb +45 -0
  33. data/chef/cookbooks/chef-solo-search/tests/test_search.rb +244 -0
  34. data/chef/cookbooks/lxc/attributes/create_lxc.rb +8 -0
  35. data/chef/cookbooks/lxc/attributes/general.rb +15 -0
  36. data/chef/cookbooks/lxc/attributes/init_bare_os.rb +15 -0
  37. data/chef/cookbooks/lxc/attributes/init_proto.rb +18 -0
  38. data/chef/cookbooks/lxc/attributes/install_ruby.rb +51 -0
  39. data/chef/cookbooks/lxc/attributes/mount_volume.rb +11 -0
  40. data/chef/cookbooks/lxc/attributes/setup_host.rb +9 -0
  41. data/chef/cookbooks/lxc/attributes/setup_proxy.rb +3 -0
  42. data/chef/cookbooks/lxc/attributes/start_lxc.rb +11 -0
  43. data/chef/cookbooks/lxc/attributes/stop_lxc.rb +3 -0
  44. data/chef/cookbooks/lxc/files/install.chef.sh +78 -0
  45. data/chef/cookbooks/lxc/metadata.json +6 -0
  46. data/chef/cookbooks/lxc/recipes/create_lxc.rb +106 -0
  47. data/chef/cookbooks/lxc/recipes/init_bare_os.rb +82 -0
  48. data/chef/cookbooks/lxc/recipes/init_proto.rb +417 -0
  49. data/chef/cookbooks/lxc/recipes/install_docker.rb +61 -0
  50. data/chef/cookbooks/lxc/recipes/install_ruby.rb +28 -0
  51. data/chef/cookbooks/lxc/recipes/mount_volume.rb +63 -0
  52. data/chef/cookbooks/lxc/recipes/setup_database.rb +22 -0
  53. data/chef/cookbooks/lxc/recipes/setup_host.rb +179 -0
  54. data/chef/cookbooks/lxc/recipes/setup_proxy.rb +157 -0
  55. data/chef/cookbooks/lxc/recipes/start_lxc.rb +180 -0
  56. data/chef/cookbooks/lxc/recipes/stop_lxc.rb +86 -0
  57. data/chef/cookbooks/mysql/CHANGELOG.md +391 -0
  58. data/chef/cookbooks/mysql/README.md +211 -0
  59. data/chef/cookbooks/mysql/attributes/default.rb +22 -0
  60. data/chef/cookbooks/mysql/libraries/helpers.rb +277 -0
  61. data/chef/cookbooks/mysql/libraries/matchers.rb +17 -0
  62. data/chef/cookbooks/mysql/libraries/provider_mysql_client.rb +10 -0
  63. data/chef/cookbooks/mysql/libraries/provider_mysql_client_debian.rb +37 -0
  64. data/chef/cookbooks/mysql/libraries/provider_mysql_client_fedora.rb +38 -0
  65. data/chef/cookbooks/mysql/libraries/provider_mysql_client_freebsd.rb +33 -0
  66. data/chef/cookbooks/mysql/libraries/provider_mysql_client_omnios.rb +41 -0
  67. data/chef/cookbooks/mysql/libraries/provider_mysql_client_rhel.rb +42 -0
  68. data/chef/cookbooks/mysql/libraries/provider_mysql_client_smartos.rb +33 -0
  69. data/chef/cookbooks/mysql/libraries/provider_mysql_client_suse.rb +37 -0
  70. data/chef/cookbooks/mysql/libraries/provider_mysql_client_ubuntu.rb +37 -0
  71. data/chef/cookbooks/mysql/libraries/provider_mysql_service.rb +10 -0
  72. data/chef/cookbooks/mysql/libraries/provider_mysql_service_debian.rb +193 -0
  73. data/chef/cookbooks/mysql/libraries/provider_mysql_service_fedora.rb +157 -0
  74. data/chef/cookbooks/mysql/libraries/provider_mysql_service_freebsd.rb +151 -0
  75. data/chef/cookbooks/mysql/libraries/provider_mysql_service_omnios.rb +232 -0
  76. data/chef/cookbooks/mysql/libraries/provider_mysql_service_rhel.rb +318 -0
  77. data/chef/cookbooks/mysql/libraries/provider_mysql_service_smartos.rb +216 -0
  78. data/chef/cookbooks/mysql/libraries/provider_mysql_service_suse.rb +170 -0
  79. data/chef/cookbooks/mysql/libraries/provider_mysql_service_ubuntu.rb +218 -0
  80. data/chef/cookbooks/mysql/libraries/resource_mysql_client.rb +11 -0
  81. data/chef/cookbooks/mysql/libraries/resource_mysql_service.rb +194 -0
  82. data/chef/cookbooks/mysql/metadata.json +40 -0
  83. data/chef/cookbooks/mysql/metadata.rb +20 -0
  84. data/chef/cookbooks/mysql/recipes/client.rb +22 -0
  85. data/chef/cookbooks/mysql/recipes/server.rb +33 -0
  86. data/chef/cookbooks/mysql/recipes/server_deprecated.rb +23 -0
  87. data/chef/cookbooks/mysql/templates/default/5.0/my.cnf.erb +38 -0
  88. data/chef/cookbooks/mysql/templates/default/5.1/my.cnf.erb +38 -0
  89. data/chef/cookbooks/mysql/templates/default/5.5/my.cnf.erb +38 -0
  90. data/chef/cookbooks/mysql/templates/default/5.6/my.cnf.erb +39 -0
  91. data/chef/cookbooks/mysql/templates/default/apparmor/usr.sbin.mysqld.erb +40 -0
  92. data/chef/cookbooks/mysql/templates/default/debian/debian.cnf.erb +12 -0
  93. data/chef/cookbooks/mysql/templates/default/debian/mysql-server.seed.erb +10 -0
  94. data/chef/cookbooks/mysql/templates/default/deprecated/my.cnf.erb +374 -0
  95. data/chef/cookbooks/mysql/templates/default/grants/grants.sql.erb +27 -0
  96. data/chef/cookbooks/mysql/templates/default/omnios/mysql.xml.erb +26 -0
  97. data/chef/cookbooks/mysql/templates/default/omnios/svc.method.mysqld.erb +29 -0
  98. data/chef/cookbooks/mysql/templates/default/smartos/mysql.xml.erb +32 -0
  99. data/chef/cookbooks/mysql/templates/default/smartos/svc.method.mysqld.erb +29 -0
  100. data/chef/cookbooks/openssl/README.md +37 -0
  101. data/chef/cookbooks/openssl/libraries/secure_password.rb +37 -0
  102. data/chef/cookbooks/openssl/metadata.json +30 -0
  103. data/chef/cookbooks/openssl/metadata.rb +8 -0
  104. data/chef/cookbooks/openssl/recipes/default.rb +19 -0
  105. data/chef/cookbooks/ssh/attributes/default.rb +8 -0
  106. data/chef/cookbooks/ssh/recipes/authorize_key.rb +20 -0
  107. data/chef/cookbooks/toaster/attributes/testing.rb +37 -0
  108. data/chef/cookbooks/toaster/libraries/default.rb +61 -0
  109. data/chef/cookbooks/toaster/recipes/post__cakephp__default.rb +27 -0
  110. data/chef/cookbooks/toaster/recipes/post__cube__default.rb +26 -0
  111. data/chef/cookbooks/toaster/recipes/post__drupal__default.rb +16 -0
  112. data/chef/cookbooks/toaster/recipes/post__icinga__default.rb +9 -0
  113. data/chef/cookbooks/toaster/recipes/post__node__default.rb +16 -0
  114. data/chef/cookbooks/toaster/recipes/post__virtualbox__default.rb +12 -0
  115. data/chef/cookbooks/toaster/recipes/post__wordpress__default.rb +12 -0
  116. data/chef/cookbooks/toaster/recipes/pre__aegir__default.rb +12 -0
  117. data/chef/cookbooks/toaster/recipes/pre__app__default.rb +3 -0
  118. data/chef/cookbooks/toaster/recipes/pre__cakephp__default.rb +24 -0
  119. data/chef/cookbooks/toaster/recipes/pre__cube__default.rb +9 -0
  120. data/chef/cookbooks/toaster/recipes/pre__disco__default.rb +21 -0
  121. data/chef/cookbooks/toaster/recipes/pre__drbd__default.rb +7 -0
  122. data/chef/cookbooks/toaster/recipes/pre__eaccelerator__default.rb +2 -0
  123. data/chef/cookbooks/toaster/recipes/pre__elasticsearch-head__default.rb +11 -0
  124. data/chef/cookbooks/toaster/recipes/pre__elasticsearch__default.rb +6 -0
  125. data/chef/cookbooks/toaster/recipes/pre__gitosis__default.rb +17 -0
  126. data/chef/cookbooks/toaster/recipes/pre__kafka__default.rb +3 -0
  127. data/chef/cookbooks/toaster/recipes/pre__munin__server.rb +6 -0
  128. data/chef/cookbooks/toaster/recipes/pre__mysql__server.rb +4 -0
  129. data/chef/cookbooks/toaster/recipes/pre__nagios__default.rb +3 -0
  130. data/chef/cookbooks/toaster/recipes/pre__netkernel__default.rb +24 -0
  131. data/chef/cookbooks/toaster/recipes/pre__php__default.rb +2 -0
  132. data/chef/cookbooks/toaster/recipes/pre__postgresql__server.rb +3 -0
  133. data/chef/cookbooks/toaster/recipes/pre__pxe_dust__default.rb +9 -0
  134. data/chef/cookbooks/toaster/recipes/pre__pxe_install_server__default.rb +6 -0
  135. data/chef/cookbooks/toaster/recipes/pre__riak__default.rb +40 -0
  136. data/chef/cookbooks/toaster/recipes/pre__sensu__default.rb +9 -0
  137. data/chef/cookbooks/toaster/recipes/pre__sol__default.rb +2 -0
  138. data/chef/cookbooks/toaster/recipes/pre__solr__default.rb +6 -0
  139. data/chef/cookbooks/toaster/recipes/pre__sonar__default.rb +2 -0
  140. data/chef/cookbooks/toaster/recipes/pre__storm__default.rb +3 -0
  141. data/chef/cookbooks/toaster/recipes/pre__vmware__tools.rb +4 -0
  142. data/chef/cookbooks/toaster/recipes/pre__wordpress__default.rb +17 -0
  143. data/chef/cookbooks/toaster/recipes/pre__xen__default.rb +7 -0
  144. data/chef/cookbooks/toaster/recipes/pre__znc__default.rb +7 -0
  145. data/chef/cookbooks/toaster/recipes/testing.rb +241 -0
  146. data/chef/cookbooks/toaster/recipes/testing_post.rb +36 -0
  147. data/chef/cookbooks/yum/CHANGELOG.md +212 -0
  148. data/chef/cookbooks/yum/README.md +268 -0
  149. data/chef/cookbooks/yum/attributes/main.rb +97 -0
  150. data/chef/cookbooks/yum/libraries/matchers.rb +27 -0
  151. data/chef/cookbooks/yum/metadata.json +34 -0
  152. data/chef/cookbooks/yum/metadata.rb +13 -0
  153. data/chef/cookbooks/yum/providers/globalconfig.rb +37 -0
  154. data/chef/cookbooks/yum/providers/repository.rb +85 -0
  155. data/chef/cookbooks/yum/recipes/default.rb +34 -0
  156. data/chef/cookbooks/yum/resources/globalconfig.rb +105 -0
  157. data/chef/cookbooks/yum/resources/repository.rb +63 -0
  158. data/chef/cookbooks/yum/templates/default/main.erb +251 -0
  159. data/chef/cookbooks/yum/templates/default/repo.erb +109 -0
  160. data/chef/cookbooks/yum-mysql-community/CHANGELOG.md +67 -0
  161. data/chef/cookbooks/yum-mysql-community/README.md +137 -0
  162. data/chef/cookbooks/yum-mysql-community/attributes/mysql-connectors-community.rb +31 -0
  163. data/chef/cookbooks/yum-mysql-community/attributes/mysql55-community.rb +29 -0
  164. data/chef/cookbooks/yum-mysql-community/attributes/mysql56-community.rb +31 -0
  165. data/chef/cookbooks/yum-mysql-community/files/default/mysql_pubkey.asc +33 -0
  166. data/chef/cookbooks/yum-mysql-community/metadata.json +30 -0
  167. data/chef/cookbooks/yum-mysql-community/metadata.rb +8 -0
  168. data/chef/cookbooks/yum-mysql-community/recipes/connectors.rb +48 -0
  169. data/chef/cookbooks/yum-mysql-community/recipes/mysql55.rb +48 -0
  170. data/chef/cookbooks/yum-mysql-community/recipes/mysql56.rb +48 -0
  171. data/config.json +34 -0
  172. data/lib/toaster/api.rb +447 -0
  173. data/lib/toaster/chef/chef_listener.rb +514 -0
  174. data/lib/toaster/chef/chef_node_inspector.rb +165 -0
  175. data/lib/toaster/chef/chef_util.rb +865 -0
  176. data/lib/toaster/chef/failsafe_resource_parser.rb +140 -0
  177. data/lib/toaster/chef/resource_inspector.rb +536 -0
  178. data/lib/toaster/db/cache.rb +98 -0
  179. data/lib/toaster/db/cached_db.rb +53 -0
  180. data/lib/toaster/db/cgi_session_cache.rb +209 -0
  181. data/lib/toaster/db/db.rb +98 -0
  182. data/lib/toaster/db/mysql.rb +18 -0
  183. data/lib/toaster/db/ram_cache.rb +203 -0
  184. data/lib/toaster/markup/jdom-1.1.jar +0 -0
  185. data/lib/toaster/markup/jdom-b7.jar +0 -0
  186. data/lib/toaster/markup/markup_util.rb +437 -0
  187. data/lib/toaster/markup/vmtools-utils-0.5.jar +0 -0
  188. data/lib/toaster/markup/xmldiff.sh +5 -0
  189. data/lib/toaster/model/additional_property.rb +11 -0
  190. data/lib/toaster/model/automation.rb +218 -0
  191. data/lib/toaster/model/automation_attribute.rb +13 -0
  192. data/lib/toaster/model/automation_run.rb +104 -0
  193. data/lib/toaster/model/ignore_property.rb +11 -0
  194. data/lib/toaster/model/key_value_pair.rb +59 -0
  195. data/lib/toaster/model/run_attribute.rb +17 -0
  196. data/lib/toaster/model/state.rb +17 -0
  197. data/lib/toaster/model/state_change.rb +79 -0
  198. data/lib/toaster/model/task.rb +292 -0
  199. data/lib/toaster/model/task_execution.rb +76 -0
  200. data/lib/toaster/model/task_parameter.rb +66 -0
  201. data/lib/toaster/model/user.rb +32 -0
  202. data/lib/toaster/ohai/_disabled_/network_ports.rb +81 -0
  203. data/lib/toaster/ohai/apache/apache.rb +48 -0
  204. data/lib/toaster/ohai/cron/cron.rb +32 -0
  205. data/lib/toaster/ohai/files/_meta.rb +30 -0
  206. data/lib/toaster/ohai/files/files.rb +20 -0
  207. data/lib/toaster/ohai/gems/gems.rb +19 -0
  208. data/lib/toaster/ohai/groups/groups.rb +20 -0
  209. data/lib/toaster/ohai/iptables/iptables.rb +48 -0
  210. data/lib/toaster/ohai/mounts/mounts.rb +26 -0
  211. data/lib/toaster/ohai/mysql/mysql.rb +31 -0
  212. data/lib/toaster/ohai/packages/_meta.rb +86 -0
  213. data/lib/toaster/ohai/packages/packages.rb +33 -0
  214. data/lib/toaster/ohai/ports/ports.rb +21 -0
  215. data/lib/toaster/ohai/routes/routes.rb +25 -0
  216. data/lib/toaster/ohai/services/services.rb +42 -0
  217. data/lib/toaster/ohai/users/users.rb +17 -0
  218. data/lib/toaster/state/convergence.rb +197 -0
  219. data/lib/toaster/state/idempotence.rb +192 -0
  220. data/lib/toaster/state/ptrace_util.rb +48 -0
  221. data/lib/toaster/state/state_node.rb +105 -0
  222. data/lib/toaster/state/state_transition.rb +38 -0
  223. data/lib/toaster/state/state_transition_graph.rb +701 -0
  224. data/lib/toaster/state/syscall_tracer.rb +317 -0
  225. data/lib/toaster/state/system_state.rb +349 -0
  226. data/lib/toaster/state/transition_edge.rb +65 -0
  227. data/lib/toaster/test/test_attribute.rb +19 -0
  228. data/lib/toaster/test/test_case.rb +175 -0
  229. data/lib/toaster/test/test_coverage.rb +147 -0
  230. data/lib/toaster/test/test_coverage_goal.rb +108 -0
  231. data/lib/toaster/test/test_generator.rb +246 -0
  232. data/lib/toaster/test/test_orchestrator.rb +165 -0
  233. data/lib/toaster/test/test_result.rb +73 -0
  234. data/lib/toaster/test/test_runner.rb +394 -0
  235. data/lib/toaster/test/test_suite.rb +151 -0
  236. data/lib/toaster/test_manager.rb +281 -0
  237. data/lib/toaster/toaster_app_service.rb +141 -0
  238. data/lib/toaster/util/blocking_map.rb +80 -0
  239. data/lib/toaster/util/combinatorial.rb +58 -0
  240. data/lib/toaster/util/config.rb +103 -0
  241. data/lib/toaster/util/docker.rb +71 -0
  242. data/lib/toaster/util/logging.rb +19 -0
  243. data/lib/toaster/util/lxc.rb +383 -0
  244. data/lib/toaster/util/mem_dump.rb +38 -0
  245. data/lib/toaster/util/proxy.rb +23 -0
  246. data/lib/toaster/util/timestamp.rb +131 -0
  247. data/lib/toaster/util/util.rb +437 -0
  248. data/lib/toaster/web_ui.rb +7 -0
  249. data/webapp/Gemfile +46 -0
  250. data/webapp/Gemfile.lock +237 -0
  251. data/webapp/Rakefile +6 -0
  252. data/webapp/app/assets/fonts/font.woff +0 -0
  253. data/webapp/app/assets/images/final_state.gif +0 -0
  254. data/webapp/app/assets/images/initial_state.gif +0 -0
  255. data/webapp/app/assets/images/loading.gif +0 -0
  256. data/webapp/app/assets/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  257. data/webapp/app/assets/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  258. data/webapp/app/assets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  259. data/webapp/app/assets/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  260. data/webapp/app/assets/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  261. data/webapp/app/assets/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  262. data/webapp/app/assets/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  263. data/webapp/app/assets/images/ui-icons_222222_256x240.png +0 -0
  264. data/webapp/app/assets/javascripts/analysis.js.coffee +3 -0
  265. data/webapp/app/assets/javascripts/application.js +16 -0
  266. data/webapp/app/assets/javascripts/execs.js.coffee +3 -0
  267. data/webapp/app/assets/javascripts/graph.js +441 -0
  268. data/webapp/app/assets/javascripts/jquery-1.7.2.js +9404 -0
  269. data/webapp/app/assets/javascripts/jquery-ui-1.8.22.js +11529 -0
  270. data/webapp/app/assets/javascripts/jquery.cookie.js +96 -0
  271. data/webapp/app/assets/javascripts/jquery.hotkeys.js +99 -0
  272. data/webapp/app/assets/javascripts/jquery.jstree.js +4551 -0
  273. data/webapp/app/assets/javascripts/jsPlumb/jquery.jsPlumb-1.3.14-all-min.js +1 -0
  274. data/webapp/app/assets/javascripts/jstree.util.js +53 -0
  275. data/webapp/app/assets/javascripts/scripts.js.coffee +3 -0
  276. data/webapp/app/assets/javascripts/settings.js.coffee +3 -0
  277. data/webapp/app/assets/javascripts/test.js.coffee +3 -0
  278. data/webapp/app/assets/javascripts/util.js.coffee +3 -0
  279. data/webapp/app/assets/stylesheets/analysis.css.scss +3 -0
  280. data/webapp/app/assets/stylesheets/application.css +49 -0
  281. data/webapp/app/assets/stylesheets/execs.css.scss +3 -0
  282. data/webapp/app/assets/stylesheets/graph.css +159 -0
  283. data/webapp/app/assets/stylesheets/jquery-ui-1.8.6.custom.css +572 -0
  284. data/webapp/app/assets/stylesheets/layout.css +151 -0
  285. data/webapp/app/assets/stylesheets/menu.css +186 -0
  286. data/webapp/app/assets/stylesheets/reset.css +41 -0
  287. data/webapp/app/assets/stylesheets/scripts.css.scss +3 -0
  288. data/webapp/app/assets/stylesheets/settings.css.scss +3 -0
  289. data/webapp/app/assets/stylesheets/test.css.scss +3 -0
  290. data/webapp/app/assets/stylesheets/util.css.scss +3 -0
  291. data/webapp/app/assets/stylesheets/websymbols/websymbols-regular-webfont.eot +0 -0
  292. data/webapp/app/assets/stylesheets/websymbols/websymbols-regular-webfont.svg +1 -0
  293. data/webapp/app/assets/stylesheets/websymbols/websymbols-regular-webfont.ttf +0 -0
  294. data/webapp/app/assets/stylesheets/websymbols/websymbols-regular-webfont.woff +0 -0
  295. data/webapp/app/controllers/analysis_controller.rb +7 -0
  296. data/webapp/app/controllers/application_controller.rb +14 -0
  297. data/webapp/app/controllers/base_controller.rb +91 -0
  298. data/webapp/app/controllers/execs_controller.rb +59 -0
  299. data/webapp/app/controllers/graph_controller.rb +17 -0
  300. data/webapp/app/controllers/scripts_controller.rb +166 -0
  301. data/webapp/app/controllers/settings_controller.rb +10 -0
  302. data/webapp/app/controllers/test_controller.rb +127 -0
  303. data/webapp/app/controllers/util_controller.rb +6 -0
  304. data/webapp/app/helpers/analysis_helper.rb +2 -0
  305. data/webapp/app/helpers/application_helper.rb +2 -0
  306. data/webapp/app/helpers/automations_helper.rb +2 -0
  307. data/webapp/app/helpers/execs_helper.rb +2 -0
  308. data/webapp/app/helpers/scripts_helper.rb +2 -0
  309. data/webapp/app/helpers/settings_helper.rb +2 -0
  310. data/webapp/app/helpers/test_helper.rb +2 -0
  311. data/webapp/app/helpers/util_helper.rb +2 -0
  312. data/webapp/app/views/analysis/convergence.html.erb +156 -0
  313. data/webapp/app/views/analysis/idempotence.html.erb +2 -0
  314. data/webapp/app/views/execs/automation_runs.html.erb +98 -0
  315. data/webapp/app/views/execs/task_executions.html.erb +154 -0
  316. data/webapp/app/views/graph/graph_frame.html +101 -0
  317. data/webapp/app/views/layouts/application.html.erb +114 -0
  318. data/webapp/app/views/scripts/edit.html.erb +58 -0
  319. data/webapp/app/views/scripts/graph.html.erb +75 -0
  320. data/webapp/app/views/scripts/import_chef.html.erb +104 -0
  321. data/webapp/app/views/scripts/scripts.html.erb +116 -0
  322. data/webapp/app/views/scripts/tasks.html.erb +139 -0
  323. data/webapp/app/views/settings/containers.html.erb +161 -0
  324. data/webapp/app/views/settings/index.html.erb +51 -0
  325. data/webapp/app/views/test/cases.html.erb +2 -0
  326. data/webapp/app/views/test/gen.html.erb +229 -0
  327. data/webapp/app/views/test/suites.html.erb +205 -0
  328. data/webapp/app/views/util/chef.html.erb +53 -0
  329. data/webapp/bin/bundle +3 -0
  330. data/webapp/bin/rails +4 -0
  331. data/webapp/bin/rake +4 -0
  332. data/webapp/config/application.rb +28 -0
  333. data/webapp/config/boot.rb +18 -0
  334. data/webapp/config/database.yml +42 -0
  335. data/webapp/config/environment.rb +5 -0
  336. data/webapp/config/environments/development.rb +35 -0
  337. data/webapp/config/environments/production.rb +80 -0
  338. data/webapp/config/environments/test.rb +36 -0
  339. data/webapp/config/initializers/backtrace_silencers.rb +7 -0
  340. data/webapp/config/initializers/devise.rb +256 -0
  341. data/webapp/config/initializers/filter_parameter_logging.rb +4 -0
  342. data/webapp/config/initializers/inflections.rb +16 -0
  343. data/webapp/config/initializers/mime_types.rb +5 -0
  344. data/webapp/config/initializers/patches.rb +13 -0
  345. data/webapp/config/initializers/secret_token.rb +12 -0
  346. data/webapp/config/initializers/session_store.rb +6 -0
  347. data/webapp/config/initializers/wrap_parameters.rb +16 -0
  348. data/webapp/config/locales/devise.en.yml +59 -0
  349. data/webapp/config/locales/en.yml +23 -0
  350. data/webapp/config/routes.rb +113 -0
  351. data/webapp/config.ru +4 -0
  352. data/webapp/db/development.sqlite3 +0 -0
  353. data/webapp/db/migrate/20140624002037_devise_create_users.rb +42 -0
  354. data/webapp/db/migrate/20140628002058_create_all_tables.rb +159 -0
  355. data/webapp/db/schema.rb +162 -0
  356. data/webapp/db/seeds.rb +7 -0
  357. data/webapp/log/development.log +167823 -0
  358. data/webapp/public/404.html +58 -0
  359. data/webapp/public/422.html +58 -0
  360. data/webapp/public/500.html +57 -0
  361. data/webapp/public/favicon.ico +0 -0
  362. data/webapp/public/robots.txt +5 -0
  363. data/webapp/test/controllers/analysis_controller_test.rb +14 -0
  364. data/webapp/test/controllers/automations_controller_test.rb +49 -0
  365. data/webapp/test/controllers/execs_controller_test.rb +9 -0
  366. data/webapp/test/controllers/executions_controller_test.rb +9 -0
  367. data/webapp/test/controllers/runs_controller_test.rb +7 -0
  368. data/webapp/test/controllers/scripts_controller_test.rb +9 -0
  369. data/webapp/test/controllers/settings_controller_test.rb +9 -0
  370. data/webapp/test/controllers/test_controller_test.rb +14 -0
  371. data/webapp/test/controllers/util_controller_test.rb +9 -0
  372. data/webapp/test/fixtures/users.yml +11 -0
  373. data/webapp/test/helpers/analysis_helper_test.rb +4 -0
  374. data/webapp/test/helpers/automations_helper_test.rb +4 -0
  375. data/webapp/test/helpers/execs_helper_test.rb +4 -0
  376. data/webapp/test/helpers/executions_helper_test.rb +4 -0
  377. data/webapp/test/helpers/runs_helper_test.rb +4 -0
  378. data/webapp/test/helpers/scripts_helper_test.rb +4 -0
  379. data/webapp/test/helpers/settings_helper_test.rb +4 -0
  380. data/webapp/test/helpers/test_helper_test.rb +4 -0
  381. data/webapp/test/helpers/util_helper_test.rb +4 -0
  382. data/webapp/test/models/user_test.rb +7 -0
  383. data/webapp/test/test_helper.rb +15 -0
  384. data/webapp/tmp/cache/assets/development/sass/1330a34c6b24ed44c0f194c03246f627289a985a/analysis.css.scssc +0 -0
  385. data/webapp/tmp/cache/assets/development/sass/1330a34c6b24ed44c0f194c03246f627289a985a/automations.css.scssc +0 -0
  386. data/webapp/tmp/cache/assets/development/sass/1330a34c6b24ed44c0f194c03246f627289a985a/execs.css.scssc +0 -0
  387. data/webapp/tmp/cache/assets/development/sass/1330a34c6b24ed44c0f194c03246f627289a985a/executions.css.scssc +0 -0
  388. data/webapp/tmp/cache/assets/development/sass/1330a34c6b24ed44c0f194c03246f627289a985a/scripts.css.scssc +0 -0
  389. data/webapp/tmp/cache/assets/development/sass/1330a34c6b24ed44c0f194c03246f627289a985a/settings.css.scssc +0 -0
  390. data/webapp/tmp/cache/assets/development/sass/1330a34c6b24ed44c0f194c03246f627289a985a/test.css.scssc +0 -0
  391. data/webapp/tmp/cache/assets/development/sass/1330a34c6b24ed44c0f194c03246f627289a985a/util.css.scssc +0 -0
  392. data/webapp/tmp/cache/assets/development/sprockets/06a1cdb3d5472dd126cffc18f548c342 +0 -0
  393. data/webapp/tmp/cache/assets/development/sprockets/0dc0562647e703ca0535da3b9fcad796 +0 -0
  394. data/webapp/tmp/cache/assets/development/sprockets/113f1c71cb0f2a786729477989122982 +0 -0
  395. data/webapp/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  396. data/webapp/tmp/cache/assets/development/sprockets/151a1c6b128721d8923ba0c380a2af17 +0 -0
  397. data/webapp/tmp/cache/assets/development/sprockets/1722fb8a6daad566c8a6d5ef31969459 +0 -0
  398. data/webapp/tmp/cache/assets/development/sprockets/1a05555c46560c6b246aa0a996679bc6 +0 -0
  399. data/webapp/tmp/cache/assets/development/sprockets/1cb7fb6aa8bd1c2b7df8f7c52442e345 +0 -0
  400. data/webapp/tmp/cache/assets/development/sprockets/1d76f803b0a83adc5ea7e7c848657967 +0 -0
  401. data/webapp/tmp/cache/assets/development/sprockets/200152f95fc464d69c425ed8fdc2fbcc +0 -0
  402. data/webapp/tmp/cache/assets/development/sprockets/2049c8927ebd046c8a3291f81041d5f1 +0 -0
  403. data/webapp/tmp/cache/assets/development/sprockets/207907100aabd08a6767e39a95b364e3 +0 -0
  404. data/webapp/tmp/cache/assets/development/sprockets/249e2d4db815922fc72419c4a1407caf +0 -0
  405. data/webapp/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  406. data/webapp/tmp/cache/assets/development/sprockets/3034e4c334b1ebed9433e33050555f18 +0 -0
  407. data/webapp/tmp/cache/assets/development/sprockets/316c88d859cc3666044e51b1dd89e872 +0 -0
  408. data/webapp/tmp/cache/assets/development/sprockets/347f43d816178c8ba11a28a771696924 +0 -0
  409. data/webapp/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  410. data/webapp/tmp/cache/assets/development/sprockets/36ab92a3b8d527ed1eff0944b5f1263d +0 -0
  411. data/webapp/tmp/cache/assets/development/sprockets/3893b852ff196f05ff6ca8e38bb2237f +0 -0
  412. data/webapp/tmp/cache/assets/development/sprockets/3c358bd5fa32d151c7aa44971dd9b96f +0 -0
  413. data/webapp/tmp/cache/assets/development/sprockets/3ce88fad85146e0bed233f5419c24d29 +0 -0
  414. data/webapp/tmp/cache/assets/development/sprockets/3dabcb7c89677292e1e019a9bac446e5 +0 -0
  415. data/webapp/tmp/cache/assets/development/sprockets/4116fac01e6d379ede37af725a592477 +0 -0
  416. data/webapp/tmp/cache/assets/development/sprockets/42628e032b8f0b16a5ba01a1fcc7b6d7 +0 -0
  417. data/webapp/tmp/cache/assets/development/sprockets/437b258a98e8fe2c87fa8e24b7ce9abf +0 -0
  418. data/webapp/tmp/cache/assets/development/sprockets/43e98ed206f05738ae305e7e1b09a840 +0 -0
  419. data/webapp/tmp/cache/assets/development/sprockets/468da8933ba442b88b2f4b0e40c2ac30 +0 -0
  420. data/webapp/tmp/cache/assets/development/sprockets/48ef3fa68e9084c7cfa84e525decc318 +0 -0
  421. data/webapp/tmp/cache/assets/development/sprockets/4b68dcc030691297629a7156361018dc +0 -0
  422. data/webapp/tmp/cache/assets/development/sprockets/50368b1bd77c9130d821cbad89ab83ac +0 -0
  423. data/webapp/tmp/cache/assets/development/sprockets/511a980807b8d16fc3fb839991041865 +0 -0
  424. data/webapp/tmp/cache/assets/development/sprockets/516a0973874a73d0d15feec9448f7466 +0 -0
  425. data/webapp/tmp/cache/assets/development/sprockets/569e21b0ca1a230c7880f8d7a8b1febf +0 -0
  426. data/webapp/tmp/cache/assets/development/sprockets/5b5543d2ed5bed100f1739fc12ebf2c5 +0 -0
  427. data/webapp/tmp/cache/assets/development/sprockets/5c10dbffb918651dc0498579ba9a6853 +0 -0
  428. data/webapp/tmp/cache/assets/development/sprockets/5c366b5370316b3e9c03d1a58cb5eb44 +0 -0
  429. data/webapp/tmp/cache/assets/development/sprockets/5fcb9466e0d5cb0e31b35957fe2d3901 +0 -0
  430. data/webapp/tmp/cache/assets/development/sprockets/61da396fb86c5ecd844a2d83ac759b4b +0 -0
  431. data/webapp/tmp/cache/assets/development/sprockets/624ba87170059068845a4651b3cd2c7c +0 -0
  432. data/webapp/tmp/cache/assets/development/sprockets/6391f61b6121feda70da6d0a22520fdd +0 -0
  433. data/webapp/tmp/cache/assets/development/sprockets/653a981829c12a52bd57b7918168a148 +0 -0
  434. data/webapp/tmp/cache/assets/development/sprockets/66479793d9e5683d9f7fa67522d1962d +0 -0
  435. data/webapp/tmp/cache/assets/development/sprockets/69c589bd224ee0df5ab02e4568e0ab39 +0 -0
  436. data/webapp/tmp/cache/assets/development/sprockets/6dd7c564897b7e66eecbb180baeef2c6 +0 -0
  437. data/webapp/tmp/cache/assets/development/sprockets/6e2b92a4e6966cb78e63207bc7888391 +0 -0
  438. data/webapp/tmp/cache/assets/development/sprockets/70adb410f59a0edc5aea8c2b2ef8a441 +0 -0
  439. data/webapp/tmp/cache/assets/development/sprockets/72cbfd5bf33945bcce154f7a4feaf04d +0 -0
  440. data/webapp/tmp/cache/assets/development/sprockets/740ee9d355ada8cf5e9beb620f2cd5cc +0 -0
  441. data/webapp/tmp/cache/assets/development/sprockets/74770a22b5d1b0b3bc3527da83706f96 +0 -0
  442. data/webapp/tmp/cache/assets/development/sprockets/759bf97655af50852816720db7b59fcb +0 -0
  443. data/webapp/tmp/cache/assets/development/sprockets/76e9c19246c684413a02af695fa2b0bc +0 -0
  444. data/webapp/tmp/cache/assets/development/sprockets/7728beeace48ca12e336d2bce0158871 +0 -0
  445. data/webapp/tmp/cache/assets/development/sprockets/77f49730c7b689f75a2e174fbd3ace2a +0 -0
  446. data/webapp/tmp/cache/assets/development/sprockets/78021a57030fd36cf82699aad9910b26 +0 -0
  447. data/webapp/tmp/cache/assets/development/sprockets/796b349b06da691fe5f069f9e3947fcb +0 -0
  448. data/webapp/tmp/cache/assets/development/sprockets/79e7505c70697cc7d34d4a8351c3b840 +0 -0
  449. data/webapp/tmp/cache/assets/development/sprockets/7b2b7d9034fc7b77daf5da1436667e6f +0 -0
  450. data/webapp/tmp/cache/assets/development/sprockets/7c2ea2ca2cdd89b062bf23f44e8f599c +0 -0
  451. data/webapp/tmp/cache/assets/development/sprockets/7ea112af55e6df12cdff377052b71420 +0 -0
  452. data/webapp/tmp/cache/assets/development/sprockets/7f27632588dd316836b009a621c0176c +0 -0
  453. data/webapp/tmp/cache/assets/development/sprockets/7fcef9f644290dea8d0e4bf13f6bb8e9 +0 -0
  454. data/webapp/tmp/cache/assets/development/sprockets/81c6bf67419a29257ed79f442c24907d +0 -0
  455. data/webapp/tmp/cache/assets/development/sprockets/83656ce9260eb473c1654420e0180167 +0 -0
  456. data/webapp/tmp/cache/assets/development/sprockets/83e8bdddefc2dce069b56e6650135397 +0 -0
  457. data/webapp/tmp/cache/assets/development/sprockets/880c796f41e5d67ae68ed239acfc91e3 +0 -0
  458. data/webapp/tmp/cache/assets/development/sprockets/8c1c39dd537d2c9990fe9c70a5646b06 +0 -0
  459. data/webapp/tmp/cache/assets/development/sprockets/8d763042da5254015767385ce324b348 +0 -0
  460. data/webapp/tmp/cache/assets/development/sprockets/91e1ccbf65ff4d9b0f42b1159796bcf2 +0 -0
  461. data/webapp/tmp/cache/assets/development/sprockets/92cdfac7698b6bb68983cf317c1cedef +0 -0
  462. data/webapp/tmp/cache/assets/development/sprockets/94cab8cbc120e152ce4c444492a3fc1d +0 -0
  463. data/webapp/tmp/cache/assets/development/sprockets/96b918c3c041b6a089c8adc870fa3aaa +0 -0
  464. data/webapp/tmp/cache/assets/development/sprockets/97cbe306627b432ab3bfb52416690d1d +0 -0
  465. data/webapp/tmp/cache/assets/development/sprockets/98da83d396c0c00eb03937ecbc2e6bfa +0 -0
  466. data/webapp/tmp/cache/assets/development/sprockets/9db04db20ec9c4a0f84ed01caa5e6e2b +0 -0
  467. data/webapp/tmp/cache/assets/development/sprockets/9dc1c251f50c828fae95d6107619c53e +0 -0
  468. data/webapp/tmp/cache/assets/development/sprockets/9e91711ab34bbf89ad1cfb4351027d36 +0 -0
  469. data/webapp/tmp/cache/assets/development/sprockets/9f587881f98b328b656e6456178418b5 +0 -0
  470. data/webapp/tmp/cache/assets/development/sprockets/9fc981560caba00621bb95d0974ad076 +0 -0
  471. data/webapp/tmp/cache/assets/development/sprockets/9fd4385f8fda99f3ddd3f133a89231d1 +0 -0
  472. data/webapp/tmp/cache/assets/development/sprockets/a32ab71649e3db15eca95bcc3a7588da +0 -0
  473. data/webapp/tmp/cache/assets/development/sprockets/a497c976969bdbb1f69875358d39d3b5 +0 -0
  474. data/webapp/tmp/cache/assets/development/sprockets/b06058d455770c1d9db6b6670bc4bf4d +0 -0
  475. data/webapp/tmp/cache/assets/development/sprockets/b3da405f1e68470ad6146a1322f2438c +0 -0
  476. data/webapp/tmp/cache/assets/development/sprockets/b4ba5853663f6721d15942ce08dd76bf +0 -0
  477. data/webapp/tmp/cache/assets/development/sprockets/b6f1534bcdbff92a16c85487f363235a +0 -0
  478. data/webapp/tmp/cache/assets/development/sprockets/b9c57b9750f8af3551b1a5d9e27f0a92 +0 -0
  479. data/webapp/tmp/cache/assets/development/sprockets/bb5be6a0ee889a15214e2442aee8c6e1 +0 -0
  480. data/webapp/tmp/cache/assets/development/sprockets/bc80a81b2d67b5ad40f3c7a2bb6e6f22 +0 -0
  481. data/webapp/tmp/cache/assets/development/sprockets/bfaba27d5ce71d292f453659b0755511 +0 -0
  482. data/webapp/tmp/cache/assets/development/sprockets/bfac6cd2984fbd5e0d762389e3c37164 +0 -0
  483. data/webapp/tmp/cache/assets/development/sprockets/c17bec9e3b5db6d8385c3d6eb362e628 +0 -0
  484. data/webapp/tmp/cache/assets/development/sprockets/c1a9eceddc0a1e41eb2992e9204f71e6 +0 -0
  485. data/webapp/tmp/cache/assets/development/sprockets/c50cd87be040044504b5c3fde1047e24 +0 -0
  486. data/webapp/tmp/cache/assets/development/sprockets/c5907cfd07b24ad19b8c80e8af618a57 +0 -0
  487. data/webapp/tmp/cache/assets/development/sprockets/c8da5594caf845a183dd1c6cd45c5433 +0 -0
  488. data/webapp/tmp/cache/assets/development/sprockets/cbc6968ed49fa14db439a64dd0a46abc +0 -0
  489. data/webapp/tmp/cache/assets/development/sprockets/cedf710ee090647b81c08675583eca62 +0 -0
  490. data/webapp/tmp/cache/assets/development/sprockets/cf1e3cebfad43293c3c470a5e437ebc9 +0 -0
  491. data/webapp/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  492. data/webapp/tmp/cache/assets/development/sprockets/d5a14f86bb4b422fdd8eb4722d966c9a +0 -0
  493. data/webapp/tmp/cache/assets/development/sprockets/d66b9cdd3230f9e5354e495e17097c49 +0 -0
  494. data/webapp/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  495. data/webapp/tmp/cache/assets/development/sprockets/dfa0ed87d851222fe58ada385e3f037d +0 -0
  496. data/webapp/tmp/cache/assets/development/sprockets/e1aa402390382db4d97b27cb094485fa +0 -0
  497. data/webapp/tmp/cache/assets/development/sprockets/e4f1db35ef9d9fbbf53252a44e381eb8 +0 -0
  498. data/webapp/tmp/cache/assets/development/sprockets/e57eb6c1ad51fd8c13afc0e719a259b5 +0 -0
  499. data/webapp/tmp/cache/assets/development/sprockets/e7c37b542e914e392ec326190cea1aa2 +0 -0
  500. data/webapp/tmp/cache/assets/development/sprockets/e923d7e19c216d4a924831f3896e007a +0 -0
  501. data/webapp/tmp/cache/assets/development/sprockets/e96a414a621483bbc89e73f11be5e7b4 +0 -0
  502. data/webapp/tmp/cache/assets/development/sprockets/eafcfc3d2561c18743c1b32f0f710c68 +0 -0
  503. data/webapp/tmp/cache/assets/development/sprockets/ecdd630f5466d45a2afa7515aaa5fc3b +0 -0
  504. data/webapp/tmp/cache/assets/development/sprockets/ee60a0a35d60cff425373970547694bd +0 -0
  505. data/webapp/tmp/cache/assets/development/sprockets/eee2c36b75709b0c3797c2a151fdd5d3 +0 -0
  506. data/webapp/tmp/cache/assets/development/sprockets/f104b66c0f89b453d0c8c73980fbab18 +0 -0
  507. data/webapp/tmp/cache/assets/development/sprockets/f26d1bc86590415685e9836ad75d1774 +0 -0
  508. data/webapp/tmp/cache/assets/development/sprockets/f4081e868eb565527099dba2c9d8c4de +0 -0
  509. data/webapp/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  510. data/webapp/tmp/cache/assets/development/sprockets/f813030b97e30415ad276bbd1f7e1fb4 +0 -0
  511. data/webapp/tmp/cache/assets/development/sprockets/f8e3e28bc9640c25da58aea46c3ac4b3 +0 -0
  512. data/webapp/tmp/cache/assets/development/sprockets/f9169d0a8b70eaf95de52b3c6ad51105 +0 -0
  513. data/webapp/tmp/cache/assets/development/sprockets/f939450f7a481e3fbeb158b81b39c624 +0 -0
  514. data/webapp/tmp/cache/assets/development/sprockets/fce73296b8298ac4c74b3e95cde4dfdb +0 -0
  515. metadata +941 -0
@@ -0,0 +1,701 @@
1
+
2
+
3
+ #
4
+ # Author: Waldemar Hummer (hummer@dsg.tuwien.ac.at)
5
+ #
6
+
7
+ require "toaster/state/state_node"
8
+ require "toaster/state/transition_edge"
9
+ require "toaster/test/test_coverage"
10
+ require "toaster/util/timestamp"
11
+ require "toaster/test/test_coverage"
12
+ require "toaster/util/combinatorial"
13
+ require "toaster/markup/markup_util"
14
+
15
+ module Toaster
16
+
17
+ class StateTransitionGraph
18
+
19
+ attr_reader :start_node, :end_node, :nodes, :edges,
20
+ :tasks, :task_executions, :ignore_properties
21
+ attr_accessor :avoid_circles
22
+
23
+ META_PROPERTIES = ["__task_num__", "__original__", "__combo__"]
24
+
25
+ def initialize
26
+ @start_node = StateNodeInitial.new
27
+ @end_node = StateNodeFinal.new
28
+ @tasks = []
29
+ @ignore_properties = []
30
+ @task_executions = {}
31
+ # set of all nodes
32
+ @nodes = Set.new
33
+ # set of nodes without start nodes and end nodes
34
+ @nodes_without_terminals = Set.new
35
+ # set of all edges
36
+ @edges = Set.new
37
+ # set of edges which connect "actual" state nodes, i.e.,
38
+ # not including edges containing a start node or end node
39
+ @edges_without_terminal_nodes = Set.new
40
+ # avoid circles in the generated graph..?
41
+ @avoid_circles = false
42
+ end
43
+
44
+ def connect(node1, node2, conditions=nil, transition=nil)
45
+ edge = TransitionEdge.new(node1, node2, conditions, transition)
46
+ @edges.add(edge)
47
+ if node1.succeeding_task
48
+ @edges_without_terminal_nodes.add(edge)
49
+ end
50
+ node1.outgoing.add(edge)
51
+ node2.incoming.add(edge)
52
+ end
53
+
54
+ def edges(include_start_and_end_nodes=false)
55
+ return @edges if include_start_and_end_nodes
56
+ return @edges_without_terminal_nodes
57
+ end
58
+
59
+ def nodes(include_terminal_nodes=false)
60
+ return @nodes if include_terminal_nodes
61
+ return @nodes_without_terminals
62
+ end
63
+
64
+ def get_state(state_props)
65
+ return nil if !state_props
66
+ # remove ignored properties from map
67
+ remove_ignore_props(state_props)
68
+ hash_code = state_props.hash
69
+ # search for existing node
70
+ @nodes_without_terminals.each do |n|
71
+ # first compare hash code
72
+ if hash_code == n.properties.hash
73
+ # now compare actual properties
74
+ if n.properties.eql?(state_props)
75
+ return n
76
+ end
77
+ end
78
+ end
79
+ return add_state(state_props)
80
+ end
81
+
82
+ def add_state(state_props)
83
+ n = StateNode.new(state_props)
84
+ @nodes.add(n)
85
+ @nodes_without_terminals.add(n)
86
+ return n
87
+ end
88
+
89
+ def self.build_graph_for_test_suite(test_suite)
90
+ return build_graph_for_automation(test_suite.automation, test_suite.coverage_goal)
91
+ end
92
+
93
+ def self.build_graph_for_automation(automation, coverage_goal=nil)
94
+ coverage_goal = TestCoverageGoal.new if !coverage_goal
95
+
96
+ if !automation
97
+ raise "Cannot build graph for nil automation."
98
+ end
99
+
100
+ ignore_properties = []
101
+ # dup here to avoid updates of active record
102
+ ignore_properties.concat(automation.ignore_properties.to_a.dup)
103
+ additional_ignores = SystemState.read_ignore_properties()
104
+ additional_ignores = [] if !additional_ignores
105
+ ignore_properties.concat(additional_ignores)
106
+ puts "DEBUG: ignore_properties: #{ignore_properties}"
107
+
108
+ # list of tasks
109
+ TimeStamp.add(nil, "get_tasks")
110
+ tasks = automation.get_globally_executed_tasks
111
+ TimeStamp.add_and_print("load automation tasks", nil, "get_tasks")
112
+ # let's make sure the list of tasks is index-based (i.e., not a Set)
113
+ # (because we want to do index-based lookaheads in the tasks array later on..)
114
+ tasks = tasks.to_a
115
+ # STG instance
116
+ graph = build_graph_for_tasks(tasks, coverage_goal, ignore_properties)
117
+
118
+ return graph
119
+ end
120
+
121
+ def self.build_graph_for_tasks(tasks, coverage_goal=nil, ignore_properties=[])
122
+ coverage_goal = TestCoverageGoal.new if !coverage_goal
123
+
124
+ TimeStamp.add(nil, "build_graph")
125
+ graph = StateTransitionGraph.new()
126
+ graph.avoid_circles = coverage_goal.repeat_N.to_i >= 0
127
+ graph.ignore_properties.concat(ignore_properties)
128
+ graph.tasks.concat(tasks)
129
+ tasks.each do |t|
130
+ t.global_executions.each do |exe|
131
+ if exe.success
132
+ graph.task_executions[t] = [] if !graph.task_executions[t]
133
+ graph.task_executions[t] << exe
134
+ end
135
+ end
136
+ end
137
+ TimeStamp.add_and_print("load task executions for list of #{tasks.size} tasks.", nil, "build_graph")
138
+
139
+ TimeStamp.add(nil, "build_graph_states")
140
+ graph.build_states_for_task_executions()
141
+ TimeStamp.add_and_print("build states from task executions", nil, "build_graph_states")
142
+
143
+ idem_numtasks = coverage_goal.idempotence
144
+ if idem_numtasks
145
+ idem_numtasks = [idem_numtasks] if !idem_numtasks.kind_of?(Array)
146
+ TimeStamp.add(nil, "extend_idem")
147
+ idem_numtasks.each do |idem|
148
+ if tasks.size >= idem
149
+ graph.extend_for_idempodence(idem, coverage_goal.only_connect_to_start)
150
+ end
151
+ end
152
+ TimeStamp.add_and_print("extend graph for idempotence", nil, "extend_idem")
153
+ end
154
+
155
+ TimeStamp.add(nil, "extend_comb")
156
+ coverage_goal.combinations.each do |type,lengths|
157
+ if type == CombinationCoverage::COMBINE_N
158
+ lengths.each do |n|
159
+ graph.extend_for_combinations(n, false)
160
+ end
161
+ elsif type == CombinationCoverage::COMBINE_N_SUCCESSIVE
162
+ lengths.each do |n|
163
+ graph.extend_for_combinations(n, true)
164
+ end
165
+ elsif type == CombinationCoverage::SKIP_N
166
+ lengths.each do |n|
167
+ graph.extend_for_skippings(n, false)
168
+ end
169
+ elsif type == CombinationCoverage::SKIP_N_SUCCESSIVE
170
+ lengths.each do |n|
171
+ graph.extend_for_skippings(n, true)
172
+ end
173
+ end
174
+ end
175
+ TimeStamp.add_and_print("extend graph for combinations", nil, "extend_comb")
176
+
177
+ return graph
178
+ end
179
+
180
+ #
181
+ # Build the basic graph nodes as a permutation over
182
+ # the pre-states and post-states of task executions
183
+ # monitored by the system.
184
+ #
185
+ def build_states_for_task_executions(insert_nil_prestate_prop_for_insertions=false)
186
+
187
+ # node front, i.e., list of temporary child nodes as
188
+ # we iterate through the tasks and build the graph
189
+ node_front = [start_node()]
190
+
191
+ count = 0
192
+
193
+ puts "INFO: Building graph states for #{tasks.size} tasks."
194
+
195
+ # nested loop 1
196
+ tasks.each do |t|
197
+ count += 1
198
+
199
+ #puts "INFO: Handling task ##{count} of #{tasks.size}. Node front size: #{node_front.size}"
200
+
201
+ execs = task_executions[t]
202
+
203
+ # initialize the hash with a single element that
204
+ # represents an "empty pre-state" with an "empty set of conditions".
205
+ # This makes sure that we always execute the innermost
206
+ # loop at least once, which is actually only relevant
207
+ # for the last task which has no "next pre-states"...
208
+ trans_next_desired_pre_states = {
209
+ {} => Set.new
210
+ }
211
+
212
+ # make a look-ahead to the pre-states of the next task in our sequence
213
+ if count < tasks.size
214
+ t_next = tasks[count]
215
+ execs_next = task_executions[t_next]
216
+ transitions_next = t_next.global_state_transitions(execs_next, insert_nil_prestate_prop_for_insertions)
217
+ # insert artificial transition, for automations which have not been executed before
218
+ if transitions_next.empty?
219
+ transitions_next << StateTransition.new
220
+ end
221
+ trans_next_desired_pre_states = StateTransitionGraph.prestates_from_transitions(transitions_next)
222
+ end
223
+ #puts "trans_next_desired_pre_states size: #{trans_next_desired_pre_states.size}"
224
+
225
+ transitions = t.global_state_transitions(execs, insert_nil_prestate_prop_for_insertions)
226
+ # insert artificial transition, for automations which have not been executed before
227
+ if transitions.empty?
228
+ transitions << StateTransition.new
229
+ end
230
+ prestates = t.global_pre_states_reduced(transitions)
231
+ desired_prestates_in_tests = prestates
232
+
233
+ log "desired_prestates_in_tests #{desired_prestates_in_tests.inspect}"
234
+
235
+ # are we handling the first task?
236
+ if count == 1
237
+ desired_prestates_in_tests.each do |pre|
238
+ # remove ignored properties
239
+ remove_ignore_props(pre)
240
+ # artificially introduce __task_num__ parameter, because
241
+ # we want to obtain a nice, cycle-free "left-to-right"
242
+ # graph that grows as we iterate through the tasks
243
+ n = get_state(pre.merge({"__task_num__" => count-1, "__original__" => true}))
244
+ n.succeeding_task = t
245
+ connect(start_node, n)
246
+ node_front << n
247
+ end
248
+ node_front.delete(start_node())
249
+ end
250
+
251
+ # copy and clear node front list
252
+ node_front_copy = node_front
253
+ node_front = []
254
+
255
+ trans_post_states = StateTransitionGraph.poststates_from_transitions(transitions)
256
+
257
+ # nested loop 2
258
+ trans_post_states.each do |post,trans_conditions|
259
+
260
+ # Since post states are determined from the state changes
261
+ # of state transitions, we might get into a situation where
262
+ # the repeated execution of a task (because we test idempotence)
263
+ # does not result in any state changes and hence we receive an
264
+ # empty post state...
265
+ # This would be incorrect and would blow up our STG!
266
+ # Hence, we only continue here if either
267
+ # - the post state is not empty, OR
268
+ # - there is only one (probably empty) post state
269
+ if !post.empty? || trans_post_states.size == 1
270
+
271
+ # remove ignored properties
272
+ remove_ignore_props(post)
273
+
274
+ # nested loop 3
275
+ node_front_copy.each do |node|
276
+
277
+ # nested loop 4
278
+ trans_next_desired_pre_states.each do |pre_next,trans_conditions_next|
279
+
280
+ new_state = {}
281
+ StateTransitionGraph.state_merge!(new_state, node.properties)
282
+ StateTransitionGraph.state_merge!(new_state, pre_next)
283
+ StateTransitionGraph.state_merge!(new_state, post)
284
+ # again, additionally introduce __task_num__ parameter
285
+ StateTransitionGraph.state_merge!(new_state, {"__task_num__" => count, "__original__" => true})
286
+
287
+ n = get_state(new_state)
288
+
289
+ n.preceding_task = t
290
+ if count < tasks.size
291
+ n.succeeding_task = tasks[count]
292
+ end
293
+
294
+ connect(node, n, trans_conditions)
295
+ if !node_front.include?(n) && StateTransitionGraph.node_satisfies_poststate(n, post)
296
+ node_front << n
297
+ end
298
+
299
+ end
300
+
301
+ end
302
+
303
+ end
304
+
305
+ end
306
+
307
+ # are we handling the last task?
308
+ if count >= tasks.size
309
+ node_front.each do |n|
310
+ connect(n, end_node())
311
+ end
312
+ end
313
+
314
+ end
315
+
316
+ return self
317
+ end
318
+
319
+ #
320
+ # Add graph nodes and edges to satisfy the
321
+ # idempotence test coverage criterion for
322
+ # a given number of tasks.
323
+ #
324
+ def extend_for_idempodence(num_tasks, only_connect_to_start=true)
325
+
326
+ nodes_before = @nodes_without_terminals.size
327
+ puts "DEBUG: Extending graph with #{nodes_before} nodes " +
328
+ "for idempotence of length=#{num_tasks}, only_connect_to_start=#{only_connect_to_start}"
329
+ @nodes_without_terminals.dup.each do |n|
330
+ if original_node?(n)
331
+ if n.succeeding_task
332
+ task_index = tasks.index(n.succeeding_task)
333
+ if !only_connect_to_start || task_index == num_tasks
334
+ connect_to_matching_prestate(n, num_tasks - 1)
335
+ end
336
+ else
337
+ task_index = tasks.index(n.preceding_task) + 1
338
+ if !only_connect_to_start || task_index == num_tasks
339
+ #puts "DEBUG: Connecting node #{n} to matching prestate, num_tasks=#{num_tasks}"
340
+ connect_to_matching_prestate(n, num_tasks - 1)
341
+ end
342
+ end
343
+ end
344
+ end
345
+ nodes_after = @nodes_without_terminals.size
346
+
347
+ end
348
+
349
+ def connect_to_matching_prestate(node, num_tasks_back)
350
+ preceding_task = get_preceding_task(node, num_tasks_back)
351
+
352
+ if preceding_task
353
+
354
+ prestate_node = nil
355
+
356
+ if !@avoid_circles
357
+ # find non-conflicting pre-state for this post-state
358
+ prestates = prestate_nodes_of_task(preceding_task)
359
+ non_conflicting_node = nil
360
+ prestates.each do |pre|
361
+ if !pre.conflicts_with?(node, META_PROPERTIES)
362
+ non_conflicting_node = pre
363
+ break
364
+ end
365
+ end
366
+ prestate_node = non_conflicting_node
367
+ else
368
+ # always create a new state node
369
+ prestate_node = nil
370
+ end
371
+
372
+ is_new_node = false
373
+ if !prestate_node
374
+ state_props = node.properties.dup
375
+ # decrease property "__task_num__"
376
+ state_props["__task_num__"] -= num_tasks_back + 1
377
+ # remove property "__original__"
378
+ state_props.delete("__original__")
379
+ prestate_node = add_state(state_props)
380
+ prestate_node.succeeding_task = preceding_task
381
+ prestate_node.preceding_task = nil
382
+ is_new_node = true
383
+ #connect_to_prestate_recursively(new_node)
384
+ end
385
+
386
+ #connect node to new node
387
+ connect(node, prestate_node, nil)
388
+
389
+ # connect new node to successor node (recursively)
390
+ if is_new_node
391
+ connect_to_successor_recursive(prestate_node)
392
+ end
393
+ #end
394
+
395
+ else
396
+ # connect to start_node
397
+ # TODO needed?
398
+ #connect(@start_node, node, nil)
399
+ end
400
+
401
+ end
402
+
403
+ def connect_to_successor_recursive(node, consider_task_convergence=false)
404
+ next_task = node.succeeding_task
405
+ # find non-conflicting pre-state of the next task
406
+ states = poststate_nodes_of_task(next_task)
407
+ non_conflicting_node = nil
408
+ if !@avoid_circles
409
+ states.each do |state|
410
+ if !state.conflicts_with?(node, META_PROPERTIES)
411
+ non_conflicting_node = state
412
+ break
413
+ end
414
+ end
415
+ end
416
+ # connect to new node
417
+ if non_conflicting_node
418
+ connect(node, non_conflicting_node)
419
+ else
420
+ state_props = node.properties.dup
421
+ # increase property "__task_num__" by 1
422
+ state_props["__task_num__"] += 1
423
+ # remove property "__original__"
424
+ state_props.delete("__original__")
425
+
426
+ if consider_task_convergence
427
+ # TODO needed?
428
+ raise "not implemented"
429
+ # add properties which represent the state change of the task execution
430
+ #execs = task_executions[next_task]
431
+ #transitions = next_task.global_state_transitions(execs)
432
+ #poststates = next_task.global_post_states_reduced(transitions)
433
+ #state_props.merge!(poststates)
434
+ end
435
+
436
+ new_node = add_state(state_props)
437
+ new_node.preceding_task = node.succeeding_task
438
+ new_node.succeeding_task = get_task_after(node.succeeding_task)
439
+ #connect node to new node
440
+ connect(node, new_node)
441
+
442
+ if new_node.succeeding_task
443
+ connect_to_successor_recursive(new_node)
444
+ else
445
+ connect(new_node, @end_node)
446
+ end
447
+ end
448
+ end
449
+
450
+ #
451
+ # Add graph nodes and edges to satisfy different task combination
452
+ # test coverage criteria.
453
+ # Args:
454
+ # - *combination_length*: length of the task combinations to be covered.
455
+ # - *only_successive*: whether the combinations have to be successive tasks.
456
+ #
457
+ def extend_for_combinations(combination_length, successive=false)
458
+ #puts "INFO generating combinations of length #{combination_length} for list with #{tasks.size} tasks, only_successive=#{successive}"
459
+ combinations = Combinatorial.combine(tasks, combination_length, successive)
460
+ extend_for_combination_set(combinations)
461
+ end
462
+
463
+ def extend_for_skippings(combination_length, successive=false)
464
+ #puts "INFO generating 'skippings' of length #{combination_length} for list with #{tasks.size} tasks, only_successive=#{successive}"
465
+ combinations = Combinatorial.skip(tasks, combination_length, successive)
466
+ extend_for_combination_set(combinations)
467
+ end
468
+
469
+ def extend_for_combination_set(combinations)
470
+
471
+ combinations.each do |combo|
472
+
473
+ node_front = [start_node]
474
+
475
+ combo_id = Util.generate_short_uid()
476
+
477
+ combo.each do |task|
478
+
479
+ node_front_copy = node_front.dup
480
+ node_front = []
481
+
482
+ node_front_copy.each do |node|
483
+
484
+ task_prestates = prestate_nodes_of_task_reachable_from_node(task, node)
485
+
486
+ task_prestates.each do |prestate_node|
487
+
488
+ prestate_node_copy = prestate_node
489
+
490
+ if combo.index(task) <= 0
491
+ prestate_node = get_state(prestate_node.properties.merge("__combo__" => combo_id))
492
+ elsif combo.index(task) >= combo.size - 1
493
+ node = get_state(node.properties.merge("__combo__" => combo_id))
494
+ else
495
+ node = get_state(node.properties.merge("__combo__" => combo_id))
496
+ prestate_node = get_state(prestate_node.properties.merge("__combo__" => combo_id))
497
+ end
498
+
499
+ connect(node, prestate_node, nil)
500
+ node_front << prestate_node_copy
501
+
502
+ end
503
+ end
504
+
505
+ end
506
+
507
+ # finally, connect all nodes in the "node front" to the end node
508
+ node_front.each do |node|
509
+ connect(node, @end_node, nil)
510
+ end
511
+
512
+ end
513
+
514
+ end
515
+
516
+ def to_simple_json(include_start_and_end_nodes=true)
517
+
518
+ if @nodes.size > 1000
519
+ puts "WARN: Graph contains #{@nodes.size} nodes. Aborting request."
520
+ return "{}"
521
+ end
522
+
523
+ json = {}
524
+ nodes = (json["nodes"] = [])
525
+ edges = (json["edges"] = [])
526
+ node_ids = {}
527
+ if include_start_and_end_nodes
528
+ node_ids[@start_node] = "__start__"
529
+ node_ids[@end_node] = "__end__"
530
+ nodes << { "ID" => "__start__", "name" => "Start", "column" => 1, "content" => "" }
531
+ nodes << { "ID" => "__end__", "name" => "End", "column" => @tasks.size + 3, "content" => "" }
532
+ end
533
+ counter = 0
534
+ # build list of nodes
535
+ @nodes.each do |n|
536
+ counter += 1
537
+ node_ids[n] = "n#{counter}"
538
+ props = n.properties.dup
539
+ task_num = props["__task_num__"]
540
+ META_PROPERTIES.each do |mp|
541
+ props.delete(mp)
542
+ end
543
+ name = "State #{counter}"
544
+ content = MarkupUtil.to_pretty_json(props)[1..-2].strip
545
+ nodes << { "ID" => node_ids[n],
546
+ "name" => name,
547
+ "content" => content,
548
+ "column" => task_num + 2
549
+ }
550
+ end
551
+ # build list of edges
552
+ nodes_with_start = @nodes_without_terminals.dup
553
+ nodes_with_start << @start_node
554
+ nodes_with_start.each do |n|
555
+ n.outgoing.each do |e|
556
+ from = node_ids[e.node_from]
557
+ to = node_ids[e.node_to]
558
+ if from && to
559
+ task = e.represented_task
560
+ link = $cgi && task ? l('auto' => '', 'task' => task.id, 't' => 'tasks') : ""
561
+ label = task ? task.name : ""
562
+ label_short = task ? ("t#{@tasks.index(task) + 1}") : ""
563
+ edges << { "from" => from, "to" => to, "href" => link,
564
+ "label" => label, "label_short" => label_short }
565
+ end
566
+ end
567
+ end
568
+ return MarkupUtil.to_pretty_json(json)
569
+ end
570
+
571
+ ##########
572
+ # Private Helper Methods
573
+ ##########
574
+
575
+ private
576
+
577
+ def original_node?(node)
578
+ return !node.properties["__original__"].nil?
579
+ end
580
+
581
+ def remove_ignore_props(state_props)
582
+ SystemState.remove_ignore_props!(state_props, @ignore_properties)
583
+ end
584
+
585
+ def get_task_after(task)
586
+ return nil if !task
587
+ return get_task_relative_to(task, 1)
588
+ end
589
+
590
+ def get_preceding_task(node, num_tasks_back=1)
591
+ return nil if !node.preceding_task
592
+ return get_task_relative_to(node.preceding_task, -num_tasks_back)
593
+ end
594
+
595
+ def get_task_relative_to(task, num_tasks_forward_or_back=1)
596
+ index = @tasks.index(task)
597
+ index = index + num_tasks_forward_or_back
598
+ return nil if index < 0
599
+ return @tasks[index]
600
+ end
601
+
602
+ def prestate_nodes_of_task(task)
603
+ result = Set.new
604
+ @nodes_without_terminals.each do |n|
605
+ if n.succeeding_task == task
606
+ result << n
607
+ end
608
+ end
609
+ return result
610
+ end
611
+
612
+ def prestate_nodes_of_task_reachable_from_node(task, reachable_from_node, result=Set.new, visited_nodes=Set.new)
613
+ if visited_nodes.include?(reachable_from_node)
614
+ # circle detected, return...
615
+ return result
616
+ end
617
+ visited_nodes << reachable_from_node
618
+ reachable_from_node.outgoing.each do |edge|
619
+ n = edge.node_to
620
+ if n.succeeding_task == task
621
+ result << n
622
+ end
623
+ prestate_nodes_of_task_reachable_from_node(task, n, result, visited_nodes)
624
+ end
625
+ return result
626
+ end
627
+
628
+ def poststate_nodes_of_task(task)
629
+ result = Set.new
630
+ @nodes_without_terminals.each do |n|
631
+ if n.preceding_task == task
632
+ result << n
633
+ end
634
+ end
635
+ return result
636
+ end
637
+
638
+ # Determines for a set of state transitions the distinct post-states,
639
+ # plus the task parameters which lead to these post-states.
640
+ #
641
+ # * *Args* :
642
+ # - +transitions+ -> Set of TaskTransition objects
643
+ # * *Returns* :
644
+ # a Hash with poststate => [conditions...]
645
+ def self.poststates_from_transitions(transitions)
646
+ result = {}
647
+ transitions.each do |t|
648
+ result[t.post_state] = Set.new if !result[t.post_state]
649
+ result[t.post_state] << t.parameters
650
+ end
651
+ return result
652
+ end
653
+
654
+ # Determines for a set of state transitions the distinct pre-states,
655
+ # plus the task parameters which lead to these pre-states.
656
+ #
657
+ # * *Args* :
658
+ # - +transitions+ -> Set of TaskTransition objects
659
+ # * *Returns* :
660
+ # a Hash with prestate => [conditions...]
661
+ def self.prestates_from_transitions(transitions)
662
+ result = {}
663
+ transitions.each do |t|
664
+ result[t.pre_state] = Set.new if !result[t.pre_state]
665
+ result[t.pre_state] << t.parameters
666
+ end
667
+ return result
668
+ end
669
+
670
+ def self.states_from_transitions(transitions)
671
+ result = {}
672
+ transitions.each do |t|
673
+ result[t.pre_state] = Set.new if !result[t.pre_state]
674
+ result[t.pre_state] << t.parameters
675
+ result[t.post_state] = Set.new if !result[t.post_state]
676
+ result[t.post_state] << t.parameters
677
+ end
678
+ return result
679
+ end
680
+
681
+ def self.node_satisfies_poststate(node, post)
682
+ return node.satisfies_poststate(post)
683
+ end
684
+
685
+ def self.state_merge(state1, state2)
686
+ state1.merge(state2)
687
+ end
688
+ def self.state_merge!(state1, state2)
689
+ state1.merge!(state2)
690
+ end
691
+
692
+ def self.log(msg)
693
+ #puts msg
694
+ end
695
+ def log(msg)
696
+ self.class.log msg
697
+ end
698
+
699
+ end
700
+
701
+ end