On 2/17/20 8:22 AM, Michal Koutný wrote:
Hello

On Thu, Feb 13, 2020 at 09:33:45AM -0700, Tom Hromatka 
<tom.hroma...@oracle.com> wrote:
[...]
+static const char * const NAMES[][MAX_NAMES] = {
+       {"tasks", "cpu.shares", "cpu.weight", "cpu.foo"},
+       {"tasks"},
+       {"tasks", "memory.limit_in_bytes", "memory.memsw.limit_in_bytes"},
+       {"tasks", "cpuset.exclusive", "cpuset.foo", "cpuset.bar", "cpuset.x"},
+       {"tasks", "namespaces.blah"}
+};
[...]
+class CgroupGetCgroupTest : public ::testing::Test {
+       protected:
+
+       void CreateNames(const char * const names[],
+                        const char * const values[],
+                        const char * const ctrl_name) {
+               char tmp_path[FILENAME_MAX];
+               FILE *f;
+               int i;
+
+               for (i = 0; i < MAX_NAMES; i++) {
+                       if (names[i] == NULL)
+                               break;
Where is the NULL value supposed to come from? (Maybe I'm missing
something but you rely on implicit zeroing by the array initializers and
I can't see how that works for arrays with exactly MAX_NAMES entries
(case for cpuset controller).

Good question.  You are correct - I am relying on implicit zeroing for
the shorter arrays.  (And the more I think about it, the more I don't
like that.  I'll explicitly populate the shorter arrays in a new rev.)

For the arrays with exactly MAX_NAMES, I'm relying on the maximum limit
in the for loop itself to exit the loop.


+       void SetUp() override {
[...]
+                       /*
+                        * arbitrarily don't make the cgroup directory in
+                        * the freezer controller
+                        */
+                       if (i == 1)
+                               continue;
Here the exception is called after "freezer" controller. (Also, maybe
controller enum may be more readable.)

Good idea on an enum.  I wanted to mimic the real world where some
cgroups aren't present in all controllers and didn't really settle
on a graceful way to do it.  I think the enum would help a lot.


+static void validate_value(const struct control_value * const cv,
+                          int names_idx)
+{
+       bool found_match = false;
+       int i;
+
+       for (i = 0; i < MAX_NAMES; i++) {
+               if (NAMES[names_idx][i] == NULL)
+                       break;
Similarly, here it's not clear when is the NULL value set.

Same (slightly) convoluted logic as above.  I'll try to refactor
it into something easier to digest.  Thanks.


+static void validate_cgc(const struct cgroup_controller * const cgc,
+                        int names_idx)
+{
+       int i, names_cnt = 0;
+
+       for (i = 0; i < MAX_NAMES; i++) {
+               if (NAMES[names_idx][i] != NULL)
+                       names_cnt++;
+       }
+
+       /* The tasks file isn't counted */
+       ASSERT_EQ(names_cnt - 1, cgc->index);
+
+       for (i = 0; i < cgc->index; i++) {
+               validate_value(cgc->values[i], names_idx);
+       }
I noticed that if a same key-value pair was present multiple times (and
some keys missing), this check would still pass.

Good find.  I had the exact same thought, but I was torn on whether
I should fix it or not.  Adding the logic to ensure all the settings
completely matched got kind of ugly - and required a lot more lines of
code.  I'll revisit it and see if I can come up with something more
graceful, but I'm struggling to find the right balance between verifying
correctness and the unwieldiness of the tests.  Thoughts?


+static void validate_cg(const struct cgroup * const cg)
[...]
+       for (i = 0, names_idx = 0; i < cg->index; i++, names_idx++) {
+               /*
+                * We did not create our cgroup under the freezer controller.
+                * Advance the index to the next controller.  memory comes
+                * immediately after it.
+                */
+               if (strcmp(cg->controller[i]->name, "memory") == 0)
+                       names_idx++;
Here the exception case is called by "memory" controller (cf "freezer"
before). That may be impractical for maintenance.

Yes, rather hideous.  I think your suggestion of the enum should help
a lot.


HTH,

Your comments over the last few months have been very helpful. My
sincere thanks!

Tom

Michal



_______________________________________________
Libcg-devel mailing list
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to