Fix executor tries to create a new deployment when a function is updated (#524)
Newdeploy manager now checks the existence of function service cache by function UID before trying to create a new deployment. And return the cached fsvc directly if the cache exists.
This commit is contained in:
@@ -117,6 +117,7 @@ func idleObjectReaper(kubeClient *kubernetes.Clientset,
|
|||||||
for _, fsvc := range funcSvcs {
|
for _, fsvc := range funcSvcs {
|
||||||
|
|
||||||
fn, err := fissionClient.Functions(fsvc.Function.Namespace).Get(fsvc.Function.Name)
|
fn, err := fissionClient.Functions(fsvc.Function.Namespace).Get(fsvc.Function.Name)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error getting function: %v", fsvc.Function.Name)
|
log.Printf("Error getting function: %v", fsvc.Function.Name)
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/client-go/pkg/api"
|
"k8s.io/client-go/pkg/api"
|
||||||
|
|
||||||
"github.com/fission/fission"
|
"github.com/fission/fission"
|
||||||
@@ -56,8 +57,9 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
FunctionServiceCache struct {
|
FunctionServiceCache struct {
|
||||||
byFunction *cache.Cache // function-key -> funcSvc : map[string]*funcSvc
|
byFunction *cache.Cache // function-key -> funcSvc : map[string]*funcSvc
|
||||||
byAddress *cache.Cache // address -> function : map[string]metav1.ObjectMeta
|
byAddress *cache.Cache // address -> function : map[string]metav1.ObjectMeta
|
||||||
|
byFunctionUID *cache.Cache // function uid -> function : map[string]metav1.ObjectMeta
|
||||||
|
|
||||||
requestChannel chan *fscRequest
|
requestChannel chan *fscRequest
|
||||||
}
|
}
|
||||||
@@ -76,10 +78,25 @@ type (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func IsNotFoundError(err error) bool {
|
||||||
|
if fe, ok := err.(fission.Error); ok {
|
||||||
|
return fe.Code == fission.ErrorNotFound
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsNameExistError(err error) bool {
|
||||||
|
if fe, ok := err.(fission.Error); ok {
|
||||||
|
return fe.Code == fission.ErrorNameExists
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func MakeFunctionServiceCache() *FunctionServiceCache {
|
func MakeFunctionServiceCache() *FunctionServiceCache {
|
||||||
fsc := &FunctionServiceCache{
|
fsc := &FunctionServiceCache{
|
||||||
byFunction: cache.MakeCache(0, 0),
|
byFunction: cache.MakeCache(0, 0),
|
||||||
byAddress: cache.MakeCache(0, 0),
|
byAddress: cache.MakeCache(0, 0),
|
||||||
|
byFunctionUID: cache.MakeCache(0, 0),
|
||||||
requestChannel: make(chan *fscRequest),
|
requestChannel: make(chan *fscRequest),
|
||||||
}
|
}
|
||||||
go fsc.service()
|
go fsc.service()
|
||||||
@@ -136,6 +153,27 @@ func (fsc *FunctionServiceCache) GetByFunction(m *metav1.ObjectMeta) (*FuncSvc,
|
|||||||
return &fsvcCopy, nil
|
return &fsvcCopy, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fsc *FunctionServiceCache) GetByFunctionUID(uid types.UID) (*FuncSvc, error) {
|
||||||
|
mI, err := fsc.byFunctionUID.Get(uid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
m := mI.(metav1.ObjectMeta)
|
||||||
|
|
||||||
|
fsvcI, err := fsc.byFunction.Get(crd.CacheKey(&m))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// update atime
|
||||||
|
fsvc := fsvcI.(*FuncSvc)
|
||||||
|
fsvc.Atime = time.Now()
|
||||||
|
|
||||||
|
fsvcCopy := *fsvc
|
||||||
|
return &fsvcCopy, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (fsc *FunctionServiceCache) Add(fsvc FuncSvc) (*FuncSvc, error) {
|
func (fsc *FunctionServiceCache) Add(fsvc FuncSvc) (*FuncSvc, error) {
|
||||||
err, existing := fsc.byFunction.Set(crd.CacheKey(fsvc.Function), &fsvc)
|
err, existing := fsc.byFunction.Set(crd.CacheKey(fsvc.Function), &fsvc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -158,16 +196,28 @@ func (fsc *FunctionServiceCache) Add(fsvc FuncSvc) (*FuncSvc, error) {
|
|||||||
// because of multiple-specialization. See issue #331.
|
// because of multiple-specialization. See issue #331.
|
||||||
err, _ = fsc.byAddress.Set(fsvc.Address, *fsvc.Function)
|
err, _ = fsc.byAddress.Set(fsvc.Address, *fsvc.Function)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if fe, ok := err.(fission.Error); ok {
|
if IsNameExistError(err) {
|
||||||
if fe.Code == fission.ErrorNameExists {
|
err = nil
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error caching fsvc: %v", err)
|
log.Printf("error caching fsvc: %v", err)
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add to byFunctionUID cache. Ignore NameExists errors
|
||||||
|
// because of multiple-specialization. See issue #331.
|
||||||
|
err, _ = fsc.byFunctionUID.Set(fsvc.Function.UID, *fsvc.Function)
|
||||||
|
if err != nil {
|
||||||
|
if IsNameExistError(err) {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error caching fsvc by function uid: %v", err)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,6 +254,7 @@ func (fsc *FunctionServiceCache) DeleteOld(fsvc *FuncSvc, minAge time.Duration)
|
|||||||
|
|
||||||
fsc.byFunction.Delete(crd.CacheKey(fsvc.Function))
|
fsc.byFunction.Delete(crd.CacheKey(fsvc.Function))
|
||||||
fsc.byAddress.Delete(fsvc.Address)
|
fsc.byAddress.Delete(fsvc.Address)
|
||||||
|
fsc.byFunctionUID.Delete(fsvc.Function.UID)
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,11 @@ func TestFunctionServiceCache(t *testing.T) {
|
|||||||
fsc.Log()
|
fsc.Log()
|
||||||
log.Panicf("Failed to get fsvc: %v", err)
|
log.Panicf("Failed to get fsvc: %v", err)
|
||||||
}
|
}
|
||||||
|
f, err = fsc.GetByFunctionUID(fsvc.Function.UID)
|
||||||
|
if err != nil {
|
||||||
|
fsc.Log()
|
||||||
|
log.Panicf("Failed to get fsvc by function uid: %v", err)
|
||||||
|
}
|
||||||
fsvc.Atime = f.Atime
|
fsvc.Atime = f.Atime
|
||||||
fsvc.Ctime = f.Ctime
|
fsvc.Ctime = f.Ctime
|
||||||
if f.Address != fsvc.Address {
|
if f.Address != fsvc.Address {
|
||||||
@@ -98,4 +103,10 @@ func TestFunctionServiceCache(t *testing.T) {
|
|||||||
fsc.Log()
|
fsc.Log()
|
||||||
log.Panicf("found fsvc while expecting empty cache: %v", err)
|
log.Panicf("found fsvc while expecting empty cache: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, err = fsc.GetByFunctionUID(fsvc.Function.UID)
|
||||||
|
if err == nil {
|
||||||
|
fsc.Log()
|
||||||
|
log.Panicf("found fsvc by function uid while expecting empty cache: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,10 @@ func (deploy *NewDeploy) createOrGetDeployment(fn *crd.Function, env *crd.Enviro
|
|||||||
}
|
}
|
||||||
|
|
||||||
existingDepl, err := deploy.kubernetesClient.ExtensionsV1beta1().Deployments(deploy.namespace).Get(deployName, metav1.GetOptions{})
|
existingDepl, err := deploy.kubernetesClient.ExtensionsV1beta1().Deployments(deploy.namespace).Get(deployName, metav1.GetOptions{})
|
||||||
if err == nil && existingDepl.Status.ReadyReplicas >= replicas {
|
if err == nil {
|
||||||
|
if existingDepl.Status.ReadyReplicas < replicas {
|
||||||
|
existingDepl, err = deploy.waitForDeploy(existingDepl, replicas)
|
||||||
|
}
|
||||||
return existingDepl, err
|
return existingDepl, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,18 +78,7 @@ func (deploy *NewDeploy) createOrGetDeployment(fn *crd.Function, env *crd.Enviro
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < 120; i++ {
|
return deploy.waitForDeploy(depl, replicas)
|
||||||
latestDepl, err := deploy.kubernetesClient.ExtensionsV1beta1().Deployments(deploy.namespace).Get(depl.Name, metav1.GetOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
//TODO check for imagePullerror
|
|
||||||
if latestDepl.Status.ReadyReplicas == replicas {
|
|
||||||
return latestDepl, err
|
|
||||||
}
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
}
|
|
||||||
return nil, errors.New("failed to create deployment within timeout window")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -459,3 +451,18 @@ func (deploy *NewDeploy) deleteSvc(ns string, name string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (deploy *NewDeploy) waitForDeploy(depl *v1beta1.Deployment, replicas int32) (*v1beta1.Deployment, error) {
|
||||||
|
for i := 0; i < 120; i++ {
|
||||||
|
latestDepl, err := deploy.kubernetesClient.ExtensionsV1beta1().Deployments(deploy.namespace).Get(depl.Name, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
//TODO check for imagePullerror
|
||||||
|
if latestDepl.Status.ReadyReplicas >= replicas {
|
||||||
|
return latestDepl, err
|
||||||
|
}
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
|
return nil, errors.New("failed to create deployment within timeout window")
|
||||||
|
}
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ type (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
FnCreate requestType = iota
|
FnCreate requestType = iota
|
||||||
|
FnUpdate
|
||||||
FnDelete
|
FnDelete
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -191,11 +192,27 @@ func (deploy *NewDeploy) GetFuncSvc(metadata *metav1.ObjectMeta) (*fscache.FuncS
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fsvc, err := deploy.fsCache.GetByFunctionUID(metadata.UID)
|
||||||
|
|
||||||
|
// If the function service cache exists, means
|
||||||
|
// the kubeObjects of function are created before.
|
||||||
|
// In this case, return cached fsvc.
|
||||||
|
if err == nil {
|
||||||
|
return fsvc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if !fscache.IsNotFoundError(err) {
|
||||||
|
log.Printf("error getting function service by uid: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
deploy.requestChannel <- &fnRequest{
|
deploy.requestChannel <- &fnRequest{
|
||||||
fn: fn,
|
fn: fn,
|
||||||
reqType: FnCreate,
|
reqType: FnCreate,
|
||||||
responseChannel: c,
|
responseChannel: c,
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := <-c
|
resp := <-c
|
||||||
if resp.error != nil {
|
if resp.error != nil {
|
||||||
return nil, resp.error
|
return nil, resp.error
|
||||||
@@ -224,6 +241,19 @@ func (deploy *NewDeploy) createFunction(fn *crd.Function) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (deploy *NewDeploy) updateFunction(fn *crd.Function) {
|
||||||
|
c := make(chan *fnResponse)
|
||||||
|
deploy.requestChannel <- &fnRequest{
|
||||||
|
fn: fn,
|
||||||
|
reqType: FnUpdate,
|
||||||
|
responseChannel: c,
|
||||||
|
}
|
||||||
|
resp := <-c
|
||||||
|
if resp.error != nil {
|
||||||
|
log.Printf("Error eager updating function: %v", resp.error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (deploy *NewDeploy) deleteFunction(fn *crd.Function) {
|
func (deploy *NewDeploy) deleteFunction(fn *crd.Function) {
|
||||||
if fn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType == fission.ExecutorTypeNewdeploy {
|
if fn.Spec.InvokeStrategy.ExecutionStrategy.ExecutorType == fission.ExecutorTypeNewdeploy {
|
||||||
c := make(chan *fnResponse)
|
c := make(chan *fnResponse)
|
||||||
@@ -336,7 +366,7 @@ func (deploy *NewDeploy) fnUpdate(oldFn *crd.Function, newFn *crd.Function) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
changed := false
|
deployChanged := false
|
||||||
|
|
||||||
if oldFn.Spec.InvokeStrategy != newFn.Spec.InvokeStrategy {
|
if oldFn.Spec.InvokeStrategy != newFn.Spec.InvokeStrategy {
|
||||||
|
|
||||||
@@ -366,59 +396,63 @@ func (deploy *NewDeploy) fnUpdate(oldFn *crd.Function, newFn *crd.Function) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hpaChanged := false
|
||||||
|
|
||||||
if newFn.Spec.InvokeStrategy.ExecutionStrategy.MinScale != oldFn.Spec.InvokeStrategy.ExecutionStrategy.MinScale {
|
if newFn.Spec.InvokeStrategy.ExecutionStrategy.MinScale != oldFn.Spec.InvokeStrategy.ExecutionStrategy.MinScale {
|
||||||
replicas := int32(newFn.Spec.InvokeStrategy.ExecutionStrategy.MinScale)
|
replicas := int32(newFn.Spec.InvokeStrategy.ExecutionStrategy.MinScale)
|
||||||
hpa.Spec.MinReplicas = &replicas
|
hpa.Spec.MinReplicas = &replicas
|
||||||
changed = true // Will start deployment update
|
deployChanged = true
|
||||||
|
hpaChanged = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if newFn.Spec.InvokeStrategy.ExecutionStrategy.MaxScale != oldFn.Spec.InvokeStrategy.ExecutionStrategy.MaxScale {
|
if newFn.Spec.InvokeStrategy.ExecutionStrategy.MaxScale != oldFn.Spec.InvokeStrategy.ExecutionStrategy.MaxScale {
|
||||||
hpa.Spec.MaxReplicas = int32(newFn.Spec.InvokeStrategy.ExecutionStrategy.MaxScale)
|
hpa.Spec.MaxReplicas = int32(newFn.Spec.InvokeStrategy.ExecutionStrategy.MaxScale)
|
||||||
|
hpaChanged = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if newFn.Spec.InvokeStrategy.ExecutionStrategy.TargetCPUPercent != oldFn.Spec.InvokeStrategy.ExecutionStrategy.TargetCPUPercent {
|
if newFn.Spec.InvokeStrategy.ExecutionStrategy.TargetCPUPercent != oldFn.Spec.InvokeStrategy.ExecutionStrategy.TargetCPUPercent {
|
||||||
targetCpupercent := int32(newFn.Spec.InvokeStrategy.ExecutionStrategy.TargetCPUPercent)
|
targetCpupercent := int32(newFn.Spec.InvokeStrategy.ExecutionStrategy.TargetCPUPercent)
|
||||||
hpa.Spec.TargetCPUUtilizationPercentage = &targetCpupercent
|
hpa.Spec.TargetCPUUtilizationPercentage = &targetCpupercent
|
||||||
|
hpaChanged = true
|
||||||
}
|
}
|
||||||
|
|
||||||
err = deploy.updateHpa(hpa)
|
if hpaChanged {
|
||||||
if err != nil {
|
err := deploy.updateHpa(hpa)
|
||||||
updateStatus(oldFn, err, "error updating HPA while updating function")
|
if err != nil {
|
||||||
return
|
updateStatus(oldFn, err, "error updating HPA while updating function")
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if oldFn.Spec.Environment != newFn.Spec.Environment {
|
if oldFn.Spec.Environment != newFn.Spec.Environment ||
|
||||||
changed = true
|
oldFn.Spec.Package.PackageRef != newFn.Spec.Package.PackageRef {
|
||||||
}
|
deployChanged = true
|
||||||
|
|
||||||
if oldFn.Spec.Package.PackageRef != newFn.Spec.Package.PackageRef {
|
|
||||||
changed = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If length of slice has changed then no need to check individual elements
|
// If length of slice has changed then no need to check individual elements
|
||||||
if len(oldFn.Spec.Secrets) != len(newFn.Spec.Secrets) {
|
if len(oldFn.Spec.Secrets) != len(newFn.Spec.Secrets) {
|
||||||
changed = true
|
deployChanged = true
|
||||||
} else {
|
} else {
|
||||||
for i, newSecret := range newFn.Spec.Secrets {
|
for i, newSecret := range newFn.Spec.Secrets {
|
||||||
if newSecret != oldFn.Spec.Secrets[i] {
|
if newSecret != oldFn.Spec.Secrets[i] {
|
||||||
changed = true
|
deployChanged = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(oldFn.Spec.ConfigMaps) != len(newFn.Spec.ConfigMaps) {
|
if len(oldFn.Spec.ConfigMaps) != len(newFn.Spec.ConfigMaps) {
|
||||||
changed = true
|
deployChanged = true
|
||||||
} else {
|
} else {
|
||||||
for i, newConfig := range newFn.Spec.ConfigMaps {
|
for i, newConfig := range newFn.Spec.ConfigMaps {
|
||||||
if newConfig != oldFn.Spec.ConfigMaps[i] {
|
if newConfig != oldFn.Spec.ConfigMaps[i] {
|
||||||
changed = true
|
deployChanged = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if changed == true {
|
if deployChanged == true {
|
||||||
env, err := deploy.fissionClient.Environments(newFn.Spec.Environment.Namespace).
|
env, err := deploy.fissionClient.Environments(newFn.Spec.Environment.Namespace).
|
||||||
Get(newFn.Spec.Environment.Name)
|
Get(newFn.Spec.Environment.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -438,7 +472,6 @@ func (deploy *NewDeploy) fnUpdate(oldFn *crd.Function, newFn *crd.Function) {
|
|||||||
updateStatus(oldFn, err, "failed to update deployment while updating function")
|
updateStatus(oldFn, err, "failed to update deployment while updating function")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,6 +534,20 @@ func (deploy *NewDeploy) getDeployLabels(fn *crd.Function, env *crd.Environment)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// updateKubeObjRefRV update the resource version of kubeObjectRef with
|
||||||
|
// given kind and return error if failed to find the reference.
|
||||||
|
func (deploy *NewDeploy) updateKubeObjRefRV(fsvc *fscache.FuncSvc, objKind string, rv string) error {
|
||||||
|
kubeObjs := fsvc.KubernetesObjects
|
||||||
|
for i, obj := range kubeObjs {
|
||||||
|
if obj.Kind == objKind {
|
||||||
|
kubeObjs[i].ResourceVersion = rv
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fsvc.KubernetesObjects = kubeObjs
|
||||||
|
return errors.New(fmt.Sprintf("error finding kubernetes object reference with kind: %v", objKind))
|
||||||
|
}
|
||||||
|
|
||||||
// updateStatus is a function which updates status of update.
|
// updateStatus is a function which updates status of update.
|
||||||
// Current implementation only logs messages, in future it will update function status
|
// Current implementation only logs messages, in future it will update function status
|
||||||
func updateStatus(fn *crd.Function, err error, message string) {
|
func updateStatus(fn *crd.Function, err error, message string) {
|
||||||
|
|||||||
+1
-1
@@ -176,7 +176,7 @@ helm_install_fission() {
|
|||||||
helm list -q|xargs -I@ bash -c "helm_uninstall_fission @"
|
helm list -q|xargs -I@ bash -c "helm_uninstall_fission @"
|
||||||
|
|
||||||
# deleting ns does take a while after command is issued
|
# deleting ns does take a while after command is issued
|
||||||
while `kubectl get ns| grep "fission-builder"`
|
while kubectl get ns| grep "fission-builder"
|
||||||
do
|
do
|
||||||
sleep 5
|
sleep 5
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -56,12 +56,19 @@ update_fn() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test_fn() {
|
test_fn() {
|
||||||
log "Doing an HTTP GET on the function's route"
|
echo "Doing an HTTP GET on the function's route"
|
||||||
response0=$(curl http://$FISSION_ROUTER/$1)
|
echo "Checking for valid response"
|
||||||
|
|
||||||
log "Checking for valid response"
|
while true; do
|
||||||
echo $response0 | grep -i $2
|
response0=$(curl http://$FISSION_ROUTER/$1)
|
||||||
|
echo $response0 | grep -i $2
|
||||||
|
if [[ $? -eq 0 ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
export -f test_fn
|
||||||
|
|
||||||
# This test only tests one path of execution: updating package and checking results of function
|
# This test only tests one path of execution: updating package and checking results of function
|
||||||
# There might be potential future tests where one can test changes in:
|
# There might be potential future tests where one can test changes in:
|
||||||
@@ -81,10 +88,10 @@ main() {
|
|||||||
create_env $env
|
create_env $env
|
||||||
create_fn $fn_name $env
|
create_fn $fn_name $env
|
||||||
create_route $fn_name
|
create_route $fn_name
|
||||||
test_fn $fn_name "world"
|
timeout 60 bash -c "test_fn $fn_name 'world'"
|
||||||
update_archive
|
update_archive
|
||||||
update_fn $fn_name $env
|
update_fn $fn_name $env
|
||||||
test_fn $fn_name "fission"
|
timeout 60 bash -c "test_fn $fn_name 'fission'"
|
||||||
log "Update function for new deployment executor passed"
|
log "Update function for new deployment executor passed"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user