Skip to content

Commit

Permalink
Modified classesmatching() function to search parent bundles with inh…
Browse files Browse the repository at this point in the history
…erit => true

Ticket: ENT-5850
Changelog: title
(cherry picked from commit c278bcf)
  • Loading branch information
craigcomstock committed Jul 27, 2023
1 parent 82a63e7 commit fc0644d
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 7 deletions.
59 changes: 59 additions & 0 deletions libpromises/eval_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -3453,6 +3453,65 @@ bool EvalContextIsIgnoringLocks(const EvalContext *ctx)
return ctx->ignore_locks;
}

StringSet *ClassesMatchingLocalRecursive(
const EvalContext *ctx,
const char *regex,
const Rlist *tags,
bool first_only,
size_t stack_index)
{
assert(ctx != NULL);
StackFrame *frame = SeqAt(ctx->stack, stack_index);
StringSet *matches;
if (frame->type == STACK_FRAME_TYPE_BUNDLE)
{
ClassTableIterator *iter = ClassTableIteratorNew(
frame->data.bundle.classes,
frame->data.bundle.owner->ns,
false,
true); // from EvalContextClassTableIteratorNewLocal()
matches = ClassesMatching(ctx, iter, regex, tags, first_only);
ClassTableIteratorDestroy(iter);
}
else
{
matches = StringSetNew(); // empty for passing up the recursion chain
}

if (stack_index > 0 && frame->inherits_previous)
{
StringSet *parent_matches = ClassesMatchingLocalRecursive(
ctx, regex, tags, first_only, stack_index - 1);
StringSetJoin(matches, parent_matches, xstrdup);
StringSetDestroy(parent_matches);
}

return matches;
}

StringSet *ClassesMatchingLocal(
const EvalContext *ctx,
const char *regex,
const Rlist *tags,
bool first_only)
{
assert(ctx != NULL);
return ClassesMatchingLocalRecursive(
ctx, regex, tags, first_only, SeqLength(ctx->stack) - 1);
}

StringSet *ClassesMatchingGlobal(
const EvalContext *ctx,
const char *regex,
const Rlist *tags,
bool first_only)
{
ClassTableIterator *iter =
EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true);
StringSet *matches = ClassesMatching(ctx, iter, regex, tags, first_only);
ClassTableIteratorDestroy(iter);
return matches;
}
StringSet *ClassesMatching(const EvalContext *ctx, ClassTableIterator *iter, const char* regex, const Rlist *tags, bool first_only)
{
StringSet *matching = StringSetNew();
Expand Down
3 changes: 2 additions & 1 deletion libpromises/eval_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,8 @@ static inline bool IsDefinedClass(const EvalContext *ctx, const char *context)
return (CheckClassExpression(ctx, context) == EXPRESSION_VALUE_TRUE);
}
StringSet *ClassesMatching(const EvalContext *ctx, ClassTableIterator *iter, const char* regex, const Rlist *tags, bool first_only);

StringSet *ClassesMatchingGlobal(const EvalContext *ctx, const char* regex, const Rlist *tags, bool first_only);
StringSet *ClassesMatchingLocal(const EvalContext *ctx, const char* regex, const Rlist *tags, bool first_only);
bool EvalProcessResult(const char *process_result, StringSet *proc_attr);
bool EvalFileResult(const char *file_result, StringSet *leaf_attr);

Expand Down
9 changes: 3 additions & 6 deletions libpromises/evalfunction.c
Original file line number Diff line number Diff line change
Expand Up @@ -1275,6 +1275,7 @@ static FnCallResult FnCallIfElse(EvalContext *ctx,

static FnCallResult FnCallClassesMatching(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs)
{
assert(finalargs != NULL);
bool count_only = false;
bool check_only = false;
unsigned count = 0;
Expand Down Expand Up @@ -1313,8 +1314,7 @@ static FnCallResult FnCallClassesMatching(EvalContext *ctx, ARG_UNUSED const Pol
Rlist *matches = NULL;

{
ClassTableIterator *iter = EvalContextClassTableIteratorNewGlobal(ctx, NULL, true, true);
StringSet *global_matches = ClassesMatching(ctx, iter, RlistScalarValue(finalargs), finalargs->next, check_only);
StringSet *global_matches = ClassesMatchingGlobal(ctx, RlistScalarValue(finalargs), finalargs->next, check_only);

StringSetIterator it = StringSetIteratorInit(global_matches);
const char *element = NULL;
Expand All @@ -1331,7 +1331,6 @@ static FnCallResult FnCallClassesMatching(EvalContext *ctx, ARG_UNUSED const Pol
}

StringSetDestroy(global_matches);
ClassTableIteratorDestroy(iter);
}

if (check_only && count >= 1)
Expand All @@ -1340,8 +1339,7 @@ static FnCallResult FnCallClassesMatching(EvalContext *ctx, ARG_UNUSED const Pol
}

{
ClassTableIterator *iter = EvalContextClassTableIteratorNewLocal(ctx);
StringSet *local_matches = ClassesMatching(ctx, iter, RlistScalarValue(finalargs), finalargs->next, check_only);
StringSet *local_matches = ClassesMatchingLocal(ctx, RlistScalarValue(finalargs), finalargs->next, check_only);

StringSetIterator it = StringSetIteratorInit(local_matches);
const char *element = NULL;
Expand All @@ -1358,7 +1356,6 @@ static FnCallResult FnCallClassesMatching(EvalContext *ctx, ARG_UNUSED const Pol
}

StringSetDestroy(local_matches);
ClassTableIteratorDestroy(iter);
}

if (check_only)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
bundle agent __main__
{
classes:
"defined_in_parent" expression => "cfengine";

methods:
"ENT-5850"
usebundle => ENT_5850,
inherit => "true";
}

bundle agent ENT_5850
{
vars:
"c_matching"
slist => classesmatching(".*");
"c_matching_defined_in_parent"
slist => classesmatching("defined_in_parent");

classes:
"defined_here" expression => "cfengine";

reports:
"$(this.promise_filename) Pass"
if => some( "defined_in_parent", c_matching);

"$(this.promise_filename) FAIL $(this.promise_filename)$(const.n)Could not find class 'defined_in_parent' in classesmatching() but it's defined"
if => and( not( some( "defined_in_parent", c_matching) ),
defined_in_parent
);

"Classes found by classesmatching() starting with 'defined' $(with)"
with => join( ", ", classesmatching("defined.*") );

"'defined_here' is defined" if => "defined_here";
"'defined_in_parent' is defined" if => "defined_in_parent";
"Running CFEngine: $(sys.cf_version)";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
bundle agent common
{
vars:
"logfile" string => "$(this.promise_dirname)$(const.dirsep)defined_classes.log";
}

bundle agent __main__
{
classes: "defined_in_main";
methods:
"init";
"first" inherit => "true";
"check";
}

bundle agent init
{
files:
"$(common.logfile)"
delete => tidy;
}

bundle agent first
{
classes: "defined_in_first";
methods: "second" inherit => "true";
}

bundle agent second
{
classes: "defined_in_second";
methods: "third" inherit => "true";
}

bundle agent third
{
vars:
"defined_classes" slist => classesmatching("defined.*");

reports:
"defined_classes: $(defined_classes)"
report_to_file => "$(common.logfile)";
}

bundle agent check
{
vars:
"expected" string => concat("defined_classes: defined_in_main$(const.n)",
"defined_classes: defined_in_first$(const.n)",
"defined_classes: defined_in_second$(const.n)");
"actual" string => readfile("$(common.logfile)", inf);

reports:
"$(this.promise_filename) Pass"
if => strcmp($(expected), $(actual));

"$(this.promise_filename) FAIL"
if => not(strcmp($(expected), $(actual)));
}

body delete tidy
{
dirlinks => "delete";
rmdirs => "true";
}

0 comments on commit fc0644d

Please sign in to comment.