summaryrefslogtreecommitdiffstats
path: root/amend/test_commands.c
diff options
context:
space:
mode:
Diffstat (limited to 'amend/test_commands.c')
-rw-r--r--amend/test_commands.c538
1 files changed, 538 insertions, 0 deletions
diff --git a/amend/test_commands.c b/amend/test_commands.c
new file mode 100644
index 000000000..be938ac26
--- /dev/null
+++ b/amend/test_commands.c
@@ -0,0 +1,538 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#undef NDEBUG
+#include <assert.h>
+#include "commands.h"
+
+static struct {
+ bool called;
+ const char *name;
+ void *cookie;
+ int argc;
+ const char **argv;
+ PermissionRequestList *permissions;
+ int returnValue;
+ char *functionResult;
+} gTestCommandState;
+
+static int
+testCommand(const char *name, void *cookie, int argc, const char *argv[],
+ PermissionRequestList *permissions)
+{
+ gTestCommandState.called = true;
+ gTestCommandState.name = name;
+ gTestCommandState.cookie = cookie;
+ gTestCommandState.argc = argc;
+ gTestCommandState.argv = argv;
+ gTestCommandState.permissions = permissions;
+ return gTestCommandState.returnValue;
+}
+
+static int
+testFunction(const char *name, void *cookie, int argc, const char *argv[],
+ char **result, size_t *resultLen, PermissionRequestList *permissions)
+{
+ gTestCommandState.called = true;
+ gTestCommandState.name = name;
+ gTestCommandState.cookie = cookie;
+ gTestCommandState.argc = argc;
+ gTestCommandState.argv = argv;
+ gTestCommandState.permissions = permissions;
+ if (result != NULL) {
+ *result = gTestCommandState.functionResult;
+ if (resultLen != NULL) {
+ *resultLen = strlen(*result);
+ }
+ }
+ return gTestCommandState.returnValue;
+}
+
+static int
+test_commands()
+{
+ Command *cmd;
+ int ret;
+ CommandArgumentType argType;
+
+ ret = commandInit();
+ assert(ret == 0);
+
+ /* Make sure we can't initialize twice.
+ */
+ ret = commandInit();
+ assert(ret < 0);
+
+ /* Try calling with some bad values.
+ */
+ ret = registerCommand(NULL, CMD_ARGS_UNKNOWN, NULL, NULL);
+ assert(ret < 0);
+
+ ret = registerCommand("hello", CMD_ARGS_UNKNOWN, NULL, NULL);
+ assert(ret < 0);
+
+ ret = registerCommand("hello", CMD_ARGS_WORDS, NULL, NULL);
+ assert(ret < 0);
+
+ cmd = findCommand(NULL);
+ assert(cmd == NULL);
+
+ argType = getCommandArgumentType(NULL);
+ assert((int)argType < 0);
+
+ ret = callCommand(NULL, -1, NULL);
+ assert(ret < 0);
+
+ ret = callBooleanCommand(NULL, false);
+ assert(ret < 0);
+
+ /* Register some commands.
+ */
+ ret = registerCommand("one", CMD_ARGS_WORDS, testCommand,
+ &gTestCommandState);
+ assert(ret == 0);
+
+ ret = registerCommand("two", CMD_ARGS_WORDS, testCommand,
+ &gTestCommandState);
+ assert(ret == 0);
+
+ ret = registerCommand("bool", CMD_ARGS_BOOLEAN, testCommand,
+ &gTestCommandState);
+ assert(ret == 0);
+
+ /* Make sure that all of those commands exist and that their
+ * argument types are correct.
+ */
+ cmd = findCommand("one");
+ assert(cmd != NULL);
+ argType = getCommandArgumentType(cmd);
+ assert(argType == CMD_ARGS_WORDS);
+
+ cmd = findCommand("two");
+ assert(cmd != NULL);
+ argType = getCommandArgumentType(cmd);
+ assert(argType == CMD_ARGS_WORDS);
+
+ cmd = findCommand("bool");
+ assert(cmd != NULL);
+ argType = getCommandArgumentType(cmd);
+ assert(argType == CMD_ARGS_BOOLEAN);
+
+ /* Make sure that no similar commands exist.
+ */
+ cmd = findCommand("on");
+ assert(cmd == NULL);
+
+ cmd = findCommand("onee");
+ assert(cmd == NULL);
+
+ /* Make sure that a double insertion fails.
+ */
+ ret = registerCommand("one", CMD_ARGS_WORDS, testCommand,
+ &gTestCommandState);
+ assert(ret < 0);
+
+ /* Make sure that bad args fail.
+ */
+ cmd = findCommand("one");
+ assert(cmd != NULL);
+
+ ret = callCommand(cmd, -1, NULL); // argc must be non-negative
+ assert(ret < 0);
+
+ ret = callCommand(cmd, 1, NULL); // argv can't be NULL if argc > 0
+ assert(ret < 0);
+
+ /* Make sure that you can't make a boolean call on a regular command.
+ */
+ cmd = findCommand("one");
+ assert(cmd != NULL);
+
+ ret = callBooleanCommand(cmd, false);
+ assert(ret < 0);
+
+ /* Make sure that you can't make a regular call on a boolean command.
+ */
+ cmd = findCommand("bool");
+ assert(cmd != NULL);
+
+ ret = callCommand(cmd, 0, NULL);
+ assert(ret < 0);
+
+ /* Set up some arguments.
+ */
+ int argc = 4;
+ const char *argv[4] = { "ONE", "TWO", "THREE", "FOUR" };
+
+ /* Make a call and make sure that it occurred.
+ */
+ cmd = findCommand("one");
+ assert(cmd != NULL);
+ memset(&gTestCommandState, 0, sizeof(gTestCommandState));
+ gTestCommandState.called = false;
+ gTestCommandState.returnValue = 25;
+ gTestCommandState.permissions = (PermissionRequestList *)1;
+ ret = callCommand(cmd, argc, argv);
+//xxx also try calling with a null argv element (should fail)
+ assert(ret == 25);
+ assert(gTestCommandState.called);
+ assert(strcmp(gTestCommandState.name, "one") == 0);
+ assert(gTestCommandState.cookie == &gTestCommandState);
+ assert(gTestCommandState.argc == argc);
+ assert(gTestCommandState.argv == argv);
+ assert(gTestCommandState.permissions == NULL);
+
+ /* Make a boolean call and make sure that it occurred.
+ */
+ cmd = findCommand("bool");
+ assert(cmd != NULL);
+
+ memset(&gTestCommandState, 0, sizeof(gTestCommandState));
+ gTestCommandState.called = false;
+ gTestCommandState.returnValue = 12;
+ gTestCommandState.permissions = (PermissionRequestList *)1;
+ ret = callBooleanCommand(cmd, false);
+ assert(ret == 12);
+ assert(gTestCommandState.called);
+ assert(strcmp(gTestCommandState.name, "bool") == 0);
+ assert(gTestCommandState.cookie == &gTestCommandState);
+ assert(gTestCommandState.argc == 0);
+ assert(gTestCommandState.argv == NULL);
+ assert(gTestCommandState.permissions == NULL);
+
+ memset(&gTestCommandState, 0, sizeof(gTestCommandState));
+ gTestCommandState.called = false;
+ gTestCommandState.returnValue = 13;
+ gTestCommandState.permissions = (PermissionRequestList *)1;
+ ret = callBooleanCommand(cmd, true);
+ assert(ret == 13);
+ assert(gTestCommandState.called);
+ assert(strcmp(gTestCommandState.name, "bool") == 0);
+ assert(gTestCommandState.cookie == &gTestCommandState);
+ assert(gTestCommandState.argc == 1);
+ assert(gTestCommandState.argv == NULL);
+ assert(gTestCommandState.permissions == NULL);
+
+ /* Try looking up permissions.
+ */
+ PermissionRequestList permissions;
+ cmd = findCommand("one");
+ assert(cmd != NULL);
+ memset(&gTestCommandState, 0, sizeof(gTestCommandState));
+ gTestCommandState.called = false;
+ gTestCommandState.returnValue = 27;
+ gTestCommandState.permissions = (PermissionRequestList *)1;
+ argv[1] = NULL; // null out an arg, which should be ok
+ ret = getCommandPermissions(cmd, argc, argv, &permissions);
+ assert(ret == 27);
+ assert(gTestCommandState.called);
+ assert(strcmp(gTestCommandState.name, "one") == 0);
+ assert(gTestCommandState.cookie == &gTestCommandState);
+ assert(gTestCommandState.argc == argc);
+ assert(gTestCommandState.argv == argv);
+ assert(gTestCommandState.permissions == &permissions);
+
+ /* Boolean command permissions
+ */
+ cmd = findCommand("bool");
+ assert(cmd != NULL);
+ memset(&gTestCommandState, 0, sizeof(gTestCommandState));
+ gTestCommandState.called = false;
+ gTestCommandState.returnValue = 55;
+ gTestCommandState.permissions = (PermissionRequestList *)1;
+ // argv[1] is still NULL
+ ret = getBooleanCommandPermissions(cmd, true, &permissions);
+ assert(ret == 55);
+ assert(gTestCommandState.called);
+ assert(strcmp(gTestCommandState.name, "bool") == 0);
+ assert(gTestCommandState.cookie == &gTestCommandState);
+ assert(gTestCommandState.argc == 1);
+ assert(gTestCommandState.argv == NULL);
+ assert(gTestCommandState.permissions == &permissions);
+
+
+ /* Smoke test commandCleanup().
+ */
+ commandCleanup();
+
+ return 0;
+}
+
+static int
+test_functions()
+{
+ Function *fn;
+ int ret;
+
+ ret = commandInit();
+ assert(ret == 0);
+
+ /* Try calling with some bad values.
+ */
+ ret = registerFunction(NULL, NULL, NULL);
+ assert(ret < 0);
+
+ ret = registerFunction("hello", NULL, NULL);
+ assert(ret < 0);
+
+ fn = findFunction(NULL);
+ assert(fn == NULL);
+
+ ret = callFunction(NULL, -1, NULL, NULL, NULL);
+ assert(ret < 0);
+
+ /* Register some functions.
+ */
+ ret = registerFunction("one", testFunction, &gTestCommandState);
+ assert(ret == 0);
+
+ ret = registerFunction("two", testFunction, &gTestCommandState);
+ assert(ret == 0);
+
+ ret = registerFunction("three", testFunction, &gTestCommandState);
+ assert(ret == 0);
+
+ /* Make sure that all of those functions exist.
+ * argument types are correct.
+ */
+ fn = findFunction("one");
+ assert(fn != NULL);
+
+ fn = findFunction("two");
+ assert(fn != NULL);
+
+ fn = findFunction("three");
+ assert(fn != NULL);
+
+ /* Make sure that no similar functions exist.
+ */
+ fn = findFunction("on");
+ assert(fn == NULL);
+
+ fn = findFunction("onee");
+ assert(fn == NULL);
+
+ /* Make sure that a double insertion fails.
+ */
+ ret = registerFunction("one", testFunction, &gTestCommandState);
+ assert(ret < 0);
+
+ /* Make sure that bad args fail.
+ */
+ fn = findFunction("one");
+ assert(fn != NULL);
+
+ // argc must be non-negative
+ ret = callFunction(fn, -1, NULL, (char **)1, NULL);
+ assert(ret < 0);
+
+ // argv can't be NULL if argc > 0
+ ret = callFunction(fn, 1, NULL, (char **)1, NULL);
+ assert(ret < 0);
+
+ // result can't be NULL
+ ret = callFunction(fn, 0, NULL, NULL, NULL);
+ assert(ret < 0);
+
+ /* Set up some arguments.
+ */
+ int argc = 4;
+ const char *argv[4] = { "ONE", "TWO", "THREE", "FOUR" };
+
+ /* Make a call and make sure that it occurred.
+ */
+ char *functionResult;
+ size_t functionResultLen;
+ fn = findFunction("one");
+ assert(fn != NULL);
+ memset(&gTestCommandState, 0, sizeof(gTestCommandState));
+ gTestCommandState.called = false;
+ gTestCommandState.returnValue = 25;
+ gTestCommandState.functionResult = "1234";
+ gTestCommandState.permissions = (PermissionRequestList *)1;
+ functionResult = NULL;
+ functionResultLen = 55;
+ ret = callFunction(fn, argc, argv,
+ &functionResult, &functionResultLen);
+//xxx also try calling with a null resultLen arg (should succeed)
+//xxx also try calling with a null argv element (should fail)
+ assert(ret == 25);
+ assert(gTestCommandState.called);
+ assert(strcmp(gTestCommandState.name, "one") == 0);
+ assert(gTestCommandState.cookie == &gTestCommandState);
+ assert(gTestCommandState.argc == argc);
+ assert(gTestCommandState.argv == argv);
+ assert(gTestCommandState.permissions == NULL);
+ assert(strcmp(functionResult, "1234") == 0);
+ assert(functionResultLen == strlen(functionResult));
+
+ /* Try looking up permissions.
+ */
+ PermissionRequestList permissions;
+ fn = findFunction("one");
+ assert(fn != NULL);
+ memset(&gTestCommandState, 0, sizeof(gTestCommandState));
+ gTestCommandState.called = false;
+ gTestCommandState.returnValue = 27;
+ gTestCommandState.permissions = (PermissionRequestList *)1;
+ argv[1] = NULL; // null out an arg, which should be ok
+ ret = getFunctionPermissions(fn, argc, argv, &permissions);
+ assert(ret == 27);
+ assert(gTestCommandState.called);
+ assert(strcmp(gTestCommandState.name, "one") == 0);
+ assert(gTestCommandState.cookie == &gTestCommandState);
+ assert(gTestCommandState.argc == argc);
+ assert(gTestCommandState.argv == argv);
+ assert(gTestCommandState.permissions == &permissions);
+
+ /* Smoke test commandCleanup().
+ */
+ commandCleanup();
+
+ return 0;
+}
+
+static int
+test_interaction()
+{
+ Command *cmd;
+ Function *fn;
+ int ret;
+
+ ret = commandInit();
+ assert(ret == 0);
+
+ /* Register some commands.
+ */
+ ret = registerCommand("one", CMD_ARGS_WORDS, testCommand, (void *)0xc1);
+ assert(ret == 0);
+
+ ret = registerCommand("two", CMD_ARGS_WORDS, testCommand, (void *)0xc2);
+ assert(ret == 0);
+
+ /* Register some functions, one of which shares a name with a command.
+ */
+ ret = registerFunction("one", testFunction, (void *)0xf1);
+ assert(ret == 0);
+
+ ret = registerFunction("three", testFunction, (void *)0xf3);
+ assert(ret == 0);
+
+ /* Look up each of the commands, and make sure no command exists
+ * with the name used only by our function.
+ */
+ cmd = findCommand("one");
+ assert(cmd != NULL);
+
+ cmd = findCommand("two");
+ assert(cmd != NULL);
+
+ cmd = findCommand("three");
+ assert(cmd == NULL);
+
+ /* Look up each of the functions, and make sure no function exists
+ * with the name used only by our command.
+ */
+ fn = findFunction("one");
+ assert(fn != NULL);
+
+ fn = findFunction("two");
+ assert(fn == NULL);
+
+ fn = findFunction("three");
+ assert(fn != NULL);
+
+ /* Set up some arguments.
+ */
+ int argc = 4;
+ const char *argv[4] = { "ONE", "TWO", "THREE", "FOUR" };
+
+ /* Call the overlapping command and make sure that the cookie is correct.
+ */
+ cmd = findCommand("one");
+ assert(cmd != NULL);
+ memset(&gTestCommandState, 0, sizeof(gTestCommandState));
+ gTestCommandState.called = false;
+ gTestCommandState.returnValue = 123;
+ gTestCommandState.permissions = (PermissionRequestList *)1;
+ ret = callCommand(cmd, argc, argv);
+ assert(ret == 123);
+ assert(gTestCommandState.called);
+ assert(strcmp(gTestCommandState.name, "one") == 0);
+ assert((int)gTestCommandState.cookie == 0xc1);
+ assert(gTestCommandState.argc == argc);
+ assert(gTestCommandState.argv == argv);
+ assert(gTestCommandState.permissions == NULL);
+
+ /* Call the overlapping function and make sure that the cookie is correct.
+ */
+ char *functionResult;
+ size_t functionResultLen;
+ fn = findFunction("one");
+ assert(fn != NULL);
+ memset(&gTestCommandState, 0, sizeof(gTestCommandState));
+ gTestCommandState.called = false;
+ gTestCommandState.returnValue = 125;
+ gTestCommandState.functionResult = "5678";
+ gTestCommandState.permissions = (PermissionRequestList *)2;
+ functionResult = NULL;
+ functionResultLen = 66;
+ ret = callFunction(fn, argc, argv, &functionResult, &functionResultLen);
+ assert(ret == 125);
+ assert(gTestCommandState.called);
+ assert(strcmp(gTestCommandState.name, "one") == 0);
+ assert((int)gTestCommandState.cookie == 0xf1);
+ assert(gTestCommandState.argc == argc);
+ assert(gTestCommandState.argv == argv);
+ assert(gTestCommandState.permissions == NULL);
+ assert(strcmp(functionResult, "5678") == 0);
+ assert(functionResultLen == strlen(functionResult));
+
+ /* Clean up.
+ */
+ commandCleanup();
+
+ return 0;
+}
+
+int
+test_cmd_fn()
+{
+ int ret;
+
+ ret = test_commands();
+ if (ret != 0) {
+ fprintf(stderr, "test_commands() failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = test_functions();
+ if (ret != 0) {
+ fprintf(stderr, "test_functions() failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = test_interaction();
+ if (ret != 0) {
+ fprintf(stderr, "test_interaction() failed: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}