hyphy 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,12 +1,10 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "sequel"
4
- gem "sqlite3"
5
3
  gem "activesupport", "~> 3.2"
4
+ gem "activerecord", "~> 3.2"
6
5
 
7
6
  group :development do
8
7
  gem "bundler"
9
- gem "database_cleaner"
10
8
  gem "jeweler"
11
9
  gem "pry-nav"
12
10
  gem "rdoc"
data/Gemfile.lock CHANGED
@@ -1,16 +1,24 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
+ activemodel (3.2.14)
5
+ activesupport (= 3.2.14)
6
+ builder (~> 3.0.0)
7
+ activerecord (3.2.14)
8
+ activemodel (= 3.2.14)
9
+ activesupport (= 3.2.14)
10
+ arel (~> 3.0.2)
11
+ tzinfo (~> 0.3.29)
4
12
  activesupport (3.2.14)
5
13
  i18n (~> 0.6, >= 0.6.4)
6
14
  multi_json (~> 1.0)
7
15
  addressable (2.3.5)
8
- builder (3.2.2)
16
+ arel (3.0.2)
17
+ builder (3.0.4)
9
18
  coderay (1.0.9)
10
- database_cleaner (1.0.1)
11
19
  diff-lcs (1.2.4)
12
- faraday (0.8.7)
13
- multipart-post (~> 1.1)
20
+ faraday (0.8.8)
21
+ multipart-post (~> 1.2.0)
14
22
  git (1.2.5)
15
23
  github_api (0.10.1)
16
24
  addressable
@@ -65,25 +73,22 @@ GEM
65
73
  rspec-expectations (2.14.0)
66
74
  diff-lcs (>= 1.1.3, < 2.0)
67
75
  rspec-mocks (2.14.1)
68
- sequel (4.0.0)
69
76
  simplecov (0.7.1)
70
77
  multi_json (~> 1.0)
71
78
  simplecov-html (~> 0.7.1)
72
79
  simplecov-html (0.7.1)
73
- slop (3.4.5)
74
- sqlite3 (1.3.7)
80
+ slop (3.4.6)
81
+ tzinfo (0.3.37)
75
82
 
76
83
  PLATFORMS
77
84
  ruby
78
85
 
79
86
  DEPENDENCIES
87
+ activerecord (~> 3.2)
80
88
  activesupport (~> 3.2)
81
89
  bundler
82
- database_cleaner
83
90
  jeweler
84
91
  pry-nav
85
92
  rdoc
86
93
  rspec
87
- sequel
88
94
  simplecov
89
- sqlite3
data/README.md CHANGED
@@ -1,6 +1,88 @@
1
1
  # Hyphy
2
2
 
3
- Hyphy is a framework for identifying SQL bottlenecks in tests.
3
+ Hyphy is a toolkit for identifying SQL bottlenecks in Ruby applications. Given
4
+ an adapter for an ORM and a Ruby block, Hyphy collects all executed queries in
5
+ a dataset. Afterward, it can filter the dataset and even benchmark the queries.
6
+ At [NationBuilder](http://nationbuilder.com/), we use this gem to conduct
7
+ performance regression tests.
8
+
9
+ ## Supported ORMs
10
+
11
+ Hyphy only comes with out of the box support for ActiveRecord. Adding a new ORM
12
+ should be easy, however.
13
+
14
+ ## Creating datasets
15
+
16
+ You can create a new dataset by initializing a `Sampler` object.
17
+ ```ruby
18
+ require 'hyphy'
19
+ sampler = Hyphy::Sampler.new(:orm => :active_record)
20
+ ```
21
+
22
+ ## Sampling queries
23
+
24
+ Once we've created our `Sampler` object, it is very easy to start collecting data.
25
+ Simply enclose the application code that you need profiled in a block and pass it
26
+ to the `profile` method. Example:
27
+
28
+ ```ruby
29
+ sampler.profile do
30
+ # Application code goes here
31
+ end
32
+ ```
33
+
34
+ ## Filtering queries
35
+
36
+ Hyphy comes with a few filters that fit common use cases. Here is how they can
37
+ be used:
38
+
39
+ ```ruby
40
+ # Only keep SQL 'select' queries
41
+ sampler.apply_filter(Hyphy::Filters::SQLFilter, :type => :select)
42
+
43
+ # Only keep queries that had a running time r such that .01 < r < .05
44
+ sampler.apply_filter(Hyphy::Filters::DurationFilter,
45
+ :duration_min => 0.01,
46
+ :duration_max => 0.05)
47
+
48
+ # Keep the top 10 results
49
+ sampler.apply_filter(Hyphy::Filters::LimitFilter,
50
+ :limit => 10)
51
+
52
+ # Benchmark each query with 10 runs (this saves the benchmark information)
53
+ sampler.apply_filter(Hyphy::Filters::BenchmarkFilter, :runs => 10)
54
+
55
+ # Using the benchmark information, keep queries that fit the
56
+ # duration requirements.
57
+ sampler.apply_filter(Hyphy::Filters::DurationFilter,
58
+ :benchmark => true,
59
+ :duration_min => 0.01,
60
+ :duration_max => 0.05))
61
+ ```
62
+
63
+ ## Accessing data
64
+
65
+ To form reports using the data that remains after filtering, we
66
+ use the `SQLStatement` objects in `sampler.dataset`.
67
+
68
+ ```ruby
69
+ sql_statement = sampler.dataset.first
70
+
71
+ sql_statement.statement
72
+ "Select * from users"
73
+
74
+ sql_statement.duration
75
+ 0.03
76
+
77
+ sql_statement.application_trace
78
+ ["/src/application/app/models/model.rb:24:in `make_query'"]
79
+
80
+ sql_statement.benchmark_runs
81
+ 10
82
+
83
+ sql_statement.benchmark_time
84
+ 0.0324
85
+ ```
4
86
 
5
87
  ## Contributing to Hyphy
6
88
 
data/Rakefile CHANGED
@@ -16,8 +16,10 @@ Jeweler::Tasks.new do |gem|
16
16
  gem.name = "hyphy"
17
17
  gem.homepage = "http://github.com/3dna/hyphy"
18
18
  gem.license = "MIT"
19
- gem.summary = %Q{Identify SQL bottlenecks in tests}
20
- gem.description = %Q{Identify SQL bottlenecks in tests}
19
+ gem.summary = %Q{A SQL bottleneck toolkit}
20
+ gem.description = %Q{Hyphy is a toolkit for identifying SQL bottlenecks in Ruby applications. Given
21
+ an adapter for an ORM and a Ruby block, Hyphy collects all executed queries in
22
+ a dataset. Afterward, it can filter the dataset and even benchmark the queries.}
21
23
  gem.email = "david@nationbuilder.com"
22
24
  gem.authors = ["David Huie"]
23
25
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.0.1
data/hyphy.gemspec CHANGED
@@ -5,19 +5,18 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "hyphy"
8
- s.version = "0.0.0"
8
+ s.version = "0.0.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["David Huie"]
12
- s.date = "2013-07-24"
13
- s.description = "Identify SQL bottlenecks in tests"
12
+ s.date = "2013-07-30"
13
+ s.description = "Hyphy is a toolkit for identifying SQL bottlenecks in Ruby applications. Given\nan adapter for an ORM and a Ruby block, Hyphy collects all executed queries in\na dataset. Afterward, it can filter the dataset and even benchmark the queries."
14
14
  s.email = "david@nationbuilder.com"
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE.txt",
17
17
  "README.md"
18
18
  ]
19
19
  s.files = [
20
- ".document",
21
20
  ".rspec",
22
21
  ".ruby-gemset",
23
22
  ".ruby-version",
@@ -29,51 +28,47 @@ Gem::Specification.new do |s|
29
28
  "VERSION",
30
29
  "hyphy.gemspec",
31
30
  "lib/hyphy.rb",
32
- "lib/hyphy/database.rb",
33
- "lib/hyphy/dataset.rb",
34
- "lib/hyphy/dataset_collection.rb",
35
31
  "lib/hyphy/filters/abstract_filter.rb",
32
+ "lib/hyphy/filters/benchmark_filter.rb",
36
33
  "lib/hyphy/filters/duration_filter.rb",
37
- "lib/hyphy/models/sql_statement.rb",
34
+ "lib/hyphy/filters/limit_filter.rb",
35
+ "lib/hyphy/filters/sql_filter.rb",
38
36
  "lib/hyphy/orm_adapters/abstract_orm_adapter.rb",
39
37
  "lib/hyphy/orm_adapters/activerecord_adapter.rb",
40
38
  "lib/hyphy/sampler.rb",
41
- "spec/dataset_collection_spec.rb",
42
- "spec/dataset_spec.rb",
39
+ "lib/hyphy/sql_statement.rb",
43
40
  "spec/filters/abstract_filter_spec.rb",
41
+ "spec/filters/benchmark_filter_spec.rb",
44
42
  "spec/filters/duration_filter_spec.rb",
43
+ "spec/filters/limit_filter_spec.rb",
44
+ "spec/filters/sql_filter_spec.rb",
45
45
  "spec/models/sql_statement_spec.rb",
46
46
  "spec/orm_adapters/activerecord_orm_adapter_spec.rb",
47
47
  "spec/sampler_spec.rb",
48
- "spec/spec_helper.rb",
49
- "specification.txt"
48
+ "spec/spec_helper.rb"
50
49
  ]
51
50
  s.homepage = "http://github.com/3dna/hyphy"
52
51
  s.licenses = ["MIT"]
53
52
  s.require_paths = ["lib"]
54
53
  s.rubygems_version = "1.8.25"
55
- s.summary = "Identify SQL bottlenecks in tests"
54
+ s.summary = "A SQL bottleneck toolkit"
56
55
 
57
56
  if s.respond_to? :specification_version then
58
57
  s.specification_version = 3
59
58
 
60
59
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
61
- s.add_runtime_dependency(%q<sequel>, [">= 0"])
62
- s.add_runtime_dependency(%q<sqlite3>, [">= 0"])
63
60
  s.add_runtime_dependency(%q<activesupport>, ["~> 3.2"])
61
+ s.add_runtime_dependency(%q<activerecord>, ["~> 3.2"])
64
62
  s.add_development_dependency(%q<bundler>, [">= 0"])
65
- s.add_development_dependency(%q<database_cleaner>, [">= 0"])
66
63
  s.add_development_dependency(%q<jeweler>, [">= 0"])
67
64
  s.add_development_dependency(%q<pry-nav>, [">= 0"])
68
65
  s.add_development_dependency(%q<rdoc>, [">= 0"])
69
66
  s.add_development_dependency(%q<rspec>, [">= 0"])
70
67
  s.add_development_dependency(%q<simplecov>, [">= 0"])
71
68
  else
72
- s.add_dependency(%q<sequel>, [">= 0"])
73
- s.add_dependency(%q<sqlite3>, [">= 0"])
74
69
  s.add_dependency(%q<activesupport>, ["~> 3.2"])
70
+ s.add_dependency(%q<activerecord>, ["~> 3.2"])
75
71
  s.add_dependency(%q<bundler>, [">= 0"])
76
- s.add_dependency(%q<database_cleaner>, [">= 0"])
77
72
  s.add_dependency(%q<jeweler>, [">= 0"])
78
73
  s.add_dependency(%q<pry-nav>, [">= 0"])
79
74
  s.add_dependency(%q<rdoc>, [">= 0"])
@@ -81,11 +76,9 @@ Gem::Specification.new do |s|
81
76
  s.add_dependency(%q<simplecov>, [">= 0"])
82
77
  end
83
78
  else
84
- s.add_dependency(%q<sequel>, [">= 0"])
85
- s.add_dependency(%q<sqlite3>, [">= 0"])
86
79
  s.add_dependency(%q<activesupport>, ["~> 3.2"])
80
+ s.add_dependency(%q<activerecord>, ["~> 3.2"])
87
81
  s.add_dependency(%q<bundler>, [">= 0"])
88
- s.add_dependency(%q<database_cleaner>, [">= 0"])
89
82
  s.add_dependency(%q<jeweler>, [">= 0"])
90
83
  s.add_dependency(%q<pry-nav>, [">= 0"])
91
84
  s.add_dependency(%q<rdoc>, [">= 0"])
@@ -1,13 +1,13 @@
1
- class Hyphy::AbstractFilter
1
+ class Hyphy::Filters::AbstractFilter
2
2
 
3
- attr_reader :dataset
3
+ attr_reader :data
4
4
 
5
- def initialize(dataset, opts={})
6
- @dataset = dataset
5
+ def initialize(data, opts={})
6
+ @data = data
7
7
  end
8
8
 
9
9
  def filter
10
- @dataset
10
+ @data
11
11
  end
12
12
 
13
13
  end
@@ -0,0 +1,30 @@
1
+ class Hyphy::Filters::BenchmarkFilter < Hyphy::Filters::AbstractFilter
2
+
3
+ def initialize(data, opts)
4
+ @runs = opts[:runs] || 1
5
+
6
+ super
7
+ end
8
+
9
+ def filter
10
+ @data.each do |sql_statement|
11
+ timing = self.class.benchmark(sql_statement, @runs)
12
+
13
+ sql_statement.benchmark_runs = @runs
14
+ sql_statement.benchmark_time = timing
15
+ end
16
+ end
17
+
18
+ def self.benchmark(sql_statement, runs)
19
+ times = []
20
+
21
+ (1..runs).each do
22
+ times << sql_statement.orm_adapter.time_statement(sql_statement)
23
+ end
24
+
25
+ # Calculate the average
26
+ average = times.reduce(:+) / times.count
27
+ average.to_f
28
+ end
29
+
30
+ end
@@ -1,20 +1,29 @@
1
- class Hyphy::DurationFilter < Hyphy::AbstractFilter
1
+ class Hyphy::Filters::DurationFilter < Hyphy::Filters::AbstractFilter
2
2
 
3
3
  attr_reader :duration_min, :duration_max
4
4
 
5
- def initialize(dataset, opts)
5
+ def initialize(data, opts)
6
6
  @duration_min = opts[:duration_min] || 0.0
7
7
  @duration_max = opts[:duration_max] || Float::INFINITY
8
+ @benchmark = opts[:benchmark] || false
9
+
10
+ if @benchmark
11
+ @duration = lambda { |sql_statement| sql_statement.benchmark_time }
12
+ else
13
+ @duration = lambda { |sql_statement| sql_statement.duration }
14
+ end
8
15
 
9
16
  super
10
17
  end
11
18
 
12
19
  def filter
13
- @dataset.select! do |sql_statement|
14
- (@duration_min <= sql_statement.duration) and (sql_statement.duration <= @duration_max)
20
+ @data.select! do |sql_statement|
21
+ next unless @duration.call(sql_statement)
22
+
23
+ (@duration_min <= @duration.call(sql_statement)) and (@duration.call(sql_statement) <= @duration_max)
15
24
  end
16
25
 
17
- @dataset.sort_by! { |sql_statement| -sql_statement.duration }
26
+ @data.sort_by! { |sql_statement| -sql_statement.duration }
18
27
  end
19
28
 
20
29
  end
@@ -0,0 +1,13 @@
1
+ class Hyphy::Filters::LimitFilter < Hyphy::Filters::AbstractFilter
2
+
3
+ def initialize(data, opts)
4
+ @limit = opts[:limit] || 10
5
+
6
+ super
7
+ end
8
+
9
+ def filter
10
+ @data = @data[(0...@limit)]
11
+ end
12
+
13
+ end
@@ -0,0 +1,21 @@
1
+ class Hyphy::Filters::SQLFilter < Hyphy::Filters::AbstractFilter
2
+
3
+ class IncorrectSQLTypeException < Exception; end
4
+
5
+ def initialize(data, opts={})
6
+ @type = opts[:type] || :select
7
+
8
+ unless [:select, :insert].include?(@type)
9
+ raise IncorrectSQLTypeException, "incorrect type: #{@type}"
10
+ end
11
+
12
+ super
13
+ end
14
+
15
+ def filter
16
+ @data.select! do |sql_statement|
17
+ sql_statement.send("#{@type}?".to_sym)
18
+ end
19
+ end
20
+
21
+ end
@@ -1,7 +1,9 @@
1
- require 'json'
2
-
3
1
  class Hyphy::AbstractORMAdapter
4
2
 
5
3
  def self.subscribe_to_sql_notifications(callback); end
6
4
 
5
+ def self.unsubscribe_to_sql_notifications(subscriber); end
6
+
7
+ def self.time_statement(statement); end
8
+
7
9
  end
@@ -1,15 +1,33 @@
1
+ require 'active_record'
1
2
  require 'active_support/notifications'
3
+ require 'benchmark'
2
4
 
3
5
  class Hyphy::ActiveRecordAdapter < Hyphy::AbstractORMAdapter
4
6
 
5
7
  def self.subscribe_to_sql_notifications(callback)
6
8
  ActiveSupport::Notifications.subscribe('sql.active_record') do |*args|
7
- sql_statement = args[4][:sql]
9
+ sql = args[4][:sql]
10
+ binds = args[4][:binds]
8
11
  start_time = args[1]
9
12
  end_time = args[2]
10
13
 
11
- callback.call(sql_statement, start_time, end_time)
14
+ sql_statement = callback.call(sql, start_time, end_time)
15
+ sql_statement.binds = binds
12
16
  end
13
17
  end
14
18
 
19
+ def self.unsubscribe_to_sql_notifications(subscriber)
20
+ ActiveSupport::Notifications.unsubscribe(subscriber)
21
+ end
22
+
23
+ def self.time_statement(sql_statement)
24
+ ActiveRecord::Base.connection.clear_query_cache
25
+
26
+ binds = sql_statement.binds
27
+ Benchmark.realtime { ActiveRecord::Base.connection.send(:exec_query,
28
+ sql_statement.statement,
29
+ 'SQL',
30
+ binds) }
31
+ end
32
+
15
33
  end
data/lib/hyphy/sampler.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  class Hyphy::Sampler
2
2
 
3
+ attr_accessor :dataset
3
4
  attr_reader :orm_adapter, :metadata_callbacks
4
5
 
5
6
  class UnsupportedORMException < Exception; end
@@ -13,25 +14,30 @@ class Hyphy::Sampler
13
14
  raise UnsupportedORMException, 'ORM #{orm} is not supported'
14
15
  end
15
16
 
17
+ @dataset = []
16
18
  @metadata_callbacks = {}
17
19
  end
18
20
 
19
- def log_sql(statement, start_time, end_time)
20
- Hyphy::SQLStatement.create(:statement => statement,
21
- :start_time => start_time,
22
- :end_time => end_time,
23
- :trace_json => JSON(caller))
21
+ def log_sql(statement, start_time, end_time, orm_adapter)
22
+ sql_statement = Hyphy::SQLStatement.new(:statement => statement,
23
+ :start_time => start_time,
24
+ :end_time => end_time,
25
+ :orm_adapter => orm_adapter,
26
+ :trace => caller)
27
+ @dataset << sql_statement
28
+ sql_statement
24
29
  end
25
30
 
26
31
  def process_metadata(sql_statement)
27
32
  @metadata_callbacks.each do |key, value_block|
28
- sql_statement.add_metadata(key, value_block.call)
33
+ sql_statement.metadata[key] = value_block.call
29
34
  end
30
35
  end
31
36
 
32
37
  def sample(statement, start_time, end_time)
33
- sql_statement = log_sql(statement, start_time, end_time)
38
+ sql_statement = log_sql(statement, start_time, end_time, @orm_adapter)
34
39
  process_metadata(sql_statement)
40
+ sql_statement
35
41
  end
36
42
 
37
43
  def add_metadata(name, &block)
@@ -39,7 +45,22 @@ class Hyphy::Sampler
39
45
  end
40
46
 
41
47
  def begin
42
- @orm_adapter.subscribe_to_sql_notifications(method(:sample))
48
+ @subscriber = @orm_adapter.subscribe_to_sql_notifications(method(:sample))
49
+ end
50
+
51
+ def stop
52
+ @orm_adapter.unsubscribe_to_sql_notifications(@subscriber)
53
+ end
54
+
55
+ def profile
56
+ self.begin
57
+ yield
58
+ self.stop
59
+ end
60
+
61
+ def apply_filter(filter_class, opts={})
62
+ filter = filter_class.new(@dataset, opts)
63
+ filter.filter
43
64
  end
44
65
 
45
66
  end
@@ -0,0 +1,52 @@
1
+ class Hyphy::SQLStatement
2
+
3
+ DIGIT_MARKER = '<digit>'
4
+
5
+ attr_accessor(:statement,
6
+ :trace,
7
+ :metadata,
8
+ :binds,
9
+ :orm_adapter,
10
+ :start_time,
11
+ :end_time,
12
+ :benchmark_runs,
13
+ :benchmark_time)
14
+
15
+ def initialize(opts={})
16
+ @statement = opts[:statement]
17
+ @start_time = opts[:start_time]
18
+ @end_time = opts[:end_time]
19
+ @orm_adapter = opts[:orm_adapter]
20
+ @trace = opts[:trace] || []
21
+ @binds = opts[:binds] || []
22
+ @metadata = opts[:metadata] || {}
23
+ end
24
+
25
+ def duration
26
+ @duration ||= (end_time - start_time)
27
+ end
28
+
29
+ def stripped_statement
30
+ @stripped_statement ||= statement.strip
31
+ end
32
+
33
+ def select?
34
+ @select ||= stripped_statement.upcase.match(/^SELECT/)
35
+ end
36
+
37
+ def insert?
38
+ @insert ||= stripped_statement.upcase.match(/^INSERT/)
39
+ end
40
+
41
+ def digitless
42
+ @digitless ||= stripped_statement.gsub(/\d+/, DIGIT_MARKER)
43
+ end
44
+
45
+ def application_trace
46
+ return @application_trace if @application_trace
47
+
48
+ regex = Regexp.new("^#{Dir.pwd}")
49
+ @application_trace ||= trace.select { |line| regex.match(line) }
50
+ end
51
+
52
+ end
data/lib/hyphy.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  module Hyphy; end
2
+ module Hyphy::Filters; end
2
3
 
3
- require 'hyphy/database'
4
- require 'hyphy/models/sql_statement'
4
+ require 'hyphy/sql_statement'
5
5
  require 'hyphy/orm_adapters/abstract_orm_adapter'
6
6
  require 'hyphy/orm_adapters/activerecord_adapter'
7
7
  require 'hyphy/sampler'
8
8
  require 'hyphy/filters/abstract_filter'
9
9
  require 'hyphy/filters/duration_filter'
10
- require 'hyphy/dataset'
11
- require 'hyphy/dataset_collection'
10
+ require 'hyphy/filters/benchmark_filter'
11
+ require 'hyphy/filters/limit_filter'
12
+ require 'hyphy/filters/sql_filter'
@@ -1,13 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Hyphy::AbstractFilter do
3
+ describe Hyphy::Filters::AbstractFilter do
4
4
 
5
- it 'stores a dataset' do
6
- dataset = [1, 2]
7
- filter = Hyphy::AbstractFilter.new(dataset)
5
+ it 'stores data' do
6
+ data = [1, 2]
7
+ filter = Hyphy::Filters::AbstractFilter.new(data)
8
8
 
9
- filter.dataset.should == dataset
10
- filter.filter.should == dataset
9
+ filter.data.should == data
10
+ filter.filter.should == data
11
11
  end
12
12
 
13
13
  end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hyphy::Filters::BenchmarkFilter do
4
+
5
+ before(:each) do
6
+ @sql_statement = Hyphy::SQLStatement.new(:statement => 'select * from table',
7
+ :orm_adapter => Hyphy::AbstractORMAdapter)
8
+ @sql_statement_times = [1.0, 2.0, 3.0]
9
+ @runs = @sql_statement_times.count
10
+
11
+ Hyphy::AbstractORMAdapter.stub(:time_statement).and_return(*@sql_statement_times)
12
+
13
+ @data = [@sql_statement]
14
+ @filter = Hyphy::Filters::BenchmarkFilter.new(@data, :runs => @runs)
15
+ @average_time = @sql_statement_times.reduce(:+) / @runs
16
+ end
17
+
18
+ describe "#filter" do
19
+
20
+ it "modifies the data to include benchmark data" do
21
+ @filter.filter
22
+
23
+ @data[0].benchmark_runs.should == @runs
24
+ @data[0].benchmark_time.should == @average_time
25
+ end
26
+
27
+ end
28
+
29
+ describe ".benchmark" do
30
+
31
+ it "it returns an average of the different run times of a statement" do
32
+ average_time = Hyphy::Filters::BenchmarkFilter.benchmark(@sql_statement, @runs)
33
+ average_time.should == @average_time
34
+ end
35
+
36
+ end
37
+
38
+ end