baleen 0.1.1 → 0.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 (116) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitmodules +3 -0
  4. data/Dockerfile +1 -0
  5. data/Gemfile +1 -0
  6. data/README.md +1 -0
  7. data/baleen.gemspec +2 -0
  8. data/baleen.yml.sample +46 -0
  9. data/bin/baleen +91 -22
  10. data/bin/baleen-server +47 -16
  11. data/lib/baleen/builder.rb +46 -0
  12. data/lib/baleen/ci_server.rb +63 -0
  13. data/lib/baleen/client.rb +19 -9
  14. data/lib/baleen/configuration.rb +24 -0
  15. data/lib/baleen/connection.rb +47 -0
  16. data/lib/baleen/default.rb +57 -0
  17. data/lib/baleen/error.rb +9 -0
  18. data/lib/baleen/job.rb +7 -5
  19. data/lib/baleen/message/base.rb +9 -40
  20. data/lib/baleen/message/exception.rb +21 -0
  21. data/lib/baleen/message/message.rb +3 -2
  22. data/lib/baleen/message/to_client.rb +32 -0
  23. data/lib/baleen/project.rb +122 -0
  24. data/lib/baleen/result_display.rb +24 -16
  25. data/lib/baleen/runner.rb +41 -92
  26. data/lib/baleen/serializable.rb +61 -0
  27. data/lib/baleen/server.rb +40 -18
  28. data/lib/baleen/task/base.rb +55 -0
  29. data/lib/baleen/task/cucumber.rb +44 -0
  30. data/lib/baleen/task/generic.rb +17 -0
  31. data/lib/baleen/task/image_update.rb +22 -0
  32. data/lib/baleen/task/run_project.rb +14 -0
  33. data/lib/baleen/task/task.rb +5 -0
  34. data/lib/baleen/utils/{colored_puts.rb → highlighter.rb} +3 -3
  35. data/lib/baleen/utils/logger.rb +74 -0
  36. data/lib/baleen/validator.rb +115 -0
  37. data/lib/baleen/version.rb +1 -1
  38. data/lib/baleen.rb +11 -3
  39. data/spec/lib/baleen/spec_result_display.rb +47 -0
  40. data/spec/lib/baleen/spec_serializable.rb +45 -0
  41. data/spec/lib/baleen/spec_task.rb +62 -0
  42. data/spec/lib/baleen/spec_validator.rb +53 -0
  43. data/spec/spec_helper.rb +31 -0
  44. metadata +62 -76
  45. data/lib/baleen/container.rb +0 -32
  46. data/lib/baleen/message/request.rb +0 -29
  47. data/lib/baleen/message/response.rb +0 -34
  48. data/poc/.gitignore +0 -15
  49. data/poc/Gemfile +0 -49
  50. data/poc/README.rdoc +0 -261
  51. data/poc/Rakefile +0 -7
  52. data/poc/app/assets/images/rails.png +0 -0
  53. data/poc/app/assets/javascripts/application.js +0 -15
  54. data/poc/app/assets/stylesheets/application.css +0 -13
  55. data/poc/app/controllers/application_controller.rb +0 -3
  56. data/poc/app/helpers/application_helper.rb +0 -2
  57. data/poc/app/mailers/.gitkeep +0 -0
  58. data/poc/app/models/.gitkeep +0 -0
  59. data/poc/app/models/ar_profile.rb +0 -3
  60. data/poc/app/views/layouts/application.html.erb +0 -14
  61. data/poc/config/application.rb +0 -62
  62. data/poc/config/boot.rb +0 -6
  63. data/poc/config/cucumber.yml +0 -8
  64. data/poc/config/database.yml +0 -28
  65. data/poc/config/environment.rb +0 -5
  66. data/poc/config/environments/development.rb +0 -37
  67. data/poc/config/environments/production.rb +0 -67
  68. data/poc/config/environments/test.rb +0 -37
  69. data/poc/config/initializers/backtrace_silencers.rb +0 -7
  70. data/poc/config/initializers/inflections.rb +0 -15
  71. data/poc/config/initializers/mime_types.rb +0 -5
  72. data/poc/config/initializers/secret_token.rb +0 -7
  73. data/poc/config/initializers/session_store.rb +0 -8
  74. data/poc/config/initializers/wrap_parameters.rb +0 -14
  75. data/poc/config/locales/en.yml +0 -5
  76. data/poc/config/routes.rb +0 -58
  77. data/poc/config.ru +0 -4
  78. data/poc/db/.gitkeep +0 -0
  79. data/poc/db/migrate/20130914144710_create_ar_profiles.rb +0 -11
  80. data/poc/db/schema.rb +0 -24
  81. data/poc/db/seeds.rb +0 -7
  82. data/poc/features/step_definitions/fake_test_steps.rb +0 -25
  83. data/poc/features/support/env.rb +0 -60
  84. data/poc/features/support/ruby_prof_cucumber.rb +0 -15
  85. data/poc/features/t1.feature +0 -12
  86. data/poc/features/t10.feature +0 -12
  87. data/poc/features/t2.feature +0 -12
  88. data/poc/features/t3.feature +0 -12
  89. data/poc/features/t4.feature +0 -12
  90. data/poc/features/t5.feature +0 -12
  91. data/poc/features/t6.feature +0 -12
  92. data/poc/features/t7.feature +0 -12
  93. data/poc/features/t8.feature +0 -12
  94. data/poc/features/t9.feature +0 -12
  95. data/poc/lib/assets/.gitkeep +0 -0
  96. data/poc/lib/tasks/.gitkeep +0 -0
  97. data/poc/lib/tasks/cucumber.rake +0 -65
  98. data/poc/public/404.html +0 -26
  99. data/poc/public/422.html +0 -26
  100. data/poc/public/500.html +0 -25
  101. data/poc/public/favicon.ico +0 -0
  102. data/poc/public/index.html +0 -241
  103. data/poc/public/robots.txt +0 -5
  104. data/poc/script/cucumber +0 -10
  105. data/poc/script/rails +0 -6
  106. data/poc/test/fixtures/.gitkeep +0 -0
  107. data/poc/test/fixtures/ar_profiles.yml +0 -11
  108. data/poc/test/functional/.gitkeep +0 -0
  109. data/poc/test/integration/.gitkeep +0 -0
  110. data/poc/test/performance/browsing_test.rb +0 -12
  111. data/poc/test/test_helper.rb +0 -13
  112. data/poc/test/unit/.gitkeep +0 -0
  113. data/poc/test/unit/ar_profile_test.rb +0 -7
  114. data/poc/vendor/assets/javascripts/.gitkeep +0 -0
  115. data/poc/vendor/assets/stylesheets/.gitkeep +0 -0
  116. data/poc/vendor/plugins/.gitkeep +0 -0
@@ -0,0 +1,44 @@
1
+ require "baleen/task/task"
2
+
3
+ module Baleen
4
+ module Task
5
+ class Cucumber < Baleen::Task::Base
6
+
7
+ include Serializable
8
+ include Baleen::Default
9
+
10
+ attr_reader :target_files
11
+
12
+ def initialize(opt)
13
+ super()
14
+ @params[:shell] = opt[:shell] || "/bin/bash"
15
+ @params[:opt] = opt[:opt] || "-c"
16
+ @params[:exe] = opt[:exe] || "bundle exec cucumber"
17
+ @params[:work_dir] = opt[:work_dir] || default_work_dir
18
+ @params[:files] = opt[:files] || default_features
19
+ @params[:concurrency] = opt[:concurrency] || default_concurrency
20
+ @params[:before_command] = opt[:before_command] || default_before_command
21
+ @params[:image] = opt[:image]
22
+ @params[:command] = opt[:command]
23
+ @params[:results] = opt[:results]
24
+ @params[:status] = opt[:status]
25
+ @params[:commit] = nil
26
+ end
27
+
28
+ def prepare
29
+ task = Generic.new(
30
+ shell: shell,
31
+ opt: opt,
32
+ work_dir: work_dir,
33
+ image: image,
34
+ command: %{find #{files} | grep "\\.feature"}
35
+ )
36
+ runner = Baleen::Runner.new(task)
37
+ result = runner.run
38
+ @target_files = result[:log].split("\n")
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,17 @@
1
+ require "baleen/task/task"
2
+
3
+ module Baleen
4
+ module Task
5
+ class Generic < Baleen::Task::Base
6
+
7
+ def initialize(opt)
8
+ super()
9
+ @params[:shell] = opt[:shell] ||="/bin/bash"
10
+ @params[:opt] = opt[:opt] ||="-c"
11
+ @params[:work_dir] = opt[:work_dir] ||="./"
12
+ @params[:image] = opt[:image]
13
+ @params[:command] = opt[:command]
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ require "baleen/task/task"
2
+
3
+ module Baleen
4
+ module Task
5
+ class ImageUpdate < Base
6
+
7
+ include Serializable
8
+
9
+ def initialize(opt)
10
+ super()
11
+ @params[:shell] = opt[:shell] ||="/bin/bash"
12
+ @params[:opt] = opt[:opt] ||="-c"
13
+ @params[:image] = opt[:image] ||="kimh/baleen-poc"
14
+ @params[:command] = opt[:command]
15
+ @params[:work_dir] = opt[:work_dir]
16
+ @params[:files] = "" # Without this, #start_runner raises exception. Need to think what to do.
17
+ @params[:concurrency] = 1
18
+ @params[:commit] = true
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ require "baleen/task/task"
2
+
3
+ module Baleen
4
+ module Task
5
+ class RunProject < Baleen::Task::Base
6
+
7
+ def initialize(opt)
8
+ super()
9
+ @params[:project] = opt[:project]
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ require "baleen/task/base"
2
+ require "baleen/task/generic"
3
+ require "baleen/task/cucumber"
4
+ require "baleen/task/image_update"
5
+ require "baleen/task/run_project"
@@ -3,15 +3,15 @@ require "colorize"
3
3
  module Kernel
4
4
  private
5
5
 
6
- def info(msg)
6
+ def hl_info(msg)
7
7
  puts msg.green
8
8
  end
9
9
 
10
- def notice(msg)
10
+ def hl_warn(msg)
11
11
  puts msg.yellow
12
12
  end
13
13
 
14
- def warning(msg)
14
+ def hl_error(msg)
15
15
  puts msg.red
16
16
  end
17
17
  end
@@ -0,0 +1,74 @@
1
+ require 'singleton'
2
+ require 'colorize'
3
+ require 'logger'
4
+
5
+ module Baleen
6
+
7
+ # End of Log
8
+ class EoL
9
+ def initialize(proc)
10
+ @proc = proc
11
+ end
12
+
13
+ def eol
14
+ @proc.call
15
+ end
16
+ end
17
+
18
+ ERROR = Logger::ERROR
19
+ WARN = Logger::WARN
20
+ INFO = Logger::INFO
21
+ DEBUG = Logger::DEBUG
22
+
23
+ class BL
24
+ include Singleton
25
+
26
+ attr_reader :log
27
+
28
+ def initialize
29
+ config = Baleen::Configuration.instance
30
+
31
+ if config.debug == DEBUG
32
+ device = STDOUT
33
+ else
34
+ dir = File.join(config.dir, "log")
35
+ FileUtils.mkdir_p dir
36
+ device = File.join(dir, "baleen.log")
37
+ Celluloid.logger = nil
38
+ end
39
+ @log = Logger.new(device)
40
+ @log.level = config.log_level
41
+ end
42
+
43
+ def self.error(msg)
44
+ instance.log.error(msg.red)
45
+ EoL.new(Proc.new{instance.log.error("")})
46
+ end
47
+
48
+ def self.warn(msg)
49
+ instance.log.warn(msg.yellow)
50
+ EoL.new(Proc.new{instance.log.warn("")})
51
+ end
52
+
53
+ def self.info(msg)
54
+ instance.log.info(msg)
55
+ EoL.new(Proc.new{instance.log.info("")})
56
+ end
57
+
58
+ def self.debug(msg)
59
+ instance.log.debug(msg.magenta)
60
+ EoL.new(Proc.new{instance.log.debug("")})
61
+ end
62
+
63
+ def self.notice(msg)
64
+ instance.log.info(msg.green)
65
+ EoL.new(Proc.new{instance.log.info("")})
66
+ end
67
+
68
+ def puts(msg)
69
+ log.info(msg)
70
+ end
71
+
72
+ end
73
+ end
74
+
@@ -0,0 +1,115 @@
1
+ require "yaml"
2
+
3
+ module Baleen
4
+ module Validation
5
+ class Validator
6
+
7
+ include Baleen::Serializable
8
+
9
+ def self.check(project)
10
+ sections = [:runner, :framework, :ci]
11
+
12
+ sections.each do |sect|
13
+ validator = Baleen::Validation.const_get(sect.to_s.capitalize)
14
+ unless validator.new(project).validate
15
+ return false
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ class Common
22
+ def initialize(yaml)
23
+ @section = self.class.to_s.split("::").last.downcase.to_sym
24
+ @project = yaml[@section]
25
+ end
26
+
27
+ def attributes
28
+ mandatory_attributes + optional_attributes
29
+ end
30
+
31
+ def validate
32
+ unless @project
33
+ hl_error "Your baleen.yml is missing the following mandatory section"
34
+ hl_warn " :#{@section}"
35
+ raise Baleen::Error::Validator::MandatoryMissing
36
+ end
37
+
38
+ mandatory = mandatory_attributes
39
+ @project.keys.each do |k|
40
+ mandatory.delete k
41
+ unless attributes.include? k
42
+ hl_error "Your baleen.yml has the following invalid attribute at :#{@section} section"
43
+ hl_warn " :#{k}"
44
+ return false
45
+ end
46
+ end
47
+
48
+ unless mandatory.empty?
49
+ hl_error "Following attributes are mandatory at :#{@section} section of baleen.yml"
50
+ mandatory.each {|m| hl_warn " :#{m}"}
51
+ raise Baleen::Error::Validator::MandatoryMissing
52
+ end
53
+
54
+ true
55
+ end
56
+
57
+ end
58
+
59
+ class Runner < Common
60
+ def mandatory_attributes
61
+ [
62
+ :image,
63
+ ]
64
+ end
65
+
66
+ def optional_attributes
67
+ [
68
+ :work_dir,
69
+ :concurrency,
70
+ :before_command,
71
+ ]
72
+ end
73
+
74
+ end
75
+
76
+ class Framework < Common
77
+
78
+ def mandatory_attributes
79
+ [
80
+ :type,
81
+ ]
82
+ end
83
+
84
+ def optional_attributes
85
+ [
86
+ target_files,
87
+ ]
88
+ end
89
+
90
+ private
91
+
92
+ def target_files
93
+ case @project[:type]
94
+ when "cucumber"; :features
95
+ end
96
+ end
97
+ end
98
+
99
+ class Ci < Common
100
+ def mandatory_attributes
101
+ [
102
+ :url,
103
+ :repo,
104
+ ]
105
+ end
106
+
107
+ def optional_attributes
108
+ [
109
+ :branch,
110
+ :build,
111
+ ]
112
+ end
113
+ end
114
+ end
115
+ end
@@ -1,3 +1,3 @@
1
1
  module Baleen
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
data/lib/baleen.rb CHANGED
@@ -1,13 +1,21 @@
1
1
  require "baleen/version"
2
2
 
3
+ require 'baleen/default'
4
+ require 'baleen/configuration'
5
+ require 'baleen/utils/logger'
6
+ require 'baleen/serializable'
3
7
  require 'baleen/client'
4
- require 'baleen/message/message'
8
+ require 'baleen/task/task'
5
9
  require 'baleen/task'
6
10
  require 'baleen/job'
7
-
8
11
  require 'baleen/server'
9
- require 'baleen/container'
10
12
  require 'baleen/runner'
13
+ require 'baleen/ci_server'
14
+ require 'baleen/connection'
15
+ require 'baleen/message/message'
16
+ require 'baleen/validator'
17
+ require 'baleen/project'
18
+ require 'baleen/builder'
11
19
 
12
20
  module Baleen
13
21
  # Your code goes here...
@@ -0,0 +1,47 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe Baleen::ResultDisplay do
4
+ describe "#summary" do
5
+ context "when all test passes" do
6
+ it "should display Pass" do
7
+ result = [
8
+ {
9
+ "status_code" => 0,
10
+ "container_id" => "aaaaaa",
11
+ "log" => "brabrabra",
12
+ "file" => "feature/t1.feature"
13
+ },
14
+ {
15
+ "status_code" => 0,
16
+ "container_id" => "bbbbbb",
17
+ "log" => "brabrabra",
18
+ "file" => "feature/t2.feature"
19
+ }
20
+ ]
21
+ displayer = Baleen::ResultDisplay.new(result, Time.now, Time.now+10)
22
+ capture(:stdout) { displayer.summary }.should include 'Pass'
23
+ end
24
+ end
25
+
26
+ context "when some test fails" do
27
+ it "should display Fail" do
28
+ result = [
29
+ {
30
+ "status_code" => 0,
31
+ "container_id" => "aaaaaa",
32
+ "log" => "brabrabra",
33
+ "file" => "feature/t1.feature"
34
+ },
35
+ {
36
+ "status_code" => 1,
37
+ "container_id" => "bbbbbb",
38
+ "log" => "brabrabra",
39
+ "file" => "feature/t2.feature"
40
+ }
41
+ ]
42
+ displayer = Baleen::ResultDisplay.new(result, Time.now, Time.now+10)
43
+ capture(:stdout) { displayer.summary }.should include 'Fail'
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,45 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe "serialization" do
4
+ context Baleen::Task::Generic do
5
+ it "should be serializable" do
6
+ task = Baleen::Task::Generic.new({})
7
+ json = task.to_json
8
+ deserialized = Baleen::Serializable.deserialize(json)
9
+
10
+ expect(deserialized.class).to eq Baleen::Task::Generic
11
+ end
12
+
13
+ end
14
+
15
+ context Baleen::Task::Cucumber do
16
+ it "should be serializable" do
17
+ task = Baleen::Task::Cucumber.new({})
18
+ json = task.to_json
19
+ deserialized = Baleen::Serializable.deserialize(json)
20
+
21
+ expect(deserialized.class).to eq Baleen::Task::Cucumber
22
+ end
23
+ end
24
+
25
+ context Baleen::Task::ImageUpdate do
26
+ it "should be serializable" do
27
+ task = Baleen::Task::ImageUpdate.new({})
28
+ json = task.to_json
29
+ deserialized = Baleen::Serializable.deserialize(json)
30
+
31
+ expect(deserialized.class).to eq Baleen::Task::ImageUpdate
32
+ end
33
+ end
34
+
35
+ context Baleen::Message::ToClient do
36
+ it "should be serializable" do
37
+ task = Baleen::Message::ToClient.new({})
38
+ json = task.to_json
39
+ deserialized = Baleen::Serializable.deserialize(json)
40
+
41
+ expect(deserialized.class).to eq Baleen::Message::ToClient
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,62 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ include Baleen::Task
4
+
5
+ describe Baleen::Task do
6
+
7
+ describe Generic do
8
+ it "executes command" do
9
+ string = "OK"
10
+ task = Baleen::Task::Generic.new(
11
+ image: base_image,
12
+ command: "echo #{string}",
13
+ )
14
+ runner = Baleen::Runner.new(task)
15
+ result = runner.run
16
+ expect(result[:log]).to include string
17
+ end
18
+ end
19
+
20
+ describe Cucumber do
21
+ it "runs cucumber test" do
22
+ task = Baleen::Task::Cucumber.new(
23
+ image: base_image,
24
+ work_dir: "/poc",
25
+ files: "features/t0.feature",
26
+ before_command: "source /etc/profile",
27
+ concurrency: 1,
28
+ )
29
+ runner = Baleen::Runner.new(task)
30
+ result = runner.run
31
+ expect(result[:log]).to include "Scenario"
32
+ end
33
+ end
34
+
35
+ describe ImageUpdate do
36
+ before :each do
37
+ Docker::Image.all.each do |i|
38
+ if i.json["container_config"]["Image"] == test_image
39
+ i.remove
40
+ end
41
+ end
42
+ @image = Docker::Image.build("from #{base_image}")
43
+ @image.tag('repo' => test_image, 'force' => true)
44
+ end
45
+
46
+ it "commit changes" do
47
+ before_id = @image.json["id"]
48
+ task = Baleen::Task::ImageUpdate.new(
49
+ image: test_image,
50
+ command: "touch ./new_file.txt",
51
+ )
52
+
53
+ runner = Baleen::Runner.new(task)
54
+ runner.run
55
+ @image = Docker::Image.build("from #{test_image}")
56
+ after_id = @image.json["id"]
57
+
58
+ expect(after_id).not_to eq(before_id)
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,53 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ include Baleen::Config
4
+
5
+ describe Baleen::Config do
6
+ context "when all mandatory attributes are given" do
7
+ it "should pass the check" do
8
+ config = {
9
+ :base => {
10
+ :baleen_server=>"127.0.0.1",
11
+ },
12
+ :runner => {
13
+ :image=>"kimh/baleen-poc",
14
+ },
15
+ :framework => {
16
+ :type => "cucumber"
17
+ }
18
+ }
19
+ expect(Baleen::Validation::Validator.check(config)).to be_true
20
+ end
21
+ end
22
+
23
+ context "when invalid attributes are given" do
24
+ it "should not pass the check" do
25
+ config = {
26
+ :base => {
27
+ :baleen_server=>"127.0.0.1",
28
+ },
29
+ :runner => {
30
+ :image=>"kimh/baleen-poc",
31
+ },
32
+ :framework => {
33
+ :type => "cucumber",
34
+ :bad =>"MJ", # This is invalid
35
+ }
36
+ }
37
+ expect(Baleen::Validation::Validator.check(config)).to be_false
38
+ end
39
+ end
40
+
41
+ context "when mandatory attributes are not given" do
42
+ it "should raise Baleen::Error::Validator::MandatoryMissing" do
43
+ config = {
44
+ :base => {
45
+ #:baleen_server is missing
46
+ :port=>5533,
47
+ }
48
+ }
49
+ expect{Baleen::Validation::Validator.check(config)}.to raise_error Baleen::Error::Validator::MandatoryMissing
50
+ end
51
+ end
52
+
53
+ end
@@ -0,0 +1,31 @@
1
+ require "rspec"
2
+ require 'stringio'
3
+ require File.expand_path('../../lib/baleen.rb', __FILE__)
4
+
5
+ RSpec.configure do |config|
6
+ unless Docker.url = ENV["docker_url"]
7
+ hl_error "You have to set 'docker_url' environment variable before running test
8
+ Ex: export docker_url=\"http://192.168.56.4:4243\""
9
+ exit 1
10
+ end
11
+ end
12
+
13
+ def base_image
14
+ ENV["test_base"] ||= "baleen/test_base"
15
+ end
16
+
17
+ def test_image
18
+ "baleen/#{example.description.gsub("\s", "-")}"
19
+ end
20
+
21
+ def capture(stream)
22
+ begin
23
+ stream = stream.to_s
24
+ eval "$#{stream} = StringIO.new"
25
+ yield
26
+ result = eval("$#{stream}").string
27
+ ensure
28
+ eval "$#{stream} = #{stream.upcase}"
29
+ end
30
+ result
31
+ end