2
* Copyright IBM Corporation. 2008
4
* Author: Sudhir Kumar <skumar@linux.vnet.ibm.com>
6
* This program is free software; you can redistribute it and/or modify it
7
* under the terms of version 2.1 of the GNU Lesser General Public License
8
* as published by the Free Software Foundation.
10
* This program is distributed in the hope that it would be useful, but
11
* WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
* Description: This file contains the test code for testing libcgroup apis.
17
#include "libcgrouptest.h"
22
/* We use mountpoint for single mount.
23
* For multimount we use mountpoint and mountpoint2.
25
char mountpoint[FILENAME_MAX], mountpoint2[FILENAME_MAX];
27
int main(int argc, char *argv[])
30
struct uid_gid_t ids = {0}; /* Set default control permissions */
32
struct cntl_val_t cval;
33
cval.val_int64 = 200000;
34
cval.val_uint64 = 200000;
36
strcpy(cval.val_string, "200000");
38
struct cgroup *cgroup1, *cgroup2, *cgroup3, *nullcgroup = NULL;
39
struct cgroup_controller *sec_controller;
40
/* In case of multimount for readability we use the controller name
41
* before the cgroup structure name */
42
struct cgroup *ctl1_cgroup1, *ctl2_cgroup1, *ctl2_cgroup2;
43
struct cgroup *mod_ctl1_cgroup1, *mod_ctl2_cgroup1, *mod_common_cgroup;
44
struct cgroup *common_cgroup;
45
char controller_name[FILENAME_MAX], control_file[FILENAME_MAX];
46
char path_control_file[FILENAME_MAX];
48
/* Get controllers name from script */
49
int ctl1 = CPU, ctl2 = MEMORY;
51
if ((argc < 2) || (argc > 6) || (atoi(argv[1]) < 0)) {
52
printf("ERROR: Wrong no of parameters recieved from script\n");
53
printf("Exiting the libcgroup testset\n");
56
fs_mounted = atoi(argv[1]);
57
cgroup_dbg("C:DBG: fs_mounted as recieved from script=%d\n",
59
/* All possible controller will be element of an enum */
63
strncpy(mountpoint, argv[4], sizeof(mountpoint));
64
cgroup_dbg("C:DBG: mountpoint1 as recieved from script=%s\n",
66
if (fs_mounted == FS_MULTI_MOUNTED) {
67
strncpy(mountpoint2, argv[5], sizeof(mountpoint2));
68
cgroup_dbg("C:DBG: mountpoint2 as recieved from "
69
"script=%s\n", mountpoint2);
75
* check if one of the supported controllers is cpu or memory
77
is_subsystem_enabled("cpu", &cpu);
78
is_subsystem_enabled("memory", &memory);
79
if (cpu == 0 && memory == 0) {
80
fprintf(stderr, "none of cpu and memory controllers"
81
" is enabled in kernel\n");
82
fprintf(stderr, "Exiting the libcgroup testcases......\n");
87
* Testsets: Testcases are broadly devided into 3 categories based on
88
* filesystem(fs) mount scenario. fs not mounted, fs mounted, fs multi
89
* mounted. Call different apis in these different scenarios.
97
* Test01: call cgroup_init() and check return values
98
* Exp outcome: error ECGROUPNOTMOUNTED
101
test_cgroup_init(ECGROUPNOTMOUNTED, 1);
104
* Test02: call cgroup_attach_task() with null group
105
* Exp outcome: error non zero return value
108
test_cgroup_attach_task(ECGROUPNOTINITIALIZED, nullcgroup,
109
NULL, NULL, 0, NULLGRP, 2);
112
* Test03: Create a valid cgroup ds and check all return values
113
* Exp outcome: no error
116
cgroup1 = create_new_cgroup_ds(0, "group1",
117
STRING, cval, ids, 3);
120
* Test04: Then Call cgroup_create_cgroup() with this valid grp
121
* Exp outcome: non zero return value
123
test_cgroup_create_cgroup(ECGROUPNOTINITIALIZED, cgroup1,
124
"group1", 0, 1, 1, 4);
127
* Test05: delete cgroup
128
* Exp outcome: non zero return value but what ?
130
test_cgroup_delete_cgroup(ECGROUPNOTINITIALIZED, cgroup1,
131
"group1", 0, 1, 1, 5);
134
* Test06: Check if cgroup_create_cgroup() handles a NULL cgroup
135
* Exp outcome: error ECGROUPNOTALLOWED
137
test_cgroup_create_cgroup(ECGROUPNOTINITIALIZED, nullcgroup,
138
"group1", 0, 1, 1, 6);
141
* Test07: delete nullcgroup
143
test_cgroup_delete_cgroup(ECGROUPNOTINITIALIZED, nullcgroup,
144
"group1", 0, 1, 1, 7);
145
/* Test08: test the wrapper */
146
test_cgroup_add_free_controller(8);
148
cgroup_free(&nullcgroup);
149
cgroup_free(&cgroup1);
155
/* Do a sanity check if cgroup fs is mounted */
156
if (check_fsmounted(0)) {
157
printf("Sanity check fails. cgroup fs not mounted\n");
158
printf("Exiting without running this set of tests\n");
163
* Test01: call cgroup_attach_task() with null group
164
* without calling cgroup_init(). We can check other apis too.
165
* Exp outcome: error ECGROUPNOTINITIALIZED
168
test_cgroup_attach_task(ECGROUPNOTINITIALIZED, nullcgroup,
169
NULL, NULL, 0, NULLGRP, 1);
172
* Test02: call cgroup_init() and check return values
173
* Exp outcome: no error. return value 0
176
test_cgroup_init(0, 2);
179
* Test03: Call cgroup_attach_task() with null group and check
180
* if return values are correct. If yes check if task exists in
181
* root group tasks file
182
* TODO: This test needs some modification in script
183
* Exp outcome: current task should be attached to root group
186
test_cgroup_attach_task(0, nullcgroup, NULL, NULL, 0,
189
* Test04: Call cgroup_attach_task_pid() with null group
193
retval = cgroup_attach_task_pid(nullcgroup, -1);
195
message(4, PASS, "attach_task_pid()", retval,
198
message(4, FAIL, "attach_task_pid()", retval,
202
* Test05: Create a valid cgroup structure
203
* Exp outcome: no error. 0 return value
205
cgroup1 = create_new_cgroup_ds(ctl1, "group1",
206
STRING, cval, ids, 5);
208
fprintf(stderr, "Failed to create new cgroup ds. "
209
"Trying with second controller\n");
210
cgroup1 = create_new_cgroup_ds(ctl2, "group1", STRING,
213
fprintf(stderr, "Failed to create cgroup ds. "
214
"Tests dependent on this structure "
215
"will fail. So exiting...\n");
221
* Test06: Then Call cgroup_create_cgroup() with this group
222
* Exp outcome: zero return value
224
test_cgroup_create_cgroup(0, cgroup1, "group1", 0, 1, 1, 6);
227
* Test07: Call cgroup_attach_task() with valid cgroup and check
228
* if return values are correct. If yes check if task exists in
229
* that group's tasks file
230
* Exp outcome: current task should be attached to that group
233
test_cgroup_attach_task(0, cgroup1, "group1", NULL,
237
* Test08: modify cgroup with the same cgroup
238
* Exp outcome: zero return value. No change.
240
set_controller(ctl1, controller_name, control_file);
241
build_path(path_control_file, mountpoint,
242
"group1", control_file);
243
strncpy(cval.val_string, "260000", sizeof(cval.val_string));
244
retval = cgroup_modify_cgroup(cgroup1);
245
/* Check if the values are changed. cval contains orig values */
246
if (!retval && !group_modified(path_control_file, STRING, cval))
247
message(8, PASS, "modify_cgroup()", retval,
250
message(8, FAIL, "modify_cgroup()", retval,
254
* Create another valid cgroup structure with same group
255
* to modify the existing group
257
cgroup2 = create_new_cgroup_ds(ctl1, "group1",
258
STRING, cval, ids, 9);
260
fprintf(stderr, "Failed to create new cgroup ds. "
261
"Trying with second controller\n");
262
cgroup2 = create_new_cgroup_ds(ctl2, "group1",
263
STRING, cval, ids, 9);
265
fprintf(stderr, "Failed to create cgroup ds. "
266
"Tests dependent on this structure "
267
"will fail. So exiting...\n");
273
* Test10: modify cgroup with this new cgroup
274
* Exp outcome: zero return value
275
* Drawback: In case of first attempt failure above for
276
* create_new_cgroup_ds(), this test will fail
278
test_cgroup_modify_cgroup(0, cgroup2, "group1",
279
1, ctl1, ctl2, STRING, 10);
282
* Test11: modify cgroup with the null cgroup
283
* Exp outcome: zero return value.
286
test_cgroup_modify_cgroup(ECGROUPNOTALLOWED, nullcgroup,
287
"group1", 1, ctl1, ctl2, STRING, 11);
290
* Create another valid cgroup structure with diff controller
291
* to modify the existing group
293
cval.val_int64 = 262144;
294
cgroup3 = create_new_cgroup_ds(ctl2, "group1",
295
INT64, cval, ids, 12);
297
fprintf(stderr, "Failed to create new cgroup ds. "
298
"Tests dependent on this structure "
299
"will fail. So exiting...\n");
304
* Test13: modify existing group with this cgroup
305
* Exp outcome: zero return value
307
test_cgroup_modify_cgroup(0, cgroup3, "group1",
308
2, ctl1, ctl2, INT64, 13);
310
/* Test14: Test cgroup_get_cgroup() api
311
* The group group1 has been created and modified in the
312
* filesystem. Read it using the api and check if the values
313
* are correct as we know all the control values now.
314
* WARN: If any of the previous api fails and control reaches
315
* here, this api also will fail. Also the test function assumes
316
* that "group1" exists in fs. So call cgroup_create_cgroup()
317
* with "group1" named group before calling this test function.
319
test_cgroup_get_cgroup(ctl1, ctl2, ids, 14);
322
* Test16: delete cgroup
323
* Exp outcome: zero return value
325
test_cgroup_delete_cgroup(0, cgroup1, "group1", 0, 1, 1, 16);
328
* Test16: Check if cgroup_create_cgroup() handles a NULL cgroup
329
* Exp outcome: error ECGROUPNOTALLOWED
331
test_cgroup_create_cgroup(ECGROUPNOTALLOWED, nullcgroup,
332
"group1", 0, 1, 1, 17);
335
* Test16: delete nullcgroup
337
test_cgroup_delete_cgroup(ECGROUPNOTALLOWED, NULL,
338
"group1", 0, 1, 1, 18);
340
/* Test17: Test the wrapper to compare cgroup
341
* Create 2 cgroups and test it
343
test_cgroup_compare_cgroup(ctl1, ctl2, 19);
345
cgroup_free(&nullcgroup);
346
cgroup_free(&cgroup1);
347
cgroup_free(&cgroup2);
348
cgroup_free(&cgroup3);
352
case FS_MULTI_MOUNTED:
354
/* Do a sanity check if cgroup fs is multi mounted */
355
if (check_fsmounted(1)) {
356
printf("Sanity check fails. cgroup fs is not multi "
357
"mounted. Exiting without running this set "
363
* Test01: call apis and check return values
368
* Scenario 1: cgroup fs is multi mounted
369
* Exp outcome: no error. 0 return value
372
test_cgroup_init(0, 1);
375
* Test02: Call cgroup_attach_task() with null group and check
376
* if return values are correct. If yes check if task exists in
377
* root group tasks file for each controller
378
* TODO: This test needs some modification in script
379
* Exp outcome: current task should be attached to root groups
382
test_cgroup_attach_task(0, nullcgroup, NULL, NULL,
386
* Test03: Create a valid cgroup structure
387
* Exp outcome: no error. 0 return value
389
ctl1_cgroup1 = create_new_cgroup_ds(ctl1, "ctl1_group1",
390
STRING, cval, ids, 3);
392
fprintf(stderr, "Failed to create new cgroup ds. "
393
"Tests dependent on this structure "
394
"will fail. So exiting...\n");
399
* Test04: Then Call cgroup_create_cgroup() with this valid grp
400
* Exp outcome: zero return value
402
test_cgroup_create_cgroup(0, ctl1_cgroup1,
403
"ctl1_group1", 0, 1, 1, 4);
406
* Test05: Create a valid cgroup structure
407
* Exp outcome: no error. 0 return value
409
ctl2_cgroup1 = create_new_cgroup_ds(ctl2, "ctl2_group1",
410
STRING, cval, ids, 5);
412
fprintf(stderr, "Failed to create new cgroup ds. "
413
"Tests dependent on this structure "
414
"will fail. So exiting...\n");
419
* Test06: Then Call cgroup_create_cgroup() with this valid grp
420
* Exp outcome: zero return value
422
test_cgroup_create_cgroup(0, ctl2_cgroup1,
423
"ctl2_group1", 0, 2, 1, 6);
426
* Test07: Call cgroup_create_cgroup() with the same group
427
* Exp outcome: zero return value as the latest changes in api
429
test_cgroup_create_cgroup(0, ctl2_cgroup1,
430
"ctl2_group1", 0, 2, 1, 7);
433
* Test06: Call cgroup_attach_task() with a group with ctl1
434
* controller and check if return values are correct. If yes
435
* check if task exists in that group under only ctl1 controller
436
* hierarchy and in the root group under other controllers
440
test_cgroup_attach_task(0, ctl1_cgroup1, "ctl1_group1",
441
NULL, 0, NOMESSAGE, 8);
444
* Test07: Call cgroup_attach_task() with a group with ctl2
445
* controller and check if return values are correct. If yes
446
* check if task exists in the groups under both controller's
450
test_cgroup_attach_task(0, ctl2_cgroup1, "ctl1_group1",
451
"ctl2_group1", 0, NOMESSAGE, 9);
454
* Test: Create a valid cgroup structure
455
* Exp outcome: no error. 0 return value
457
ctl2_cgroup2 = create_new_cgroup_ds(ctl2, "ctl2_group2",
458
STRING, cval, ids, 10);
460
fprintf(stderr, "Failed to create new cgroup ds. "
461
"Tests dependent on this structure "
462
"will fail. So exiting...\n");
467
* Test08: Try to attach a task to this non existing group.
468
* Group does not exist in fs so should return ECGROUPNOTEXIST
471
test_cgroup_attach_task(ECGROUPNOTEXIST, ctl2_cgroup2,
472
NULL, NULL, 0, NOTCRTDGRP, 11);
475
* Create another valid cgroup structure with same group name
476
* to modify the existing group ctl1_group1
477
* Exp outcome: no error. 0 return value
479
mod_ctl1_cgroup1 = create_new_cgroup_ds(ctl1, "ctl1_group1",
480
STRING, cval, ids, 12);
481
if (!mod_ctl1_cgroup1) {
482
fprintf(stderr, "Failed to create new cgroup ds. "
483
"Tests dependent on this structure "
484
"will fail. So exiting...\n");
489
* Test09: modify existing cgroup with this new cgroup
490
* Exp outcome: zero return value and control value modified
492
test_cgroup_modify_cgroup(0, mod_ctl1_cgroup1, "ctl1_group1",
493
1, ctl1, ctl2, STRING, 13);
496
* Create another valid cgroup structure with same group name
497
* to modify the existing group ctl2_group1
498
* Exp outcome: no error. 0 return value
500
mod_ctl2_cgroup1 = create_new_cgroup_ds(ctl2, "ctl2_group1",
501
STRING, cval, ids, 14);
502
if (!mod_ctl2_cgroup1) {
503
fprintf(stderr, "Failed to create new cgroup ds. "
504
"Tests dependent on this structure "
505
"will fail. So exiting...\n");
510
* Test10: modify existing cgroup with this new cgroup
511
* Exp outcome: zero return value and control value modified
513
test_cgroup_modify_cgroup(0, mod_ctl2_cgroup1, "ctl2_group1",
514
2, ctl1, ctl2, STRING, 15);
517
* Test11: delete cgroups
518
* Exp outcome: zero return value
520
test_cgroup_delete_cgroup(0, ctl1_cgroup1,
521
"ctl1_group1", 0, 1, 1, 16);
524
* Test09: delete other cgroups too
525
* Exp outcome: zero return value
527
test_cgroup_delete_cgroup(0, ctl2_cgroup1,
528
"ctl2_group1", 0, 1, 1, 17);
531
* Test15: Create a valid cgroup structure
532
* which has multiple controllers
533
* Exp outcome: no error. 0 return value
535
common_cgroup = create_new_cgroup_ds(ctl1, "commongroup",
536
STRING, cval, ids, 18);
537
if (!common_cgroup) {
538
fprintf(stderr, "Failed to create new cgroup ds. "
539
"Tests dependent on this structure "
540
"will fail. So exiting...\n");
544
/* Add one more controller to the cgroup */
545
/* This also needs to be a function.. will do?? */
546
retval = set_controller(ctl2, controller_name, control_file);
548
fprintf(stderr, "Setting controller failled "
549
" Exiting without running further testcases\n");
552
if (!cgroup_add_controller(common_cgroup, controller_name)) {
553
message(15, FAIL, "add_controller()", retval,
555
fprintf(stderr, "Adding second controller failled "
556
" Exiting without running further testcases\n");
561
* Test11: Then Call cgroup_create_cgroup() with this valid grp
562
* Exp outcome: zero return value
564
test_cgroup_create_cgroup(0, common_cgroup,
565
"commongroup", 1, 2, 1, 19);
568
* Test12: Call cgroup_attach_task() with this common group
569
* and check if return values are correct. If yes check if
570
* task exists in the group under both controller's hierarchy
573
test_cgroup_attach_task(0, common_cgroup, "commongroup",
574
"commongroup", 0, COMMONGRP, 20);
577
* Test18: Create a valid cgroup structure to modify the
578
* commongroup which is under multiple controllers
579
* Exp outcome: no error. 0 return value
581
mod_common_cgroup = create_new_cgroup_ds(ctl1, "commongroup",
582
STRING, cval, ids, 21);
583
if (!common_cgroup) {
584
fprintf(stderr, "Failed to create new cgroup ds. "
585
"Tests dependent on this structure "
586
"will fail. So exiting...\n");
590
/* Add one more controller to the cgroup */
591
/* This also needs to be a function.. will do?? */
592
retval = set_controller(ctl2, controller_name, control_file);
594
fprintf(stderr, "Setting controller failled "
595
" Exiting without running further testcases\n");
598
sec_controller = cgroup_add_controller(mod_common_cgroup,
600
if (!sec_controller) {
601
message(18, FAIL, "add_controller()", retval,
603
fprintf(stderr, "Adding second controller failled "
604
" Exiting without running further testcases\n");
608
strncpy(cval.val_string, "7000064", sizeof(cval.val_string));
609
retval = cgroup_add_value_string(sec_controller,
610
control_file, cval.val_string);
612
printf("The cgroup_modify_cgroup() test will fail\n");
615
* Test14: modify existing cgroup with this new cgroup
616
* Exp outcome: zero return value and control value modified
618
test_cgroup_modify_cgroup(0, mod_common_cgroup, "commongroup",
619
0, ctl1, ctl2, STRING, 22);
622
* Test15: delete this common cgroup
623
* Exp outcome: zero return value
625
test_cgroup_delete_cgroup(0, common_cgroup,
626
"commongroup", 1, 2, 1, 23);
627
test_cgroup_get_cgroup(ctl1, ctl2, ids, 24);
629
/* Free the cgroup structures */
630
cgroup_free(&nullcgroup);
631
cgroup_free(&ctl1_cgroup1);
632
cgroup_free(&ctl2_cgroup1);
633
cgroup_free(&ctl2_cgroup2);
638
fprintf(stderr, "ERROR: Wrong parameters recieved from script. \
646
void test_cgroup_modify_cgroup(int retcode, struct cgroup *cgrp,
647
const char *name, int which_ctl, int ctl1,
648
int ctl2, int value_type, int i)
651
struct cntl_val_t cval = {0, 0, 0, "1000"};
652
char path1_control_file[FILENAME_MAX], path2_control_file[FILENAME_MAX];
653
char controller_name[FILENAME_MAX], control_file[FILENAME_MAX];
655
/* Check, In case some error is expected due to a negative scenario */
657
retval = cgroup_modify_cgroup(cgrp);
658
if (retval == retcode)
659
message(i, PASS, "modify_cgroup()", retval,
662
message(i, FAIL, "modify_cgroup()", retval,
668
/* Now there is no error and it is a genuine call */
669
retval = cgroup_modify_cgroup(cgrp);
671
message(i, FAIL, "modify_cgroup()", retval, info[NOMESSAGE]);
675
/* Let us now check if the group modified in file system */
676
switch (which_ctl) { /* group modified under which controllers */
678
case 1: /* group is modified under ctl1 which is always
679
* mounted at mountpoint in both cases */
680
set_controller(ctl1, controller_name, control_file);
681
build_path(path1_control_file, mountpoint, name, control_file);
682
/* this approach will be changed in coming patches */
683
strncpy(cval.val_string, "260000", sizeof(cval.val_string));
685
if (!group_modified(path1_control_file, value_type, cval))
686
message(i, PASS, "modify_cgroup()", retval,
689
message(i, FAIL, "modify_cgroup()", retval,
693
case 2: /* group is modified under ctl2 which may be
694
* mounted at mountpoint or mountpoint2 */
695
set_controller(ctl2, controller_name, control_file);
697
if (fs_mounted == FS_MOUNTED) /* group under mountpoint */
698
build_path(path2_control_file, mountpoint,
700
else /* group under mountpoint2 */
701
build_path(path2_control_file, mountpoint2,
704
/* this approach will be changed in coming patches */
705
strncpy(cval.val_string, "7000064", sizeof(cval.val_string));
706
cval.val_int64 = 262144;
707
if (!group_modified(path2_control_file, value_type, cval))
708
message(i, PASS, "modify_cgroup()", retval,
711
message(i, FAIL, "modify_cgroup()", retval,
716
/* ctl1 is always mounted at mountpoint */
717
set_controller(ctl1, controller_name, control_file);
718
build_path(path1_control_file, mountpoint,
720
/* ctl2 may be mounted at mountpoint or mountpoint2 depending
721
* on single or multiple mount case */
722
if (fs_mounted == FS_MOUNTED) { /* group under mountpoint */
723
set_controller(ctl2, controller_name, control_file);
724
build_path(path2_control_file, mountpoint,
726
} else { /* group under mountpoint2 */
727
set_controller(ctl2, controller_name, control_file);
728
build_path(path2_control_file, mountpoint2,
731
/* this approach will be changed in coming patches */
732
strncpy(cval.val_string, "260000", sizeof(cval.val_string));
733
if (!group_modified(path1_control_file, value_type, cval)) {
734
strncpy(cval.val_string, "7000064",
735
sizeof(cval.val_string));
736
if (!group_modified(path2_control_file,
738
message(i, PASS, "modify_cgroup()",
739
retval, info[GRPMODINBOTHCTLS]);
741
message(i, FAIL, "modify_cgroup()",
742
retval, info[GRPNOTMODIN2NDCTL]);
744
message(i, FAIL, "modify_cgroup()", retval,
745
info[GRPNOTMODINANYCTL]);
750
printf("Wrong controller parameter received....\n");
751
message(i, FAIL, "modify_cgroup()", retval, info[NOMESSAGE]);