Rcov report for: app/models/hudson_build.rb

NameTotal linesLines of codeTotal coverageCode coverage
app/models/hudson_build.rb215179
94.88%
94.41%
1 # $Id$
2 
3 require 'hudson_api_error'
4 require 'hudson_exceptions'
5 require 'rexml_helper'
6 include RexmlHelper
7 
8 class HudsonBuild < ActiveRecord::Base
9   unloadable
10   has_many :changesets, :class_name => 'HudsonBuildChangeset', :dependent => :destroy
11   has_one :test_result, :class_name => 'HudsonBuildTestResult', :dependent => :destroy
12   has_many :artifacts, :class_name => 'HudsonBuildArtifact', :dependent => :destroy
13   belongs_to :job, :class_name => 'HudsonJob', :foreign_key => 'hudson_job_id'
14   belongs_to :author, :class_name => 'User', :foreign_key => 'caused_by'
15 
16   # ���������������������������
17   validates_presence_of :hudson_job_id, :number
18 
19   # ���������������������������
20   validates_uniqueness_of :number, :scope => :hudson_job_id
21 
22   acts_as_event :title => Proc.new {|o| 
23                                   retval = "#{l(:label_build)} #{o.job.name} #{o.number}: #{o.result}" unless o.building?
24                                   retval = "#{l(:label_build)} #{o.job.name} #{o.number}: #{l(:notice_building)}" if o.building?
25                                   retval
26                                 },
27                   :description => Proc.new{|o|
28                                   items = []
29                                   items << o.test_result.description_for_activity if o.test_result != nil
30                                   items << HudsonBuildChangeset.description_for_activity(o.changesets) if o.changesets.length > 0
31                                   items.join("; ")
32                                 },
33                   :datetime => :finished_at
34 
35   acts_as_activity_provider :type => 'hudson',
36                              :timestamp => "#{HudsonBuild.table_name}.finished_at",
37                              :author_key => "#{HudsonBuild.table_name}.caused_by",
38                              :find_options => {:include => {:job => :project}},
39                              :permission => :view_hudson
40 
41   include HudsonHelper
42   extend RexmlHelper
43 
44   def project
45     return nil unless job
46     return job.project
47   end
48 
49   def event_url(options ={})
50     return url_for(:user)
51   end
52 
53   def url_for(type = :user)
54     return "" unless self.job
55     return "" unless self.job.settings
56     return "" unless (self.job.name && self.job.name.length > 0)
57     return "#{self.job.settings.url_for(type)}job/#{self.job.name}/#{self.number}"
58   end
59 
60   def building?
61     return true if "true" == self.building
62     return false
63   end
64 
65   def update_by_api(elem)
66     return unless elem
67     self.number = get_element_value(elem, "number")
68     self.result = get_element_value(elem, "result")
69     self.finished_at = Time.at(get_element_value(elem, "timestamp").to_f / 1000)
70     self.building = get_element_value(elem, "building")
71     self.caused_by = 1 # Redmine Admin
72     self.error = ""
73   end
74 
75   def update_by_rss(elem)
76     info = HudsonBuild.parse_rss(elem)
77     self.number = info[:number] unless self.number
78     return unless info[:number].to_i == self.number
79     self.result = info[:result]
80     self.finished_at = info[:published]
81     self.building = info[:building]
82     self.caused_by = 1
83     self.error = ""
84   end
85 
86   def add_changesets_from_xml(element)
87     element.children.each do |child|
88       next if child.is_a?(REXML::Text)
89       next if "changeSet" != child.name
90       child.children.each do |item|
91         next if item.is_a?(REXML::Text)
92         next if "item" != item.name
93         changeset = new_changeset(item)
94         changeset.save
95         self.changesets << changeset
96       end
97     end
98   end
99 
100   def add_testresult_from_xml(element)
101     test_result = nil
102     element.children.each do |child|
103       next if child.is_a?(REXML::Text)
104       next if "action" != child.name
105       next if "testReport" != get_element_value(child, "urlName")
106       test_result = new_test_result(child)
107       test_result.save
108       self.test_result = test_result
109       break
110     end
111   end
112 
113   def add_artifact_from_xml(element)
114     element.children.each do |child|
115       next if child.is_a?(REXML::Text)
116       next if "artifact" != child.name
117       artifact = new_artifact(child)
118       artifact.save
119       self.artifacts << artifact
120     end
121   end
122 
123   def new_test_result(elem)
124     retval = HudsonBuildTestResult.new
125     retval.hudson_build_id = self.id
126     retval.fail_count = get_element_value(elem, "failCount")
127     retval.skip_count = get_element_value(elem, "skipCount")
128     retval.total_count = get_element_value(elem, "totalCount")
129     return retval
130   end
131 
132   def new_changeset(elem)
133     retval = HudsonBuildChangeset.new
134     retval.hudson_build_id = self.id
135     retval.repository_id = self.project.repository.id
136     retval.revision = get_revision_no(elem)
137     return retval
138   end
139 
140   def new_artifact(elem)
141     retval = HudsonBuildArtifact.new
142     retval.hudson_build_id = self.id
143     retval.display_path = get_element_value(elem,"displayPath")
144     retval.file_name = get_element_value(elem, "fileName")
145     retval.relative_path = get_element_value(elem, "relativePath")
146     return retval
147   end
148 
149   def get_revision_no(elem)
150     retval = get_element_value(elem, "revision")
151     return retval if retval != ""
152     retval = get_element_value(elem, "rev") # for mercurial or hudson 1.340
153     return retval
154   end
155 
156 end
157 
158 def HudsonBuild.count_of(job)
159   return 0 unless job
160   return 0 unless job.is_a?(HudsonJob)
161   return HudsonBuild.count_by_sql(["select count(*) from #{HudsonBuild.table_name} where hudson_job_id = ?", job.id])
162 end
163 
164 def HudsonBuild.parse_rss(entry)
165   params = get_element_value(entry, "title").scan(/(.*)#(.*)\s\((.*)\)/)[0]
166   retval = {}
167   retval[:name] = params[0].strip
168   retval[:number] = params[1]
169   retval[:result] = params[2]
170   retval[:url] = "#{entry.elements['link'].attributes['href']}"
171   retval[:published] = Time.xmlschema(get_element_value(entry, "published")).localtime
172   retval[:building] = "false"
173   return retval
174 end
175 
176 def HudsonBuild.exists_number?(job_id, number)
177 
178   return false unless job_id
179   return false unless number
180 
181   return HudsonBuild.exists?(["#{HudsonBuild.table_name}.hudson_job_id = ? AND #{HudsonBuild.table_name}.number = ?", job_id, number])
182 
183 end
184 
185 def HudsonBuild.to_be_updated?(job_id, number)
186   return !HudsonBuild.exists?(["#{HudsonBuild.table_name}.hudson_job_id = ? AND #{HudsonBuild.table_name}.number = ? AND #{HudsonBuild.table_name}.building = 'false'", job_id, number])
187 end
188 
189 def HudsonBuild.find_by_changeset(changeset)
190   return HudsonNoBuild.new() unless changeset
191   retval = HudsonBuild.find(:all,
192                             :order=>"#{HudsonBuild.table_name}.number",
193                             :conditions=> ["#{HudsonBuildChangeset.table_name}.repository_id = ? and #{HudsonBuildChangeset.table_name}.revision = ?", changeset.repository.id, changeset.revision],
194                             :joins=> "INNER JOIN #{HudsonBuildChangeset.table_name} ON #{HudsonBuildChangeset.table_name}.hudson_build_id = #{HudsonBuild.table_name}.id")
195   return retval
196 end
197 
198 class HudsonNoBuild
199   attr_reader :hudson_job_id, :number, :error, :building, :url, :result, :artifacts
200 
201   def initialize
202     @hudson_job_id = ""
203     @number = ""
204     @error = ""
205     @building = ""
206     @url = ""
207     @result = ""
208     @artifacts = []
209   end
210 
211   def building?
212     return false
213   end
214 
215 end