From: martyntaylor <[email protected]>
---
src/app/models/instance.rb | 49 ++++++++++++--
src/app/models/instance_observer.rb | 22 +++++--
src/db/migrate/20090804142049_create_instances.rb | 10 +++-
src/spec/factories/instance.rb | 8 ++-
src/spec/models/instance_observer_spec.rb | 70 +++++++++++++++++++--
src/spec/models/instance_spec.rb | 23 +++++++
6 files changed, 160 insertions(+), 22 deletions(-)
diff --git a/src/app/models/instance.rb b/src/app/models/instance.rb
index 25d17bd..07d0784 100644
--- a/src/app/models/instance.rb
+++ b/src/app/models/instance.rb
@@ -52,10 +52,12 @@ class Instance < ActiveRecord::Base
STATE_STOPPED = "stopped"
STATE_CREATE_FAILED = "create_failed"
- validates_inclusion_of :state,
- :in => [STATE_NEW, STATE_PENDING, STATE_RUNNING,
+ STATES = [STATE_NEW, STATE_PENDING, STATE_RUNNING,
STATE_SHUTTING_DOWN, STATE_STOPPED, STATE_CREATE_FAILED]
+ validates_inclusion_of :state,
+ :in => STATES
+
def get_action_list(user=nil)
# return empty list rather than nil
# FIXME: not handling pending state now -- only current state
@@ -101,11 +103,44 @@ class Instance < ActiveRecord::Base
self.realm = provider.realms.find_by_name(realm_name) unless
realm_name.nil?
end
- def total_run_time
- if state == STATE_RUNNING
- acc_run_time + (Time.now - time_last_start)
- else
- acc_run_time
+ # Returns the total time that this instance has been in the state
+ def total_state_time(state)
+
+ if !STATES.include?(state)
+ return "Error, could not calculate state time: invalid state"
+ end
+
+ case state
+ when STATE_PENDING
+ if self.state == STATE_PENDING
+ return acc_pending_time + (Time.now - time_last_pending)
+ else
+ return acc_pending_time
+ end
+
+ when STATE_RUNNING
+ if self.state == STATE_RUNNING
+ return acc_running_time + (Time.now - time_last_running)
+ else
+ return acc_running_time
+ end
+
+ when STATE_SHUTTING_DOWN
+ if self.state == STATE_SHUTTING_DOWN
+ return acc_shutting_down_time + (Time.now - time_last_shutting_down)
+ else
+ return acc_shutting_down_time
+ end
+
+ when STATE_STOPPED
+ if self.state == STATE_STOPPED
+ return acc_stopped_time + (Time.now - time_last_stopped)
+ else
+ return acc_stopped_time
+ end
+
+ else
+ return "Error, could not calculate state time: state is not monitored"
end
end
diff --git a/src/app/models/instance_observer.rb
b/src/app/models/instance_observer.rb
index 81e75ea..283991d 100644
--- a/src/app/models/instance_observer.rb
+++ b/src/app/models/instance_observer.rb
@@ -4,19 +4,29 @@ class InstanceObserver < ActiveRecord::Observer
if an_instance.changed?
change = an_instance.changes['state']
if change
- update_timestamps(change[0], change[1], an_instance)
+ update_state_timestamps(change[1], an_instance)
+ update_accumulative_state_time(change[0], an_instance)
end
end
end
- def update_timestamps(state_from, state_to, an_instance)
- if state_to == Instance::STATE_RUNNING
- an_instance.time_last_start = Time.now
- elsif state_from == Instance::STATE_RUNNING && state_to ==
Instance::STATE_STOPPED
- an_instance.acc_run_time = an_instance.acc_run_time + (Time.now -
an_instance.time_last_start)
+ def update_state_timestamps(state_to, an_instance)
+ case state_to
+ when Instance::STATE_PENDING then an_instance.time_last_pending =
Time.now
+ when Instance::STATE_RUNNING then an_instance.time_last_running =
Time.now
+ when Instance::STATE_SHUTTING_DOWN then
an_instance.time_last_shutting_down = Time.now
+ when Instance::STATE_STOPPED then an_instance.time_last_stopped =
Time.now
end
end
+ def update_accumulative_state_time(state_from, an_instance)
+ case state_from
+ when Instance::STATE_PENDING then an_instance.acc_pending_time +=
Time.now - an_instance.time_last_pending
+ when Instance::STATE_RUNNING then an_instance.acc_running_time +=
Time.now - an_instance.time_last_running
+ when Instance::STATE_SHUTTING_DOWN then
an_instance.acc_shutting_down_time += Time.now -
an_instance.time_last_shutting_down
+ when Instance::STATE_STOPPED then an_instance.acc_stopped_time +=
Time.now - an_instance.time_last_stopped
+ end
+ end
end
InstanceObserver.instance
\ No newline at end of file
diff --git a/src/db/migrate/20090804142049_create_instances.rb
b/src/db/migrate/20090804142049_create_instances.rb
index a571b68..335b93f 100644
--- a/src/db/migrate/20090804142049_create_instances.rb
+++ b/src/db/migrate/20090804142049_create_instances.rb
@@ -33,8 +33,14 @@ class CreateInstances < ActiveRecord::Migration
t.string :private_address
t.string :state
t.integer :lock_version, :default => 0
- t.integer :acc_run_time, :default => 0
- t.timestamp :time_last_start
+ t.integer :acc_pending_time, :default => 0
+ t.integer :acc_running_time, :default => 0
+ t.integer :acc_shutting_down_time, :default => 0
+ t.integer :acc_stopped_time, :default => 0
+ t.timestamp :time_last_pending
+ t.timestamp :time_last_running
+ t.timestamp :time_last_shutting_down
+ t.timestamp :time_last_stopped
t.timestamps
end
end
diff --git a/src/spec/factories/instance.rb b/src/spec/factories/instance.rb
index 12156ec..3a453c3 100644
--- a/src/spec/factories/instance.rb
+++ b/src/spec/factories/instance.rb
@@ -7,6 +7,10 @@ Factory.define :instance do |i|
i.state "running"
end
-Factory.define :pending_instance, :parent => :instance do |pi|
- pi.state "pending"
+Factory.define :pending_instance, :parent => :instance do |i|
+ i.state Instance::STATE_PENDING
+end
+
+Factory.define :new_instance, :parent => :instance do |i|
+ i.state Instance::STATE_NEW
end
\ No newline at end of file
diff --git a/src/spec/models/instance_observer_spec.rb
b/src/spec/models/instance_observer_spec.rb
index 65e0d50..9e3dcc7 100644
--- a/src/spec/models/instance_observer_spec.rb
+++ b/src/spec/models/instance_observer_spec.rb
@@ -4,26 +4,86 @@ describe InstanceObserver do
before(:each) do
@timestamp = Time.now
- @instance = Factory :pending_instance
+ @instance = Factory :new_instance
+ end
+
+ it "should set started at timestamp when instance goes to state pending" do
+ @instance.state = Instance::STATE_PENDING
+ @instance.save
+
+ @instance.time_last_pending.should >= @timestamp
end
it "should set started at timestamp when instance goes to state running" do
@instance.state = Instance::STATE_RUNNING
@instance.save
- @instance.time_last_start.should >= @timestamp
+ @instance.time_last_running.should >= @timestamp
+ end
+
+ it "should set started at timestamp when instance goes to state shutting
down" do
+ @instance.state = Instance::STATE_SHUTTING_DOWN
+ @instance.save
+
+ @instance.time_last_shutting_down.should >= @timestamp
+ end
+
+ it "should set started at timestamp when instance goes to state stopped" do
+ @instance.state = Instance::STATE_STOPPED
+ @instance.save
+
+ @instance.time_last_stopped.should >= @timestamp
end
- it "should set accumlated run time when instance goes to from state running
to state stopped" do
+ it "should set accumlated pending time when instance changes state from
state pending" do
+ @instance.state = Instance::STATE_PENDING
+ @instance.save
+
+ sleep(1)
+
@instance.state = Instance::STATE_RUNNING
+ @instance.save
+
+ @instance.acc_pending_time.should >= 1
+ @instance.acc_pending_time.should <= 2
+ end
+
+ it "should set accumlated running time when instance changes state from
state running" do
+ @instance.state = Instance::STATE_RUNNING
+ @instance.save
+
+ sleep(1)
+
+ @instance.state = Instance::STATE_SHUTTING_DOWN
+ @instance.save
+
+ @instance.acc_running_time.should >= 1
+ @instance.acc_running_time.should <= 2
+ end
+
+ it "should set accumlated shutting down time when instance changes state
from state shutting down" do
+ @instance.state = Instance::STATE_SHUTTING_DOWN
@instance.save;
- sleep(2)
+ sleep(1)
@instance.state = Instance::STATE_STOPPED
@instance.save
- @instance.acc_run_time.should >= 2
+ @instance.acc_shutting_down_time.should >= 1
+ @instance.acc_shutting_down_time.should <= 2
end
+ it "should set accumlated stopped time when instance changes state from
state stopped" do
+ @instance.state = Instance::STATE_STOPPED
+ @instance.save
+
+ sleep(1)
+
+ @instance.state = Instance::STATE_PENDING
+ @instance.save
+
+ @instance.acc_stopped_time.should >= 1
+ @instance.acc_stopped_time.should <= 2
+ end
end
\ No newline at end of file
diff --git a/src/spec/models/instance_spec.rb b/src/spec/models/instance_spec.rb
index afdc0e0..0eaf837 100644
--- a/src/spec/models/instance_spec.rb
+++ b/src/spec/models/instance_spec.rb
@@ -111,5 +111,28 @@ describe Instance do
@instance.front_end_realm.should eql('mock2:john doe/different realm')
end
+ it "should properly calculate the total time that the instance has been in a
monitored state" do
+ instance = Factory :new_instance
+
+ [ Instance::STATE_PENDING, Instance::STATE_RUNNING,
Instance::STATE_SHUTTING_DOWN, Instance::STATE_STOPPED ].each do |s|
+ # Test when instance is still in the same state
+ instance.state = s
+ instance.save
+
+ sleep(2)
+
+ instance.total_state_time(s).should >= 2
+ instance.total_state_time(s).should <= 3
+
+ # Test when instance has changed state
+ sleep(1)
+ instance.state = Instance::STATE_NEW
+ instance.save
+ sleep(1)
+
+ instance.total_state_time(s).should >= 3
+ instance.total_state_time(s).should <= 4
+ end
+ end
end
--
1.6.6.1
_______________________________________________
deltacloud-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/deltacloud-devel