From: martyntaylor <mtay...@redhat.com>

---
 src/app/controllers/instance_controller.rb        |    1 +
 src/app/controllers/users_controller.rb           |    7 ++-
 src/app/models/instance.rb                        |    1 +
 src/app/models/instance_observer.rb               |   30 ++++-----
 src/app/models/quota.rb                           |   27 +++++---
 src/app/models/user.rb                            |    3 +
 src/db/migrate/20090804142049_create_instances.rb |    1 +
 src/db/migrate/20090917192602_create_users.rb     |    1 +
 src/spec/factories/instance.rb                    |    1 +
 src/spec/factories/user.rb                        |    1 +
 src/spec/models/instance_observer_spec.rb         |   25 ++++---
 src/spec/models/quota_spec.rb                     |   68 +++++++++++++++++++++
 12 files changed, 128 insertions(+), 38 deletions(-)
 create mode 100644 src/spec/models/quota_spec.rb

diff --git a/src/app/controllers/instance_controller.rb 
b/src/app/controllers/instance_controller.rb
index e2a1eaf..666649a 100644
--- a/src/app/controllers/instance_controller.rb
+++ b/src/app/controllers/instance_controller.rb
@@ -105,6 +105,7 @@ class InstanceController < ApplicationController
   def create
     @instance = Instance.new(params[:instance])
     @instance.state = Instance::STATE_NEW
+    @instance.owner_id = current_user
     require_privilege(Privilege::INSTANCE_MODIFY,
                       Pool.find(@instance.pool_id))
     #FIXME: This should probably be in a transaction
diff --git a/src/app/controllers/users_controller.rb 
b/src/app/controllers/users_controller.rb
index bb68542..8488509 100644
--- a/src/app/controllers/users_controller.rb
+++ b/src/app/controllers/users_controller.rb
@@ -30,6 +30,11 @@ class UsersController < ApplicationController
   def create
     require_privilege(Privilege::USER_MODIFY) unless current_user.nil?
     @user = User.new(params[:user])
+
+    #TODO Set Quota Values to SelfService Settings Default Quota
+    @user_quota = Quota.new
+    @user.quota_id = @user_quota.id
+
     @registration = RegistrationService.new(@user)
     if @registration.save
       flash[:notice] = "User registered!"
@@ -65,4 +70,4 @@ class UsersController < ApplicationController
   def index
     @users = User.all
   end
-end
+end
\ No newline at end of file
diff --git a/src/app/models/instance.rb b/src/app/models/instance.rb
index 0212e24..7788b0c 100644
--- a/src/app/models/instance.rb
+++ b/src/app/models/instance.rb
@@ -32,6 +32,7 @@ class Instance < ActiveRecord::Base
   belongs_to :hardware_profile
   belongs_to :image
   belongs_to :realm
+  belongs_to :owner, :class_name => "User", :foreign_key => "owner_id"
 
   validates_presence_of :pool_id
   validates_presence_of :hardware_profile_id
diff --git a/src/app/models/instance_observer.rb 
b/src/app/models/instance_observer.rb
index 70537ac..3ec83c8 100644
--- a/src/app/models/instance_observer.rb
+++ b/src/app/models/instance_observer.rb
@@ -32,34 +32,32 @@ class InstanceObserver < ActiveRecord::Observer
   end
 
   def update_quota(state_from, state_to, an_instance)
-
     hwp = an_instance.hardware_profile
     pool = an_instance.pool
     cloud_account = an_instance.cloud_account
-
-    [cloud_account, pool].each do |parent|
+    user = an_instance.owner
+    [cloud_account, pool, user].each do |parent|
       if parent
         quota = parent.quota
         if quota
-         if state_to == Instance::STATE_RUNNING
-           quota.running_instances += 1
-         elsif state_from == Instance::STATE_RUNNING
-           quota.running_instances -= 1
-         end
+          if state_to == Instance::STATE_RUNNING
+            quota.running_instances += 1
+          elsif state_from == Instance::STATE_RUNNING
+            quota.running_instances -= 1
+          end
 
-         if state_from != nil
-           if !ACTIVE_STATES.include?(state_from) && 
ACTIVE_STATES.include?(state_to)
-             quota.total_instances += 1
-      elsif ACTIVE_STATES.include?(state_from) && 
!ACTIVE_STATES.include?(state_to)
-             quota.total_instances -= 1
-           end
+          if state_from != nil
+            if !ACTIVE_STATES.include?(state_from) && 
ACTIVE_STATES.include?(state_to)
+              quota.total_instances += 1
+            elsif ACTIVE_STATES.include?(state_from) && 
!ACTIVE_STATES.include?(state_to)
+              quota.total_instances -= 1
+            end
           end
           quota.save!
         end
       end
     end
   end
-
 end
 
-InstanceObserver.instance
+InstanceObserver.instance
\ No newline at end of file
diff --git a/src/app/models/quota.rb b/src/app/models/quota.rb
index f882878..7b1b3f9 100644
--- a/src/app/models/quota.rb
+++ b/src/app/models/quota.rb
@@ -23,6 +23,7 @@ class Quota < ActiveRecord::Base
 
   has_one :pool
   has_one :cloud_account
+  has_one :user
 
   QuotaResource = Struct.new(:name, :used, :max, :available, :unit)
 
@@ -34,20 +35,26 @@ class Quota < ActiveRecord::Base
 
   RESOURCE_NAMES = [ RESOURCE_RUNNING_INSTANCES, RESOURCE_TOTAL_INSTANCES ]
 
-  def can_create_instance?(instance)
-    potential_total_instances = total_instances + 1
-    if (Quota.no_limit(maximum_total_instances) || maximum_total_instances >= 
potential_total_instances)
-         return true
+  def self.can_create_instance?(instance)
+    [instance.owner, instance.pool, instance.cloud_account].each do |parent|
+      quota = Quota.find(parent.quota_id)
+      potential_total_instances = quota.total_instances + 1
+      if !Quota.no_limit(quota.maximum_total_instances) && 
(quota.maximum_total_instances < potential_total_instances)
+        return false
+      end
     end
-    return false
+    return true
   end
 
-  def can_start_instance?(instance)
-    potential_running_instances = running_instances + 1
-    if (Quota.no_limit(maximum_running_instances) || maximum_running_instances 
>= potential_running_instances)
-         return true
+  def self.can_start_instance?(instance)
+    [instance.owner, instance.pool, instance.cloud_account].each do |parent|
+      quota = Quota.find(parent.quota_id)
+      potential_running_instances = quota.running_instances + 1
+      if !Quota.no_limit(quota.maximum_running_instances) && 
quota.maximum_running_instances < potential_running_instances
+        return false
+      end
     end
-    return false
+    return true
   end
 
   def quota_resources()
diff --git a/src/app/models/user.rb b/src/app/models/user.rb
index b08d03d..fc0cbdc 100644
--- a/src/app/models/user.rb
+++ b/src/app/models/user.rb
@@ -24,4 +24,7 @@ class User < ActiveRecord::Base
 
   has_many :permissions
   has_many :owned_pools, :class_name => "Pool", :foreign_key => "owner_id"
+  has_many :owned_instances, :class_name => "Instance", :foreign_key => 
"owner_id"
+
+  belongs_to :quota
 end
diff --git a/src/db/migrate/20090804142049_create_instances.rb 
b/src/db/migrate/20090804142049_create_instances.rb
index 42706e1..d6bcbc9 100644
--- a/src/db/migrate/20090804142049_create_instances.rb
+++ b/src/db/migrate/20090804142049_create_instances.rb
@@ -27,6 +27,7 @@ class CreateInstances < ActiveRecord::Migration
       t.integer   :hardware_profile_id, :null => false
       t.integer   :image_id, :null => false
       t.integer   :realm_id
+      t.integer   :owner_id
       t.integer   :pool_id, :null => false
       t.integer   :cloud_account_id
       t.string    :public_address
diff --git a/src/db/migrate/20090917192602_create_users.rb 
b/src/db/migrate/20090917192602_create_users.rb
index 67706fb..1d9fd1d 100644
--- a/src/db/migrate/20090917192602_create_users.rb
+++ b/src/db/migrate/20090917192602_create_users.rb
@@ -31,6 +31,7 @@ class CreateUsers < ActiveRecord::Migration
       t.string    :perishable_token,    :null => false
       t.string    :first_name
       t.string    :last_name
+      t.integer   :quota_id
       # Magic columns, just like ActiveRecord's created_at and updated_at.
       # These are automatically maintained by Authlogic if they are present.
       t.integer   :login_count,         :null => false, :default => 0
diff --git a/src/spec/factories/instance.rb b/src/spec/factories/instance.rb
index f73a691..6fb6a12 100644
--- a/src/spec/factories/instance.rb
+++ b/src/spec/factories/instance.rb
@@ -6,6 +6,7 @@ Factory.define :instance do |i|
   i.image_id 1
   i.pool_id 1
   i.state "running"
+  i.association :owner, :factory => :user
 end
 
 Factory.define :pending_instance, :parent => :instance do |i|
diff --git a/src/spec/factories/user.rb b/src/spec/factories/user.rb
index 778aa30..e737a35 100644
--- a/src/spec/factories/user.rb
+++ b/src/spec/factories/user.rb
@@ -5,6 +5,7 @@ Factory.define :user do |u|
   u.password_confirmation 'secret'
   u.first_name 'John'
   u.last_name 'Smith'
+  u.association :quota
 end
 
 Factory.define :tuser, :parent => :user do |u|
diff --git a/src/spec/models/instance_observer_spec.rb 
b/src/spec/models/instance_observer_spec.rb
index ae5ee0d..e4a2de2 100644
--- a/src/spec/models/instance_observer_spec.rb
+++ b/src/spec/models/instance_observer_spec.rb
@@ -11,8 +11,11 @@ describe InstanceObserver do
    @pool_quota = Factory :quota
    @pool = Factory(:pool, :quota_id => @pool_quota.id)
 
+   @user_quota = Factory :quota
+   @user = Factory(:user, :quota_id => @user_quota.id)
+
    @hwp = Factory :mock_hwp1
-   @instance = Factory(:new_instance, :pool => @pool, :hardware_profile => 
@hwp, :cloud_account_id => @cloud_account.id)
+   @instance = Factory(:new_instance, :pool => @pool, :hardware_profile => 
@hwp, :cloud_account_id => @cloud_account.id, :owner => @user)
   end
 
   it "should set started at timestamp when instance goes to state pending" do
@@ -95,15 +98,15 @@ describe InstanceObserver do
     @instance.acc_stopped_time.should <= 2
   end
 
-  it "should not update quota on pool and cloud account when an instance is 
state new" do
-    [...@cloud_account_quota, @pool_quota].each do |quota|
+  it "should not update quota on pool, user and cloud account when an instance 
is state new" do
+    [...@cloud_account_quota, @pool_quota, @user_quota].each do |quota|
       quota = Quota.find(quota)
       quota.total_instances.should == 0
     end
   end
 
-  it "should update quota on pool and cloud account when an instance fgoes to 
state pending" do
-    [...@cloud_account_quota, @pool_quota].each do |quota|
+  it "should update quota on pool, user and cloud account when an instance 
goes to state pending" do
+    [...@cloud_account_quota, @pool_quota, @user_quota].each do |quota|
       @instance.state = Instance::STATE_PENDING
       @instance.save
 
@@ -112,35 +115,35 @@ describe InstanceObserver do
     end
   end
 
-  it "should update cloud account and pool quota when an instance goes into an 
inactive state" do
+  it "should update cloud accoun, pool  and user quota when an instance goes 
into an inactive state" do
     @instance.state = Instance::STATE_CREATE_FAILED
     @instance.save!
 
-    [...@cloud_account_quota, @pool_quota].each do |quota|
+    [...@cloud_account_quota, @pool_quota, @user_quota].each do |quota|
       quota = Quota.find(quota)
       quota.total_instances.should == 0
     end
   end
 
-  it "should update pool and cloud account quota when an instance state goes 
to running" do
+  it "should update pool, cloud account and user quota when an instance state 
goes to running" do
     @instance.state = Instance::STATE_RUNNING
     @instance.save!
 
-    [...@cloud_account_quota, @pool_quota].each do |quota|
+    [...@cloud_account_quota, @pool_quota, @user_quota].each do |quota|
       quota = Quota.find(quota.id)
       quota.running_instances.should == 1
       quota.total_instances.should == 1
     end
   end
 
-  it "should update a pool and cloud account quota when an instance state goes 
from running to another active state" do
+  it "should update a pool, cloud account and user quota when an instance 
state goes from running to another active state" do
     @instance.state = Instance::STATE_RUNNING
     @instance.save!
 
     @instance.state = Instance::STATE_SHUTTING_DOWN
     @instance.save!
 
-    [...@cloud_account_quota, @pool_quota].each do |quota|
+    [...@cloud_account_quota, @pool_quota, @user_quota].each do |quota|
       quota = Quota.find(quota.id)
 
       quota.running_instances.should == 0
diff --git a/src/spec/models/quota_spec.rb b/src/spec/models/quota_spec.rb
new file mode 100644
index 0000000..233bb84
--- /dev/null
+++ b/src/spec/models/quota_spec.rb
@@ -0,0 +1,68 @@
+require 'spec_helper'
+
+describe Quota do
+
+  before(:each) do
+   @cloud_account_quota = Factory :quota
+   @cloud_account = Factory(:mock_cloud_account, :quota_id => 
@cloud_account_quota.id)
+
+   @pool_quota = Factory :quota
+   @pool = Factory(:pool, :quota_id => @pool_quota.id)
+
+   @user_quota = Factory :quota
+   @user = Factory(:user, :quota_id => @user_quota.id)
+
+   @hwp = Factory :mock_hwp1
+   @instance = Factory(:new_instance, :pool => @pool, :hardware_profile => 
@hwp, :cloud_account_id => @cloud_account.id, :owner => @user)
+  end
+
+  it "should return true when asking if an instance can be created/started 
when there is sufficient quota space" do
+    Quota.can_create_instance?(@instance).should == true
+    Quota.can_start_instance?(@instance).should == true
+  end
+
+  it "should return false when asking if an instance can be created/started 
when the user quota is reached" do
+    @user_quota.total_instances = @user_quota.maximum_total_instances
+    @user_quota.running_instances = @user_quota.maximum_running_instances
+    @user_quota.save!
+
+    Quota.can_create_instance?(@instance).should == false
+    Quota.can_start_instance?(@instance).should == false
+  end
+
+  it "should return false when asking if an instance can be created/started 
when the pool quota is reached" do
+    @pool_quota.total_instances = @pool_quota.maximum_total_instances
+    @pool_quota.running_instances = @pool_quota.maximum_running_instances
+    @pool_quota.save!
+
+    Quota.can_create_instance?(@instance).should == false
+    Quota.can_start_instance?(@instance).should == false
+  end
+
+  it "should return false when asking if an instance can be created/started 
when the cloud account quota is reached" do
+    @cloud_account_quota.total_instances = 
@cloud_account_quota.maximum_total_instances
+    @cloud_account_quota.running_instances = 
@cloud_account_quota.maximum_running_instances
+    @cloud_account_quota.save!
+
+    Quota.can_create_instance?(@instance).should == false
+    Quota.can_start_instance?(@instance).should == false
+  end
+
+  it "should return false when asking if an instance can be created/started 
when the all quotas are reached" do
+    @user_quota.total_instances = @user_quota.maximum_total_instances
+    @user_quota.running_instances = @user_quota.maximum_running_instances
+    @user_quota.save!
+
+    @pool_quota.total_instances = @pool_quota.maximum_total_instances
+    @pool_quota.running_instances = @pool_quota.maximum_running_instances
+    @pool_quota.save!
+
+    @cloud_account_quota.total_instances = 
@cloud_account_quota.maximum_total_instances
+    @cloud_account_quota.running_instances = 
@cloud_account_quota.maximum_running_instances
+    @cloud_account_quota.save!
+
+    Quota.can_create_instance?(@instance).should == false
+    Quota.can_start_instance?(@instance).should == false
+  end
+
+end
\ No newline at end of file
-- 
1.7.1.1

_______________________________________________
deltacloud-devel mailing list
deltacloud-devel@lists.fedorahosted.org
https://fedorahosted.org/mailman/listinfo/deltacloud-devel

Reply via email to