require_relative "../helpers" describe BigBench::PostProcessor::Environment do before(:each) do BigBench.config.duration = 7.seconds BigBench.config.output = "spec/tests/sample_results_small.ljson" class << self include BigBench::PostProcessor::Environment end @total_trackings = 3_875 end it "should allow to iterate over each tracking" do all_trackings = 0 each_tracking do |tracking| tracking.is_a?(Hash).should be_true all_trackings += 1 end all_trackings.should == @total_trackings end it "should collect a trackings array with all trackings" do trackings.size.should == @total_trackings trackings.each do |tracking| tracking.is_a?(Hash).should be_true end end context "statistics", :statistics do it "should calculate the minimum" do statistics.durations.min.should == 1 statistics(1.minute).durations.min.should == 1 statistics.requests.min.should == 28 statistics.methods(:get).min.should == 19 statistics.statuses(200).min.should == 28 statistics.paths("/").min.should == 19 end it "should calculate the maximum" do statistics.durations.max.should == 26 statistics.requests.max.should == 591 statistics.methods(:get).max.should == 394 statistics.statuses(200).max.should == 591 statistics.paths("/").max.should == 394 end it "should calculate the mean - average" do statistics.durations.mean.should == 1.1945806451612904 statistics.durations.average.should == 1.1945806451612904 statistics.requests.mean.should == 484.375 statistics.methods(:get).mean.should == 323.0 statistics.statuses(200).mean.should == 484.375 statistics.paths("/").mean.should == 323.0 end it "should calculate the standard_deviation - sd" do statistics.durations.standard_deviation.should == 0.3565219562955294 statistics.durations.sd.should == 0.3565219562955294 statistics.requests.sd.should == 114.09375 statistics.methods(:get).sd.should == 76.0 statistics.statuses(200).sd.should == 114.09375 statistics.paths("/").sd.should == 76.0 end it "should calculate the squared_deviation - variance" do statistics.durations.squared_deviation.should == 1.8738803080123505 statistics.durations.variance.should == 1.8738803080123505 statistics.requests.variance.should == 30844.734375 statistics.methods(:get).variance.should == 13687.25 statistics.statuses(200).variance.should == 30844.734375 statistics.paths("/").variance.should == 13682.0 end end context "normal_distribution", :gauss do it "should work with durations" do validate_normal_distribution(normal_distribution.durations).should be_true normal_distribution.durations.formula.should == "1 / sqrt(2 * pi * 0.06692176830748373) * e**( -0.5 * (x - 1.1776612630893981)**2 / 0.06692176830748373)" end it "should work with requests" do validate_normal_distribution(normal_distribution.requests).should be_true normal_distribution.requests.formula.should == "1 / sqrt(2 * pi * 114.09375) * e**( -0.5 * (x - 484.375)**2 / 114.09375)" end it "should work with methods" do validate_normal_distribution(normal_distribution.methods(:get)).should be_true normal_distribution.methods(:get).formula.should == "1 / sqrt(2 * pi * 76.0) * e**( -0.5 * (x - 323.0)**2 / 76.0)" end it "should work with statuses" do validate_normal_distribution(normal_distribution.statuses(200)).should be_true normal_distribution.statuses(200).formula.should == "1 / sqrt(2 * pi * 114.09375) * e**( -0.5 * (x - 484.375)**2 / 114.09375)" end it "should work with paths" do validate_normal_distribution(normal_distribution.paths("/")).should be_true normal_distribution.paths("/").formula.should == "1 / sqrt(2 * pi * 76.0) * e**( -0.5 * (x - 323.0)**2 / 76.0)" end end context "cluster", :cluster do it "should work with timesteps" do cluster.timesteps.size.should == 8 cluster(1.second).timesteps.size.should == 8 cluster(1.minute).timesteps.size.should == 1 end it "should work with durations" do cluster.durations.size.should == 8 cluster.durations.each{ |duration| duration.is_a?(Float) } end it "should work with requests" do cluster.requests.size.should == 8 cluster.requests.each{ |requests| requests.is_a?(Integer) } end it "should work with methods" do cluster.methods(:get).size.should == 8 cluster.methods(:post).size.should == 8 cluster.methods(:nothing).size.should == 8 cluster.methods(:post).each{ |requests| requests.is_a?(Integer) } cluster.methods(:nothing).each{ |requests| requests.is_a?(Integer) } end it "should work with statuses" do cluster.statuses(200).size.should == 8 cluster.statuses(404).size.should == 8 cluster.statuses("nothing").size.should == 8 cluster.statuses(200).each{ |requests| requests.is_a?(Integer) } cluster.statuses(404).each{ |requests| requests.is_a?(Integer) } end it "should work with paths" do cluster.paths("/").size.should == 8 cluster.paths("/pages").size.should == 8 cluster.paths("nothing").size.should == 8 cluster.paths("/").each{ |requests| requests.is_a?(Integer) } cluster.paths("/pages").each{ |requests| requests.is_a?(Integer) } end end context "linear regression", :linreg do it "should create durations with the default timebase" do polynomial_regression.durations.x.size.should == 8 polynomial_regression.durations.y.size.should == 8 polynomial_regression.durations.derivation(0).size.should == 8 polynomial_regression.durations.derivation(1).size.should == 8 polynomial_regression.durations.degree.should == 1 polynomial_regression.durations.coefficients.should == [1.174433419687437, 0.0009222409719889246] polynomial_regression.durations.formula.should == "1.174433419687437 + 0.0009222409719889246x^1" polynomial_regression.durations.formula(1).should == "0.0009222409719889246" end it "should create requests with the default timebase" do polynomial_regression.requests.x.size.should == 8 polynomial_regression.requests.y.size.should == 8 polynomial_regression.requests.derivation(0).size.should == 8 polynomial_regression.requests.derivation(1).size.should == 8 polynomial_regression.requests.degree.should == 1 polynomial_regression.requests.coefficients.should == [334.5000000000001, 42.82142857142857] polynomial_regression.requests.formula.should == "334.5000000000001 + 42.82142857142857x^1" polynomial_regression.requests.formula(1).should == "42.82142857142857" end it "should create methods with the default timebase" do polynomial_regression.methods(:get).x.size.should == 8 polynomial_regression.methods(:get).y.size.should == 8 polynomial_regression.methods(:get).derivation(0).size.should == 8 polynomial_regression.methods(:get).derivation(1).size.should == 8 polynomial_regression.methods(:get).degree.should == 1 polynomial_regression.methods(:get).coefficients.should == [223.25000000000006, 28.499999999999996] polynomial_regression.methods(:get).formula.should == "223.25000000000006 + 28.499999999999996x^1" polynomial_regression.methods(:get).formula(1).should == "28.499999999999996" end it "should create statuses with the default timebase" do polynomial_regression.statuses(200).x.size.should == 8 polynomial_regression.statuses(200).y.size.should == 8 polynomial_regression.statuses(200).derivation(0).size.should == 8 polynomial_regression.statuses(200).derivation(1).size.should == 8 polynomial_regression.statuses(200).degree.should == 1 polynomial_regression.statuses(200).coefficients.should == [334.5000000000001, 42.82142857142857] polynomial_regression.statuses(200).formula.should == "334.5000000000001 + 42.82142857142857x^1" polynomial_regression.statuses(200).formula(1).should == "42.82142857142857" end it "should create paths with the default timebase" do polynomial_regression.paths("/").x.size.should == 8 polynomial_regression.paths("/").y.size.should == 8 polynomial_regression.paths("/").derivation(0).size.should == 8 polynomial_regression.paths("/").derivation(1).size.should == 8 polynomial_regression.paths("/").degree.should == 1 polynomial_regression.paths("/").coefficients.should == [223.00000000000006, 28.571428571428566] polynomial_regression.paths("/").formula.should == "223.00000000000006 + 28.571428571428566x^1" polynomial_regression.paths("/").formula(1).should == "28.571428571428566" end it "should create durations with a too small custom timebase" do lambda{ polynomial_regression(:timebase => 1.minute).durations.x.size.should == 1 }.should raise_exception, "Regression is not possible for a single time value, choose a smaller timebase" end it "should create durations with a too small custom timebase" do polynomial_regression(:timebase => 4.seconds).durations.x.size.should == 2 polynomial_regression(:timebase => 4.seconds).durations.y.size.should == 2 polynomial_regression(:timebase => 4.seconds).durations.derivation(0).size.should == 2 polynomial_regression(:timebase => 4.seconds).durations.derivation(1).size.should == 2 polynomial_regression(:timebase => 4.seconds).durations.degree.should == 1 polynomial_regression(:timebase => 4.seconds).durations.coefficients.should == [1.2389749702026223, -0.07830132432187575] polynomial_regression(:timebase => 4.seconds).durations.formula.should == "1.2389749702026223 + -0.07830132432187575x^1" polynomial_regression(:timebase => 4.seconds).durations.formula(1).should == "-0.07830132432187575" end end context "quadratic regression", :quadreg do it "should create durations with the default timebase" do polynomial_regression(:degree => 2).durations.x.size.should == 8 polynomial_regression(:degree => 2).durations.y.size.should == 8 polynomial_regression(:degree => 2).durations.derivation(0).size.should == 8 polynomial_regression(:degree => 2).durations.derivation(1).size.should == 8 polynomial_regression(:degree => 2).durations.degree.should == 2 polynomial_regression(:degree => 2).durations.coefficients.should == [1.1347571673566461, 0.04059849330278298, -0.005668036047256117] polynomial_regression(:degree => 2).durations.formula.should == "1.1347571673566461 + 0.04059849330278298x^1 + -0.005668036047256117x^2" polynomial_regression(:degree => 2).durations.formula(1).should == "0.04059849330278298 + 2*-0.005668036047256117x^1" end end context "appearing", :appearing do it "should list statuses" do appearing.statuses.should == [200] end it "should list methods" do appearing.methods.should == ["get", "post"] end it "should list paths" do appearing.paths.should == ["/", "/basic/auth"] end end context "benchmark scope", :benchmark do before(:each) do BigBench.config.output = "spec/tests/sample_results_small.ljson" BigBench.benchmark("index page" => "http://localhost:3001"){ get "/" } BigBench.benchmark("logout page" => "http://localhost:3001"){ get "/" } end it "should offer an iterator over the benchmarks and set the scope", :scope do run_benchmarks = [] each_benchmark do |benchmark| scope.should == benchmark.name run_benchmarks << scope end run_benchmarks.should == ["index page", "logout page"] end it "should scope cluster" do scope_to_benchmark("index page") do cluster.requests.size.should == 8 end scope_to_benchmark("logout page") do cluster.requests.size.should == 8 end lambda{ scope_to_benchmark("not existant"){}}.should raise_exception BigBench::PostProcessor::Environment::BenchmarkNotFound, "Could not find Benchmark: 'not existant'. Available benchmarks are: index page, logout page" end it "should scope statistics" do scope_to_benchmark("index page") do statistics.requests.min.should == 14 statistics.requests.mean.should == 470.75 statistics.requests.max.should == 577 statistics.requests.sd.should == 114.875 statistics.requests.variance.should == 31206.6875 end scope_to_benchmark("logout page") do statistics.requests.min.should == 5 statistics.requests.mean.should == 13.625 statistics.requests.max.should == 42 statistics.requests.sd.should == 7.28125 statistics.requests.variance.should == 127.234375 end lambda{ scope_to_benchmark("not existant"){}}.should raise_exception BigBench::PostProcessor::Environment::BenchmarkNotFound, "Could not find Benchmark: 'not existant'. Available benchmarks are: index page, logout page" end it "should scope normal_distribution" do scope_to_benchmark("index page") do validate_normal_distribution(normal_distribution.requests).should be_true validate_normal_distribution(normal_distribution.durations).should be_true end scope_to_benchmark("logout page") do validate_normal_distribution(normal_distribution.requests).should be_true validate_normal_distribution(normal_distribution.durations).should be_true end lambda{ scope_to_benchmark("not existant"){}}.should raise_exception BigBench::PostProcessor::Environment::BenchmarkNotFound, "Could not find Benchmark: 'not existant'. Available benchmarks are: index page, logout page" end it "should scope polynomial_regression", :benchmark_regression do scope_to_benchmark("index page") do polynomial_regression.durations.x.size.should == 8 polynomial_regression.durations.y.size.should == 8 polynomial_regression.durations.derivation(0).size.should == 8 polynomial_regression.durations.derivation(1).size.should == 8 polynomial_regression.durations.degree.should == 1 polynomial_regression.durations.coefficients.should == [1.1646812659828312, 0.0032629471307769192] polynomial_regression.durations.formula.should == "1.1646812659828312 + 0.0032629471307769192x^1" polynomial_regression.durations.formula(1).should == "0.0032629471307769192" end scope_to_benchmark("logout page") do polynomial_regression.durations.x.size.should == 8 polynomial_regression.durations.y.size.should == 8 polynomial_regression.durations.derivation(0).size.should == 8 polynomial_regression.durations.derivation(1).size.should == 8 polynomial_regression.durations.degree.should == 1 polynomial_regression.durations.coefficients.should == [1.0714285714285718, -0.0012755102040815924] polynomial_regression.durations.formula.should == "1.0714285714285718 + -0.0012755102040815924x^1" polynomial_regression.durations.formula(1).should == "-0.0012755102040815924" end lambda{ scope_to_benchmark("not existant"){}}.should raise_exception BigBench::PostProcessor::Environment::BenchmarkNotFound, "Could not find Benchmark: 'not existant'. Available benchmarks are: index page, logout page" end end context "inkonsistant test data", :inconsistant do before(:each) do BigBench.config.duration = 20.seconds BigBench.config.output = "spec/tests/result.ljson" end it "should work with statistics" do statistics.durations.min.should == 82 statistics(1.minute).durations.min.should == 82 statistics.requests.min.should == 0 statistics.methods(:get).min.should == 0 statistics.statuses(200).min.should == 0 statistics.paths("/").min.should == 0 statistics.methods(:get).max.should == 9 statistics.durations.mean.should == 310.3720930232558 statistics.durations.average.should == 310.3720930232558 statistics.durations.sd.should == 330.36776636019465 statistics.requests.sd.should == 2.2675736961451247 statistics.durations.variance.should == 157094.37317468924 statistics.requests.variance.should == 8.616780045351472 end it "should work with normal_distribution" do validate_normal_distribution(normal_distribution.durations).should be_true normal_distribution.durations.formula.should == "1 / sqrt(2 * pi * 453.6664147140337) * e**( -0.5 * (x - 484.0502645502645)**2 / 453.6664147140337)" end it "should work with clusters" do cluster.timesteps.should have(21).timesteps cluster(1.second).should have(21).timesteps cluster(1.minute).should have(1).timesteps cluster.methods(:get).should have(21).entries cluster.methods(:post).should have(21).entries cluster.methods(:nothing).should have(21).entries end it "should work with a polynomial regression" do polynomial_regression.durations.x.size.should == 21 polynomial_regression.durations.y.size.should == 21 polynomial_regression.durations.derivation(0).size.should == 21 polynomial_regression.durations.derivation(1).size.should == 21 polynomial_regression.durations.degree.should == 1 polynomial_regression.durations.coefficients.should == [695.226310726311, -21.117604617604627] polynomial_regression.durations.formula.should == "695.226310726311 + -21.117604617604627x^1" polynomial_regression.durations.formula(1).should == "-21.117604617604627" end end end