diff --git a/libpromises/eval_context.c b/libpromises/eval_context.c index 7f56480f97..1d50f4eeab 100644 --- a/libpromises/eval_context.c +++ b/libpromises/eval_context.c @@ -2832,12 +2832,20 @@ bool EvalContextFunctionCacheGet(const EvalContext *ctx, const FnCall *fp ARG_UNUSED, const Rlist *args, Rval *rval_out) { + assert(fp != NULL); + assert(fp->name != NULL); + assert(ctx != NULL); + if (!(ctx->eval_options & EVAL_OPTION_CACHE_SYSTEM_FUNCTIONS)) { return false; } - Rval *rval = FuncCacheMapGet(ctx->function_cache, args); + // The cache key is made of the function name and all args values + Rlist *args_copy = RlistCopy(args); + Rlist *key = RlistPrepend(&args_copy, fp->name, RVAL_TYPE_SCALAR); + Rval *rval = FuncCacheMapGet(ctx->function_cache, key); + RlistDestroy(key); if (rval) { if (rval_out) @@ -2856,6 +2864,10 @@ void EvalContextFunctionCachePut(EvalContext *ctx, const FnCall *fp ARG_UNUSED, const Rlist *args, const Rval *rval) { + assert(fp != NULL); + assert(fp->name != NULL); + assert(ctx != NULL); + if (!(ctx->eval_options & EVAL_OPTION_CACHE_SYSTEM_FUNCTIONS)) { return; @@ -2863,7 +2875,11 @@ void EvalContextFunctionCachePut(EvalContext *ctx, Rval *rval_copy = xmalloc(sizeof(Rval)); *rval_copy = RvalCopy(*rval); - FuncCacheMapInsert(ctx->function_cache, RlistCopy(args), rval_copy); + + Rlist *args_copy = RlistCopy(args); + Rlist *key = RlistPrepend(&args_copy, fp->name, RVAL_TYPE_SCALAR); + + FuncCacheMapInsert(ctx->function_cache, key, rval_copy); } /* cfPS and associated machinery */ diff --git a/tests/acceptance/01_vars/02_functions/cache_name.cf b/tests/acceptance/01_vars/02_functions/cache_name.cf new file mode 100644 index 0000000000..abbace9238 --- /dev/null +++ b/tests/acceptance/01_vars/02_functions/cache_name.cf @@ -0,0 +1,51 @@ +####################################################### +# +# Test that the function result cache checks function name +# +####################################################### + +body common control +{ + inputs => { "../../default.cf.sub" }; + bundlesequence => { default("$(this.promise_filename)") }; + version => "1.0"; +} + +####################################################### + + +bundle agent init +{ + vars: + "agent_regex" string => ".*cf-agent.*"; +} + +####################################################### + +bundle common test +{ + meta: + "description" -> { "CFE-4244" } + string => "Test that the function result cache checks function name"; + + vars: + "res1" data => findprocesses("${init.agent_regex}"); + + classes: + # must not reuse result from previous line + # is reused, produces a type error + "_pass" expression => processexists("${init.agent_regex}"); +} + + +####################################################### + +bundle agent check +{ + methods: + _pass:: + "pass" usebundle => dcs_pass("$(this.promise_filename)"); + + !_pass:: + "pass" usebundle => dcs_fail("$(this.promise_filename)"); +}