Skip to content

Commit

Permalink
added unit tests for cli/command
Browse files Browse the repository at this point in the history
Fixes: #800
Fixes: #801
Fixes: #802

Adding basic unit tests for the command functionality in
cli/command.h.

Signed-off-by: Michael Engel <mengel@redhat.com>
  • Loading branch information
engelmi authored and mwperina committed Mar 8, 2024
1 parent dd889c3 commit bcb71f5
Show file tree
Hide file tree
Showing 9 changed files with 501 additions and 0 deletions.
79 changes: 79 additions & 0 deletions src/libbluechi/test/cli/command/command_add_option_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#include "libbluechi/cli/command.h"


static const OptionType option_types[] = {
{'f', "force", 1 },
{ 'r', "reload", 11},
{ 0, NULL, 0 },
};

int main() {
bool result = true;

_cleanup_command_ Command *command = new_command();

/* adding command option without value */
int r = command_add_option(command, 'f', NULL, &option_types[0]);
if (r < 0) {
fprintf(stderr, "FAILED: Unexpected error adding command option: %s\n", strerror(-r));
return EXIT_FAILURE;
}

/* adding same command option with value */
r = command_add_option(command, 'f', "value", &option_types[0]);
if (r < 0) {
fprintf(stderr, "FAILED: Unexpected error adding command option: %s\n", strerror(-r));
return EXIT_FAILURE;
}

/* adding different command option without value */
r = command_add_option(command, 'r', NULL, &option_types[1]);
if (r < 0) {
fprintf(stderr, "FAILED: Unexpected error adding command option: %s\n", strerror(-r));
return EXIT_FAILURE;
}

/* Test validation:
* Check that command options have been added without other functions
* from command.h
*/

int option_count = 0;
int expected_option_count = 3;

CommandOption *curr = NULL;
CommandOption *next = NULL;
LIST_FOREACH_SAFE(options, curr, next, command->command_options) {
// first command found
if (curr->key == 'f' && curr->value == NULL && curr->is_flag) {
option_count++;
}
// second command found
else if (curr->key == 'f' && curr->value != NULL && streq(curr->value, "value") &&
!curr->is_flag) {
option_count++;
}
// third command found
else if (curr->key == 'r' && curr->value == NULL && curr->is_flag) {
option_count++;
} else {
fprintf(stderr, "FAILED: Found unexpected command option with key: %d\n", curr->key);
result = false;
}
}

if (option_count != expected_option_count) {
fprintf(stderr, "FAILED: Missing command options detected\n");
}

if (result) {
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}
150 changes: 150 additions & 0 deletions src/libbluechi/test/cli/command/command_execute_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#include "libbluechi/cli/command.h"


static int method_dummy_call_count = 0;
static int method_dummy(UNUSED Command *command, UNUSED void *userdata) {
method_dummy_call_count++;
return 0;
}

static int usage_dummy_call_count = 0;
static void usage_dummy() {
usage_dummy_call_count++;
}


bool test_command_execute_is_help() {
usage_dummy_call_count = 0;
method_dummy_call_count = 0;

const Method method = { "dummy", 0, 0, 0, method_dummy, usage_dummy };

_cleanup_command_ Command *command = new_command();
command->is_help = true;
command->method = &method;

bool result = true;
int r = command_execute(command, NULL);
if (r != 0) {
fprintf(stderr,
"FAILED (%s): Expected command_execute for help method return 0, but got %d\n",
__func__,
r);
result = false;
}
if (usage_dummy_call_count != 1) {
fprintf(stderr,
"FAILED (%s): Expected command_execute to call usage(), but did not\n",
__func__);
result = false;
}

return result;
}

bool test_command_execute_min_max_args() {
usage_dummy_call_count = 0;
method_dummy_call_count = 0;

// define method with min_args=1 and max_args=2
const Method method = { "dummy", 1, 2, 0, method_dummy, usage_dummy };

_cleanup_command_ Command *command = new_command();
command->is_help = false;
command->method = &method;

bool result = true;

command->opargc = 0;
int r = command_execute(command, NULL);
if (r != -EINVAL) {
fprintf(stderr,
"FAILED (%s): Expected command_execute with too few arguments to return %d, but got %d\n",
__func__,
-EINVAL,
r);
result = false;
}

command->opargc = 3;
r = command_execute(command, NULL);
if (r != -EINVAL) {
fprintf(stderr,
"FAILED (%s): Expected command_execute with too many arguments to return %d, but got %d\n",
__func__,
-EINVAL,
r);
result = false;
}

if (usage_dummy_call_count != 0) {
fprintf(stderr,
"FAILED (%s): Expected command_execute not to call usage(), but did\n",
__func__);
result = false;
}
if (method_dummy_call_count != 0) {
fprintf(stderr,
"FAILED (%s): Expected command_execute not to call dispatch(), but did\n",
__func__);
result = false;
}

return result;
}

bool test_command_execute_dispatch() {
usage_dummy_call_count = 0;
method_dummy_call_count = 0;

const Method method = { "dummy", 0, 0, 0, method_dummy, usage_dummy };

_cleanup_command_ Command *command = new_command();
command->is_help = false;
command->opargc = 0;
command->method = &method;

bool result = true;
int r = command_execute(command, NULL);
if (r != 0) {
fprintf(stderr,
"FAILED (%s): Expected command_execute to return %d on dispatch(), but got %d\n",
__func__,
0,
r);
}
if (usage_dummy_call_count != 0) {
fprintf(stderr,
"FAILED (%s): Expected command_execute not to call usage(), but did\n",
__func__);
result = false;
}
if (method_dummy_call_count != 1) {
fprintf(stderr,
"FAILED (%s): Expected command_execute to call dispatch() exactly once, but called it %d times\n",
__func__,
method_dummy_call_count);
result = false;
}

return result;
}

int main() {
bool result = true;

result = result && test_command_execute_is_help();
result = result && test_command_execute_min_max_args();
result = result && test_command_execute_dispatch();

if (result) {
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}
63 changes: 63 additions & 0 deletions src/libbluechi/test/cli/command/command_flag_exists_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#include "libbluechi/cli/command.h"


static const OptionType option_types[] = {
{'f', "force", 1 },
{ 'r', "reload", 11},
{ 0, NULL, 0 },
};

int main() {
bool result = true;

_cleanup_command_ Command *command = new_command();

/* adding command option without value */
int r = command_add_option(command, 'f', NULL, &option_types[0]);
if (r < 0) {
fprintf(stderr, "FAILED: Unexpected error adding command option: %s\n", strerror(-r));
return EXIT_FAILURE;
}

/* adding same command option with value */
r = command_add_option(command, 'f', "value", &option_types[0]);
if (r < 0) {
fprintf(stderr, "FAILED: Unexpected error adding command option: %s\n", strerror(-r));
return EXIT_FAILURE;
}

/* adding different command option without value */
r = command_add_option(command, 'r', NULL, &option_types[1]);
if (r < 0) {
fprintf(stderr, "FAILED: Unexpected error adding command option: %s\n", strerror(-r));
return EXIT_FAILURE;
}

/* Test validation:
* Check command_flag_exists finds added options and test if
*/

if (!command_flag_exists(command, 'f')) {
fprintf(stderr, "FAILED: Expected flag 'f' to exist, but couldn't find it\n");
result = false;
}
if (!command_flag_exists(command, 'r')) {
fprintf(stderr, "FAILED: Expected flag 'r' to exist, but couldn't find it\n");
result = false;
}
if (command_flag_exists(command, 'x')) {
fprintf(stderr, "FAILED: Found unexpected flag 'x'\n");
result = false;
}

if (result) {
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}
59 changes: 59 additions & 0 deletions src/libbluechi/test/cli/command/command_get_option_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#include "libbluechi/cli/command.h"


static const OptionType option_types[] = {
{'f', "force", 1 },
{ 'r', "reload", 11},
{ 0, NULL, 0 },
};

int main() {
bool result = true;

_cleanup_command_ Command *command = new_command();

/* adding same command option with value */
int r = command_add_option(command, 'f', "yes", &option_types[0]);
if (r < 0) {
fprintf(stderr, "FAILED: Unexpected error adding command option: %s\n", strerror(-r));
return EXIT_FAILURE;
}

/* adding different command option without value */
r = command_add_option(command, 'r', NULL, &option_types[1]);
if (r < 0) {
fprintf(stderr, "FAILED: Unexpected error adding command option: %s\n", strerror(-r));
return EXIT_FAILURE;
}

/* Test validation:
* Check command_get_option get the value of an option if found by key
*/

char *got = command_get_option(command, 'f');
if (got == NULL || !streq(got, "yes")) {
fprintf(stderr, "FAILED: Expected value 'yes' for flag 'f', but got '%s'\n", got);
result = false;
}
got = command_get_option(command, 'r');
if (got != NULL) {
fprintf(stderr, "FAILED: Expected NULL value for flag 'r', but got '%s'\n", got);
result = false;
}
got = command_get_option(command, 'x');
if (got != NULL) {
fprintf(stderr, "FAILED: Expected NULL value for unknown flag 'x', but got '%s'\n", got);
result = false;
}

if (result) {
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}
Loading

0 comments on commit bcb71f5

Please sign in to comment.