baleen 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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