Commit e07a944c authored by Ashley Gau's avatar Ashley Gau

add Get/Set methods, mutex on instanceGroupAttrs.

parent 7fff54cf
...@@ -28,6 +28,7 @@ import ( ...@@ -28,6 +28,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"sync"
alpha "google.golang.org/api/compute/v0.alpha" alpha "google.golang.org/api/compute/v0.alpha"
beta "google.golang.org/api/compute/v0.beta" beta "google.golang.org/api/compute/v0.beta"
...@@ -228,44 +229,90 @@ func InsertAlphaAddressHook(ctx context.Context, key *meta.Key, obj *alpha.Addre ...@@ -228,44 +229,90 @@ func InsertAlphaAddressHook(ctx context.Context, key *meta.Key, obj *alpha.Addre
return convertAndInsertAlphaAddress(key, obj, m.Objects, meta.VersionAlpha, projectID) return convertAndInsertAlphaAddress(key, obj, m.Objects, meta.VersionAlpha, projectID)
} }
// Map from InstanceGroup key to list of Instances // InstanceGroupAttributes maps from InstanceGroup key to a map of Instances
type instanceGroupAttributes struct { type InstanceGroupAttributes struct {
instanceMap map[meta.Key][]*ga.InstanceWithNamedPorts InstanceMap map[meta.Key]map[string]*ga.InstanceWithNamedPorts
Lock *sync.Mutex
} }
// AddInstancesHook mocks adding instances from an InstanceGroup // AddInstances adds a list of Instances passed by InstanceReference
func AddInstancesHook(ctx context.Context, key *meta.Key, req *ga.InstanceGroupsAddInstancesRequest, m *cloud.MockInstanceGroups) error { func (igAttrs *InstanceGroupAttributes) AddInstances(key *meta.Key, instanceRefs []*ga.InstanceReference) error {
_, err := m.Get(ctx, key) igAttrs.Lock.Lock()
if err != nil { defer igAttrs.Lock.Unlock()
return &googleapi.Error{
Code: http.StatusNotFound, instancesWithNamedPorts, ok := igAttrs.InstanceMap[*key]
Message: fmt.Sprintf("Key: %s was not found in InstanceGroups", key.String()), if !ok {
instancesWithNamedPorts = make(map[string]*ga.InstanceWithNamedPorts)
} }
for _, instance := range instanceRefs {
iWithPort := &ga.InstanceWithNamedPorts{
Instance: instance.Instance,
} }
if m.X == nil { instancesWithNamedPorts[instance.Instance] = iWithPort
m.X = instanceGroupAttributes{ }
instanceMap: make(map[meta.Key][]*ga.InstanceWithNamedPorts),
igAttrs.InstanceMap[*key] = instancesWithNamedPorts
return nil
}
// RemoveInstances removes a list of Instances passed by InstanceReference
func (igAttrs *InstanceGroupAttributes) RemoveInstances(key *meta.Key, instanceRefs []*ga.InstanceReference) error {
igAttrs.Lock.Lock()
defer igAttrs.Lock.Unlock()
instancesWithNamedPorts, ok := igAttrs.InstanceMap[*key]
if !ok {
instancesWithNamedPorts = make(map[string]*ga.InstanceWithNamedPorts)
}
for _, instanceToRemove := range instanceRefs {
if _, ok := instancesWithNamedPorts[instanceToRemove.Instance]; ok {
delete(instancesWithNamedPorts, instanceToRemove.Instance)
} else {
return &googleapi.Error{
Code: http.StatusBadRequest,
Message: fmt.Sprintf("%s is not a member of %s", instanceToRemove.Instance, key.String()),
} }
} }
}
igAttrs.InstanceMap[*key] = instancesWithNamedPorts
return nil
}
var attrs instanceGroupAttributes // List gets a list of InstanceWithNamedPorts
attrs = m.X.(instanceGroupAttributes) func (igAttrs *InstanceGroupAttributes) List(key *meta.Key) []*ga.InstanceWithNamedPorts {
igAttrs.Lock.Lock()
defer igAttrs.Lock.Unlock()
instances, ok := attrs.instanceMap[*key] instancesWithNamedPorts, ok := igAttrs.InstanceMap[*key]
if !ok { if !ok {
instances = []*ga.InstanceWithNamedPorts{} instancesWithNamedPorts = make(map[string]*ga.InstanceWithNamedPorts)
} }
for _, instance := range req.Instances { var instanceList []*ga.InstanceWithNamedPorts
iWithPort := &ga.InstanceWithNamedPorts{ for _, val := range instancesWithNamedPorts {
Instance: instance.Instance, instanceList = append(instanceList, val)
} }
instances = append(instances, iWithPort) return instanceList
}
// AddInstancesHook mocks adding instances from an InstanceGroup
func AddInstancesHook(ctx context.Context, key *meta.Key, req *ga.InstanceGroupsAddInstancesRequest, m *cloud.MockInstanceGroups) error {
_, err := m.Get(ctx, key)
if err != nil {
return &googleapi.Error{
Code: http.StatusNotFound,
Message: fmt.Sprintf("Key: %s was not found in InstanceGroups", key.String()),
}
} }
attrs.instanceMap[*key] = instances var attrs InstanceGroupAttributes
attrs = m.X.(InstanceGroupAttributes)
attrs.AddInstances(key, req.Instances)
m.X = attrs m.X = attrs
return nil return nil
} }
...@@ -280,17 +327,9 @@ func ListInstancesHook(ctx context.Context, key *meta.Key, req *ga.InstanceGroup ...@@ -280,17 +327,9 @@ func ListInstancesHook(ctx context.Context, key *meta.Key, req *ga.InstanceGroup
} }
} }
if m.X == nil { var attrs InstanceGroupAttributes
m.X = instanceGroupAttributes{instanceMap: make(map[meta.Key][]*ga.InstanceWithNamedPorts)} attrs = m.X.(InstanceGroupAttributes)
} instances := attrs.List(key)
var attrs instanceGroupAttributes
attrs = m.X.(instanceGroupAttributes)
instances, ok := attrs.instanceMap[*key]
if !ok {
instances = []*ga.InstanceWithNamedPorts{}
}
return instances, nil return instances, nil
} }
...@@ -305,32 +344,9 @@ func RemoveInstancesHook(ctx context.Context, key *meta.Key, req *ga.InstanceGro ...@@ -305,32 +344,9 @@ func RemoveInstancesHook(ctx context.Context, key *meta.Key, req *ga.InstanceGro
} }
} }
if m.X == nil { var attrs InstanceGroupAttributes
m.X = instanceGroupAttributes{ attrs = m.X.(InstanceGroupAttributes)
instanceMap: make(map[meta.Key][]*ga.InstanceWithNamedPorts), attrs.RemoveInstances(key, req.Instances)
}
}
var attrs instanceGroupAttributes
attrs = m.X.(instanceGroupAttributes)
instances, ok := attrs.instanceMap[*key]
if !ok {
instances = []*ga.InstanceWithNamedPorts{}
}
for _, instanceToRemove := range req.Instances {
for i, instance := range instances {
if instanceToRemove.Instance == instance.Instance {
// Delete instance from instances without preserving order
instances[i] = instances[len(instances)-1]
instances = instances[:len(instances)-1]
break
}
}
}
attrs.instanceMap[*key] = instances
m.X = attrs m.X = attrs
return nil return nil
} }
......
...@@ -23,6 +23,7 @@ package gce ...@@ -23,6 +23,7 @@ package gce
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"sync"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
...@@ -102,6 +103,10 @@ func fakeGCECloud(vals TestClusterValues) (*GCECloud, error) { ...@@ -102,6 +103,10 @@ func fakeGCECloud(vals TestClusterValues) (*GCECloud, error) {
c.MockAddresses.InsertHook = mock.InsertAddressHook c.MockAddresses.InsertHook = mock.InsertAddressHook
c.MockAlphaAddresses.InsertHook = mock.InsertAlphaAddressHook c.MockAlphaAddresses.InsertHook = mock.InsertAlphaAddressHook
c.MockInstanceGroups.X = mock.InstanceGroupAttributes{
InstanceMap: make(map[meta.Key]map[string]*compute.InstanceWithNamedPorts),
Lock: &sync.Mutex{},
}
c.MockInstanceGroups.AddInstancesHook = mock.AddInstancesHook c.MockInstanceGroups.AddInstancesHook = mock.AddInstancesHook
c.MockInstanceGroups.RemoveInstancesHook = mock.RemoveInstancesHook c.MockInstanceGroups.RemoveInstancesHook = mock.RemoveInstancesHook
c.MockInstanceGroups.ListInstancesHook = mock.ListInstancesHook c.MockInstanceGroups.ListInstancesHook = mock.ListInstancesHook
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment