Exemple #1
0
void test_negative_rows(void)
{
   TEST_IGNORE();
   TEST_ASSERT_TRUE((create_triangle(-1) == NULL));
}
static bool add_keys(int count)
{
    static const ssize_t sz = 10;
    char key_buf[sz];
    char tag_buf[sz];
    char value_buf[sz];

    for (int i = 0; i < count; i++) {

        KineticEntry entry = {
            .key = ByteBuffer_CreateAndAppendFormattedCString(key_buf, sz, "key_%d", i),
            .tag = ByteBuffer_CreateAndAppendFormattedCString(tag_buf, sz, "tag_%d", i),
            .value = ByteBuffer_CreateAndAppendFormattedCString(value_buf, sz, "val_%d", i),
            .algorithm = KINETIC_ALGORITHM_SHA1,
            .force = true,
        };

        KineticStatus status = KineticClient_Put(Fixture.session, &entry, NULL);
        TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status);
    }
    return true;
}

typedef enum { CMD_NEXT, CMD_PREVIOUS } GET_CMD;

static void compare_against_offset_key(GET_CMD cmd, bool metadataOnly)
{
    static const ssize_t sz = 10;
    char key_buf[sz];
    char tag_buf[sz];
    char value_buf[sz];
    char key_exp_buf[sz];
    char value_exp_buf[sz];

    const int count = 3;

    TEST_ASSERT_TRUE(add_keys(count));    /* add keys [key_X -> test_X] */

    int low = 0;
    int high = count;
    int8_t offset = 0;

    switch (cmd) {
    case CMD_NEXT:
        low = 1;
        offset = -1;
        break;
    case CMD_PREVIOUS:
        high = count - 1;
        offset = +1;
        break;
    default:
        TEST_ASSERT(false);
    }

    for (int i = low; i < high; i++) {
        ByteBuffer keyBuffer = ByteBuffer_CreateAndAppendFormattedCString(key_buf, sz, "key_%d", i + offset);
        ByteBuffer tagBuffer = ByteBuffer_CreateAndAppendFormattedCString(tag_buf, sz, "tag_%d", i + offset);
        ByteBuffer valueBuffer = ByteBuffer_Create(value_buf, sz, 0);

        printf("KEY '%s'\n", key_buf);

        KineticEntry entry = {
            .key = keyBuffer,
            .tag = tagBuffer,
            .value = valueBuffer,
            .algorithm = KINETIC_ALGORITHM_SHA1,
            .metadataOnly = metadataOnly,
        };
        KineticStatus status = KINETIC_STATUS_INVALID;

        switch (cmd) {
        case CMD_NEXT:
            status = KineticClient_GetNext(Fixture.session, &entry, NULL);
            break;
        case CMD_PREVIOUS:
            status = KineticClient_GetPrevious(Fixture.session, &entry, NULL);
            break;
        default:
            TEST_ASSERT(false);
        }
        
        TEST_ASSERT_EQUAL_KineticStatus(KINETIC_STATUS_SUCCESS, status);

        ByteBuffer expectedKeyBuffer = ByteBuffer_CreateAndAppendFormattedCString(key_exp_buf, sz, "key_%d", i);
        ByteBuffer expectedValueBuffer = ByteBuffer_CreateAndAppendFormattedCString(value_exp_buf, sz, "val_%d", i);

        TEST_ASSERT_EQUAL_ByteBuffer(expectedKeyBuffer, entry.key);
        if (!metadataOnly) {
            TEST_ASSERT_EQUAL_ByteBuffer(expectedValueBuffer, entry.value);
        }
    }
}

void test_GetNext_should_retrieve_object_and_metadata_from_device(void)
{
    compare_against_offset_key(CMD_NEXT, false);
}
void test_stream_disconnect ()
{
    size_t len = MAX_SOCKET_STRING;
    char bind_endpoint[MAX_SOCKET_STRING];
    char connect_endpoint[MAX_SOCKET_STRING];
    void *sockets[2];

    sockets[SERVER] = test_context_socket (ZMQ_STREAM);
    int enabled = 1;
    TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
      sockets[SERVER], ZMQ_STREAM_NOTIFY, &enabled, sizeof (enabled)));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (sockets[SERVER], "tcp://0.0.0.0:*"));
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_getsockopt (sockets[SERVER], ZMQ_LAST_ENDPOINT, bind_endpoint, &len));

    //  Apparently Windows can't connect to 0.0.0.0. A better fix would be welcome.
#ifdef ZMQ_HAVE_WINDOWS
    sprintf (connect_endpoint, "tcp://127.0.0.1:%s",
             strrchr (bind_endpoint, ':') + 1);
#else
    strcpy (connect_endpoint, bind_endpoint);
#endif

    sockets[CLIENT] = test_context_socket (ZMQ_STREAM);
    TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
      sockets[CLIENT], ZMQ_STREAM_NOTIFY, &enabled, sizeof (enabled)));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (sockets[CLIENT], connect_endpoint));

    // wait for connect notification
    // Server: Grab the 1st frame (peer routing id).
    zmq_msg_t peer_frame;
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&peer_frame));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&peer_frame, sockets[SERVER], 0));
    TEST_ASSERT_GREATER_THAN_INT (0, zmq_msg_size (&peer_frame));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&peer_frame));
    TEST_ASSERT_TRUE (has_more (sockets[SERVER]));

    // Server: Grab the 2nd frame (actual payload).
    zmq_msg_t data_frame;
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&data_frame));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&data_frame, sockets[SERVER], 0));
    TEST_ASSERT_EQUAL_INT (0, zmq_msg_size (&data_frame));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&data_frame));

    // Client: Grab the 1st frame (peer routing id).
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&peer_frame));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&peer_frame, sockets[CLIENT], 0));
    TEST_ASSERT_GREATER_THAN_INT (0, zmq_msg_size (&peer_frame));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&peer_frame));
    TEST_ASSERT_TRUE (has_more (sockets[CLIENT]));

    // Client: Grab the 2nd frame (actual payload).
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&data_frame));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_recv (&data_frame, sockets[CLIENT], 0));
    TEST_ASSERT_EQUAL_INT (0, zmq_msg_size (&data_frame));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&data_frame));

    // Send initial message.
    char blob_data[256];
    size_t blob_size = sizeof (blob_data);
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_getsockopt (sockets[CLIENT], ZMQ_ROUTING_ID, blob_data, &blob_size));
    TEST_ASSERT_GREATER_THAN (0, blob_size);
    zmq_msg_t msg;
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init_size (&msg, blob_size));
    memcpy (zmq_msg_data (&msg), blob_data, blob_size);
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_msg_send (&msg, sockets[dialog[0].turn], ZMQ_SNDMORE));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&msg));
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_msg_init_size (&msg, strlen (dialog[0].text)));
    memcpy (zmq_msg_data (&msg), dialog[0].text, strlen (dialog[0].text));
    TEST_ASSERT_SUCCESS_ERRNO (
      zmq_msg_send (&msg, sockets[dialog[0].turn], ZMQ_SNDMORE));
    TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&msg));

    // TODO: make sure this loop doesn't loop forever if something is wrong
    //       with the test (or the implementation).

    int step = 0;
    while (step < steps) {
        // Wait until something happens.
        zmq_pollitem_t items[] = {
          {sockets[SERVER], 0, ZMQ_POLLIN, 0},
          {sockets[CLIENT], 0, ZMQ_POLLIN, 0},
        };
        TEST_ASSERT_SUCCESS_ERRNO (zmq_poll (items, 2, 100));

        // Check for data received by the server.
        if (items[SERVER].revents & ZMQ_POLLIN) {
            TEST_ASSERT_EQUAL_INT (CLIENT, dialog[step].turn);

            // Grab the 1st frame (peer routing id).
            zmq_msg_t peer_frame;
            TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&peer_frame));
            TEST_ASSERT_SUCCESS_ERRNO (
              zmq_msg_recv (&peer_frame, sockets[SERVER], 0));
            TEST_ASSERT_GREATER_THAN_INT (0, zmq_msg_size (&peer_frame));
            TEST_ASSERT_TRUE (has_more (sockets[SERVER]));

            // Grab the 2nd frame (actual payload).
            zmq_msg_t data_frame;
            TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&data_frame));
            TEST_ASSERT_SUCCESS_ERRNO (
              zmq_msg_recv (&data_frame, sockets[SERVER], 0));

            // Make sure payload matches what we expect.
            const char *const data = (const char *) zmq_msg_data (&data_frame);
            const size_t size = zmq_msg_size (&data_frame);
            // 0-length frame is a disconnection notification.  The server
            // should receive it as the last step in the dialogue.
            if (size == 0) {
                ++step;
                TEST_ASSERT_EQUAL_INT (steps, step);
            } else {
                TEST_ASSERT_EQUAL_INT (strlen (dialog[step].text), size);
                TEST_ASSERT_EQUAL_STRING_LEN (dialog[step].text, data, size);

                ++step;

                TEST_ASSERT_LESS_THAN_INT (steps, step);

                // Prepare the response.
                TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&data_frame));
                TEST_ASSERT_SUCCESS_ERRNO (
                  zmq_msg_init_size (&data_frame, strlen (dialog[step].text)));
                memcpy (zmq_msg_data (&data_frame), dialog[step].text,
                        zmq_msg_size (&data_frame));

                // Send the response.
                TEST_ASSERT_SUCCESS_ERRNO (
                  zmq_msg_send (&peer_frame, sockets[SERVER], ZMQ_SNDMORE));
                TEST_ASSERT_SUCCESS_ERRNO (
                  zmq_msg_send (&data_frame, sockets[SERVER], ZMQ_SNDMORE));
            }

            // Release resources.
            TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&peer_frame));
            TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&data_frame));
        }

        // Check for data received by the client.
        if (items[CLIENT].revents & ZMQ_POLLIN) {
            TEST_ASSERT_EQUAL_INT (SERVER, dialog[step].turn);

            // Grab the 1st frame (peer routing id).
            zmq_msg_t peer_frame;
            TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&peer_frame));
            TEST_ASSERT_SUCCESS_ERRNO (
              zmq_msg_recv (&peer_frame, sockets[CLIENT], 0));
            TEST_ASSERT_GREATER_THAN_INT (0, zmq_msg_size (&peer_frame));
            TEST_ASSERT_TRUE (has_more (sockets[CLIENT]));

            // Grab the 2nd frame (actual payload).
            zmq_msg_t data_frame;
            TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_init (&data_frame));
            TEST_ASSERT_SUCCESS_ERRNO (
              zmq_msg_recv (&data_frame, sockets[CLIENT], 0));
            TEST_ASSERT_GREATER_THAN_INT (0, zmq_msg_size (&data_frame));

            // Make sure payload matches what we expect.
            const char *const data = (const char *) zmq_msg_data (&data_frame);
            const size_t size = zmq_msg_size (&data_frame);
            TEST_ASSERT_EQUAL_INT (strlen (dialog[step].text), size);
            TEST_ASSERT_EQUAL_STRING_LEN (dialog[step].text, data, size);

            ++step;

            // Prepare the response (next line in the dialog).
            TEST_ASSERT_LESS_THAN_INT (steps, step);
            TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&data_frame));
            TEST_ASSERT_SUCCESS_ERRNO (
              zmq_msg_init_size (&data_frame, strlen (dialog[step].text)));
            memcpy (zmq_msg_data (&data_frame), dialog[step].text,
                    zmq_msg_size (&data_frame));

            // Send the response.
            TEST_ASSERT_SUCCESS_ERRNO (
              zmq_msg_send (&peer_frame, sockets[CLIENT], ZMQ_SNDMORE));
            TEST_ASSERT_SUCCESS_ERRNO (
              zmq_msg_send (&data_frame, sockets[CLIENT], ZMQ_SNDMORE));

            // Release resources.
            TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&peer_frame));
            TEST_ASSERT_SUCCESS_ERRNO (zmq_msg_close (&data_frame));
        }
    }
    TEST_ASSERT_EQUAL_INT (steps, step);
    test_context_socket_close (sockets[CLIENT]);
    test_context_socket_close (sockets[SERVER]);
}
/****************************************************************************
 * Name: CanWrite
 *
 * Description:
 *   Test DEV_ERR_NODE can be opened for writing
 *
 * Input Parameters:
 *   None
 *
 * Returned Value:
 *   None
 *
 * Assumptions/Limitations:
 *   None
 *
 ****************************************************************************/
TEST(DeviceNodeAccess, CanWrite)
{
  device = open(DEV_ERR_NODE, O_WRONLY);
  TEST_ASSERT_TRUE(device >= 0);
}
Exemple #5
0
void
test_DecryptValid(void) {
	cache_secretsize = keyLength;

	TEST_ASSERT_TRUE(MD5authdecrypt(keytype, (u_char*)key, (u_int32*)expectedPacket, packetLength, 20));
}
Exemple #6
0
void testNotTrue(void)
{
    EXPECT_ABORT_BEGIN
    TEST_ASSERT_TRUE(0);
    VERIFY_FAILS_END
}
void test_turn_of_the_25th_century(void)
{
    TEST_ASSERT_TRUE(is_leap_year(2400));;
}
void test_lower_case_only(void)
{
   TEST_ASSERT_TRUE(isIsogram("isogram"));
}
Exemple #9
0
static void test_is_numeric_returns_true_if_invalid_octet(void)
{
	TEST_ASSERT_TRUE(is_numeric("08"));
	TEST_ASSERT_TRUE(is_numeric("09"));
}
void test_multiple_whitespace(void)
{
   TEST_ASSERT_TRUE(isIsogram("Emily Jung Schwartzkopf"));
}
void test_empty_string(void)
{
   TEST_ASSERT_TRUE(isIsogram(""));
}
void test_duplicated_non_letter_char(void)
{
   TEST_ASSERT_TRUE(isIsogram("Hjelmqvist-Gryb-Zock-Pfund-Wax"));
}
void test_non_letter_char(void)
{
   TEST_ASSERT_TRUE(isIsogram("thumbscrew-japingly"));
}
void test_longest_known_isogram(void)
{
   TEST_ASSERT_TRUE(isIsogram("subdermatoglyphic"));
}
Exemple #15
0
//Yup, nice comment
void test_TheFirstThingToTest(void)
{
    TEST_ASSERT(1);

    TEST_ASSERT_TRUE(1);
}
Exemple #16
0
static void gba_item_pocket_test(
    struct pkmn_item_list* p_item_pocket,
    enum pkmn_game game
)
{
    TEST_ASSERT_NOT_NULL(p_item_pocket);
    TEST_ASSERT_NOT_NULL(p_item_pocket->p_internal);

    size_t expected_capacity = 0;
    if(is_game_rs(game))
    {
        expected_capacity = 20;
    }
    else if(game == PKMN_GAME_EMERALD)
    {
        expected_capacity = 30;
    }
    else
    {
        expected_capacity = 42;
    }

    enum pkmn_error error = PKMN_ERROR_NONE;

    TEST_ASSERT_EQUAL_STRING("Items", p_item_pocket->p_name);
    TEST_ASSERT_EQUAL(game, p_item_pocket->game);
    TEST_ASSERT_EQUAL(expected_capacity, p_item_pocket->capacity);

    // Make sure item slots start as completely empty.
    test_item_list_initial_values(p_item_pocket);

    // Confirm errors are returned when expected.
    test_item_list_out_of_range_error(
        p_item_pocket,
        PKMN_ITEM_POTION
    );

    // Make sure we can't add items from other pockets.
    static const enum pkmn_item wrong_pocket_items[] =
    {
        PKMN_ITEM_BICYCLE,
        PKMN_ITEM_MASTER_BALL,
        PKMN_ITEM_HM01,
        PKMN_ITEM_RAZZ_BERRY
    };
    test_item_list_invalid_items(p_item_pocket, wrong_pocket_items, 4);

    // Make sure we can't add items from later generations.
    static const enum pkmn_item wrong_generation_items[] =
    {
        PKMN_ITEM_PINK_BOW,
        PKMN_ITEM_BLACK_SLUDGE,
        PKMN_ITEM_BINDING_BAND,
        PKMN_ITEM_BEEDRILLITE
    };
    test_item_list_invalid_items(p_item_pocket, wrong_generation_items, 4);

    // Make sure we can't add items from Gamecube games.
    static const enum pkmn_item gamecube_items[] =
    {
        PKMN_ITEM_TIME_FLUTE,
        PKMN_ITEM_POKE_SNACK
    };
    test_item_list_invalid_items(p_item_pocket, gamecube_items, 2);

    static const enum pkmn_item items[] =
    {
        PKMN_ITEM_POTION,
        PKMN_ITEM_ORANGE_MAIL,
        PKMN_ITEM_LAVA_COOKIE,
        PKMN_ITEM_STARDUST,
        PKMN_ITEM_SHADOW_MAIL,
        PKMN_ITEM_PINK_SCARF,
        PKMN_ITEM_ANTIDOTE,
        PKMN_ITEM_GREEN_SHARD
    };

    // Test setting items by index.
    test_item_list_set_item(
        p_item_pocket,
        items,
        3
    );

    // Start adding and removing items, and make sure the numbers are accurate.
    test_item_list_add_remove(
        p_item_pocket,
        items,
        8
    );

    struct pkmn_item_enum_list valid_items =
    {
        .p_enums = NULL,
        .length = 0
    };
    error = pkmn_item_list_get_valid_items(
                p_item_pocket,
                &valid_items
            );
    PKMN_TEST_ASSERT_SUCCESS(error);
    TEST_ASSERT_NOT_NULL(valid_items.p_enums);
    TEST_ASSERT_TRUE(valid_items.length > 0);

    struct pkmn_string_list valid_item_names =
    {
        .pp_strings = NULL,
        .length = 0
    };
    error = pkmn_item_list_get_valid_item_names(
                p_item_pocket,
                &valid_item_names
            );
    PKMN_TEST_ASSERT_SUCCESS(error);
    TEST_ASSERT_NOT_NULL(valid_item_names.pp_strings);
    TEST_ASSERT_EQUAL(
        valid_items.length,
        valid_item_names.length
    );

    error = pkmn_item_enum_list_free(&valid_items);
    TEST_ASSERT_NULL(valid_items.p_enums);
    TEST_ASSERT_EQUAL(0, valid_items.length);

    error = pkmn_string_list_free(&valid_item_names);
    TEST_ASSERT_NULL(valid_item_names.pp_strings);
    TEST_ASSERT_EQUAL(0, valid_item_names.length);
}

static void gba_key_item_pocket_test(
    struct pkmn_item_list* p_key_item_pocket,
    enum pkmn_game game
)
{
    TEST_ASSERT_NOT_NULL(p_key_item_pocket);
    TEST_ASSERT_NOT_NULL(p_key_item_pocket->p_internal);

    enum pkmn_error error = PKMN_ERROR_NONE;

    size_t expected_capacity = 0;
    if(is_game_rs(game))
    {
        expected_capacity = 20;
    }
    else
    {
        expected_capacity = 30;
    }

    TEST_ASSERT_EQUAL_STRING("Key Items", p_key_item_pocket->p_name);
    TEST_ASSERT_EQUAL(game, p_key_item_pocket->game);
    TEST_ASSERT_EQUAL(expected_capacity, p_key_item_pocket->capacity);

    // Make sure item slots start as completely empty.
    test_item_list_initial_values(p_key_item_pocket);

    // Confirm errors are returned when expected.
    test_item_list_out_of_range_error(
        p_key_item_pocket,
        PKMN_ITEM_BASEMENT_KEY
    );

    // Make sure we can't add items from other pockets.
    static const enum pkmn_item wrong_pocket_items[] =
    {
        PKMN_ITEM_POTION,
        PKMN_ITEM_MASTER_BALL,
        PKMN_ITEM_HM01,
        PKMN_ITEM_RAZZ_BERRY
    };
    test_item_list_invalid_items(p_key_item_pocket, wrong_pocket_items, 4);

    // Make sure we can't add items from later generations.
    static const enum pkmn_item wrong_generation_items[] =
    {
        PKMN_ITEM_GS_BALL,
        PKMN_ITEM_POFFIN_CASE,
        PKMN_ITEM_DNA_SPLICERS,
        PKMN_ITEM_AQUA_SUIT
    };
    test_item_list_invalid_items(p_key_item_pocket, wrong_generation_items, 4);

    // Make sure we can't add items from incompatible Generation III games.
    static const enum pkmn_item gcn_items[] =
    {
        PKMN_ITEM_EIN_FILE_S,
        PKMN_ITEM_POWERUP_PART,
        PKMN_ITEM_GONZAPS_KEY,
        PKMN_ITEM_KRANE_MEMO_1
    };
    static const enum pkmn_item frlg_items[] =
    {
        PKMN_ITEM_HELIX_FOSSIL,
        PKMN_ITEM_TEA,
        PKMN_ITEM_RUBY
    };
    static const enum pkmn_item emerald_items[] =
    {
        PKMN_ITEM_MAGMA_EMBLEM,
        PKMN_ITEM_OLD_SEA_MAP
    };
    test_item_list_invalid_items(p_key_item_pocket, gcn_items, 4);
    if(is_game_rs(game))
    {
        test_item_list_invalid_items(p_key_item_pocket, frlg_items, 3);
    }
    if(game != PKMN_GAME_EMERALD)
    {
        test_item_list_invalid_items(p_key_item_pocket, emerald_items, 2);
    }

    static const enum pkmn_item items[] =
    {
        PKMN_ITEM_WAILMER_PAIL,
        PKMN_ITEM_BASEMENT_KEY,
        PKMN_ITEM_METEORITE,
        PKMN_ITEM_OLD_ROD,
        PKMN_ITEM_RED_ORB,
        PKMN_ITEM_ROOT_FOSSIL,
        PKMN_ITEM_CONTEST_PASS,
        PKMN_ITEM_EON_TICKET
    };

    // Test setting items by index.
    test_item_list_set_item(
        p_key_item_pocket,
        items,
        3
    );

    // Start adding and removing items, and make sure the numbers are accurate.
    test_item_list_add_remove(
        p_key_item_pocket,
        items,
        8
    );

    struct pkmn_item_enum_list valid_items =
    {
        .p_enums = NULL,
        .length = 0
    };
    error = pkmn_item_list_get_valid_items(
                p_key_item_pocket,
                &valid_items
            );
    PKMN_TEST_ASSERT_SUCCESS(error);
    TEST_ASSERT_NOT_NULL(valid_items.p_enums);
    TEST_ASSERT_TRUE(valid_items.length > 0);

    struct pkmn_string_list valid_item_names =
    {
        .pp_strings = NULL,
        .length = 0
    };
    error = pkmn_item_list_get_valid_item_names(
                p_key_item_pocket,
                &valid_item_names
            );
    PKMN_TEST_ASSERT_SUCCESS(error);
    TEST_ASSERT_NOT_NULL(valid_item_names.pp_strings);
    TEST_ASSERT_EQUAL(
        valid_items.length,
        valid_item_names.length
    );

    error = pkmn_item_enum_list_free(&valid_items);
    TEST_ASSERT_NULL(valid_items.p_enums);
    TEST_ASSERT_EQUAL(0, valid_items.length);

    error = pkmn_string_list_free(&valid_item_names);
    TEST_ASSERT_NULL(valid_item_names.pp_strings);
}

static void gba_ball_pocket_test(
    struct pkmn_item_list* p_ball_pocket,
    enum pkmn_game game
)
{
    TEST_ASSERT_NOT_NULL(p_ball_pocket);
    TEST_ASSERT_NOT_NULL(p_ball_pocket->p_internal);

    size_t expected_capacity = 0;
    if(is_game_frlg(game))
    {
        expected_capacity = 13;
    }
    else
    {
        expected_capacity = 16;
    }

    TEST_ASSERT_EQUAL_STRING("Poké Balls", p_ball_pocket->p_name);
    TEST_ASSERT_EQUAL(game, p_ball_pocket->game);
    TEST_ASSERT_EQUAL(expected_capacity, p_ball_pocket->capacity);

    enum pkmn_error error = PKMN_ERROR_NONE;

    // Make sure item slots start as completely empty.
    test_item_list_initial_values(p_ball_pocket);

    // Confirm errors are returned when expected.
    test_item_list_out_of_range_error(
        p_ball_pocket,
        PKMN_ITEM_MASTER_BALL
    );

    // Make sure we can't add items from other pockets.
    static const enum pkmn_item wrong_pocket_items[] =
    {
        PKMN_ITEM_BICYCLE,
        PKMN_ITEM_POTION,
        PKMN_ITEM_HM01,
        PKMN_ITEM_RAZZ_BERRY
    };
    test_item_list_invalid_items(p_ball_pocket, wrong_pocket_items, 4);

    // Make sure we can't add items from later generations.
    static const enum pkmn_item wrong_generation_items[] =
    {
        PKMN_ITEM_MOON_BALL,
        PKMN_ITEM_HEAL_BALL,
        PKMN_ITEM_DREAM_BALL
    };
    test_item_list_invalid_items(p_ball_pocket, wrong_generation_items, 3);

    static const enum pkmn_item items[] =
    {
        PKMN_ITEM_MASTER_BALL,
        PKMN_ITEM_ULTRA_BALL,
        PKMN_ITEM_GREAT_BALL,
        PKMN_ITEM_POKE_BALL,
        PKMN_ITEM_SAFARI_BALL,
        PKMN_ITEM_NET_BALL,
        PKMN_ITEM_DIVE_BALL,
        PKMN_ITEM_NEST_BALL
    };

    // Test setting items by index.
    test_item_list_set_item(
        p_ball_pocket,
        items,
        3
    );

    // Start adding and removing items, and make sure the numbers are accurate.
    test_item_list_add_remove(
        p_ball_pocket,
        items,
        8
    );

    struct pkmn_item_enum_list valid_items =
    {
        .p_enums = NULL,
        .length = 0
    };
    error = pkmn_item_list_get_valid_items(
                p_ball_pocket,
                &valid_items
            );
    PKMN_TEST_ASSERT_SUCCESS(error);
    TEST_ASSERT_NOT_NULL(valid_items.p_enums);
    TEST_ASSERT_TRUE(valid_items.length > 0);

    struct pkmn_string_list valid_item_names =
    {
        .pp_strings = NULL,
        .length = 0
    };
    error = pkmn_item_list_get_valid_item_names(
                p_ball_pocket,
                &valid_item_names
            );
    PKMN_TEST_ASSERT_SUCCESS(error);
    TEST_ASSERT_NOT_NULL(valid_item_names.pp_strings);
    TEST_ASSERT_EQUAL(
        valid_items.length,
        valid_item_names.length
    );

    error = pkmn_item_enum_list_free(&valid_items);
    TEST_ASSERT_NULL(valid_items.p_enums);
    TEST_ASSERT_EQUAL(0, valid_items.length);

    error = pkmn_string_list_free(&valid_item_names);
    TEST_ASSERT_NULL(valid_item_names.pp_strings);
    TEST_ASSERT_EQUAL(0, valid_item_names.length);
}

static void gba_tmhm_pocket_test(
    struct pkmn_item_list* p_tmhm_pocket,
    enum pkmn_game game
)
{
    TEST_ASSERT_NOT_NULL(p_tmhm_pocket);
    TEST_ASSERT_NOT_NULL(p_tmhm_pocket->p_internal);

    enum pkmn_error error = PKMN_ERROR_NONE;

    const char* expected_pocket_name = NULL;
    size_t expected_capacity = 0;
    if(is_game_frlg(game))
    {
        expected_pocket_name = "TM Case";
        expected_capacity = 58;
    }
    else
    {
        expected_pocket_name = "TMs & HMs";
        expected_capacity = 64;
    }

    TEST_ASSERT_EQUAL_STRING(expected_pocket_name, p_tmhm_pocket->p_name);
    TEST_ASSERT_EQUAL(game, p_tmhm_pocket->game);
    TEST_ASSERT_EQUAL(expected_capacity, p_tmhm_pocket->capacity);

    // Make sure item slots start as completely empty.
    test_item_list_initial_values(p_tmhm_pocket);

    // Confirm errors are returned when expected.
    test_item_list_out_of_range_error(
        p_tmhm_pocket,
        PKMN_ITEM_TM01
    );

    // Make sure we can't add items from other pockets.
    static const enum pkmn_item wrong_pocket_items[] =
    {
        PKMN_ITEM_BICYCLE,
        PKMN_ITEM_POTION,
        PKMN_ITEM_GREAT_BALL,
        PKMN_ITEM_RAZZ_BERRY
    };
    test_item_list_invalid_items(p_tmhm_pocket, wrong_pocket_items, 4);

    // Make sure we can't add items from later generations.
    static const enum pkmn_item wrong_generation_items[] =
    {
        PKMN_ITEM_TM51
    };
    test_item_list_invalid_items(p_tmhm_pocket, wrong_generation_items, 1);

    static const enum pkmn_item items[] =
    {
        PKMN_ITEM_TM01,
        PKMN_ITEM_HM01,
        PKMN_ITEM_TM02,
        PKMN_ITEM_HM02,
        PKMN_ITEM_TM03,
        PKMN_ITEM_HM03,
        PKMN_ITEM_TM04,
        PKMN_ITEM_HM04
    };

    // Test setting items by index.
    test_item_list_set_item(
        p_tmhm_pocket,
        items,
        3
    );

    // Start adding and removing items, and make sure the numbers are accurate.
    test_item_list_add_remove(
        p_tmhm_pocket,
        items,
        8
    );

    struct pkmn_item_enum_list valid_items =
    {
        .p_enums = NULL,
        .length = 0
    };
    error = pkmn_item_list_get_valid_items(
                p_tmhm_pocket,
                &valid_items
            );
    PKMN_TEST_ASSERT_SUCCESS(error);
    TEST_ASSERT_NOT_NULL(valid_items.p_enums);
    TEST_ASSERT_TRUE(valid_items.length > 0);

    struct pkmn_string_list valid_item_names =
    {
        .pp_strings = NULL,
        .length = 0
    };
    error = pkmn_item_list_get_valid_item_names(
                p_tmhm_pocket,
                &valid_item_names
            );
    PKMN_TEST_ASSERT_SUCCESS(error);
    TEST_ASSERT_NOT_NULL(valid_item_names.pp_strings);
    TEST_ASSERT_EQUAL(
        valid_items.length,
        valid_item_names.length
    );

    error = pkmn_item_enum_list_free(&valid_items);
    TEST_ASSERT_NULL(valid_items.p_enums);
    TEST_ASSERT_EQUAL(0, valid_items.length);

    error = pkmn_string_list_free(&valid_item_names);
    TEST_ASSERT_NULL(valid_item_names.pp_strings);
    TEST_ASSERT_EQUAL(0, valid_item_names.length);
}

static void gba_berry_pocket_test(
    struct pkmn_item_list* p_berry_pocket,
    enum pkmn_game game
)
{
    TEST_ASSERT_NOT_NULL(p_berry_pocket);
    TEST_ASSERT_NOT_NULL(p_berry_pocket->p_internal);

    enum pkmn_error error = PKMN_ERROR_NONE;

    const char* expected_pocket_name = NULL;
    size_t expected_capacity = 0;
    if(is_game_frlg(game))
    {
        expected_pocket_name = "Berry Pouch";
        expected_capacity = 43;
    }
    else
    {
        expected_pocket_name = "Berries";
        expected_capacity = 46;
    }

    TEST_ASSERT_EQUAL_STRING(expected_pocket_name, p_berry_pocket->p_name);
    TEST_ASSERT_EQUAL(game, p_berry_pocket->game);
    TEST_ASSERT_EQUAL(expected_capacity, p_berry_pocket->capacity);

    // Make sure item slots start as completely empty.
    test_item_list_initial_values(p_berry_pocket);

    // Confirm errors are returned when expected.
    test_item_list_out_of_range_error(
        p_berry_pocket,
        PKMN_ITEM_ORAN_BERRY
    );

    // Make sure we can't add items from other pockets.
    static const enum pkmn_item wrong_pocket_items[] =
    {
        PKMN_ITEM_BICYCLE,
        PKMN_ITEM_POTION,
        PKMN_ITEM_GREAT_BALL,
        PKMN_ITEM_TM01
    };
    test_item_list_invalid_items(p_berry_pocket, wrong_pocket_items, 4);

    // Make sure we can't add items from later generations.
    static const enum pkmn_item wrong_generation_items[] =
    {
        PKMN_ITEM_BERRY,
        PKMN_ITEM_OCCA_BERRY,
        PKMN_ITEM_ROSELI_BERRY
    };
    test_item_list_invalid_items(p_berry_pocket, wrong_generation_items, 3);

    static const enum pkmn_item items[] =
    {
        PKMN_ITEM_CHERI_BERRY,
        PKMN_ITEM_RAZZ_BERRY,
        PKMN_ITEM_LUM_BERRY,
        PKMN_ITEM_PINAP_BERRY,
        PKMN_ITEM_ASPEAR_BERRY,
        PKMN_ITEM_IAPAPA_BERRY,
        PKMN_ITEM_WIKI_BERRY,
        PKMN_ITEM_APICOT_BERRY
    };

    // Test setting items by index.
    test_item_list_set_item(
        p_berry_pocket,
        items,
        3
    );

    // Start adding and removing items, and make sure the numbers are accurate.
    test_item_list_add_remove(
        p_berry_pocket,
        items,
        8
    );

    struct pkmn_item_enum_list valid_items =
    {
        .p_enums = NULL,
        .length = 0
    };
    error = pkmn_item_list_get_valid_items(
                p_berry_pocket,
                &valid_items
            );
    PKMN_TEST_ASSERT_SUCCESS(error);
    TEST_ASSERT_NOT_NULL(valid_items.p_enums);
    TEST_ASSERT_TRUE(valid_items.length > 0);

    struct pkmn_string_list valid_item_names =
    {
        .pp_strings = NULL,
        .length = 0
    };
    error = pkmn_item_list_get_valid_item_names(
                p_berry_pocket,
                &valid_item_names
            );
    PKMN_TEST_ASSERT_SUCCESS(error);
    TEST_ASSERT_NOT_NULL(valid_item_names.pp_strings);
    TEST_ASSERT_EQUAL(
        valid_items.length,
        valid_item_names.length
    );

    error = pkmn_item_enum_list_free(&valid_items);
    TEST_ASSERT_NULL(valid_items.p_enums);
    TEST_ASSERT_EQUAL(0, valid_items.length);

    error = pkmn_string_list_free(&valid_item_names);
    TEST_ASSERT_NULL(valid_item_names.pp_strings);
    TEST_ASSERT_EQUAL(0, valid_item_names.length);
}

static void gba_item_pc_test(enum pkmn_game game)
{
    struct pkmn_item_list item_pc =
    {
        .p_name = NULL,
        .game = PKMN_GAME_NONE,
        .capacity = 0,
        .p_internal = NULL
    };

    enum pkmn_error error = PKMN_ERROR_NONE;

    error = pkmn_item_list_init(
                "PC",
                game,
                &item_pc
            );
    PKMN_TEST_ASSERT_SUCCESS(error);

    TEST_ASSERT_EQUAL_STRING("PC", item_pc.p_name);
    TEST_ASSERT_EQUAL(game, item_pc.game);
    TEST_ASSERT_EQUAL(50, item_pc.capacity);
    TEST_ASSERT_NOT_NULL(item_pc.p_internal);

    // Make sure item slots start as completely empty.
    test_item_list_initial_values(&item_pc);

    // Confirm errors are returned when expected.
    test_item_list_out_of_range_error(
        &item_pc,
        PKMN_ITEM_POTION
    );

    // Make sure we can't add items from later generations.
    test_item_list_invalid_items(
        &item_pc,
        WRONG_GAME_ALL_POCKET_ITEMS,
        9
    );

    // Test setting items by index.
    test_item_list_set_item(
        &item_pc,
        ALL_POCKET_ITEMS,
        3
    );

    // Start adding and removing items, and make sure the numbers are accurate.
    test_item_list_add_remove(
        &item_pc,
        ALL_POCKET_ITEMS,
        8
    );

    struct pkmn_item_enum_list valid_items =
    {
        .p_enums = NULL,
        .length = 0
    };
    error = pkmn_item_list_get_valid_items(
                &item_pc,
                &valid_items
            );
    PKMN_TEST_ASSERT_SUCCESS(error);
    TEST_ASSERT_NOT_NULL(valid_items.p_enums);
    TEST_ASSERT_TRUE(valid_items.length > 0);

    struct pkmn_string_list valid_item_names =
    {
        .pp_strings = NULL,
        .length = 0
    };
    error = pkmn_item_list_get_valid_item_names(
                &item_pc,
                &valid_item_names
            );
    PKMN_TEST_ASSERT_SUCCESS(error);
    TEST_ASSERT_NOT_NULL(valid_item_names.pp_strings);
    TEST_ASSERT_EQUAL(
        valid_items.length,
        valid_item_names.length
    );

    struct pkmn_item_enum_list full_item_list =
    {
        .p_enums = NULL,
        .length = 0
    };
    error = pkmn_database_item_list(
                item_pc.game,
                &full_item_list
            );
    PKMN_TEST_ASSERT_SUCCESS(error);
    TEST_ASSERT_NOT_NULL(full_item_list.p_enums);

    struct pkmn_string_list full_item_name_list =
    {
        .pp_strings = NULL,
        .length = 0
    };
    error = pkmn_database_item_name_list(
                item_pc.game,
                &full_item_name_list
            );
    PKMN_TEST_ASSERT_SUCCESS(error);
    TEST_ASSERT_NOT_NULL(full_item_name_list.pp_strings);

    if(is_game_frlg(game))
    {
        TEST_ASSERT_EQUAL(full_item_list.length-2, valid_items.length);
        TEST_ASSERT_EQUAL(full_item_name_list.length-2, valid_item_names.length);

        TEST_ASSERT_FALSE(string_list_contains(&valid_item_names, "Berry Pouch"));
        TEST_ASSERT_FALSE(string_list_contains(&valid_item_names, "TM Case"));
    }
    else
    {
        TEST_ASSERT_EQUAL(full_item_list.length, valid_items.length);
        TEST_ASSERT_EQUAL(full_item_name_list.length, valid_item_names.length);
    }

    error = pkmn_item_enum_list_free(&valid_items);
    PKMN_TEST_ASSERT_SUCCESS(error);
    error = pkmn_string_list_free(&valid_item_names);
    PKMN_TEST_ASSERT_SUCCESS(error);

    error = pkmn_item_enum_list_free(&full_item_list);
    PKMN_TEST_ASSERT_SUCCESS(error);
    error = pkmn_string_list_free(&full_item_name_list);
    PKMN_TEST_ASSERT_SUCCESS(error);

    error = pkmn_item_list_free(&item_pc);
    PKMN_TEST_ASSERT_SUCCESS(error);
    TEST_ASSERT_NULL(item_pc.p_internal);
}

static void get_bag_pockets(
    struct pkmn_item_bag* p_item_bag,
    struct pkmn_item_list* p_item_pocket_out,
    struct pkmn_item_list* p_key_item_pocket_out,
    struct pkmn_item_list* p_ball_pocket_out,
    struct pkmn_item_list* p_tmhm_pocket_out,
    const char* tmhm_pocket_name,
    struct pkmn_item_list* p_berry_pocket_out,
    const char* berry_pocket_name
)
{
    TEST_ASSERT_NOT_NULL(p_item_bag);
    TEST_ASSERT_NOT_NULL(p_item_pocket_out);
    TEST_ASSERT_NOT_NULL(p_key_item_pocket_out);
    TEST_ASSERT_NOT_NULL(p_ball_pocket_out);
    TEST_ASSERT_NOT_NULL(p_tmhm_pocket_out);
    TEST_ASSERT_NOT_NULL(tmhm_pocket_name);
    TEST_ASSERT_NOT_NULL(p_berry_pocket_out);
    TEST_ASSERT_NOT_NULL(berry_pocket_name);

    enum pkmn_error error = PKMN_ERROR_NONE;

    error = pkmn_item_bag_get_pocket(
                p_item_bag,
                "Items",
                p_item_pocket_out
            );
    PKMN_TEST_ASSERT_SUCCESS(error);

    error = pkmn_item_bag_get_pocket(
                p_item_bag,
                "Key Items",
                p_key_item_pocket_out
            );
    PKMN_TEST_ASSERT_SUCCESS(error);

    error = pkmn_item_bag_get_pocket(
                p_item_bag,
                "Poké Balls",
                p_ball_pocket_out
            );
    PKMN_TEST_ASSERT_SUCCESS(error);

    error = pkmn_item_bag_get_pocket(
                p_item_bag,
                tmhm_pocket_name,
                p_tmhm_pocket_out
            );
    PKMN_TEST_ASSERT_SUCCESS(error);

    error = pkmn_item_bag_get_pocket(
                p_item_bag,
                berry_pocket_name,
                p_berry_pocket_out
            );
    PKMN_TEST_ASSERT_SUCCESS(error);
}

static void gba_item_bag_test(enum pkmn_game game)
{
    enum pkmn_error error = PKMN_ERROR_NONE;

    struct pkmn_item_bag item_bag =
    {
        .game = PKMN_GAME_NONE,
        .pocket_names =
        {
            .pp_strings = NULL,
            .length = 0
        },
        .p_internal = NULL
    };

    error = pkmn_item_bag_init(
                game,
                &item_bag
            );
    PKMN_TEST_ASSERT_SUCCESS(error);
    TEST_ASSERT_NOT_NULL(item_bag.p_internal);

    TEST_ASSERT_EQUAL_STRING(
        "None",
        pkmn_item_bag_strerror(&item_bag)
    );

    TEST_ASSERT_NOT_NULL(item_bag.pocket_names.pp_strings);
    TEST_ASSERT_EQUAL(5, item_bag.pocket_names.length);

    test_item_bag_pocket_names(&item_bag);

    const char* tmhm_pocket_name = NULL;
    const char* berry_pocket_name = NULL;
    if(is_game_frlg(game))
    {
        tmhm_pocket_name = "TM Case";
        berry_pocket_name = "Berry Pouch";
    }
    else
    {
        tmhm_pocket_name = "TMs & HMs";
        berry_pocket_name = "Berries";
    }

    struct pkmn_item_list item_pocket;
    struct pkmn_item_list key_item_pocket;
    struct pkmn_item_list ball_pocket;
    struct pkmn_item_list tmhm_pocket;
    struct pkmn_item_list berry_pocket;

    get_bag_pockets(
        &item_bag,
        &item_pocket,
        &key_item_pocket,
        &ball_pocket,
        &tmhm_pocket,
        tmhm_pocket_name,
        &berry_pocket,
        berry_pocket_name
    );
    TEST_ASSERT_NOT_NULL(item_pocket.p_internal);
    TEST_ASSERT_NOT_NULL(key_item_pocket.p_internal);
    TEST_ASSERT_NOT_NULL(ball_pocket.p_internal);
    TEST_ASSERT_NOT_NULL(tmhm_pocket.p_internal);
    TEST_ASSERT_NOT_NULL(berry_pocket.p_internal);

    gba_item_pocket_test(&item_pocket, game);
    gba_key_item_pocket_test(&key_item_pocket, game);
    gba_ball_pocket_test(&ball_pocket, game);
    gba_tmhm_pocket_test(&tmhm_pocket, game);
    gba_berry_pocket_test(&berry_pocket, game);

    // Make sure adding items through the bag adds to the proper pockets.
    check_num_items(&item_pocket, 0);
    check_num_items(&key_item_pocket, 0);
    check_num_items(&ball_pocket, 0);
    check_num_items(&tmhm_pocket, 0);
    check_num_items(&berry_pocket, 0);
    for(size_t item_index = 0; item_index < 8; ++item_index)
    {
        pkmn_item_bag_add(
            &item_bag,
            ALL_POCKET_ITEMS[item_index],
            5
        );
        PKMN_TEST_ASSERT_SUCCESS(error);
    }

    check_item_at_index(&item_pocket, 0, PKMN_ITEM_POTION, 5);
    check_item_at_index(&item_pocket, 1, PKMN_ITEM_NONE, 0);

    check_item_at_index(&key_item_pocket, 0, PKMN_ITEM_MACH_BIKE, 5);
    check_item_at_index(&key_item_pocket, 1, PKMN_ITEM_WAILMER_PAIL, 5);
    check_item_at_index(&key_item_pocket, 2, PKMN_ITEM_NONE, 0);

    check_item_at_index(&ball_pocket, 0, PKMN_ITEM_GREAT_BALL, 5);
    check_item_at_index(&ball_pocket, 1, PKMN_ITEM_MASTER_BALL, 5);
    check_item_at_index(&ball_pocket, 2, PKMN_ITEM_NONE, 0);

    check_item_at_index(&tmhm_pocket, 0, PKMN_ITEM_TM01, 5);
    check_item_at_index(&tmhm_pocket, 1, PKMN_ITEM_HM04, 5);
    check_item_at_index(&tmhm_pocket, 2, PKMN_ITEM_NONE, 0);

    check_item_at_index(&berry_pocket, 0, PKMN_ITEM_ASPEAR_BERRY, 5);
    check_item_at_index(&berry_pocket, 1, PKMN_ITEM_NONE, 0);

    // Make sure removing items through the bag removes from the proper pockets.
    for(size_t item_index = 0; item_index < 8; ++item_index)
    {
        pkmn_item_bag_remove(
            &item_bag,
            ALL_POCKET_ITEMS[item_index],
            5
        );
        PKMN_TEST_ASSERT_SUCCESS(error);
    }
    check_num_items(&item_pocket, 0);
    check_num_items(&key_item_pocket, 0);
    check_num_items(&ball_pocket, 0);
    check_num_items(&tmhm_pocket, 0);
    check_num_items(&berry_pocket, 0);

    check_item_at_index(&item_pocket, 0, PKMN_ITEM_NONE, 0);
    check_item_at_index(&item_pocket, 1, PKMN_ITEM_NONE, 0);

    check_item_at_index(&key_item_pocket, 0, PKMN_ITEM_NONE, 0);
    check_item_at_index(&key_item_pocket, 1, PKMN_ITEM_NONE, 0);
    check_item_at_index(&key_item_pocket, 2, PKMN_ITEM_NONE, 0);

    check_item_at_index(&ball_pocket, 0, PKMN_ITEM_NONE, 0);
    check_item_at_index(&ball_pocket, 1, PKMN_ITEM_NONE, 0);
    check_item_at_index(&ball_pocket, 2, PKMN_ITEM_NONE, 0);

    check_item_at_index(&tmhm_pocket, 0, PKMN_ITEM_NONE, 0);
    check_item_at_index(&tmhm_pocket, 1, PKMN_ITEM_NONE, 0);
    check_item_at_index(&tmhm_pocket, 2, PKMN_ITEM_NONE, 0);

    check_item_at_index(&berry_pocket, 0, PKMN_ITEM_NONE, 0);
    check_item_at_index(&berry_pocket, 1, PKMN_ITEM_NONE, 0);

    // Make sure we can't add items from later generations.
    test_item_bag_invalid_items(
        &item_bag,
        WRONG_GAME_ALL_POCKET_ITEMS,
        9
    );

    // Free pockets and bag.

    error = pkmn_item_list_free(&item_pocket);
    PKMN_TEST_ASSERT_SUCCESS(error);

    error = pkmn_item_list_free(&key_item_pocket);
    PKMN_TEST_ASSERT_SUCCESS(error);

    error = pkmn_item_list_free(&ball_pocket);
    PKMN_TEST_ASSERT_SUCCESS(error);

    error = pkmn_item_list_free(&tmhm_pocket);
    PKMN_TEST_ASSERT_SUCCESS(error);

    error = pkmn_item_list_free(&berry_pocket);
    PKMN_TEST_ASSERT_SUCCESS(error);

    error = pkmn_item_bag_free(&item_bag);
    PKMN_TEST_ASSERT_SUCCESS(error);
}

#define GBA_ITEM_TESTS(test_game_enum, test_game) \
void test_gba_item_pocket_ ## test_game () \
{ \
    enum pkmn_error error = PKMN_ERROR_NONE; \
 \
    struct pkmn_item_list item_pocket = \
    { \
        .p_name = NULL, \
        .game = PKMN_GAME_NONE, \
        .capacity = 0, \
        .p_internal = NULL \
    }; \
 \
    error = pkmn_item_list_init( \
                "Items", \
                test_game_enum, \
                &item_pocket \
            ); \
    PKMN_TEST_ASSERT_SUCCESS(error); \
    TEST_ASSERT_NOT_NULL(item_pocket.p_internal); \
 \
    gba_item_pocket_test( \
        &item_pocket, \
        test_game_enum \
    ); \
 \
    error = pkmn_item_list_free(&item_pocket); \
    PKMN_TEST_ASSERT_SUCCESS(error); \
    TEST_ASSERT_NULL(item_pocket.p_internal); \
} \
void test_gba_key_item_pocket_ ## test_game () \
{ \
    enum pkmn_error error = PKMN_ERROR_NONE; \
 \
    struct pkmn_item_list key_item_pocket = \
    { \
        .p_name = NULL, \
        .game = PKMN_GAME_NONE, \
        .capacity = 0, \
        .p_internal = NULL \
    }; \
 \
    error = pkmn_item_list_init( \
                "Key Items", \
                test_game_enum, \
                &key_item_pocket \
            ); \
    PKMN_TEST_ASSERT_SUCCESS(error); \
    TEST_ASSERT_NOT_NULL(key_item_pocket.p_internal); \
 \
    gba_key_item_pocket_test( \
        &key_item_pocket, \
        test_game_enum \
    ); \
 \
    error = pkmn_item_list_free(&key_item_pocket); \
    PKMN_TEST_ASSERT_SUCCESS(error); \
    TEST_ASSERT_NULL(key_item_pocket.p_internal); \
} \
void test_gba_ball_pocket_ ## test_game () \
{ \
    enum pkmn_error error = PKMN_ERROR_NONE; \
 \
    struct pkmn_item_list ball_pocket = \
    { \
        .p_name = NULL, \
        .game = PKMN_GAME_NONE, \
        .capacity = 0, \
        .p_internal = NULL \
    }; \
 \
    error = pkmn_item_list_init( \
                "Poké Balls", \
                test_game_enum, \
                &ball_pocket \
            ); \
    PKMN_TEST_ASSERT_SUCCESS(error); \
    TEST_ASSERT_NOT_NULL(ball_pocket.p_internal); \
 \
    gba_ball_pocket_test( \
        &ball_pocket, \
        test_game_enum \
    ); \
 \
    error = pkmn_item_list_free(&ball_pocket); \
    PKMN_TEST_ASSERT_SUCCESS(error); \
    TEST_ASSERT_NULL(ball_pocket.p_internal); \
} \
void test_gba_tmhm_pocket_ ## test_game () \
{ \
    enum pkmn_error error = PKMN_ERROR_NONE; \
 \
    struct pkmn_item_list tmhm_pocket = \
    { \
        .p_name = NULL, \
        .game = PKMN_GAME_NONE, \
        .capacity = 0, \
        .p_internal = NULL \
    }; \
 \
    const char* pocket_name = NULL; \
    if(is_game_frlg(test_game_enum)) \
    { \
        pocket_name = "TM Case"; \
    } \
    else \
    { \
        pocket_name = "TMs & HMs"; \
    } \
 \
    error = pkmn_item_list_init( \
                pocket_name, \
                test_game_enum, \
                &tmhm_pocket \
            ); \
    PKMN_TEST_ASSERT_SUCCESS(error); \
    TEST_ASSERT_NOT_NULL(tmhm_pocket.p_internal); \
 \
    gba_tmhm_pocket_test( \
        &tmhm_pocket, \
        test_game_enum \
    ); \
 \
    error = pkmn_item_list_free(&tmhm_pocket); \
    PKMN_TEST_ASSERT_SUCCESS(error); \
    TEST_ASSERT_NULL(tmhm_pocket.p_internal); \
} \
void test_gba_berry_pocket_ ## test_game () \
{ \
    enum pkmn_error error = PKMN_ERROR_NONE; \
 \
    struct pkmn_item_list berry_pocket = \
    { \
        .p_name = NULL, \
        .game = PKMN_GAME_NONE, \
        .capacity = 0, \
        .p_internal = NULL \
    }; \
 \
    const char* pocket_name = NULL; \
    if(is_game_frlg(test_game_enum)) \
    { \
        pocket_name = "Berry Pouch"; \
    } \
    else \
    { \
        pocket_name = "Berries"; \
    } \
 \
    error = pkmn_item_list_init( \
                pocket_name, \
                test_game_enum, \
                &berry_pocket \
            ); \
    PKMN_TEST_ASSERT_SUCCESS(error); \
    TEST_ASSERT_NOT_NULL(berry_pocket.p_internal); \
 \
    gba_berry_pocket_test( \
        &berry_pocket, \
        test_game_enum \
    ); \
 \
    error = pkmn_item_list_free(&berry_pocket); \
    PKMN_TEST_ASSERT_SUCCESS(error); \
    TEST_ASSERT_NULL(berry_pocket.p_internal); \
} \
void test_gba_item_pc_ ## test_game () \
{ \
    gba_item_pc_test(test_game_enum); \
} \
void test_gba_item_bag_ ## test_game () \
{ \
    gba_item_bag_test(test_game_enum); \
}

GBA_ITEM_TESTS(PKMN_GAME_RUBY, Ruby)
GBA_ITEM_TESTS(PKMN_GAME_SAPPHIRE, Sapphire)
GBA_ITEM_TESTS(PKMN_GAME_EMERALD, Emerald)
GBA_ITEM_TESTS(PKMN_GAME_FIRERED, FireRed)
GBA_ITEM_TESTS(PKMN_GAME_LEAFGREEN, LeafGreen)
Exemple #17
0
void testTrue(void)
{
    TEST_ASSERT(1);

    TEST_ASSERT_TRUE(1);
}
void test_KineticOperation_BuildPut_should_build_and_execute_a_PUT_operation_to_create_a_new_object(void)
{
    LOG_LOCATION;
    ByteArray value = ByteArray_CreateWithCString("Luke, I am your father");
    ByteArray key = ByteArray_CreateWithCString("foobar");
    ByteArray newVersion = ByteArray_CreateWithCString("v1.0");
    ByteArray tag = ByteArray_CreateWithCString("some_tag");

    KineticConnection_IncrementSequence_Expect(&Connection);

    // PUT
    // The PUT operation sets the value and metadata for a given key. If a value
    // already exists in the store for the given key, the client must pass a
    // value for dbVersion which matches the stored version for this key to
    // overwrite the value metadata. This behavior can be overridden (so that
    // the version is ignored and the value and metadata are always written) by
    // setting forced to true in the KeyValue option.
    //
    // Request Message:
    //
    // command {
    //   // See top level cross cutting concerns for header details
    //   header {
    //     clusterVersion: ...
    //     identity: ...
    //     connectionID: ...
    //     sequence: ...
    //     messageType: PUT
    //   }
    //   body: {
    //     keyValue {
    //       // Required bytes
    //       // The key for the value being set
    //       key: "..."
    //
    //       // Required bytes
    //       // Versions are set on objects to support optimistic locking.
    //       // For operations that modify data, if the dbVersion sent in the
    //       // request message does not match the version stored in the db, the
    //       // request will fail.
    //       dbVersion: "..."
    //
    //       // Required bytes
    //       // Specifies what the next version of the data will be if this
    //       // operation is successful.
    //       newVersion: "..."
    //
    //       // Optional bool, default false
    //       // Setting force to true ignores potential version mismatches
    //       // and carries out the operation.
    //       force: true
    //
    //       // Optional bytes
    //       // The integrity value for the data. This value should be computed
    //       // by the client application by applying the hash algorithm
    //       // specified below to the value (and only to the value).
    //       // The algorithm used should be specified in the algorithm field.
    //       // The Kinetic Device will not do any processing on this value.
    //       tag: "..."
    //
    //       // Optional enum
    //       // The algorithm used by the client to compute the tag.
    //       // The allowed values are: SHA1, SHA2, SHA3, CRC32, CRC64
    //       algorithm: ...
    //
    //       // Optional Synchronization enum value, defaults to WRITETHROUGH
    //       // Allows client to specify if the data must be written to disk
    //       // immediately, or can be written in the future.
    //       //
    //       // WRITETHROUGH:  This request is made persistent before returning.
    //       //                This does not effect any other pending operations.
    //       // WRITEBACK:     They can be made persistent when the drive chooses,
    //       //            or when a subsequent FLUSH is give to the drive.
    //       // FLUSH:     All pending information that has not been written is
    //       //        pushed to the disk and the command that specifies
    //       //        FLUSH is written last and then returned. All WRITEBACK writes
    //       //        that have received ending status will be guaranteed to be
    //       //        written before the FLUSH operation is returned completed.
    //       synchronization: ...
    //     }
    KineticEntry entry = {
        .key = ByteBuffer_CreateWithArray(key),
        .newVersion = ByteBuffer_CreateWithArray(newVersion),
        // .dbVersion = ByteBuffer_CreateWithArray(BYTE_ARRAY_NONE),
        .tag = ByteBuffer_CreateWithArray(tag),
        .algorithm = KINETIC_ALGORITHM_SHA1,
        .value = ByteBuffer_CreateWithArray(value),
    };
    KineticMessage_ConfigureKeyValue_Expect(&Operation.request->protoData.message, &entry);
    //   }
    // }
    // hmac: "..."
    //

    // Build the operation
    KineticOperation_BuildPut(&Operation, &entry);

    // Ensure proper message type
    TEST_ASSERT_TRUE(Request.proto->command->header->has_messageType);
    TEST_ASSERT_EQUAL(KINETIC_PROTO_MESSAGE_TYPE_PUT, Request.proto->command->header->messageType);

    TEST_ASSERT_EQUAL_ByteArray(value, Operation.request->entry.value.array);
    TEST_ASSERT_EQUAL(0, Operation.request->entry.value.bytesUsed);
    TEST_ASSERT_ByteBuffer_NULL(Response.entry.value);
}
void test_turn_of_the_21st_century(void)
{
    TEST_ASSERT_TRUE(is_leap_year(2000));
}
void test_KineticOperation_BuildGet_should_build_a_GET_operation(void)
{
    LOG_LOCATION;
    const ByteArray key = ByteArray_CreateWithCString("foobar");
    ByteArray value = {.data = ValueData, .len = sizeof(ValueData)};
    KineticEntry entry = {
        .key = ByteBuffer_CreateWithArray(key),
        .value = ByteBuffer_CreateWithArray(value),
    };

    KineticConnection_IncrementSequence_Expect(&Connection);
    KineticMessage_ConfigureKeyValue_Expect(&Request.protoData.message, &entry);

    KineticOperation_BuildGet(&Operation, &entry);

    // GET
    // The GET operation is used to retrieve the value and metadata for a given key.
    //
    // Request Message:
    // command {
    //   header {
    //     // See above for descriptions of these fields
    //     clusterVersion: ...
    //     identity: ...
    //     connectionID: ...
    //     sequence: ...
    //
    //     // The mesageType should be GET
    //     messageType: GET
    TEST_ASSERT_TRUE(Request.proto->command->header->has_messageType);
    TEST_ASSERT_EQUAL(KINETIC_PROTO_MESSAGE_TYPE_GET, Request.proto->command->header->messageType);
    //   }
    //   body {
    //     keyValue {
    //       // See above
    //       key: "..."
    //     }
    //   }
    // }
    // // See above
    // hmac: "..."

    TEST_ASSERT_ByteBuffer_NULL(Request.entry.value);
    TEST_ASSERT_EQUAL_ByteArray(value, Operation.response->entry.value.array);
    TEST_ASSERT_EQUAL(0, Operation.response->entry.value.bytesUsed);
}

void test_KineticOperation_BuildGet_should_build_a_GET_operation_requesting_metadata_only(void)
{
    LOG_LOCATION;
    const ByteArray key = ByteArray_CreateWithCString("foobar");
    ByteArray value = ByteArray_Create(ValueData, sizeof(ValueData));
    KineticEntry entry = {
        .key = ByteBuffer_CreateWithArray(key),
        .metadataOnly = true,
        .value = ByteBuffer_CreateWithArray(value),
    };

    KineticConnection_IncrementSequence_Expect(&Connection);
    KineticMessage_ConfigureKeyValue_Expect(&Request.protoData.message, &entry);

    KineticOperation_BuildGet(&Operation, &entry);

    // GET
    // The GET operation is used to retrieve the value and metadata for a given key.
    //
    // Request Message:
    // command {
    //   header {
    //     // See above for descriptions of these fields
    //     clusterVersion: ...
    //     identity: ...
    //     connectionID: ...
    //     sequence: ...
    //
    //     // The mesageType should be GET
    //     messageType: GET
    TEST_ASSERT_TRUE(Request.proto->command->header->has_messageType);
    TEST_ASSERT_EQUAL(KINETIC_PROTO_MESSAGE_TYPE_GET, Request.proto->command->header->messageType);
    //   }
    //   body {
    //     keyValue {
    //       // See above
    //       key: "..."
    //     }
    //   }
    // }
    // // See above
    // hmac: "..."

    TEST_ASSERT_ByteBuffer_NULL(Request.entry.value);
    TEST_ASSERT_ByteBuffer_NULL(Response.entry.value);
}


void test_KineticOperation_BuildDelete_should_build_a_DELETE_operation(void)
{
    LOG_LOCATION;
    const ByteArray key = ByteArray_CreateWithCString("foobar");
    KineticEntry entry = {.key = ByteBuffer_CreateWithArray(key)};

    KineticConnection_IncrementSequence_Expect(&Connection);
    KineticMessage_ConfigureKeyValue_Expect(&Request.protoData.message, &entry);

    KineticOperation_BuildDelete(&Operation, &entry);

    // The `DELETE` operation removes the entry for a given key. It respects the
    // same locking behavior around `dbVersion` and `force` as described in the previous sections.
    // The following request will remove a key value pair to the store.
    //
    // ```
    // command {
    //   // See top level cross cutting concerns for header details
    //   header {
    //     clusterVersion: ...
    //     identity: ...
    //     connectionID: ...
    //     sequence: ...
    //     // messageType should be DELETE
    //     messageType: DELETE
    TEST_ASSERT_TRUE(Request.proto->command->header->has_messageType);
    TEST_ASSERT_EQUAL(KINETIC_PROTO_MESSAGE_TYPE_DELETE, Request.proto->command->header->messageType);
    //   }
    //   body {
    //     keyValue {
    //       key: "..."
    //       // See write operation cross cutting concerns
    //       synchronization: ...
    //     }
    //   }
    // }
    // hmac: "..."

    TEST_ASSERT_ByteBuffer_NULL(Request.entry.value);
    TEST_ASSERT_ByteBuffer_NULL(Response.entry.value);
}
void test_a_known_leap_year(void)
{
    TEST_ASSERT_TRUE(is_leap_year(1996));
}
Exemple #22
0
void test_Bus_SendRequest_should_reject_bad_arguments(void)
{
    struct bus b = {
        .log_level = 0,
    };
    TEST_ASSERT_FALSE(Bus_SendRequest(NULL, NULL));
    TEST_ASSERT_FALSE(Bus_SendRequest(&b, NULL));

    bus_user_msg msg = {
        .fd = -1,
    };
    TEST_ASSERT_FALSE(Bus_SendRequest(&b, &msg));
}

void test_Bus_SendRequest_should_return_false_if_allocation_fails(void)
{
    test_box = NULL;  // simulate allocation fail
    struct bus b = {
        .log_level = 0,
    };
    bus_user_msg msg = {
        .fd = 123,
    };
    TEST_ASSERT_FALSE(Bus_SendRequest(&b, &msg));
}

void test_Bus_SendRequest_should_reject_send_on_unregistered_socket(void)
{
    struct bus b = {
        .log_level = 0,
    };
    bus_user_msg msg = {
        .fd = 123,
    };
    test_box = calloc(1, sizeof(*test_box));
    TEST_ASSERT(test_box);
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));

    struct yacht fake_yacht = { .size = 0, };

    b.fd_set = &fake_yacht;
    TEST_ASSERT(b.fd_set);

    Yacht_Get_ExpectAndReturn(b.fd_set, msg.fd, &value, false);
    TEST_ASSERT_FALSE(Bus_SendRequest(&b, &msg));

    TEST_ASSERT_EQUAL(0, pthread_mutex_destroy(&b.fd_set_lock));
}

void test_Bus_SendRequest_should_reject_equal_sequence_IDs(void)
{
    struct bus b = {
        .log_level = 0,
    };
    bus_user_msg msg = {
        .fd = 123,
        .seq_id = 3,
    };
    test_box = calloc(1, sizeof(*test_box));
    TEST_ASSERT(test_box);
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));

    struct yacht fake_yacht = { .size = 0, };

    b.fd_set = &fake_yacht;
    TEST_ASSERT(b.fd_set);

    connection_info fake_ci = {
        .largest_wr_seq_id_seen = msg.seq_id,
    };
    value = &fake_ci;
    Yacht_Get_ExpectAndReturn(b.fd_set, msg.fd, &value, true);

    TEST_ASSERT_FALSE(Bus_SendRequest(&b, &msg));

    TEST_ASSERT_EQUAL(0, pthread_mutex_destroy(&b.fd_set_lock));
}

void test_Bus_SendRequest_should_reject_lower_sequence_IDs(void)
{
    struct bus b = {
        .log_level = 0,
    };
    bus_user_msg msg = {
        .fd = 123,
        .seq_id = 3,
    };
    test_box = calloc(1, sizeof(*test_box));
    TEST_ASSERT(test_box);
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));

    struct yacht fake_yacht = { .size = 0, };

    b.fd_set = &fake_yacht;
    TEST_ASSERT(b.fd_set);

    connection_info fake_ci = {
        .largest_wr_seq_id_seen = msg.seq_id + 1,
    };
    value = &fake_ci;
    Yacht_Get_ExpectAndReturn(b.fd_set, msg.fd, &value, true);

    TEST_ASSERT_FALSE(Bus_SendRequest(&b, &msg));

    TEST_ASSERT_EQUAL(0, pthread_mutex_destroy(&b.fd_set_lock));
}

void test_Bus_SendRequest_should_expose_callee_send_rejection(void)
{
    struct bus b = {
        .log_level = 0,
    };
    bus_user_msg msg = {
        .fd = 123,
        .seq_id = 3,
    };
    test_box = calloc(1, sizeof(*test_box));
    TEST_ASSERT(test_box);
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));

    struct yacht fake_yacht = { .size = 0, };

    b.fd_set = &fake_yacht;
    TEST_ASSERT(b.fd_set);

    connection_info fake_ci = {
        .largest_wr_seq_id_seen = msg.seq_id - 1,
    };
    value = &fake_ci;
    Yacht_Get_ExpectAndReturn(b.fd_set, msg.fd, &value, true);

    Send_DoBlockingSend_ExpectAndReturn(&b, test_box, false);
    TEST_ASSERT_FALSE(Bus_SendRequest(&b, &msg));

    TEST_ASSERT_EQUAL(0, pthread_mutex_destroy(&b.fd_set_lock));
}

void test_Bus_SendRequest_should_return_true_on_successful_delivery_queueing(void)
{
    struct bus b = {
        .log_level = 0,
    };
    bus_user_msg msg = {
        .fd = 123,
        .seq_id = 3,
    };
    test_box = calloc(1, sizeof(*test_box));
    TEST_ASSERT(test_box);
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));

    struct yacht fake_yacht = { .size = 0, };

    b.fd_set = &fake_yacht;
    TEST_ASSERT(b.fd_set);

    connection_info fake_ci = {
        .largest_wr_seq_id_seen = msg.seq_id - 1,
    };
    value = &fake_ci;
    Yacht_Get_ExpectAndReturn(b.fd_set, msg.fd, &value, true);

    Send_DoBlockingSend_ExpectAndReturn(&b, test_box, true);
    TEST_ASSERT_TRUE(Bus_SendRequest(&b, &msg));

    TEST_ASSERT_EQUAL(0, pthread_mutex_destroy(&b.fd_set_lock));
}

void test_Bus_RegisterSocket_should_expose_memory_failures(void)
{
    struct listener fake_listener;
    struct listener *listeners[] = {
        &fake_listener,
    };
    struct bus b = {
        .listener_count = 1,
        .listeners = listeners,
    };
    fake_listener.bus = &b;

    TEST_ASSERT_FALSE(Bus_RegisterSocket(&b, BUS_SOCKET_PLAIN, 4, NULL));
}

void test_Bus_RegisterSocket_should_expose_SSL_connection_failure(void)
{
    struct listener fake_listener;
    struct listener *listeners[] = {
        &fake_listener,
    };
    struct bus b = {
        .listener_count = 1,
        .listeners = listeners,
    };
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));
    fake_listener.bus = &b;
    test_ci = calloc(1, sizeof(*test_ci));

    BusSSL_Connect_ExpectAndReturn(&b, 35, NULL);
    TEST_ASSERT_FALSE(Bus_RegisterSocket(&b, BUS_SOCKET_SSL, 35, NULL));
    TEST_ASSERT_EQUAL(0, pthread_mutex_destroy(&b.fd_set_lock));
}

void test_Bus_RegisterSocket_should_expose_hash_table_failure(void)
{
    struct listener fake_listener;
    struct listener *listeners[] = {
        &fake_listener,
    };
    struct bus b = {
        .listener_count = 1,
        .listeners = listeners,
    };
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));
    fake_listener.bus = &b;
    test_ci = calloc(1, sizeof(*test_ci));

    struct yacht fake_yacht = { .size = 0, };
    b.fd_set = &fake_yacht;
    Yacht_Set_ExpectAndReturn(b.fd_set, 35, test_ci, &old_value, false);
    TEST_ASSERT_FALSE(Bus_RegisterSocket(&b, BUS_SOCKET_PLAIN, 35, NULL));
}

void test_Bus_RegisterSocket_should_expose_Listener_AddSocket_failure(void)
{
    struct listener fake_listener;
    struct listener *listeners[] = {
        &fake_listener,
    };
    struct bus b = {
        .listener_count = 1,
        .listeners = listeners,
    };
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));
    fake_listener.bus = &b;
    test_ci = calloc(1, sizeof(*test_ci));

    struct yacht fake_yacht = { .size = 0, };
    b.fd_set = &fake_yacht;
    Yacht_Set_ExpectAndReturn(b.fd_set, 35, test_ci, &old_value, true);
    Listener_AddSocket_ExpectAndReturn(&fake_listener, test_ci, &completion_pipe, false);
    
    TEST_ASSERT_FALSE(Bus_RegisterSocket(&b, BUS_SOCKET_PLAIN, 35, NULL));
}

void test_Bus_RegisterSocket_should_expose_poll_error(void)
{
    struct listener fake_listener;
    struct listener *listeners[] = {
        &fake_listener,
    };
    struct bus b = {
        .listener_count = 1,
        .listeners = listeners,
    };
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));
    fake_listener.bus = &b;
    test_ci = calloc(1, sizeof(*test_ci));

    struct yacht fake_yacht = { .size = 0, };
    b.fd_set = &fake_yacht;
    Yacht_Set_ExpectAndReturn(b.fd_set, 35, test_ci, &old_value, true);
    Listener_AddSocket_ExpectAndReturn(&fake_listener, test_ci, &completion_pipe, true);
    completion_pipe = 123;
    BusPoll_OnCompletion_ExpectAndReturn(&b, 123, false);

    TEST_ASSERT_FALSE(Bus_RegisterSocket(&b, BUS_SOCKET_PLAIN, 35, NULL));
}

void test_Bus_RegisterSocket_should_successfully_add_plain_socket(void)
{
    struct listener fake_listener;
    struct listener *listeners[] = {
        &fake_listener,
    };
    struct bus b = {
        .listener_count = 1,
        .listeners = listeners,
    };
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));
    fake_listener.bus = &b;
    test_ci = calloc(1, sizeof(*test_ci));

    struct yacht fake_yacht = { .size = 0, };
    b.fd_set = &fake_yacht;
    Yacht_Set_ExpectAndReturn(b.fd_set, 35, test_ci, &old_value, true);
    Listener_AddSocket_ExpectAndReturn(&fake_listener, test_ci, &completion_pipe, true);
    completion_pipe = 123;
    BusPoll_OnCompletion_ExpectAndReturn(&b, 123, true);

    TEST_ASSERT_TRUE(Bus_RegisterSocket(&b, BUS_SOCKET_PLAIN, 35, NULL));
    TEST_ASSERT_EQUAL(35, test_ci->fd);
}

void test_Bus_RegisterSocket_should_successfully_add_SSL_socket(void)
{
    struct listener fake_listener;
    struct listener *listeners[] = {
        &fake_listener,
    };
    struct bus b = {
        .listener_count = 1,
        .listeners = listeners,
    };
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));
    fake_listener.bus = &b;
    test_ci = calloc(1, sizeof(*test_ci));

    SSL fake_ssl;
    BusSSL_Connect_ExpectAndReturn(&b, 35, &fake_ssl);

    struct yacht fake_yacht = { .size = 0, };
    b.fd_set = &fake_yacht;
    Yacht_Set_ExpectAndReturn(b.fd_set, 35, test_ci, &old_value, true);
    Listener_AddSocket_ExpectAndReturn(&fake_listener, test_ci, &completion_pipe, true);
    completion_pipe = 123;
    BusPoll_OnCompletion_ExpectAndReturn(&b, 123, true);

    TEST_ASSERT_TRUE(Bus_RegisterSocket(&b, BUS_SOCKET_SSL, 35, NULL));
    TEST_ASSERT_EQUAL(&fake_ssl, test_ci->ssl);
}

void test_Bus_ReleaseSocket_should_expose_Listener_RemoveSocket_failure(void)
{
    struct listener fake_listener;
    struct listener *listeners[] = {
        &fake_listener,
    };
    struct bus b = {
        .listener_count = 1,
        .listeners = listeners,
    };
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));
    fake_listener.bus = &b;

    int fd = 3;
    Listener_RemoveSocket_ExpectAndReturn(&fake_listener, fd, &completion_pipe, false);

    void *old_udata = NULL;
    TEST_ASSERT_FALSE(Bus_ReleaseSocket(&b, fd, &old_udata));
}

void test_Bus_ReleaseSocket_should_expose_poll_IO_error(void)
{
    struct listener fake_listener;
    struct listener *listeners[] = {
        &fake_listener,
    };
    struct bus b = {
        .listener_count = 1,
        .listeners = listeners,
    };
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));
    fake_listener.bus = &b;

    int fd = 3;
    completion_pipe = 123;
    Listener_RemoveSocket_ExpectAndReturn(&fake_listener, fd, &completion_pipe, true);
    BusPoll_OnCompletion_ExpectAndReturn(&b, completion_pipe, false);

    void *old_udata = NULL;
    TEST_ASSERT_FALSE(Bus_ReleaseSocket(&b, fd, &old_udata));
}

void test_Bus_ReleaseSocket_should_expose_hash_table_error(void)
{
    struct listener fake_listener;
    struct listener *listeners[] = {
        &fake_listener,
    };
    struct bus b = {
        .listener_count = 1,
        .listeners = listeners,
    };
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));
    fake_listener.bus = &b;

    int fd = 3;
    completion_pipe = 155;
    Listener_RemoveSocket_ExpectAndReturn(&fake_listener, fd, &completion_pipe, true);
    BusPoll_OnCompletion_ExpectAndReturn(&b, completion_pipe, true);

    struct yacht fake_yacht = { .size = 0, };
    b.fd_set = &fake_yacht;
    Yacht_Remove_ExpectAndReturn(b.fd_set, fd, &old_value, false);

    void *old_udata = NULL;
    TEST_ASSERT_FALSE(Bus_ReleaseSocket(&b, fd, &old_udata));
}

void test_Bus_ReleaseSocket_should_expose_SSL_disconnection_failure(void)
{
    struct listener fake_listener;
    struct listener *listeners[] = {
        &fake_listener,
    };
    struct bus b = {
        .listener_count = 1,
        .listeners = listeners,
    };
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));
    fake_listener.bus = &b;

    int fd = 3;
    completion_pipe = 155;
    Listener_RemoveSocket_ExpectAndReturn(&fake_listener, fd, &completion_pipe, true);
    BusPoll_OnCompletion_ExpectAndReturn(&b, completion_pipe, true);

    struct yacht fake_yacht = { .size = 0, };
    b.fd_set = &fake_yacht;
    Yacht_Remove_ExpectAndReturn(b.fd_set, fd, &old_value, true);

    SSL fake_ssl;
    test_ci = calloc(1, sizeof(connection_info));
    old_value = test_ci;
    test_ci->ssl = &fake_ssl;

    BusSSL_Disconnect_ExpectAndReturn(&b, test_ci->ssl, false);

    void *old_udata = NULL;
    TEST_ASSERT_FALSE(Bus_ReleaseSocket(&b, fd, &old_udata));
}

void test_Bus_ReleaseSocket_should_return_true_on_successful_socket_disconnection(void)
{
    struct listener fake_listener;
    struct listener *listeners[] = {
        &fake_listener,
    };
    struct bus b = {
        .listener_count = 1,
        .listeners = listeners,
    };
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));
    fake_listener.bus = &b;

    int fd = 3;
    completion_pipe = 155;
    Listener_RemoveSocket_ExpectAndReturn(&fake_listener, fd, &completion_pipe, true);
    BusPoll_OnCompletion_ExpectAndReturn(&b, completion_pipe, true);

    test_ci = calloc(1, sizeof(connection_info));
    old_value = test_ci;
    test_ci->ssl = BUS_NO_SSL;

    struct yacht fake_yacht = { .size = 0, };
    b.fd_set = &fake_yacht;
    Yacht_Remove_ExpectAndReturn(b.fd_set, fd, &old_value, true);

    void *old_udata = NULL;
    TEST_ASSERT_TRUE(Bus_ReleaseSocket(&b, fd, &old_udata));
}

void test_Bus_ReleaseSocket_should_return_true_on_successful_SSL_socket_disconnection(void)
{
    struct listener fake_listener;
    struct listener fake_listener2;
    struct listener *listeners[] = {
        &fake_listener,
        &fake_listener2,
    };
    struct bus b = {
        .listener_count = 2,
        .listeners = listeners,
    };
    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b.fd_set_lock, NULL));
    fake_listener.bus = &b;

    int fd = 3;
    completion_pipe = 155;
    Listener_RemoveSocket_ExpectAndReturn(&fake_listener2, fd, &completion_pipe, true);
    BusPoll_OnCompletion_ExpectAndReturn(&b, completion_pipe, true);

    struct yacht fake_yacht = { .size = 0, };
    b.fd_set = &fake_yacht;
    Yacht_Remove_ExpectAndReturn(b.fd_set, fd, &old_value, true);

    SSL fake_ssl;
    test_ci = calloc(1, sizeof(connection_info));
    old_value = test_ci;
    test_ci->ssl = &fake_ssl;

    BusSSL_Disconnect_ExpectAndReturn(&b, test_ci->ssl, true);

    void *old_udata = NULL;
    TEST_ASSERT_TRUE(Bus_ReleaseSocket(&b, fd, &old_udata));
}

void test_Bus_Shutdown_should_be_idempotent(void)
{
    struct bus b = {
        .shutdown_state = SHUTDOWN_STATE_SHUTTING_DOWN,
    };
    TEST_ASSERT_FALSE(Bus_Shutdown(&b));

    b.shutdown_state = SHUTDOWN_STATE_HALTED;
    TEST_ASSERT_FALSE(Bus_Shutdown(&b));
}

void test_Bus_Shutdown_should_expose_listener_shut_down_failure(void)
{
    struct listener fake_listener;
    struct listener fake_listener2;
    struct listener *listeners[] = {
        &fake_listener,
        &fake_listener2,
    };
    bool joined[] = {false, false};
    struct bus b = {
        .shutdown_state = SHUTDOWN_STATE_RUNNING,
        .listener_count = 2,
        .listeners = listeners,
        .joined = joined,
    };

    struct yacht fake_yacht = { .size = 0, };
    b.fd_set = &fake_yacht;
    Yacht_Free_Expect(b.fd_set, free_connection_cb, &b);

    Listener_Shutdown_ExpectAndReturn(b.listeners[0], &completion_pipe, false);

    TEST_ASSERT_FALSE(Bus_Shutdown(&b));
    TEST_ASSERT_EQUAL(SHUTDOWN_STATE_RUNNING, b.shutdown_state);
}

void test_Bus_Shutdown_should_expose_poll_IO_error(void)
{
    struct listener fake_listener;
    struct listener fake_listener2;
    struct listener *listeners[] = {
        &fake_listener,
        &fake_listener2,
    };
    bool joined[] = {false, false};
    struct bus b = {
        .shutdown_state = SHUTDOWN_STATE_RUNNING,
        .listener_count = 2,
        .listeners = listeners,
        .joined = joined,
    };

    struct yacht fake_yacht = { .size = 0, };
    b.fd_set = &fake_yacht;
    Yacht_Free_Expect(b.fd_set, free_connection_cb, &b);

    completion_pipe = 155;
    Listener_Shutdown_ExpectAndReturn(b.listeners[0], &completion_pipe, true);
    BusPoll_OnCompletion_ExpectAndReturn(&b, completion_pipe, false);

    TEST_ASSERT_FALSE(Bus_Shutdown(&b));
    TEST_ASSERT_EQUAL(SHUTDOWN_STATE_RUNNING, b.shutdown_state);
}

void test_Bus_Shutdown_should_expose_pthread_join_failure(void)
{
    struct listener fake_listener;
    struct listener fake_listener2;
    struct listener *listeners[] = {
        &fake_listener,
        &fake_listener2,
    };
    bool joined[] = {false, false};
    pthread_t threads[2];
    struct bus b = {
        .shutdown_state = SHUTDOWN_STATE_RUNNING,
        .listener_count = 2,
        .listeners = listeners,
        .joined = joined,
        .threads = threads,        
    };

    struct yacht fake_yacht = { .size = 0, };
    b.fd_set = &fake_yacht;
    Yacht_Free_Expect(b.fd_set, free_connection_cb, &b);

    completion_pipe = 155;
    Listener_Shutdown_ExpectAndReturn(b.listeners[0], &completion_pipe, true);
    BusPoll_OnCompletion_ExpectAndReturn(&b, completion_pipe, true);
    syscall_pthread_join_ExpectAndReturn(b.threads[0], &unused, -1);

    TEST_ASSERT_FALSE(Bus_Shutdown(&b));
    TEST_ASSERT_EQUAL(SHUTDOWN_STATE_RUNNING, b.shutdown_state);
}

void test_Bus_Shutdown_should_shut_down_internal_resources(void)
{
    struct listener fake_listener;
    struct listener fake_listener2;
    struct listener *listeners[] = {
        &fake_listener,
        &fake_listener2,
    };
    bool joined[] = {false, false};
    pthread_t threads[2];
    struct bus b = {
        .shutdown_state = SHUTDOWN_STATE_RUNNING,
        .listener_count = 2,
        .listeners = listeners,
        .joined = joined,
        .threads = threads,
    };

    struct yacht fake_yacht = { .size = 0, };
    b.fd_set = &fake_yacht;
    Yacht_Free_Expect(b.fd_set, free_connection_cb, &b);

    completion_pipe = 155;
    for (int i = 0; i < 2; i++) {
        Listener_Shutdown_ExpectAndReturn(b.listeners[i], &completion_pipe, true);
        BusPoll_OnCompletion_ExpectAndReturn(&b, completion_pipe, true);
        syscall_pthread_join_ExpectAndReturn(b.threads[i], &unused, 0);
    }

    TEST_ASSERT_TRUE(Bus_Shutdown(&b));
    TEST_ASSERT_EQUAL(SHUTDOWN_STATE_HALTED, b.shutdown_state);
}

void test_Bus_Free_should_call_shutdown_if_not_shut_down(void)
{
    struct listener fake_listener;
    struct listener fake_listener2;

    struct listener **listeners = calloc(2, sizeof(*listeners));
    listeners[0] = &fake_listener;
    listeners[1] = &fake_listener2;

    bool *joined = calloc(2, sizeof(bool));
    pthread_t *threads = calloc(2, sizeof(*threads));
    struct bus *b = calloc(1, sizeof(*b));

    b->shutdown_state = SHUTDOWN_STATE_RUNNING;
    b->listener_count = 2;
    b->listeners = listeners;
    b->joined = joined;
    b->threads = threads;

    struct yacht fake_yacht = { .size = 0, };
    b->fd_set = &fake_yacht;
    Yacht_Free_Expect(b->fd_set, free_connection_cb, b);

    completion_pipe = 155;
    for (int i = 0; i < 2; i++) {
        Listener_Shutdown_ExpectAndReturn(b->listeners[i], &completion_pipe, true);
        BusPoll_OnCompletion_ExpectAndReturn(b, completion_pipe, true);
        syscall_pthread_join_ExpectAndReturn(b->threads[i], &unused, 0);
    }

    struct threadpool fake_threadpool = {
        .max_threads = 8,
    };
    b->threadpool = &fake_threadpool;

    Listener_Free_Expect(b->listeners[0]);
    Listener_Free_Expect(b->listeners[1]);
    Threadpool_Shutdown_ExpectAndReturn(b->threadpool, false, true);
    Threadpool_Free_Expect(b->threadpool);

    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b->fd_set_lock, NULL));
    BusSSL_CtxFree_Expect(b);
    Bus_Free(b);
}

void test_Bus_Free_should_free_bus(void)
{
    struct listener fake_listener;
    struct listener fake_listener2;

    struct listener **listeners = calloc(2, sizeof(*listeners));
    listeners[0] = &fake_listener;
    listeners[1] = &fake_listener2;

    bool *joined = calloc(2, sizeof(bool));
    pthread_t *threads = calloc(2, sizeof(*threads));
    struct bus *b = calloc(1, sizeof(*b));

    b->shutdown_state = SHUTDOWN_STATE_HALTED;
    b->listener_count = 2;
    b->listeners = listeners;
    b->joined = joined;
    b->threads = threads;

    struct threadpool fake_threadpool = {
        .max_threads = 8,
    };
    b->threadpool = &fake_threadpool;

    Listener_Free_Expect(b->listeners[0]);
    Listener_Free_Expect(b->listeners[1]);
    Threadpool_Shutdown_ExpectAndReturn(b->threadpool, false, true);
    Threadpool_Free_Expect(b->threadpool);

    TEST_ASSERT_EQUAL(0, pthread_mutex_init(&b->fd_set_lock, NULL));
    BusSSL_CtxFree_Expect(b);
    Bus_Free(b);
}
/****************************************************************************
 * Name: CanNotReadWrite
 *
 * Description:
 *   Test DEV_ERR_NODE can not be opened for read-write
 *
 * Input Parameters:
 *   None
 *
 * Returned Value:
 *   None
 *
 * Assumptions/Limitations:
 *   None
 *
 ****************************************************************************/
TEST(DeviceNodeAccess, CanNotReadWrite)
{
  device = open(DEV_ERR_NODE, O_RDWR);
  TEST_ASSERT_TRUE(device < 0);
}
Exemple #24
0
TEST(sensorlib, LineVisibleFirst) {
  SET(sensors, 0, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023);
  TEST_ASSERT_TRUE(is_line_visible());
}
/****************************************************************************
 * Name: Character
 *
 * Description:
 *   Test PWR_BTN_NODE is a character device
 *
 * Input Parameters:
 *   None
 *
 * Returned Value:
 *   None
 *
 * Assumptions/Limitations:
 *   None
 *
 ****************************************************************************/
TEST(DeviceNodePermissions, Character)
{
    TEST_ASSERT_TRUE(S_ISCHR(st.st_mode));
}
Exemple #26
0
TEST(sensorlib, LineVisibleLast) {
  SET(sensors, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 0);
  TEST_ASSERT_TRUE(is_line_visible());
}
Exemple #27
0
void EnumSetTest::TestEnumSet() {
    EnumSet<myEnum,
            MAX_NONBOOLEAN+1,
            LIMIT_BOOLEAN>
                            flags;

    logln("Enum is from [%d..%d]\n", MAX_NONBOOLEAN+1,
          LIMIT_BOOLEAN);

    TEST_ASSERT_TRUE(flags.get(THING1) == FALSE);
    TEST_ASSERT_TRUE(flags.get(THING2) == FALSE);
    TEST_ASSERT_TRUE(flags.get(THING3) == FALSE);

    logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n",          flags.get(THING1),          flags.get(THING2),          flags.get(THING3));
    logln("Value now: %d\n", flags.getAll());
    flags.clear();
    logln("clear -Value now: %d\n", flags.getAll());
    logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n",          flags.get(THING1),          flags.get(THING2),          flags.get(THING3));
    TEST_ASSERT_TRUE(flags.get(THING1) == FALSE);
    TEST_ASSERT_TRUE(flags.get(THING2) == FALSE);
    TEST_ASSERT_TRUE(flags.get(THING3) == FALSE);
    flags.add(THING1);
    logln("set THING1 -Value now: %d\n", flags.getAll());
    TEST_ASSERT_TRUE(flags.get(THING1) == TRUE);
    TEST_ASSERT_TRUE(flags.get(THING2) == FALSE);
    TEST_ASSERT_TRUE(flags.get(THING3) == FALSE);
    logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n",          flags.get(THING1),          flags.get(THING2),          flags.get(THING3));
    flags.add(THING3);
    logln("set THING3 -Value now: %d\n", flags.getAll());
    TEST_ASSERT_TRUE(flags.get(THING1) == TRUE);
    TEST_ASSERT_TRUE(flags.get(THING2) == FALSE);
    TEST_ASSERT_TRUE(flags.get(THING3) == TRUE);
    logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n",          flags.get(THING1),          flags.get(THING2),          flags.get(THING3));
    flags.remove(THING2);
    TEST_ASSERT_TRUE(flags.get(THING1) == TRUE);
    TEST_ASSERT_TRUE(flags.get(THING2) == FALSE);
    TEST_ASSERT_TRUE(flags.get(THING3) == TRUE);
    logln("remove THING2 -Value now: %d\n", flags.getAll());
    logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n",          flags.get(THING1),          flags.get(THING2),          flags.get(THING3));
    flags.remove(THING1);
    TEST_ASSERT_TRUE(flags.get(THING1) == FALSE);
    TEST_ASSERT_TRUE(flags.get(THING2) == FALSE);
    TEST_ASSERT_TRUE(flags.get(THING3) == TRUE);
    logln("remove THING1 -Value now: %d\n", flags.getAll());
    logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n",          flags.get(THING1),          flags.get(THING2),          flags.get(THING3));

    flags.clear();
    logln("clear -Value now: %d\n", flags.getAll());
    logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n",          flags.get(THING1),          flags.get(THING2),          flags.get(THING3));
    TEST_ASSERT_TRUE(flags.get(THING1) == FALSE);
    TEST_ASSERT_TRUE(flags.get(THING2) == FALSE);
    TEST_ASSERT_TRUE(flags.get(THING3) == FALSE);
}
Exemple #28
0
TEST(sensorlib, LineVisibleBorderCase) {
  // note: sensor reading visible is value=1023-sensors[i] > 400;
  SET(sensors, 622, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023);
  TEST_ASSERT_TRUE(is_line_visible());
}
Exemple #29
0
void test_uart_read()
{
    TEST_ASSERT_TRUE(U1RXREG == ReadUART1());
}
Exemple #30
0
void *getStackPointer(ProcessBase process) {
    TEST_ASSERT_TRUE(IsValid(process));
    return MOCK->stackPointer;
}