Added unit tests for incrementing usage

This commit is contained in:
derekwaynecarr 2015-01-26 13:43:55 -05:00
parent 4887d71c51
commit 9674f08504
4 changed files with 354 additions and 2 deletions

View File

@ -36,6 +36,7 @@ type FakeAction struct {
type Fake struct {
Actions []FakeAction
PodsList api.PodList
CtrlList api.ReplicationControllerList
Ctrl api.ReplicationController
ServiceList api.ServiceList
EndpointsList api.EndpointsList

View File

@ -31,7 +31,7 @@ type FakeReplicationControllers struct {
func (c *FakeReplicationControllers) List(selector labels.Selector) (*api.ReplicationControllerList, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "list-controllers"})
return &api.ReplicationControllerList{}, nil
return api.Scheme.CopyOrDie(&c.Fake.CtrlList).(*api.ReplicationControllerList), nil
}
func (c *FakeReplicationControllers) Get(name string) (*api.ReplicationController, error) {

View File

@ -32,7 +32,7 @@ import (
func init() {
admission.RegisterPlugin("ResourceQuota", func(client client.Interface, config io.Reader) (admission.Interface, error) {
return &quota{client: client}, nil
return NewResourceQuota(client), nil
})
}
@ -40,6 +40,10 @@ type quota struct {
client client.Interface
}
func NewResourceQuota(client client.Interface) admission.Interface {
return &quota{client: client}
}
var kindToResourceName = map[string]api.ResourceName{
"pods": api.ResourcePods,
"services": api.ResourceServices,

View File

@ -15,3 +15,350 @@ limitations under the License.
*/
package resourcequota
import (
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
)
func TestAdmissionIgnoresDelete(t *testing.T) {
namespace := "default"
handler := NewResourceQuota(&client.Fake{})
err := handler.Admit(admission.NewAttributesRecord(nil, namespace, "pods", "DELETE"))
if err != nil {
t.Errorf("ResourceQuota should admit all deletes", err)
}
}
func TestIncrementUsagePods(t *testing.T) {
namespace := "default"
client := &client.Fake{
PodsList: api.PodList{
Items: []api.Pod{
{
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace},
Spec: api.PodSpec{
Volumes: []api.Volume{{Name: "vol"}},
Containers: []api.Container{{Name: "ctr", Image: "image", Memory: resource.MustParse("1Gi"), CPU: resource.MustParse("100m")}},
},
},
},
},
}
status := &api.ResourceQuotaStatus{
Hard: api.ResourceList{},
Used: api.ResourceList{},
}
r := api.ResourcePods
status.Hard[r] = resource.MustParse("2")
status.Used[r] = resource.MustParse("1")
dirty, err := IncrementUsage(admission.NewAttributesRecord(&api.Pod{}, namespace, "pods", "CREATE"), status, client)
if err != nil {
t.Errorf("Unexpected error", err)
}
if !dirty {
t.Errorf("Expected the status to get incremented, therefore should have been dirty")
}
quantity := status.Used[r]
if quantity.Value() != int64(2) {
t.Errorf("Expected new item count to be 2, but was %s", quantity.String())
}
}
func TestIncrementUsageMemory(t *testing.T) {
namespace := "default"
client := &client.Fake{
PodsList: api.PodList{
Items: []api.Pod{
{
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace},
Spec: api.PodSpec{
Volumes: []api.Volume{{Name: "vol"}},
Containers: []api.Container{{Name: "ctr", Image: "image", Memory: resource.MustParse("1Gi"), CPU: resource.MustParse("100m")}},
},
},
},
},
}
status := &api.ResourceQuotaStatus{
Hard: api.ResourceList{},
Used: api.ResourceList{},
}
r := api.ResourceMemory
status.Hard[r] = resource.MustParse("2Gi")
status.Used[r] = resource.MustParse("1Gi")
newPod := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace},
Spec: api.PodSpec{
Volumes: []api.Volume{{Name: "vol"}},
Containers: []api.Container{{Name: "ctr", Image: "image", Memory: resource.MustParse("1Gi"), CPU: resource.MustParse("100m")}},
}}
dirty, err := IncrementUsage(admission.NewAttributesRecord(newPod, namespace, "pods", "CREATE"), status, client)
if err != nil {
t.Errorf("Unexpected error", err)
}
if !dirty {
t.Errorf("Expected the status to get incremented, therefore should have been dirty")
}
expectedVal := resource.MustParse("2Gi")
quantity := status.Used[r]
if quantity.Value() != expectedVal.Value() {
t.Errorf("Expected %v was %v", expectedVal.Value(), quantity.Value())
}
}
func TestExceedUsageMemory(t *testing.T) {
namespace := "default"
client := &client.Fake{
PodsList: api.PodList{
Items: []api.Pod{
{
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace},
Spec: api.PodSpec{
Volumes: []api.Volume{{Name: "vol"}},
Containers: []api.Container{{Name: "ctr", Image: "image", Memory: resource.MustParse("1Gi"), CPU: resource.MustParse("100m")}},
},
},
},
},
}
status := &api.ResourceQuotaStatus{
Hard: api.ResourceList{},
Used: api.ResourceList{},
}
r := api.ResourceMemory
status.Hard[r] = resource.MustParse("2Gi")
status.Used[r] = resource.MustParse("1Gi")
newPod := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace},
Spec: api.PodSpec{
Volumes: []api.Volume{{Name: "vol"}},
Containers: []api.Container{{Name: "ctr", Image: "image", Memory: resource.MustParse("3Gi"), CPU: resource.MustParse("100m")}},
}}
_, err := IncrementUsage(admission.NewAttributesRecord(newPod, namespace, "pods", "CREATE"), status, client)
if err == nil {
t.Errorf("Expected memory usage exceeded error")
}
}
func TestIncrementUsageCPU(t *testing.T) {
namespace := "default"
client := &client.Fake{
PodsList: api.PodList{
Items: []api.Pod{
{
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace},
Spec: api.PodSpec{
Volumes: []api.Volume{{Name: "vol"}},
Containers: []api.Container{{Name: "ctr", Image: "image", Memory: resource.MustParse("1Gi"), CPU: resource.MustParse("100m")}},
},
},
},
},
}
status := &api.ResourceQuotaStatus{
Hard: api.ResourceList{},
Used: api.ResourceList{},
}
r := api.ResourceCPU
status.Hard[r] = resource.MustParse("200m")
status.Used[r] = resource.MustParse("100m")
newPod := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace},
Spec: api.PodSpec{
Volumes: []api.Volume{{Name: "vol"}},
Containers: []api.Container{{Name: "ctr", Image: "image", Memory: resource.MustParse("1Gi"), CPU: resource.MustParse("100m")}},
}}
dirty, err := IncrementUsage(admission.NewAttributesRecord(newPod, namespace, "pods", "CREATE"), status, client)
if err != nil {
t.Errorf("Unexpected error", err)
}
if !dirty {
t.Errorf("Expected the status to get incremented, therefore should have been dirty")
}
expectedVal := resource.MustParse("200m")
quantity := status.Used[r]
if quantity.Value() != expectedVal.Value() {
t.Errorf("Expected %v was %v", expectedVal.Value(), quantity.Value())
}
}
func TestExceedUsageCPU(t *testing.T) {
namespace := "default"
client := &client.Fake{
PodsList: api.PodList{
Items: []api.Pod{
{
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace},
Spec: api.PodSpec{
Volumes: []api.Volume{{Name: "vol"}},
Containers: []api.Container{{Name: "ctr", Image: "image", Memory: resource.MustParse("1Gi"), CPU: resource.MustParse("100m")}},
},
},
},
},
}
status := &api.ResourceQuotaStatus{
Hard: api.ResourceList{},
Used: api.ResourceList{},
}
r := api.ResourceCPU
status.Hard[r] = resource.MustParse("200m")
status.Used[r] = resource.MustParse("100m")
newPod := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace},
Spec: api.PodSpec{
Volumes: []api.Volume{{Name: "vol"}},
Containers: []api.Container{{Name: "ctr", Image: "image", Memory: resource.MustParse("1Gi"), CPU: resource.MustParse("500m")}},
}}
_, err := IncrementUsage(admission.NewAttributesRecord(newPod, namespace, "pods", "CREATE"), status, client)
if err == nil {
t.Errorf("Expected CPU usage exceeded error")
}
}
func TestExceedUsagePods(t *testing.T) {
namespace := "default"
client := &client.Fake{
PodsList: api.PodList{
Items: []api.Pod{
{
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace},
Spec: api.PodSpec{
Volumes: []api.Volume{{Name: "vol"}},
Containers: []api.Container{{Name: "ctr", Image: "image", Memory: resource.MustParse("1Gi"), CPU: resource.MustParse("100m")}},
},
},
},
},
}
status := &api.ResourceQuotaStatus{
Hard: api.ResourceList{},
Used: api.ResourceList{},
}
r := api.ResourcePods
status.Hard[r] = resource.MustParse("1")
status.Used[r] = resource.MustParse("1")
_, err := IncrementUsage(admission.NewAttributesRecord(&api.Pod{}, namespace, "pods", "CREATE"), status, client)
if err == nil {
t.Errorf("Expected error because this would exceed your quota")
}
}
func TestIncrementUsageServices(t *testing.T) {
namespace := "default"
client := &client.Fake{
ServiceList: api.ServiceList{
Items: []api.Service{
{
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace},
},
},
},
}
status := &api.ResourceQuotaStatus{
Hard: api.ResourceList{},
Used: api.ResourceList{},
}
r := api.ResourceServices
status.Hard[r] = resource.MustParse("2")
status.Used[r] = resource.MustParse("1")
dirty, err := IncrementUsage(admission.NewAttributesRecord(&api.Service{}, namespace, "services", "CREATE"), status, client)
if err != nil {
t.Errorf("Unexpected error", err)
}
if !dirty {
t.Errorf("Expected the status to get incremented, therefore should have been dirty")
}
quantity := status.Used[r]
if quantity.Value() != int64(2) {
t.Errorf("Expected new item count to be 2, but was %s", quantity.String())
}
}
func TestExceedUsageServices(t *testing.T) {
namespace := "default"
client := &client.Fake{
ServiceList: api.ServiceList{
Items: []api.Service{
{
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace},
},
},
},
}
status := &api.ResourceQuotaStatus{
Hard: api.ResourceList{},
Used: api.ResourceList{},
}
r := api.ResourceServices
status.Hard[r] = resource.MustParse("1")
status.Used[r] = resource.MustParse("1")
_, err := IncrementUsage(admission.NewAttributesRecord(&api.Service{}, namespace, "services", "CREATE"), status, client)
if err == nil {
t.Errorf("Expected error because this would exceed usage")
}
}
func TestIncrementUsageReplicationControllers(t *testing.T) {
namespace := "default"
client := &client.Fake{
CtrlList: api.ReplicationControllerList{
Items: []api.ReplicationController{
{
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace},
},
},
},
}
status := &api.ResourceQuotaStatus{
Hard: api.ResourceList{},
Used: api.ResourceList{},
}
r := api.ResourceReplicationControllers
status.Hard[r] = resource.MustParse("2")
status.Used[r] = resource.MustParse("1")
dirty, err := IncrementUsage(admission.NewAttributesRecord(&api.ReplicationController{}, namespace, "replicationControllers", "CREATE"), status, client)
if err != nil {
t.Errorf("Unexpected error", err)
}
if !dirty {
t.Errorf("Expected the status to get incremented, therefore should have been dirty")
}
quantity := status.Used[r]
if quantity.Value() != int64(2) {
t.Errorf("Expected new item count to be 2, but was %s", quantity.String())
}
}
func TestExceedUsageReplicationControllers(t *testing.T) {
namespace := "default"
client := &client.Fake{
CtrlList: api.ReplicationControllerList{
Items: []api.ReplicationController{
{
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: namespace},
},
},
},
}
status := &api.ResourceQuotaStatus{
Hard: api.ResourceList{},
Used: api.ResourceList{},
}
r := api.ResourceReplicationControllers
status.Hard[r] = resource.MustParse("1")
status.Used[r] = resource.MustParse("1")
_, err := IncrementUsage(admission.NewAttributesRecord(&api.ReplicationController{}, namespace, "replicationControllers", "CREATE"), status, client)
if err == nil {
t.Errorf("Expected error for exceeding hard limits")
}
}