From: martyntaylor <[email protected]>

---
 src/app/models/instance.rb                        |    8 ++++
 src/app/models/instance_observer.rb               |   22 ++++++++++++
 src/app/models/task.rb                            |   24 ++++++++++++-
 src/app/models/task_observer.rb                   |   24 +++++++++++++
 src/db/migrate/20090804142049_create_instances.rb |   24 +++++++------
 src/db/migrate/20090831140000_create_tasks.rb     |    1 +
 src/spec/factories/instance.rb                    |    4 ++
 src/spec/models/instance_observer_spec.rb         |   29 ++++++++++++++++
 src/spec/models/task_observer_spec.rb             |   38 +++++++++++++++++++++
 src/spec/models/task_spec.rb                      |    5 ++-
 10 files changed, 165 insertions(+), 14 deletions(-)
 create mode 100644 src/app/models/instance_observer.rb
 create mode 100644 src/app/models/task_observer.rb
 create mode 100644 src/spec/models/instance_observer_spec.rb
 create mode 100644 src/spec/models/task_observer_spec.rb

diff --git a/src/app/models/instance.rb b/src/app/models/instance.rb
index fa89844..83b07ef 100644
--- a/src/app/models/instance.rb
+++ b/src/app/models/instance.rb
@@ -101,5 +101,13 @@ 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
+    end
+  end
+
 
 end
diff --git a/src/app/models/instance_observer.rb 
b/src/app/models/instance_observer.rb
new file mode 100644
index 0000000..81e75ea
--- /dev/null
+++ b/src/app/models/instance_observer.rb
@@ -0,0 +1,22 @@
+class InstanceObserver < ActiveRecord::Observer
+
+  def after_save(an_instance)
+    if an_instance.changed?
+      change = an_instance.changes['state']
+      if change
+        update_timestamps(change[0], change[1], 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)
+    end
+  end
+
+end
+
+InstanceObserver.instance
\ No newline at end of file
diff --git a/src/app/models/task.rb b/src/app/models/task.rb
index 6cb907e..7cf7347 100644
--- a/src/app/models/task.rb
+++ b/src/app/models/task.rb
@@ -21,6 +21,7 @@
 
 class Task < ActiveRecord::Base
   belongs_to :task_target,       :polymorphic => true
+
   # InstanceTask association
   belongs_to :instance,          :class_name => "Instance",
                                  :foreign_key => "task_target_id"
@@ -37,8 +38,28 @@ class Task < ActiveRecord::Base
   COMPLETED_STATES = [STATE_FINISHED, STATE_FAILED, STATE_CANCELED]
   WORKING_STATES   = [STATE_QUEUED, STATE_RUNNING, STATE_PAUSED]
 
+  # - Failure Codes -
+
+  # Failures that happen in the provider
+  PROVIDER_OVER_QUOTA = "PROVIDER_OVER_QUOTA"
+  PROVIDER_FAILED_TASK = "PROVIDER_FAILED_TASK"
+  PROVIDER_CONNECTION_FAILURE = "PROVIDER_CONNECTION_FAILURE"
+
+  # Failures that happen in the aggregator
+  AGGREGATOR_OVER_POOL_QUOTA = "AGGREGATOR_OVER_POOL_QUOTA"
+  AGGREGATOR_OVER_USER_QUOTA = "AGGREGATOR_OVER_USER_QUOTA"
+  AGGREGATOR_NO_MATCHING_PROVIDER = "AGGREGATOR_NO_MATCHING_PROVIDER"
+
+  PROVIDER_FAILURE_CODES = [PROVIDER_OVER_QUOTA, PROVIDER_FAILED_TASK, 
PROVIDER_CONNECTION_FAILURE]
+  AGGREGATOR_FAILURE_CODES = [AGGREGATOR_OVER_POOL_QUOTA, 
AGGREGATOR_OVER_USER_QUOTA, AGGREGATOR_NO_MATCHING_PROVIDER]
+
+  FAILURE_CODES = PROVIDER_FAILURE_CODES + AGGREGATOR_FAILURE_CODES + [nil]
+
+  validates_inclusion_of :failure_code,
+    :in => FAILURE_CODES
+
   validates_inclusion_of :type,
-   :in => %w( InstanceTask )
+    :in => %w( InstanceTask )
 
   validates_inclusion_of :state,
     :in => COMPLETED_STATES + WORKING_STATES
@@ -82,6 +103,7 @@ class Task < ActiveRecord::Base
   def type_label
     self.class.name[0..-5]
   end
+
   def task_obj
     ""
   end
diff --git a/src/app/models/task_observer.rb b/src/app/models/task_observer.rb
new file mode 100644
index 0000000..2614519
--- /dev/null
+++ b/src/app/models/task_observer.rb
@@ -0,0 +1,24 @@
+class TaskObserver < ActiveRecord::Observer
+
+  END_STATES = [ Task::STATE_CANCELED, Task::STATE_FAILED, 
Task::STATE_FINISHED ]
+
+  def after_save(a_task)
+    if a_task.changed?
+      change = a_task.changes['state']
+      if change
+        update_timestamp(change[0], change[1], a_task)
+      end
+    end
+  end
+
+  def update_timestamp(state_from, state_to, a_task)
+    if END_STATES.include?(state_to)
+      a_task.time_ended = Time.now
+    elsif state_to == Task::STATE_RUNNING
+      a_task.time_started = Time.now
+    end
+  end
+
+end
+
+TaskObserver.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 714a7e4..b1e7f80 100644
--- a/src/db/migrate/20090804142049_create_instances.rb
+++ b/src/db/migrate/20090804142049_create_instances.rb
@@ -22,17 +22,19 @@
 class CreateInstances < ActiveRecord::Migration
   def self.up
     create_table :instances do |t|
-      t.string  :external_key
-      t.string  :name, :null => false, :limit => 1024
-      t.integer :hardware_profile_id, :null => false
-      t.integer :image_id, :null => false
-      t.integer :realm_id
-      t.integer :pool_id, :null => false
-      t.integer :cloud_account_id
-      t.string  :public_address
-      t.string  :private_address
-      t.string  :state
-      t.integer :lock_version, :default => 0
+      t.string   :external_key
+      t.string   :name, :null => false, :limit => 1024
+      t.integer  :hardware_profile_id, :null => false
+      t.integer  :image_id, :null => false
+      t.integer  :realm_id
+      t.integer  :pool_id, :null => false
+      t.integer  :cloud_account_id
+      t.string   :public_address
+      t.string   :private_address
+      t.string   :state
+      t.datetime :time_last_start
+      t.integer  :acc_run_time, :default => 0
+      t.integer  :lock_version, :default => 0
       t.timestamps
     end
   end
diff --git a/src/db/migrate/20090831140000_create_tasks.rb 
b/src/db/migrate/20090831140000_create_tasks.rb
index a9e099f..823b9d0 100644
--- a/src/db/migrate/20090831140000_create_tasks.rb
+++ b/src/db/migrate/20090831140000_create_tasks.rb
@@ -24,6 +24,7 @@ class CreateTasks < ActiveRecord::Migration
       t.string    :type
       t.string    :action
       t.string    :state
+      t.string    :failure_code
       t.integer   :task_target_id
       t.string    :task_target_type
       t.string    :args
diff --git a/src/spec/factories/instance.rb b/src/spec/factories/instance.rb
index 0cd1ea2..5855e9d 100644
--- a/src/spec/factories/instance.rb
+++ b/src/spec/factories/instance.rb
@@ -6,3 +6,7 @@ Factory.define :instance do |i|
   i.pool_id 1
   i.state "running"
 end
+
+Factory.define :queued_instance, :parent => :instance do |qi|
+  qi.state "pending"
+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
new file mode 100644
index 0000000..1d1a33a
--- /dev/null
+++ b/src/spec/models/instance_observer_spec.rb
@@ -0,0 +1,29 @@
+require 'spec_helper'
+
+describe InstanceObserver do
+
+  before(:each) do
+   @timestamp = Time.now
+   @instance = Factory :queued_instance
+  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
+  end
+
+  it "should set accumlated run time when instance goes to from state running 
to state stopped" do
+    @instance.state = Instance::STATE_RUNNING
+    @instance.save;
+
+    sleep(2)
+
+    @instance.state = Instance::STATE_STOPPED
+    @instance.save
+
+    @instance.acc_run_time.should >= 2
+  end
+
+end
\ No newline at end of file
diff --git a/src/spec/models/task_observer_spec.rb 
b/src/spec/models/task_observer_spec.rb
new file mode 100644
index 0000000..6a376b3
--- /dev/null
+++ b/src/spec/models/task_observer_spec.rb
@@ -0,0 +1,38 @@
+require 'spec_helper'
+
+describe TaskObserver do
+
+  before(:each) do
+    @timestamp = Time.now
+    @task = InstanceTask.new({})
+  end
+
+  it "should set started at timestamp when the task goes to state running" do
+    @task.state = Task::STATE_RUNNING
+    @task.save
+
+    @task.time_started.should >= @timestamp
+  end
+
+  it "should set ended timestamp when the task has finished" do
+    @task.state = Task::STATE_FINISHED
+    @task.save
+
+    @task.time_ended.should >= @timestamp
+  end
+
+  it "should set ended timestamp when the task is cancelled" do
+    @task.state = Task::STATE_CANCELED
+    @task.save
+
+    @task.time_ended.should >= @timestamp
+  end
+
+  it "should set ended timestamp when the task has failed" do
+    @task.state = Task::STATE_FAILED
+    @task.save
+
+    @task.time_ended.should >= @timestamp
+  end
+
+end
\ No newline at end of file
diff --git a/src/spec/models/task_spec.rb b/src/spec/models/task_spec.rb
index d392cb2..674c567 100644
--- a/src/spec/models/task_spec.rb
+++ b/src/spec/models/task_spec.rb
@@ -6,8 +6,9 @@ describe Task do
     @valid_attributes = { :created_at => Time.now,
       :time_started => Time.now + 3.minutes,
       :time_ended => Time.now + 5.minutes,
-      :state => Task::STATE_FINISHED }
-    @task = InstanceTask.new( {} )
+      :state => Task::STATE_FINISHED,
+      :failure_code => nil }
+    @task = InstanceTask.new({})
   end
 
   it "should be valid with the test data" do
-- 
1.6.6.1

_______________________________________________
deltacloud-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/deltacloud-devel

Reply via email to