Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

r375: issue 20 : make outside build error show on dashboard

  • Loading branch information...
commit 7744d61fc9d14bc3bececd811e6eaa71b877b38c 1 parent b782961
@geniuslinda geniuslinda authored
View
28 .project
@@ -1,11 +1,17 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>cruisecontrolrb</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- </buildSpec>
- <natures>
- </natures>
-</projectDescription>
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>ccrb</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.rubypeople.rdt.core.rubybuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.rubypeople.rdt.core.rubynature</nature>
+ </natures>
+</projectDescription>
View
21 app/models/build.rb
@@ -14,7 +14,7 @@ def run
build_log = artifact 'build.log'
File.open(artifact('cruise_config.rb'), 'w') {|f| f << @project.config_file_content }
- raise @project.error_message unless @project.config_valid?
+ raise ConfigError.new(@project.error_message) unless @project.config_valid?
# build_command must be set before doing chdir, because there may be some relative paths
build_command = self.command
@@ -27,9 +27,24 @@ def run
rescue => e
File.open(build_log, 'a'){|f| f << e.message }
CruiseControl::Log.verbose? ? CruiseControl::Log.debug(e) : CruiseControl::Log.info(e.message)
- @status.fail!((Time.now - (time || Time.now)).ceil)
+ time_escaped = (Time.now - (time || Time.now)).ceil
+ if e.is_a? ConfigError
+ @status.fail!(time_escaped, e.message)
+ else
+ @status.fail!(time_escaped)
+ end
end
-
+
+ def brief_error
+ if File.size(@status.status_file) > 0
+ return "config error"
+ end
+ unless plugin_errors.empty?
+ return "plugin error"
+ end
+ nil
+ end
+
def abort
FileUtils.rm_rf artifacts_directory
end
View
34 app/models/build_status.rb
@@ -1,5 +1,5 @@
class BuildStatus
-
+
def initialize(artifacts_directory)
@artifacts_directory = artifacts_directory
end
@@ -19,7 +19,7 @@ def incomplete?
def failed?
read_latest_status == 'failed'
end
-
+
def start!
remove_status_file
touch_status_file("incomplete")
@@ -30,11 +30,11 @@ def succeed!(elapsed_time)
touch_status_file("success.in#{elapsed_time}s")
end
- def fail!(elapsed_time)
+ def fail!(elapsed_time, error_message=nil)
remove_status_file
- touch_status_file("failed.in#{elapsed_time}s")
+ touch_status_file("failed.in#{elapsed_time}s", error_message)
end
-
+
def created_at
if file = status_file
File.mtime(file)
@@ -63,32 +63,36 @@ def elapsed_time
file = status_file
match_elapsed_time(File.basename(file))
end
-
+
def match_elapsed_time(file_name)
match = /^build_status\.[^\.]+\.in(\d+)s$/.match(file_name)
raise 'Could not parse elapsed time.' if !match or !$1
$1.to_i
end
-
+
+ def status_file
+ Dir["#{@artifacts_directory}/build_status.*"].first
+ end
+
private
def read_latest_status
file = status_file
file ? match_status(File.basename(file)).downcase : 'never_built'
end
-
+
def remove_status_file
FileUtils.rm_f(Dir["#{@artifacts_directory}/build_status.*"])
end
- def touch_status_file(status)
- FileUtils.touch("#{@artifacts_directory}/build_status.#{status}")
- end
-
- def status_file
- Dir["#{@artifacts_directory}/build_status.*"].first
+ def touch_status_file(status, error_message=nil)
+ filename = "#{@artifacts_directory}/build_status.#{status}"
+ FileUtils.touch(filename)
+ if error_message
+ File.open(filename, "w"){|f|f.write error_message}
+ end
end
-
+
def match_status(file_name)
/^build_status\.([^\.]+)(\..+)?/.match(file_name)[1]
end
View
3  app/models/config_error.rb
@@ -0,0 +1,3 @@
+class ConfigError < StandardError
+
+end
View
1  app/models/project.rb
@@ -153,6 +153,7 @@ def find_build(label)
end
def last_build_status
+ return "failed" if BuilderStatus.new(self).fatal?
builds.empty? ? 'never_built' : last_build.status
end
View
6 app/views/projects/_project.rhtml
@@ -57,7 +57,11 @@
</div>
<% end %>
<%= show_revisions_in_build(revisions_in_build(latest_build)) %>
- <% end %>
+ <br>
+ <% if latest_build.brief_error %>
+ <div><%= link_to latest_build.brief_error, {:action => 'show', :id => project.name}, {:class => "failed"} %></div>
+ <% end %>
+ <% end %>
</td>
</tr>
View
4 builder_plugins/installed/builder_status.rb
@@ -22,6 +22,10 @@ def status
end
end
+ def fatal?
+ status == 'svn_error'
+ end
+
def build_initiated
set_status 'building'
end
View
3  builder_plugins/installed/minimal_console_logger.rb
@@ -22,7 +22,8 @@ def new_revisions_detected(new_revisions)
def build_loop_failed(error)
puts "Build loop failed"
- puts "#{error.class}: #{error.message}\n" + error.backtrace.map { |line| " #{line}" }.join("\n")
+ puts "#{error.class}: #{error.message}"
+ puts error.backtrace.map { |line| " #{line}" }.join("\n") rescue nil
end
def configuration_modified
View
3  builder_plugins/installed/project_logger.rb
@@ -35,7 +35,8 @@ def new_revisions_detected(new_revisions)
def build_loop_failed(error)
CruiseControl::Log.event("Build loop failed", :debug)
- CruiseControl::Log.debug("#{error.class}: #{error.message}\n" + error.backtrace.map { |line| " #{line}" }.join("\n"))
+ backtrace = error.backtrace.map { |line| " #{line}" }.join("\n") rescue ""
+ CruiseControl::Log.debug("#{error.class}: #{error.message}\n#{backtrace}")
end
end
View
2  script/builder
@@ -73,7 +73,7 @@ begin
write_to_log_and_console "Builder for project '#{project.name}' started"
puts "Logging to: #{File.expand_path(CRUISE_OPTIONS[:log_file_name])}"
- while (true) do
+ while (true) do
catch(:reload_project) do
project.scheduler.run
end
View
22 test/test_helper.rb
@@ -21,7 +21,7 @@
ActionMailer::Base.perform_deliveries = true
class Test::Unit::TestCase
-
+
def assert_raises(arg1 = nil, arg2 = nil)
expected_error = arg1.is_a?(Exception) ? arg1 : nil
expected_class = arg1.is_a?(Class) ? arg1 : nil
@@ -39,11 +39,11 @@ def assert_raises(arg1 = nil, arg2 = nil)
assert_matched(expected_message, e.message, "Unexpected error message") if expected_message.is_a? Regexp
end
end
-
+
def assert_false(expression)
assert_equal false, expression
end
-
+
def in_total_sandbox(&block)
in_sandbox do |sandbox|
@dir = File.expand_path(sandbox.root)
@@ -53,14 +53,14 @@ def in_total_sandbox(&block)
yield(sandbox)
end
end
-
+
def with_sandbox_project(&block)
in_total_sandbox do |sandbox|
FileUtils.mkdir_p("#{sandbox.root}/work")
-
+
project = Project.new('my_project')
project.path = sandbox.root
-
+
yield(sandbox, project)
end
end
@@ -80,7 +80,7 @@ def create_project_stub(name, last_build_status = 'failed', last_five_builds = [
project
end
-
+
def create_build_stub(label, status, time = Time.at(0))
build = Object.new
build.stubs(:label).returns(label)
@@ -90,19 +90,21 @@ def create_build_stub(label, status, time = Time.at(0))
build.stubs(:successful?).returns(status == 'success')
build.stubs(:incomplete?).returns(status == 'incomplete')
build.stubs(:changeset).returns("bobby checked something in")
+ build.stubs(:brief_error).returns(nil)
+
build
end
-
+
class FakeSourceControl
attr_reader :username
def initialize(username)
@username = username
end
-
+
def checkout(dir)
File.open("#{dir}/README", "w") {|f| f << "some text"}
end
-
+
end
end
View
2  test/unit/build_status_test.rb
@@ -126,7 +126,7 @@ def test_elapsed_time_in_progress_ceils_fractionals
Time.expects(:now).returns(time_with_fractional_seconds)
assert_equal 10, BuildStatus.new("artifacts_directory").elapsed_time_in_progress
end
-
+
private
def assert_exception_when_parsing_elapsed_time(file_name)
View
23 test/unit/build_test.rb
@@ -130,7 +130,7 @@ def test_status
Build.new(project, 123).status
end
end
-
+
def test_build_command_customization
with_sandbox_project do |sandbox, project|
build_with_defaults = Build.new(project, '1')
@@ -183,4 +183,25 @@ def test_build_should_fail_if_project_config_is_invalid
end
end
+ def test_should_pass_error_to_build_status_if_config_file_is_invalid
+ with_sandbox_project do |sandbox, project|
+ sandbox.new :file => "build-1/build.log"
+ project.stubs(:error_message).returns("fail message")
+ project.stubs(:"config_valid?").returns(false)
+
+ build = Build.new(project, 1)
+ build.run
+ assert_equal "fail message", File.open("build-1/build_status.failed.in0s"){|f|f.read}
+ assert_equal "config error", build.brief_error
+ end
+ end
+
+ def test_should_pass_error_to_build_status_if_plugin_error_happens
+ with_sandbox_project do |sandbox, project|
+ sandbox.new :file => "build-1/build_status.success.in0s"
+ build = Build.new(project, 1)
+ build.stubs(:plugin_errors).returns("plugin error")
+ assert_equal "plugin error", build.brief_error
+ end
+ end
end
View
7 test/unit/builder_status_test.rb
@@ -16,7 +16,7 @@ def test_build_initiated_creates_file__building__
FileUtils.expects(:touch).with('project_root/builder_status.building')
@builder_status.build_initiated
end
-
+
def test_sleeping_creates_file__sleeping__
Dir.stubs(:'[]').returns(['project_root/builder_status.foo'])
FileUtils.expects(:rm_f).with(['project_root/builder_status.foo'])
@@ -97,4 +97,9 @@ def test_build_loop_failed_should_set_status_according_exception_passed_in
@builder_status.expects(:set_status).with("error")
@builder_status.build_loop_failed(e)
end
+
+ def test_should_know_fatal_status
+ @builder_status.expects(:status).returns("svn_error")
+ assert @builder_status.fatal?
+ end
end
View
7 test/unit/project_test.rb
@@ -417,6 +417,13 @@ def test_should_remember_settings
assert @project.error_message.empty?
end
end
+
+ def test_last_build_status_should_be_failed_if_builder_status_is_fatal
+ builder_status = Object.new
+ builder_status.expects(:"fatal?").returns(true)
+ BuilderStatus.expects(:new).with(@project).returns(builder_status)
+ assert_equal "failed", @project.last_build_status
+ end
private
Please sign in to comment.
Something went wrong with that request. Please try again.