kaya 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +26 -0
- data/CHANGELOG +52 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/NOTAS +19 -0
- data/README.md +279 -0
- data/Rakefile +1 -0
- data/bin/kaya +4 -0
- data/documentation/api.md +47 -0
- data/documentation/api_execution_data.md +47 -0
- data/documentation/configuration.md +13 -0
- data/documentation/custom_parameters.md +117 -0
- data/documentation/document_kaya.md +122 -0
- data/documentation/link.md +12 -0
- data/documentation/results.md +119 -0
- data/documentation/start.md +19 -0
- data/documentation/suites.md +60 -0
- data/documentation/test_suite_information.md +9 -0
- data/kaya.gemspec +42 -0
- data/lib/generators/task_rack.rb +160 -0
- data/lib/generators/templates/Gemfile.tt +2 -0
- data/lib/generators/templates/config.ru.tt +2 -0
- data/lib/generators/templates/kaya_conf.tt +49 -0
- data/lib/generators/templates/kaya_log.tt +0 -0
- data/lib/generators/templates/sidekiq_log.tt +0 -0
- data/lib/generators/templates/tasks.kaya.tt +10 -0
- data/lib/generators/templates/unicorn.rb.tt +21 -0
- data/lib/kaya/API/error.rb +17 -0
- data/lib/kaya/API/execution.rb +141 -0
- data/lib/kaya/API/result.rb +49 -0
- data/lib/kaya/API/results.rb +31 -0
- data/lib/kaya/API/suite.rb +42 -0
- data/lib/kaya/API/suites.rb +36 -0
- data/lib/kaya/background_jobs/sidekiq.rb +35 -0
- data/lib/kaya/background_jobs/workers/execution_checker.rb +20 -0
- data/lib/kaya/background_jobs/workers/garbage_cleaner.rb +31 -0
- data/lib/kaya/commands/bye.rb +12 -0
- data/lib/kaya/commands/help.rb +13 -0
- data/lib/kaya/commands/install.rb +27 -0
- data/lib/kaya/commands/reset.rb +39 -0
- data/lib/kaya/commands/reset_suites.rb +40 -0
- data/lib/kaya/commands/restart.rb +9 -0
- data/lib/kaya/commands/start.rb +104 -0
- data/lib/kaya/commands/stop.rb +53 -0
- data/lib/kaya/cuba.rb +287 -0
- data/lib/kaya/cucumber/features.rb +15 -0
- data/lib/kaya/cucumber/task.rb +64 -0
- data/lib/kaya/custom/execution_data.rb +50 -0
- data/lib/kaya/custom/params.rb +34 -0
- data/lib/kaya/database/mongo_connector.rb +285 -0
- data/lib/kaya/error/errors.rb +55 -0
- data/lib/kaya/execution.rb +57 -0
- data/lib/kaya/results/result.rb +493 -0
- data/lib/kaya/results/results.rb +47 -0
- data/lib/kaya/suites/custom/params.rb +151 -0
- data/lib/kaya/suites/suite.rb +177 -0
- data/lib/kaya/suites/suites.rb +130 -0
- data/lib/kaya/support/clean.rb +12 -0
- data/lib/kaya/support/configuration.rb +254 -0
- data/lib/kaya/support/console.rb +11 -0
- data/lib/kaya/support/documentation.rb +34 -0
- data/lib/kaya/support/error_handler_helper.rb +24 -0
- data/lib/kaya/support/files_cleanner.rb +136 -0
- data/lib/kaya/support/git.rb +161 -0
- data/lib/kaya/support/if_config.rb +14 -0
- data/lib/kaya/support/logo.rb +23 -0
- data/lib/kaya/support/logs.rb +37 -0
- data/lib/kaya/support/notification.rb +127 -0
- data/lib/kaya/support/processes.rb +96 -0
- data/lib/kaya/support/query_string.rb +22 -0
- data/lib/kaya/support/request.rb +32 -0
- data/lib/kaya/support/risk.rb +9 -0
- data/lib/kaya/support/time_helper.rb +11 -0
- data/lib/kaya/support/update.rb +65 -0
- data/lib/kaya/version.rb +3 -0
- data/lib/kaya/view/body.mote +60 -0
- data/lib/kaya/view/custom/params/select_list.mote +14 -0
- data/lib/kaya/view/custom/params/text.mote +9 -0
- data/lib/kaya/view/custom/params.mote +9 -0
- data/lib/kaya/view/error_handler.mote +40 -0
- data/lib/kaya/view/features/feature.mote +14 -0
- data/lib/kaya/view/features/features_list.mote +10 -0
- data/lib/kaya/view/features.mote +57 -0
- data/lib/kaya/view/footer.mote +10 -0
- data/lib/kaya/view/git_information.mote +21 -0
- data/lib/kaya/view/help/main.mote +21 -0
- data/lib/kaya/view/help/page.mote +2 -0
- data/lib/kaya/view/help/search_result.mote +29 -0
- data/lib/kaya/view/help.mote +72 -0
- data/lib/kaya/view/javascript.mote +96 -0
- data/lib/kaya/view/logs/log.mote +3 -0
- data/lib/kaya/view/modals.mote +31 -0
- data/lib/kaya/view/navigation_bar.mote +48 -0
- data/lib/kaya/view/not_found.mote +40 -0
- data/lib/kaya/view/parser.rb +79 -0
- data/lib/kaya/view/results/all.mote +59 -0
- data/lib/kaya/view/results/console.mote +106 -0
- data/lib/kaya/view/results/detailed_info.mote +112 -0
- data/lib/kaya/view/results/report.mote +1 -0
- data/lib/kaya/view/results/result.mote +23 -0
- data/lib/kaya/view/results/results.mote +52 -0
- data/lib/kaya/view/screenshot.mote +42 -0
- data/lib/kaya/view/sections.rb +25 -0
- data/lib/kaya/view/styles.mote +58 -0
- data/lib/kaya/view/suites/suite.mote +73 -0
- data/lib/kaya/view/suites/suites.mote +9 -0
- data/lib/kaya/view/view.rb +72 -0
- data/lib/kaya.rb +175 -0
- data/test/features/install.feature +18 -0
- data/test/features/support/env.rb +3 -0
- metadata +395 -0
@@ -0,0 +1,285 @@
|
|
1
|
+
require 'mongo'
|
2
|
+
|
3
|
+
module Kaya
|
4
|
+
module Database
|
5
|
+
class MongoConnector
|
6
|
+
|
7
|
+
include Mongo
|
8
|
+
|
9
|
+
def initialize(opts={host: "localhost", port: 27017, username: nil, pass: nil})
|
10
|
+
|
11
|
+
project_name = Dir.pwd.split("/").last
|
12
|
+
@@db_name = "#{project_name}_kaya"
|
13
|
+
|
14
|
+
@@client = MongoClient.new(opts[:host], opts[:port])
|
15
|
+
|
16
|
+
|
17
|
+
@@db = @@client.db(@@db_name)
|
18
|
+
@@auth = @@db.authenticate(opts[:username], opts[:pass]) if opts[:username] and opts[:pass]
|
19
|
+
|
20
|
+
@@suites = @@db.collection("suites")
|
21
|
+
@@suites.ensure_index({"last_result" => 1})
|
22
|
+
|
23
|
+
@@results = @@db.collection("results")
|
24
|
+
@@results.ensure_index({"_id" => 1})
|
25
|
+
@@results.ensure_index({"started_at" => 1, "_id" => 1})
|
26
|
+
|
27
|
+
@@documentation = @@db.collection("documentation")
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.connected?
|
31
|
+
begin
|
32
|
+
@@db and true
|
33
|
+
rescue
|
34
|
+
false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Removes all documents of documentation from the DB
|
39
|
+
def self.clean_documentation
|
40
|
+
@@db.drop_collection("documentation")
|
41
|
+
end
|
42
|
+
|
43
|
+
# Inserts a document of documentation in the DB
|
44
|
+
def self.insert_documentation document
|
45
|
+
@@documentation.insert(document)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Return an array with all documents of documentation
|
49
|
+
def self.get_all_documentation
|
50
|
+
@@documentation.find().to_a
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns the body html of a page
|
54
|
+
def self.help_body page
|
55
|
+
result = @@documentation.find({"title" => page}).to_a.first
|
56
|
+
result["body"].to_s if result != nil
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns the title of a page
|
60
|
+
def self.help_title page
|
61
|
+
result = @@documentation.find({"title" => page}).to_a.first
|
62
|
+
result["title"].to_s.gsub('_', ' ').capitalize if result != nil
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns a document from the DB for a certain title
|
66
|
+
def self.help_search title
|
67
|
+
@@documentation.find({:$or => [{ "title" => /#{title}/ },{ "title" => /#{title.upcase}/ },{ "body" => /#{title}/ }]}).to_a
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.generate_id
|
71
|
+
Time.now.to_f.to_s.gsub( ".","")[0..12].to_i
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns a list of collections
|
75
|
+
def self.collections
|
76
|
+
["suites","results"]
|
77
|
+
end
|
78
|
+
|
79
|
+
# Drops all kaya collections
|
80
|
+
def self.drop_collections
|
81
|
+
db = self.kaya_db
|
82
|
+
collections.each do |collection|
|
83
|
+
db.drop_collection(collection) if collection != "documentation"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.kaya_db
|
88
|
+
MongoClient.new().db(@@db_name)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Update suites collection with suites that comes from cucumber.yml file
|
92
|
+
# All given suites will be active. Others will be deactivated
|
93
|
+
# @param [Hash] cucumber_yml_suites
|
94
|
+
def self.update_suites cucumber_yml_suites
|
95
|
+
|
96
|
+
existing_suites = self.suites
|
97
|
+
|
98
|
+
existing_suites_name_list = existing_suites.map{|suite| suite["name"]}
|
99
|
+
|
100
|
+
cucumber_yml_suites.each_with_index do |cucumber_suite, index|
|
101
|
+
|
102
|
+
suite_data = existing_suites.select{|suite| suite["name"]==cucumber_suite["name"]}.first
|
103
|
+
|
104
|
+
# if exist, so update it, else creates a new one
|
105
|
+
if suite_data
|
106
|
+
#Delete it from list and update it
|
107
|
+
existing_suites.delete(suite_data)
|
108
|
+
suite_data["command"] = cucumber_suite["command"]
|
109
|
+
suite_data["custom"] = cucumber_suite["custom"]
|
110
|
+
suite_data["active"] = true
|
111
|
+
suite_data["index"] = index
|
112
|
+
|
113
|
+
# Updates register with new data
|
114
|
+
self.update_suite(suite_data)
|
115
|
+
print "UPDATED: #{suite_data['_id']}\n\n"
|
116
|
+
else
|
117
|
+
# Creates a new one
|
118
|
+
suite_data = self.suite_data_structure
|
119
|
+
suite_data["name"] = cucumber_suite["name"]
|
120
|
+
suite_data["command"] = cucumber_suite["command"]
|
121
|
+
suite_data["custom"] = cucumber_suite["custom"]
|
122
|
+
suite_data["branch"] = Kaya::Support::Git.actual_branch
|
123
|
+
|
124
|
+
# Saves register with new data
|
125
|
+
id = self.insert_suite(suite_data)
|
126
|
+
|
127
|
+
print "INSERTED: #{id}\n\n"
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
# If at least one existing suite isn't con cucumber yml file, so deactivate them
|
135
|
+
unless existing_suites.empty?
|
136
|
+
existing_suites.each do |suite|
|
137
|
+
|
138
|
+
print "DEACTIVATED: #{suite['_id']}\n\n"
|
139
|
+
deactivate_suite(suite["_id"])
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
# Inserts a suite in suites collection
|
146
|
+
# @param [Hash] suite_data (see suite_data_structure method)
|
147
|
+
def self.insert_suite suite_data
|
148
|
+
@@suites.insert(suite_data)
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
# Update record for a given suite
|
153
|
+
# @param [Hash] suite_data
|
154
|
+
def self.update_suite suite_data
|
155
|
+
@@suites.update( {"_id" => suite_data["_id"]}, suite_data)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Returns the entire record for a given suite name
|
159
|
+
# @param [String] suite_name
|
160
|
+
# @return [Hash] all suite data
|
161
|
+
def self.suite_data_for suite_id
|
162
|
+
suite_id = suite_id.to_i if suite_id.respond_to? :to_i
|
163
|
+
@@suites.find({"_id" => suite_id}).to_a.first
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.suite_data_for_name(suite_name)
|
167
|
+
id = self.suite_id_for(suite_name)
|
168
|
+
@@suites.find({"_id" => id}).to_a.first
|
169
|
+
end
|
170
|
+
|
171
|
+
# Returns the _id for a given suite name
|
172
|
+
# @param [String] suite_name
|
173
|
+
# @return [String] _id
|
174
|
+
def self.suite_id_for suite_name, active=nil
|
175
|
+
criteria = {"name" => suite_name}
|
176
|
+
criteria.store("active",true) if active
|
177
|
+
result = @@suites.find(criteria).to_a.first
|
178
|
+
result.nil? ? nil : result["_id"]
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.suites active=true
|
182
|
+
criteria ={}
|
183
|
+
criteria["active"]=active if active
|
184
|
+
@@suites.ensure_index({"last_result" => 1})
|
185
|
+
@@suites.find(criteria, :sort => ["last_result", -1]).to_a || []
|
186
|
+
end
|
187
|
+
|
188
|
+
# Returns all active suites
|
189
|
+
def self.all_suites
|
190
|
+
@@suites.find({"active" => true}).to_a
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
|
196
|
+
# RESULTS COLLECTION METHODS
|
197
|
+
|
198
|
+
# Creates a result data andc
|
199
|
+
# returns de id for that register
|
200
|
+
# @param [Hash] execution_data
|
201
|
+
# @return [String] id for created result
|
202
|
+
def self.insert_result(result_data)
|
203
|
+
begin
|
204
|
+
@@results.insert(result_data)
|
205
|
+
true
|
206
|
+
rescue
|
207
|
+
false
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# Returns all results for a given suite_id
|
212
|
+
def self.results_for suite_id
|
213
|
+
@@results.ensure_index({"started_at" => 1, "_id" => 1})
|
214
|
+
res = @@results.find({}, :sort => ["started_at", -1]).to_a
|
215
|
+
unless res.empty?
|
216
|
+
res.select{|result| result["suite"]["id"]==ensure_int(suite_id)}
|
217
|
+
else
|
218
|
+
[]
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# Updates result register with the given data
|
223
|
+
#
|
224
|
+
def self.update_result result_data_structure
|
225
|
+
begin
|
226
|
+
@@results.update( {"_id" => result_data_structure["_id"]}, result_data_structure)
|
227
|
+
true
|
228
|
+
rescue
|
229
|
+
false
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def self.result_data_for_id(result_id)
|
234
|
+
@@results.find({"_id" => ensure_int(result_id)}).to_a.first
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
# Returns value as Fixnum if it is not
|
239
|
+
# @param [Object] value
|
240
|
+
# @return [Fixnum]
|
241
|
+
def self.ensure_int(value)
|
242
|
+
value and value.to_i if value.respond_to? :to_i
|
243
|
+
end
|
244
|
+
|
245
|
+
# Returns all result
|
246
|
+
# @return [Array] results from results coll
|
247
|
+
def self.all_results
|
248
|
+
@@results.ensure_index({"started_at" => 1, "_id" => 1})
|
249
|
+
res = @@results.find({}, :sort => ['_id', -1])
|
250
|
+
if res
|
251
|
+
res.to_a
|
252
|
+
else
|
253
|
+
[]
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def self.all_results_ids
|
258
|
+
all_results.map{|res| res['_id']}
|
259
|
+
end
|
260
|
+
|
261
|
+
def self.find_results_for_key key
|
262
|
+
all_actual_results = self.all_results
|
263
|
+
if !all_actual_results.empty?
|
264
|
+
all_actual_results.select do |result|
|
265
|
+
result["suite"]["name"].include?(key) or result["execution_name"].include?(key) or result["summary"].include?(key) or result["command"].include?(key)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def self.find_results_for_status status
|
271
|
+
all_actual_results = self.all_results
|
272
|
+
if !all_actual_results.empty?
|
273
|
+
all_actual_results.select do |result|
|
274
|
+
result["summary"].include?(status) or result["status"].include?(status)
|
275
|
+
end.map{|result| result["_id"]}
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def self.find_by criteria={}
|
280
|
+
search_criteria = {}
|
281
|
+
end
|
282
|
+
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Kaya
|
2
|
+
module Error
|
3
|
+
# Raised when there is an error related to Suites.
|
4
|
+
class Suite < StandardError
|
5
|
+
attr_reader :suite_name
|
6
|
+
|
7
|
+
def initialize(suite_name, message=nil)
|
8
|
+
@suite_name = suite_name
|
9
|
+
message = message
|
10
|
+
super(message)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Raised when there is an error related to Results.
|
15
|
+
class Result < StandardError
|
16
|
+
attr_reader :id
|
17
|
+
|
18
|
+
def initialize(id, message=nil)
|
19
|
+
@id = id
|
20
|
+
message = message
|
21
|
+
super(message)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
class KayaFile < StandardError
|
27
|
+
def initialize file_path
|
28
|
+
super("Could not find '#{file_path} file" )
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class KayaDir < StandardError
|
33
|
+
def initialize file_path
|
34
|
+
super("Could not find '#{file_path}' dir")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Raised when there is an error related to Results
|
39
|
+
class CucumberYML < StandardError
|
40
|
+
|
41
|
+
def initialize()
|
42
|
+
super("Could not find cucumber.yml file to get test suites from")
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
# Raised when there is an error related to Help.
|
48
|
+
class Help < StandardError
|
49
|
+
def initialize(message=nil)
|
50
|
+
message = message
|
51
|
+
super(message)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Kaya
|
2
|
+
class Execution
|
3
|
+
|
4
|
+
|
5
|
+
# Run/Execute the commmand
|
6
|
+
# @param [Hash] execution_data = { :suite_id, :label }
|
7
|
+
def self.run! execution_request_data
|
8
|
+
|
9
|
+
if Kaya::Support::Configuration.use_git?
|
10
|
+
Kaya::Support::Git.reset_hard and Kaya::Support::Git.pull
|
11
|
+
$K_LOG.debug "Git pulled" if $K_LOG
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
result = Kaya::Results::Result.new(execution_request_data)
|
16
|
+
$K_LOG.debug "Result created with id => #{result.id}" if $K_LOG
|
17
|
+
|
18
|
+
result_id = result.id
|
19
|
+
|
20
|
+
if execution_request_data["type"] == "cucumber"
|
21
|
+
$K_LOG.debug "Execution type: Cucumber" if $K_LOG
|
22
|
+
Kaya::Cucumber::Task.run(result)
|
23
|
+
|
24
|
+
$K_LOG.debug "Task started" if $K_LOG
|
25
|
+
|
26
|
+
|
27
|
+
if result = Results::Result.get(result_id)
|
28
|
+
|
29
|
+
result.append_result_to_console_output!
|
30
|
+
|
31
|
+
result.save_report!
|
32
|
+
|
33
|
+
result.get_summary!
|
34
|
+
|
35
|
+
result.get_status!
|
36
|
+
|
37
|
+
result = nil
|
38
|
+
end
|
39
|
+
|
40
|
+
result_id
|
41
|
+
|
42
|
+
else # ANOTHER TYPE OF EXECUTION
|
43
|
+
$K_LOG.debug "Execution type: #{execution_request_data[:type]}" if $K_LOG
|
44
|
+
puts "TODO: Another type of execution (no cucumber execution)"
|
45
|
+
|
46
|
+
Time.now.to_i # must return an id number
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|