https://svn.lrde.epita.fr/svn/ranch/trunk
Index: ChangeLog
from Nicolas Desprès <nicolas.despres(a)lrde.epita.fr>
Draw regression graph.
* web/ranch/app/controllers/graph_controller.rb: New. Collect data
and send them to the grapher.
* web/ranch/test/functional/graph_controller_test.rb: New. Test the
graph controller.
* web/ranch/app/helpers/graph_helper.rb: New. Add a tag that helps to
draw a regression graph in a view.
* web/ranch/lib/grapher.rb: New. Generate a graph using
`ruby-gdchart'.
* web/ranch/app/controllers/graph_form_controller.rb: Add the draw
request.
* web/ranch/test/functional/graph_form_controller_test.rb: .
* web/ranch/app/views/graph_form/index.rhtml: Draw the graph.
* web/ranch/app/models/output.rb: New. The model for the outputs
table.
* web/ranch/test/unit/output_test.rb: New. Test the model.
* web/ranch/test/fixtures/outputs.yml: New. Add some fixtures.
* web/ranch/test/fixtures/benches.yml,
* web/ranch/test/fixtures/projects.yml: Update to the new DB schema.
* web/ranch/app/models/bench.rb: Add the relationship with the
outputs table.
* web/ranch/config/environment.rb: Require some libs.
* web/ranch/db/schema.rb: Add the outputs table.
app/controllers/graph_controller.rb | 39 ++++++++++++++++++++++++++
app/controllers/graph_form_controller.rb | 11 ++++++-
app/helpers/graph_helper.rb | 18 ++++++++++++
app/models/bench.rb | 1
app/models/output.rb | 5 +++
app/views/graph_form/index.rhtml | 13 +++++++-
config/environment.rb | 3 ++
db/schema.rb | 11 +++++++
lib/grapher.rb | 27 ++++++++++++++++++
test/fixtures/benches.yml | 19 ++++++------
test/fixtures/outputs.yml | 12 ++++++++
test/fixtures/projects.yml | 3 ++
test/functional/graph_controller_test.rb | 19 ++++++++++++
test/functional/graph_form_controller_test.rb | 20 ++++++++++++-
test/unit/output_test.rb | 10 ++++++
15 files changed, 196 insertions(+), 15 deletions(-)
Index: web/ranch/test/unit/output_test.rb
--- web/ranch/test/unit/output_test.rb (revision 0)
+++ web/ranch/test/unit/output_test.rb (revision 0)
@@ -0,0 +1,10 @@
+require File.dirname(__FILE__) + '/../test_helper'
+
+class OutputTest < Test::Unit::TestCase
+ fixtures :outputs
+
+ # Replace this with your real tests.
+ def test_truth
+ assert_kind_of Output, outputs(:first)
+ end
+end
Index: web/ranch/test/functional/graph_controller_test.rb
--- web/ranch/test/functional/graph_controller_test.rb (revision 0)
+++ web/ranch/test/functional/graph_controller_test.rb (revision 0)
@@ -0,0 +1,19 @@
+require File.dirname(__FILE__) + '/../test_helper'
+require 'graph_controller'
+
+# Re-raise errors caught by the controller.
+class GraphController; def rescue_action(e) raise e end; end
+
+class GraphControllerTest < Test::Unit::TestCase
+ def setup
+ @controller = GraphController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ # Replace this with your real tests.
+ def test_truth
+ #FIXME: test me
+ assert true
+ end
+end
Index: web/ranch/test/functional/graph_form_controller_test.rb
--- web/ranch/test/functional/graph_form_controller_test.rb (revision 12)
+++ web/ranch/test/functional/graph_form_controller_test.rb (working copy)
@@ -13,13 +13,29 @@
@response = ActionController::TestResponse.new
end
- # Replace this with your real tests.
- def test_truth
+ def test_index
get :index, { :project_id => 1, :bench_name => 'determinize' }
assert_response :success
assert_template 'index'
assert_not_nil assigns(:project)
assert_not_nil assigns(:bench_name)
+ assert !assigns(:draw_on)
end
+
+ def test_draw
+ post :draw, {
+ :project_id => 1,
+ :bench_name => 'determinize',
+ :revision => { :start => 0, :stop => 10 }
+ }
+ assert_response :success
+ assert_template 'index'
+
+ assert_not_nil assigns(:project)
+ assert_not_nil assigns(:bench_name)
+ assert_not_nil assigns(:revision)
+ assert assigns(:draw_on)
+ end
+
end
Index: web/ranch/test/fixtures/outputs.yml
--- web/ranch/test/fixtures/outputs.yml (revision 0)
+++ web/ranch/test/fixtures/outputs.yml (revision 0)
@@ -0,0 +1,12 @@
+<% id = 0 %>
+
+<% val = 5; (1..10).each do |rev| %>
+<%= "determinize_r#{rev}_utime:" %>
+ id: <%= id += 1 %>
+ name: utime
+ value: <%= val += rev %>
+ unit: sec
+ bench_id: <%= rev %>
+ arg_num: 1
+<% end %>
+
Index: web/ranch/test/fixtures/benches.yml
--- web/ranch/test/fixtures/benches.yml (revision 12)
+++ web/ranch/test/fixtures/benches.yml (working copy)
@@ -1,26 +1,25 @@
# Read about fixtures at
http://ar.rubyonrails.org/classes/Fixtures.html
-<% id = 1 %>
+<% id = 0 %>
-determinize_r1:
- id: <% id += 1 %>
- project_id: 1
- name: determinize
-determinize_r2:
- id: <% id += 1 %>
+<% (1..10).each do |rev| %>
+<%= "determinize_r#{rev}:" %>
+ id: <%= id += 1 %>
project_id: 1
name: determinize
+ revision: <%= rev %>
+<% end %>
quotient:
- id: <% id += 1 %>
+ id: <%= id += 1 %>
project_id: 1
name: quotient
open:
- id: <% id += 1 %>
+ id: <%= id += 1 %>
project_id: 2
name: open
close:
- id: <% id += 1 %>
+ id: <%= id += 1 %>
project_id: 2
name: close
Index: web/ranch/test/fixtures/projects.yml
--- web/ranch/test/fixtures/projects.yml (revision 12)
+++ web/ranch/test/fixtures/projects.yml (working copy)
@@ -2,7 +2,10 @@
vaucanson:
id: 1
name: Vaucanson
+ head_revision: 10
+
olena:
id: 2
name: Olena
+ head_revision: 100
Index: web/ranch/app/helpers/graph_helper.rb
--- web/ranch/app/helpers/graph_helper.rb (revision 0)
+++ web/ranch/app/helpers/graph_helper.rb (revision 0)
@@ -0,0 +1,18 @@
+module GraphHelper
+
+ def graph_reg_tag(project_id, bench_name, rev_start, rev_stop, options={})
+ url = {
+ :controller => 'graph',
+ :action => 'regression',
+ :project_id => project_id,
+ :bench_name => bench_name,
+ :rev_start => rev_start,
+ :rev_stop => rev_stop
+ }
+ options = url.merge(options)
+ "<img src=\"#{url_for options}\" " +
+ "class=\"#{options[:class] || 'regression_graph'}\" "+
+ "alt=\"Regression graph\" />"
+ end
+
+end
Index: web/ranch/app/models/bench.rb
--- web/ranch/app/models/bench.rb (revision 12)
+++ web/ranch/app/models/bench.rb (working copy)
@@ -1,5 +1,6 @@
class Bench < ActiveRecord::Base
belongs_to :project
+ has_many :output
end
Index: web/ranch/app/models/output.rb
--- web/ranch/app/models/output.rb (revision 0)
+++ web/ranch/app/models/output.rb (revision 0)
@@ -0,0 +1,5 @@
+class Output < ActiveRecord::Base
+
+ belongs_to :bench
+
+end
Index: web/ranch/app/controllers/graph_controller.rb
--- web/ranch/app/controllers/graph_controller.rb (revision 0)
+++ web/ranch/app/controllers/graph_controller.rb (revision 0)
@@ -0,0 +1,39 @@
+class GraphController < ApplicationController
+
+ load 'grapher.rb'
+
+ def regression
+ @project = Project.find params[:project_id]
+ @bench_name = params[:bench_name]
+ @output_num = 1 #FIXME: manage several outputs
+
+ values = Bench.find_by_sql "SELECT outputs.value, benches.revision " +
+ "FROM outputs, benches " +
+ "WHERE benches.project_id = #{(a)project.id} " +
+ "AND benches.name = '#@bench_name' " +
+ "AND outputs.bench_id = benches.id " +
+ "AND outputs.arg_num = #@output_num " +
+ "AND #{params[:rev_start]} <=benches.revision " +
+ "AND benches.revision <= #{params[:rev_stop]} " +
+ "ORDER BY benches.revision"
+
+ data = values.collect { |v| v.value.to_f }
+ labels = values.collect { |v| "r#{v.revision}" }
+
+ filename = "regression_#{@project.name}_#@bench_name"
+ Tempfile.open(filename) do |f|
+ File.open(f.path, 'w') do |io|
+ Grapher.regression(io,
+ "#{(a)project.name}name}: #@bench_name",
+ "utime(sec)", #FIXME: gather this info from the DB
+ data,
+ labels)
+ end
+ send_file(f.path,
+ :disposition => 'inline',
+ :type => 'image/jpeg',
+ :filename => "#{filename}.jpg")
+ end
+ end
+
+end
Index: web/ranch/app/controllers/graph_form_controller.rb
--- web/ranch/app/controllers/graph_form_controller.rb (revision 12)
+++ web/ranch/app/controllers/graph_form_controller.rb (working copy)
@@ -1,10 +1,19 @@
class GraphFormController < ApplicationController
-
+ helper :graph
layout 'ranch'
def index
@bench_name = params[:bench_name]
@project = Project.find params[:project_id]
+ @draw_on = false
+ end
+
+ def draw
+ @bench_name = params[:bench_name]
+ @project = Project.find params[:project_id]
+ @revision = params[:revision]
+ @draw_on = true
+ render :action => 'index'
end
end
Index: web/ranch/app/views/graph_form/index.rhtml
--- web/ranch/app/views/graph_form/index.rhtml (revision 12)
+++ web/ranch/app/views/graph_form/index.rhtml (working copy)
@@ -13,12 +13,21 @@
<td>Stop</td>
</tr>
<tr>
- <td><%= text_field "revision", "start", "size"
=> 8, "value" => 0 %></td>
- <td><%= text_field "revision", "stop", "size"
=> 8, "value" => 10 %></td>
+ <td><%= text_field "revision", "start", "size"
=> 8,
+ "value" => 0 %></td>
+ <td><%= text_field "revision", "stop", "size"
=> 8,
+ "value" => @project.head_revision %></td>
</tr>
</table>
</center>
</p>
<%= submit_tag "Draw" %>
<%= end_form_tag %>
+
+<% if @draw_on %>
+ <%= graph_reg_tag @project.id, @bench_name,
+ @revision[:start], @revision[:stop] %>
+<% else %>
+ <%= content_tag "p", "No chart to display - click Draw" %>
+<% end %>
</div>
Index: web/ranch/config/environment.rb
--- web/ranch/config/environment.rb (revision 12)
+++ web/ranch/config/environment.rb (working copy)
@@ -49,3 +49,6 @@
# end
# Include your application configuration below
\ No newline at end of file
+require 'grapher'
+require 'tempfile'
+
Index: web/ranch/db/schema.rb
--- web/ranch/db/schema.rb (revision 12)
+++ web/ranch/db/schema.rb (working copy)
@@ -12,8 +12,19 @@
add_index "benches", ["project_id"], :name =>
"project_id"
+ create_table "outputs", :force => true do |t|
+ t.column "name", :string, :limit => 128, :default =>
"noname", :null => false
+ t.column "value", :float, :default => 0.0, :null => false
+ t.column "unit", :string, :limit => 128, :default =>
"nounit", :null => false
+ t.column "bench_id", :integer, :limit => 10, :default => 0, :null
=> false
+ t.column "arg_num", :integer, :limit => 8, :default => 1, :null =>
false
+ end
+
+ add_index "outputs", ["bench_id"], :name =>
"bench_id"
+
create_table "projects", :force => true do |t|
t.column "name", :string, :default => "noname", :null =>
false
+ t.column "head_revision", :integer, :limit => 10, :default => 0,
:null => false
end
end
Index: web/ranch/lib/grapher.rb
--- web/ranch/lib/grapher.rb (revision 0)
+++ web/ranch/lib/grapher.rb (revision 0)
@@ -0,0 +1,27 @@
+require_gem 'ruby-gdchart'
+
+module Grapher
+
+ def self.regression(io, title, ytitle, data, labels)
+ gdc = GDChart.new
+ gdc.title = title
+ gdc.title_size = GDChart::GIANT
+ gdc.set_color = [ 0x00FF00 ]
+ gdc.bg_color = 0xFFFFFF
+ gdc.xtitle = "Revision"
+ gdc.ytitle = ytitle
+ xsize = 600
+ ysize = 300
+ numsets = 1
+ gdc.image_type = GDChart::JPEG
+ gdc.out_graph(xsize,
+ ysize,
+ io,
+ GDChart::LINE,
+ labels.size,
+ labels,
+ numsets,
+ data)
+ end
+
+end