* add functionality to wait for specialization by keeping track of incoming requests * format executor package * fix required capacity to specialise new pod condition * move handling concurrency logic into pool cache from executor * remove unused methods and structs * implement queue in to store the svc wait * create a queue struct and its methods to handle concurrent inputs * use newly created queue to store waiting for svc requests * add waiting requests in queue and use them when a svc is ready * set function to request in queue if the context is still alive * remove concurrency approach to set svc for waiting requests * update the active requests whenever requests from pool are assigned a svc * add doc to define why the conditions exist * remove unwanted params in strcut and clean up code * set error while getting svc value if sum of specialization in progress and specialized is only more than concurrency limit * remove duplicate functions and unnecessary values in struct * close svc channel on set value and create constants for default concurrency and rpp * get next value in queue in case context is timed out for fetched value * remove specializationInProgress counter from pool cache * return in case the queue is empty wihle setting func to svc * test getSvcVaue and setSvcValue in poolcache * add unit tests for GetConcurrent and GetRequestsPerPod methods * reorder imports * add fuzzy testing for getSVCValue and setSVCValue in poolcache * restructure go mod file and update pool cache test cases * Add tests and bug fixes * refactor code and add test cases * add svcWaiting check while setting svc value --------- Signed-off-by: Sanket Sudake <sanketsudake@gmail.com> Co-authored-by: Sanket Sudake <sanketsudake@gmail.com>
214 lines
4.4 KiB
Go
214 lines
4.4 KiB
Go
package fscache
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"testing"
|
|
"time"
|
|
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
apiv1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/api/resource"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
fv1 "github.com/fission/fission/pkg/apis/core/v1"
|
|
)
|
|
|
|
func panicIf(err error) {
|
|
if err != nil {
|
|
log.Panicf("Error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestFunctionServiceCache(t *testing.T) {
|
|
config := zap.NewDevelopmentConfig()
|
|
config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
|
logger, err := config.Build()
|
|
panicIf(err)
|
|
|
|
fsc := MakeFunctionServiceCache(logger)
|
|
if fsc == nil {
|
|
log.Panicf("error creating cache")
|
|
}
|
|
|
|
var fsvc *FuncSvc
|
|
now := time.Now()
|
|
|
|
objects := []apiv1.ObjectReference{
|
|
{
|
|
Kind: "pod",
|
|
Name: "xxx",
|
|
APIVersion: "v1",
|
|
Namespace: "fission-function",
|
|
},
|
|
{
|
|
Kind: "pod",
|
|
Name: "xxx2",
|
|
APIVersion: "v1",
|
|
Namespace: "fission-function",
|
|
},
|
|
}
|
|
|
|
fsvc = &FuncSvc{
|
|
Function: &metav1.ObjectMeta{
|
|
Name: "foo",
|
|
UID: "1212",
|
|
},
|
|
Environment: &fv1.Environment{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "foo-env",
|
|
UID: "2323",
|
|
},
|
|
Spec: fv1.EnvironmentSpec{
|
|
Version: 1,
|
|
Runtime: fv1.Runtime{
|
|
Image: "fission/foo-env",
|
|
},
|
|
Builder: fv1.Builder{},
|
|
},
|
|
},
|
|
Address: "xxx",
|
|
KubernetesObjects: objects,
|
|
Ctime: now,
|
|
Atime: now,
|
|
}
|
|
_, err = fsc.Add(*fsvc)
|
|
if err != nil {
|
|
fsc.Log()
|
|
log.Panicf("Failed to add fsvc: %v", err)
|
|
}
|
|
|
|
_, err = fsc.GetByFunction(fsvc.Function)
|
|
if err != nil {
|
|
fsc.Log()
|
|
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.Ctime = f.Ctime
|
|
if f.Address != fsvc.Address {
|
|
fsc.Log()
|
|
log.Panicf("Incorrect fsvc \n(expected: %#v)\n (found: %#v)", fsvc, f)
|
|
}
|
|
|
|
err = fsc.TouchByAddress(fsvc.Address)
|
|
if err != nil {
|
|
fsc.Log()
|
|
log.Panicf("Failed to touch fsvc: %v", err)
|
|
}
|
|
|
|
deleted, err := fsc.DeleteOld(fsvc, 0)
|
|
if err != nil {
|
|
fsc.Log()
|
|
log.Panicf("Failed to delete fsvc: %v", err)
|
|
}
|
|
if !deleted {
|
|
fsc.Log()
|
|
log.Panicf("Did not delete fsvc")
|
|
}
|
|
|
|
_, err = fsc.GetByFunction(fsvc.Function)
|
|
if err == nil {
|
|
fsc.Log()
|
|
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)
|
|
}
|
|
}
|
|
|
|
func TestFunctionServiceNewCache(t *testing.T) {
|
|
logger, err := zap.NewDevelopment()
|
|
panicIf(err)
|
|
|
|
fsc := MakeFunctionServiceCache(logger)
|
|
if fsc == nil {
|
|
log.Panicf("error creating cache")
|
|
}
|
|
|
|
var fsvc *FuncSvc
|
|
now := time.Now()
|
|
|
|
objects := []apiv1.ObjectReference{
|
|
{
|
|
Kind: "pod",
|
|
Name: "xxx",
|
|
APIVersion: "v1",
|
|
Namespace: "fission-function",
|
|
},
|
|
{
|
|
Kind: "pod",
|
|
Name: "xxx2",
|
|
APIVersion: "v1",
|
|
Namespace: "fission-function",
|
|
},
|
|
}
|
|
|
|
fsvc = &FuncSvc{
|
|
Function: &metav1.ObjectMeta{
|
|
Name: "foo",
|
|
UID: "1212",
|
|
},
|
|
Environment: &fv1.Environment{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "foo-env",
|
|
UID: "2323",
|
|
},
|
|
Spec: fv1.EnvironmentSpec{
|
|
Version: 1,
|
|
Runtime: fv1.Runtime{
|
|
Image: "fission/foo-env",
|
|
},
|
|
Builder: fv1.Builder{},
|
|
},
|
|
},
|
|
Address: "xxx",
|
|
KubernetesObjects: objects,
|
|
CPULimit: resource.MustParse("5m"),
|
|
Ctime: now,
|
|
Atime: now,
|
|
}
|
|
fn := &fv1.Function{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "foo",
|
|
UID: "1212",
|
|
},
|
|
}
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
fsc.AddFunc(ctx, *fsvc, 10)
|
|
concurrency := 10
|
|
_, err = fsc.GetFuncSvc(ctx, fsvc.Function, 5, concurrency)
|
|
if err != nil {
|
|
logger.Panic("received error while retrieving value from cache")
|
|
}
|
|
|
|
key := fmt.Sprintf("%v_%v", fn.ObjectMeta.UID, fn.ObjectMeta.ResourceVersion)
|
|
fsc.MarkAvailable(key, fsvc.Address)
|
|
|
|
_, err = fsc.GetFuncSvc(ctx, fsvc.Function, 5, concurrency)
|
|
if err != nil {
|
|
logger.Panic("received error while retrieving value from cache")
|
|
}
|
|
|
|
vals, err := fsc.ListOldForPool(30 * time.Second)
|
|
if err != nil {
|
|
logger.Panic("received error while get list of old values")
|
|
}
|
|
if len(vals) != 0 {
|
|
logger.Panic(fmt.Sprintln("list of old values didn't matched the expected: 1", "received", len(vals)))
|
|
}
|
|
fsc.DeleteFunctionSvc(ctx, fsvc)
|
|
}
|