Permalink
Browse files

[fix] Include app instances in memory quota checks

This commit fixes a bug where number of instances of an app was not
taken into account when computing the total memory consumed by the app.
This caused memory quota check for the org to be erroneous.

Change-Id: I4a7171292e41e2c438daf82b21fbd439bce1cef8
  • Loading branch information...
1 parent 0607a2c commit 33cd195a257575cc3530514257a7c7db06113c6e @kowshik kowshik committed Jan 4, 2013
@@ -170,13 +170,19 @@ def validate_route(route)
def additional_memory_requested
default_memory = db_schema[:memory][:default].to_i
+ default_instances = db_schema[:instances][:default].to_i
+
mem = memory ? memory : default_memory
+ num_instances = instances ? instances : default_instances
+ total_requested_memory = mem * num_instances
- return mem if new?
+ return total_requested_memory if new?
app_from_db = self.class.find(:guid => guid)
- existing_memory = app_from_db[:memory]
- mem - existing_memory > 0 ? mem - existing_memory : 0
+ total_existing_memory = app_from_db[:memory] * app_from_db[:instances]
+ additional_memory = total_requested_memory - total_existing_memory
+ return additional_memory if additional_memory > 0
+ 0
end
def check_memory_quota
@@ -7,6 +7,7 @@ class InvalidDomainRelation < InvalidRelation; end
one_to_many :spaces
one_to_many :service_instances, :dataset => lambda { VCAP::CloudController::Models::ServiceInstance.
filter(:space => spaces) }
+ one_to_many :apps, :dataset => lambda { VCAP::CloudController::Models::App.filter(:space => spaces) }
many_to_many :domains, :before_add => :validate_domain
add_association_dependencies :domains => :nullify
@@ -101,27 +102,21 @@ def paid_services_allowed?
quota_definition.non_basic_services_allowed
end
- # We cannot have apps as a separate dataset. The reason is that sequel
- # automatically converts Sequel::Dataset objects to an array when defining
- # an association. This prevents us from using functional operations such as
- # filter/sum on the dataset.
def free_memory_apps
- VCAP::CloudController::Models::App.filter(:space => spaces,
- :production => false)
+ apps_dataset.filter(:production => false)
end
def paid_memory_apps
- VCAP::CloudController::Models::App.filter(:space => spaces,
- :production => true)
+ apps_dataset.filter(:production => true)
end
def free_memory_remaining
- free_memory_used = free_memory_apps.sum(:memory) || 0
+ free_memory_used = free_memory_apps.sum(:memory * :instances) || 0
quota_definition.free_memory_limit - free_memory_used
end
def paid_memory_remaining
- paid_memory_used = paid_memory_apps.sum(:memory) || 0
+ paid_memory_used = paid_memory_apps.sum(:memory * :instances) || 0
quota_definition.paid_memory_limit - paid_memory_used
end
@@ -534,7 +534,8 @@ module VCAP::CloudController
expect do
Models::App.make(:space => space,
:production => true,
- :memory => 129)
+ :memory => 65,
+ :instances => 2)
end.to raise_error(Sequel::ValidationFailed,
/memory paid_quota_exceeded/)
end
@@ -545,7 +546,8 @@ module VCAP::CloudController
expect do
Models::App.make(:space => space,
:production => true,
- :memory => 128)
+ :memory => 64,
+ :instances => 2)
end.to_not raise_error
end
end
@@ -556,19 +558,21 @@ module VCAP::CloudController
space = Models::Space.make(:organization => org)
app = Models::App.make(:space => space,
:production => true,
- :memory => 128)
- app.memory = 129
+ :memory => 64,
+ :instances => 2)
+ app.memory = 65
expect { app.save }.to raise_error(Sequel::ValidationFailed,
/memory paid_quota_exceeded/)
end
- it "should raise error when quota is not exceeded" do
+ it "should not raise error when quota is not exceeded" do
org = Models::Organization.make(:quota_definition => paid_quota)
space = Models::Space.make(:organization => org)
app = Models::App.make(:space => space,
:production => true,
- :memory => 127)
- app.memory = 128
+ :memory => 63,
+ :instances => 2)
+ app.memory = 64
expect { app.save }.to_not raise_error
end
end
@@ -581,7 +585,8 @@ module VCAP::CloudController
space = Models::Space.make(:organization => org)
expect do
Models::App.make(:space => space,
- :memory => 129)
+ :memory => 65,
+ :instances => 2)
end.to raise_error(Sequel::ValidationFailed,
/memory free_quota_exceeded/)
end
@@ -591,7 +596,8 @@ module VCAP::CloudController
space = Models::Space.make(:organization => org)
expect do
Models::App.make(:space => space,
- :memory => 128)
+ :memory => 64,
+ :instances => 2)
end.to_not raise_error
end
end
@@ -601,8 +607,9 @@ module VCAP::CloudController
org = Models::Organization.make(:quota_definition => free_quota)
space = Models::Space.make(:organization => org)
app = Models::App.make(:space => space,
- :memory => 128)
- app.memory = 129
+ :memory => 64,
+ :instances => 2)
+ app.memory = 65
expect { app.save }.to raise_error(Sequel::ValidationFailed,
/memory free_quota_exceeded/)
end
@@ -611,8 +618,9 @@ module VCAP::CloudController
org = Models::Organization.make(:quota_definition => free_quota)
space = Models::Space.make(:organization => org)
app = Models::App.make(:space => space,
- :memory => 127)
- app.memory = 128
+ :memory => 63,
+ :instances => 2)
+ app.memory = 64
expect { app.save }.to_not raise_error
end
end
@@ -157,25 +157,31 @@ module VCAP::CloudController
context "memory quota" do
let(:quota) do
- Models::QuotaDefinition.make(:free_memory_limit => 512,
- :paid_memory_limit => 512)
+ Models::QuotaDefinition.make(:free_memory_limit => 500,
+ :paid_memory_limit => 500)
end
it "should return the memory available when no apps are running" do
org = Models::Organization.make(:quota_definition => quota)
- org.free_memory_remaining.should == 512
- org.paid_memory_remaining.should == 512
+ org.free_memory_remaining.should == 500
+ org.paid_memory_remaining.should == 500
end
it "should return the memory remaining when apps are consuming memory" do
org = Models::Organization.make(:quota_definition => quota)
space = Models::Space.make(:organization => org)
- Models::App.make(:space => space, :production => false, :memory => 200)
- Models::App.make(:space => space, :production => true, :memory => 100)
-
- org.free_memory_remaining.should == 312
- org.paid_memory_remaining.should == 412
+ Models::App.make(:space => space,
+ :production => false,
+ :memory => 200,
+ :instances => 2)
+ Models::App.make(:space => space,
+ :production => true,
+ :memory => 100,
+ :instances => 1)
+
+ org.free_memory_remaining.should == 100
+ org.paid_memory_remaining.should == 400
end
end
end

0 comments on commit 33cd195

Please sign in to comment.