For some reason GIT ignored my composed message :( Should have read:
Dependent on the series of audit patches: 0001-Average-Time-to-Submit-time-to-Provider-Task-Model-A.patch 0002-Added-Auditing-for-Average-max-min-also-running-time.patch 0003-Added-Task-Ended-Timestamp-for-calculating-Task-Runt.patch 0004-Added-method-for-calculating-task-runtime.patch 0005-Added-failure-codes-to-task-model.patch 0006-Added-Timing-for-Instance-Change-State.patch ----- Original Message ----- From: [email protected] To: [email protected] Cc: "martyntaylor" <[email protected]> Sent: Tuesday, May 18, 2010 3:55:24 PM GMT +00:00 GMT Britain, Ireland, Portugal Subject: [PATCH aggregator] Added DataService for Task QoS Submission stats From: martyntaylor <[email protected]> --- src/app/util/data_service.rb | 66 ++++++++++++++++++++++++++++++ src/spec/util/data_service_spec.rb | 77 ++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 0 deletions(-) create mode 100644 src/app/util/data_service.rb create mode 100644 src/spec/util/data_service_spec.rb diff --git a/src/app/util/data_service.rb b/src/app/util/data_service.rb new file mode 100644 index 0000000..773134e --- /dev/null +++ b/src/app/util/data_service.rb @@ -0,0 +1,66 @@ +class DataService + + DataPoint = Struct.new(:time, :average, :max, :min) + + # This will return array of data points between start and end, if there is a data point where the interval start + interval end + # is greater than the end time, it will be ignored + # Example: + # start = 12.30, end = 12.32, interval = 45secs + # Intervals: 12.30.00 - 12.30.45, 12.30.45 - 12.31.30 will be returned. Interval 12.31.30 - 12.32.15 will not + def self.qos_task_submission_stats(start_time, end_time, interval_length, pool, action) + + data = [] + until start_time > (end_time - interval_length) do + interval_time = start_time + interval_length + + tasks = Task.find(:all, :conditions => { :time_submitted => start_time..interval_time, + :time_started => start_time..Time.now, + :failure_code => [nil, Task::FAILURE_PROVIDER_RETURNED_FAILED], + :action => action, + :task_target_id => pool.instances + }) + if tasks.length == 0 + return data + else + data << tasks_submissions_mean_max_min(start_time, tasks) + start_time = interval_time + end + end + + return data + end + + def self.tasks_submissions_mean_max_min(time, tasks) + + first_pass = true + + total_time = nil + maximum_time = nil + minimum_time = nil + + tasks.each do |task| + + if(first_pass == true) + total_time = task.submission_time + maximum_time = task.submission_time + minimum_time = task.submission_time + first_pass = false + else + total_time += task.submission_time + + if task.submission_time > maximum_time + maximum_time = task.submission_time + end + + if task.submission_time< minimum_time + minimum_time = task.submission_time + end + end + + end + average_time = total_time / tasks.length + + return DataPoint.new(time, average_time, maximum_time, minimum_time) + end + +end \ No newline at end of file diff --git a/src/spec/util/data_service_spec.rb b/src/spec/util/data_service_spec.rb new file mode 100644 index 0000000..25982bd --- /dev/null +++ b/src/spec/util/data_service_spec.rb @@ -0,0 +1,77 @@ +require 'spec_helper' +#TODO this should be dealt with upstream, possibly in spec_helper +require 'app/util/data_service' + +describe DataService do + + it "should calculate the average, max and min task submission times" do + tasks = [] + instance = Factory :instance + + for i in 1..10 do + time = Time.now + task = Task.new(:instance => instance, :type => "InstanceTask", :state => Task::STATE_PENDING, :failure_code => nil) + task.time_submitted = time + time += i + task.time_started = time + task.save + tasks << task + end + + data_point = DataService::tasks_submissions_mean_max_min(Time.now, tasks) + + data_point.average.should == 5.5 + data_point.min.should == 1 + data_point.max.should == 10 + end + + it "should create data points for the average, max and min task submission times between two times at given intervals" do + + expected_averages = [ 20, 40, 60, 80, 100] + + interval_length = 30 + + no_intervals = expected_averages.length + end_time = Time.now.getutc + start_time = end_time - (interval_length * no_intervals) + + pool = Factory :pool + instance = Factory(:instance, :pool_id => pool.id) + + interval_time = start_time + expected_averages.each do |avg| + submission_time = interval_time + (interval_length / 2) + for i in 1..9 do + # the rhs calculates the a series of times that has an average of the avg time with range: + # (avg time / 10 * 2) - (avg time / 10 * 2 * 9) + # Example: avg_time = 20; range => { 4, 8, 12 ... 32, 36 } + started_time = submission_time + ((avg / 10) * 2) * i + + task = InstanceTask.new(:instance => instance, + :type => "InstanceTask", + :state => Task::STATE_QUEUED, + :failure_code => nil, + :action => InstanceTask::ACTION_CREATE) + task.created_at = submission_time + task.time_submitted = submission_time + task.time_started = started_time + task.save! + end + interval_time += interval_length + end + + data_points = DataService.qos_task_submission_stats(start_time, end_time, interval_length, pool, InstanceTask::ACTION_CREATE) + + for i in 0...data_points.length + average_time = expected_averages[i] + dp = data_points[i] + + dp.average.should == average_time + # The multiplications could be set as static numbers but are left as calculations for easier understanding of code + dp.max.should == (average_time / 10) * 2 * 9 + dp.min.should == (average_time / 10) * 2 + end + + end + +end -- 1.6.6.1 _______________________________________________ deltacloud-devel mailing list [email protected] https://fedorahosted.org/mailman/listinfo/deltacloud-devel
