Пример #1
0
static void didRunJavaScript(WKSerializedScriptValueRef resultSerializedScriptValue, WKErrorRef error, void* context)
{
    EXPECT_EQ(reinterpret_cast<void*>(0x1234578), context);
    EXPECT_NULL(resultSerializedScriptValue);

    // FIXME: We should also check the error, but right now it's always null.
    // Assert that it's null so we can revisit when this changes.
    EXPECT_NULL(error);

    testDone = true;
}
Пример #2
0
TEST_F(SQLTests, select_parser_test) {
	std::string query = "SELECT customer_id, SUM(order_value) FROM customers JOIN orders ON customers.id = orders.customer_id GROUP BY customer_id ORDER BY SUM(order_value) DESC;";

	SQLStatementList* list = SQLParser::parseSQLString(query.c_str());
	EXPECT_TRUE(list->isValid);
	if (!list->isValid) fprintf(stderr, "Parsing failed: %s (%s)\n", query.c_str(), list->parser_msg);

	
	EXPECT_EQ(list->numStatements(), 1);
	EXPECT_EQ(list->getStatement(0)->type(), kStmtSelect);

	SelectStatement* stmt = (SelectStatement*) list->getStatement(0);

	EXPECT_NOTNULL(stmt->select_list);
	EXPECT_NOTNULL(stmt->from_table);
	EXPECT_NOTNULL(stmt->group_by);
	EXPECT_NOTNULL(stmt->order);

	EXPECT_NULL(stmt->where_clause);
	EXPECT_NULL(stmt->union_select);
	EXPECT_NULL(stmt->limit);

	// Select List
	EXPECT_EQ(stmt->select_list->size(), 2);
	EXPECT_EQ(stmt->select_list->at(0)->type, kExprColumnRef);
	EXPECT_STREQ(stmt->select_list->at(0)->name, "customer_id");
	EXPECT_EQ(stmt->select_list->at(1)->type, kExprFunctionRef);
	EXPECT_STREQ(stmt->select_list->at(1)->name, "SUM");
	EXPECT_STREQ(stmt->select_list->at(1)->expr->name, "order_value");

	// Join Table
	JoinDefinition* join = stmt->from_table->join;
	EXPECT_EQ(stmt->from_table->type, kTableJoin);
	EXPECT_NOTNULL(join);
	EXPECT_STREQ(join->left->name, "customers");
	EXPECT_STREQ(join->right->name, "orders");
	EXPECT_EQ(join->condition->type, kExprOperator);
	EXPECT_STREQ(join->condition->expr->name, "id");
	EXPECT_STREQ(join->condition->expr->table, "customers");
	EXPECT_STREQ(join->condition->expr2->name, "customer_id");
	EXPECT_STREQ(join->condition->expr2->table, "orders");

	// Group By
	EXPECT_EQ(stmt->group_by->columns->size(), 1);
	EXPECT_STREQ(stmt->group_by->columns->at(0)->name, "customer_id");

	// Order By
	EXPECT_EQ(stmt->order->type, kOrderDesc);
	EXPECT_EQ(stmt->order->expr->type, kExprFunctionRef);
	EXPECT_STREQ(stmt->order->expr->name, "SUM");
	EXPECT_STREQ(stmt->order->expr->expr->name, "order_value");
}
Пример #3
0
static void testFree()
{
  Hash_T h0 = Hash_new(0);
  Hash_free(&h0);
  EXPECT_NULL(h0);

  Hash_T h1 = Hash_new(1);
  Hash_free(&h1);
  EXPECT_NULL(h1);

  Hash_T h2 = Hash_new(2);
  Hash_free(&h2);
  EXPECT_NULL(h2);
}
Пример #4
0
bool TestClear() {
    BEGIN_TEST;

    StringList list;
    list.push_front("bar");

    EXPECT_NONNULL(list.first());
    list.clear();
    EXPECT_NULL(list.next());
    EXPECT_NULL(list.first());
    EXPECT_EQ(list.length(), 0);

    END_TEST;
}
Пример #5
0
static void testInsert()
{
  // test general case
  Hash_T h0 = Hash_new(0);
  EXPECT_EQ_UINT32(0, h0->nElements);
  EXPECT_EQ_UINT32(0, h0->tableSize);

  int key1 = 123;
  char* value1 = "1";
  h0 = Hash_insert(h0, Atom_newFromInt64(key1), value1);
  EXPECT_NOT_NULL(h0);
  EXPECT_EQ_UINT32(1, h0->nElements);
  EXPECT_EQ_UINT32(1, h0->tableSize);

  int key2 = -27;
  char value2[] = "value2";
  h0 = Hash_insert(h0, Atom_newFromInt64(key2), value2);
  EXPECT_NOT_NULL(h0);
  EXPECT_EQ_UINT32(2, h0->nElements);
  EXPECT_EQ_UINT32(3, h0->tableSize);

  char * key3 = "abc";
  int16_t value3 = 1056;
  Str_T s = Str_newFromInt16(value3);
  h0 = Hash_insert(h0, Atom_newFromString(key3), Str_str(s));
  EXPECT_NOT_NULL(h0);
  EXPECT_EQ_UINT32(3, h0->nElements);
  EXPECT_EQ_UINT32(3, h0->tableSize);
  Str_free(&s);

  Hash_free(&h0);
  EXPECT_NULL(h0);
}
Пример #6
0
bool close_single_present_handle() {
    BEGIN_TEST;

    zx_handle_t* channel_0 = new zx_handle_t;
    // Capture the extra handle here; it will not be cleaned by fidl_close_handles
    zx::channel channel_1 = {};

    // Unsafely open a channel, which should be closed automatically by fidl_close_handles
    {
        zx_handle_t out0, out1;
        EXPECT_EQ(zx_channel_create(0, &out0, &out1), ZX_OK);
        *channel_0 = out0;
        channel_1 = zx::channel(out1);
    }

    nonnullable_handle_message_layout message = {};
    message.inline_struct.handle = *channel_0;

    EXPECT_TRUE(helper_expect_peer_valid(channel_1.get()));

    const char* error = nullptr;
    auto status = fidl_close_handles(&nonnullable_handle_message_type, &message, &error);

    EXPECT_EQ(status, ZX_OK);
    EXPECT_NULL(error, error);
    EXPECT_TRUE(helper_expect_peer_invalid(channel_1.get()));
    EXPECT_EQ(message.inline_struct.handle, ZX_HANDLE_INVALID);

    delete channel_0;

    END_TEST;
}
Пример #7
0
bool TestList() {
    BEGIN_TEST;
    PathFixture fixture;
    ASSERT_TRUE(fixture.Create());

    Path path;
    ASSERT_EQ(ZX_OK, path.Push(fixture.path("foo")));

    fbl::unique_ptr<StringList> list;
    list = path.List();
    EXPECT_STR_EQ(list->first(), "ba");
    EXPECT_NULL(list->next());

    ASSERT_EQ(ZX_OK, path.Push("ba"));
    list = path.List();

    EXPECT_EQ(list->length(), 2);
    list->erase_if("r");
    list->erase_if("z");
    EXPECT_TRUE(list->is_empty());

    ASSERT_EQ(ZX_OK, path.Push("z/qu/ux"));
    list = path.List();
    EXPECT_TRUE(list->is_empty());

    END_TEST;
}
Пример #8
0
static void
testFree()
{
  Storage_T s3 = Storage_new(3);
  Storage_free(&s3);
  EXPECT_NULL(s3);
}
Пример #9
0
static void didFailProvisionalLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, WKErrorRef error, WKTypeRef userData, const void* clientInfo)
{
    EXPECT_EQ(static_cast<uint32_t>(kWKFrameLoadStateFinished), WKFrameGetFrameLoadState(frame));

    WKURLRef url = WKFrameCopyProvisionalURL(frame);
    EXPECT_NULL(url);

    testDone = true;
}
Пример #10
0
TEST(ZXTestCAssertionTest, AssertNullFailures) {
    char b;
    char* a = &b;

    EXPECT_NULL(a, "EXPECT_NOT_NULL identified NULL.");
    ZX_ASSERT_MSG(!_ZXTEST_ABORT_IF_ERROR, "EXPECT marked the the test as error.");
    ASSERT_NULL(a, "ASSERT_NOT_NULL identified NULL.");
    ZX_ASSERT_MSG(_ZXTEST_ABORT_IF_ERROR, "Assert was did not abort test.");
}
Пример #11
0
static bool ralloc_specific_c_api_test(void) {
    BEGIN_TEST;

    // Make a pool and attach it to an allocator.  Then add the test regions to it.
    ralloc_allocator_t* alloc = NULL;
    {
        ralloc_pool_t* pool;
        ASSERT_EQ(ZX_OK, ralloc_create_pool(REGION_POOL_MAX_SIZE, &pool), "");
        ASSERT_NONNULL(pool, "");

        // Create an allocator and add our region pool to it.
        ASSERT_EQ(ZX_OK, ralloc_create_allocator(&alloc), "");
        ASSERT_NONNULL(alloc, "");
        ASSERT_EQ(ZX_OK, ralloc_set_region_pool(alloc, pool), "");

        // Release our pool reference.  The allocator should be holding onto its own
        // reference at this point.
        ralloc_release_pool(pool);
    }

    for (size_t i = 0; i < countof(ALLOC_SPECIFIC_REGIONS); ++i)
        EXPECT_EQ(ZX_OK, ralloc_add_region(alloc, &ALLOC_SPECIFIC_REGIONS[i], false), "");

    // Run the alloc by size tests.  Hold onto the regions it allocates so they
    // can be cleaned up properly when the test finishes.
    const ralloc_region_t* regions[countof(ALLOC_SPECIFIC_TESTS)];
    memset(regions, 0, sizeof(regions));

    for (size_t i = 0; i < countof(ALLOC_SPECIFIC_TESTS); ++i) {
        const alloc_specific_alloc_test_t* TEST = ALLOC_SPECIFIC_TESTS + i;
        zx_status_t res = ralloc_get_specific_region_ex(alloc, &TEST->req, regions + i);

        // Make sure we get the test result we were expecting.
        EXPECT_EQ(TEST->res, res, "");

        // If the allocation claimed to succeed, we should have gotten back a
        // non-null region which exactly matches our requested region.
        if (res == ZX_OK) {
            ASSERT_NONNULL(regions[i], "");
            EXPECT_EQ(TEST->req.base, regions[i]->base, "");
            EXPECT_EQ(TEST->req.size, regions[i]->size, "");
        } else {
            EXPECT_NULL(regions[i], "");
        }
    }

    // Put the regions we have allocated back in the allocator.
    for (size_t i = 0; i < countof(regions); ++i)
        if (regions[i])
            ralloc_put_region(regions[i]);

    // Destroy our allocator.
    ralloc_destroy_allocator(alloc);

    END_TEST;
}
Пример #12
0
static void didCommitLoadForFrame(WKPageRef page, WKFrameRef frame, WKTypeRef userData, const void* clientInfo)
{
    State* state = reinterpret_cast<State*>(const_cast<void*>(clientInfo));
    EXPECT_TRUE(state->didDecidePolicyForNavigationAction);
    EXPECT_TRUE(state->didStartProvisionalLoadForFrame);

    // The provisional URL should be null.
    EXPECT_NULL(WKFrameCopyProvisionalURL(frame));

    state->didCommitLoadForFrame = true;
}
Пример #13
0
bool close_out_of_line_array_of_nonnullable_handles() {
    BEGIN_TEST;

    zx_handle_t* channels_0 = new zx_handle_t[4];
    // Capture the extra handles here; these will not be cleaned by fidl_close_handles
    zx::channel channels_1[4] = {};

    // Unsafely open a few channels, which should be closed automatically by fidl_close_handles
    for (int i = 0; i < 4; i++) {
        zx_handle_t out0, out1;
        EXPECT_EQ(zx_channel_create(0, &out0, &out1), ZX_OK);
        channels_0[i] = out0;
        channels_1[i] = zx::channel(out1);
    }

    out_of_line_array_of_nonnullable_handles_message_layout message = {};
    message.inline_struct.maybe_array = &message.data;
    for (int i = 0; i < 4; i++) {
        message.data.handles[i] = channels_0[i];
    }

    EXPECT_TRUE(helper_expect_peer_valid(channels_1[0].get()));
    EXPECT_TRUE(helper_expect_peer_valid(channels_1[1].get()));
    EXPECT_TRUE(helper_expect_peer_valid(channels_1[2].get()));
    EXPECT_TRUE(helper_expect_peer_valid(channels_1[3].get()));

    const char* error = nullptr;
    auto status = fidl_close_handles(&out_of_line_array_of_nonnullable_handles_message_type,
                                     &message, &error);

    EXPECT_EQ(status, ZX_OK);
    EXPECT_NULL(error, error);

    EXPECT_TRUE(helper_expect_peer_invalid(channels_1[0].get()));
    EXPECT_TRUE(helper_expect_peer_invalid(channels_1[1].get()));
    EXPECT_TRUE(helper_expect_peer_invalid(channels_1[2].get()));
    EXPECT_TRUE(helper_expect_peer_invalid(channels_1[3].get()));

    // The handles have been closed; it is an error to re-close them.
    EXPECT_EQ(zx_handle_close(channels_0[0]), ZX_ERR_BAD_HANDLE);
    EXPECT_EQ(zx_handle_close(channels_0[1]), ZX_ERR_BAD_HANDLE);
    EXPECT_EQ(zx_handle_close(channels_0[2]), ZX_ERR_BAD_HANDLE);
    EXPECT_EQ(zx_handle_close(channels_0[3]), ZX_ERR_BAD_HANDLE);

    // Handles in the message struct are released.
    EXPECT_EQ(message.data.handles[0], ZX_HANDLE_INVALID);
    EXPECT_EQ(message.data.handles[1], ZX_HANDLE_INVALID);
    EXPECT_EQ(message.data.handles[2], ZX_HANDLE_INVALID);
    EXPECT_EQ(message.data.handles[3], ZX_HANDLE_INVALID);

    delete[] channels_0;

    END_TEST;
}
Пример #14
0
int main(int argc, char **argv)
{
    struct s2n_connection *conn;

    BEGIN_TEST();

    EXPECT_NULL(conn = s2n_connection_new(S2N_CLIENT));

    EXPECT_SUCCESS(setenv("S2N_ENABLE_CLIENT_MODE", "1", 0));
    EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT));
    EXPECT_SUCCESS(s2n_connection_free(conn));

    END_TEST();
}
Пример #15
0
static void testInt16()
{
  // test all APIs for type int16_t
  const unsigned trace = 0;
  Str_T s = Str_newFromInt16(27);
  EXPECT_NOT_NULL(s);
  char *cP = Str_str(s);
  EXPECT_NOT_NULL(cP);
  EXPECT_TRUE(strcmp("int16_t", s->valueTypeName) == 0);
  EXPECT_EQ_INT16(27, Str_valueInt16(s));
  if (trace) // "s as str should be funny"
    fprintf(stderr, "s as str: %s as int16: %d\n",
            Str_str(s), Str_valueInt16(s));
  Str_free(&s);
  EXPECT_NULL(s);
}
Пример #16
0
bool close_present_too_large_nullable_vector_of_handles() {
    BEGIN_TEST;
    zx_handle_t* channels_0 = new zx_handle_t[kTooBigNumHandles];
    // Capture the extra handles here; these will not be cleaned by fidl_close_handles
    zx::channel channels_1[kTooBigNumHandles] = {};

    // Unsafely open a few channels, which should be closed automatically by fidl_close_handles
    for (int i = 0; i < kTooBigNumHandles; i++) {
        zx_handle_t out0, out1;
        EXPECT_EQ(zx_channel_create(0, &out0, &out1), ZX_OK);
        channels_0[i] = out0;
        channels_1[i] = zx::channel(out1);
    }

    unbounded_too_large_nullable_vector_of_handles_message_layout message = {};
    message.inline_struct.vector = fidl_vector_t{kTooBigNumHandles, &message.handles[0]};
    for (int i = 0; i < kTooBigNumHandles; i++) {
        message.handles[i] = channels_0[i];
        EXPECT_TRUE(helper_expect_peer_valid(channels_1[i].get()));
    }

    const char* error = nullptr;
    auto status =
        fidl_close_handles(&unbounded_too_large_nullable_vector_of_handles_message_type,
                           &message,
                           &error);

    EXPECT_EQ(status, ZX_OK);
    EXPECT_NULL(error, error);

    for (int i = 0; i < kTooBigNumHandles; i++) {
        EXPECT_TRUE(helper_expect_peer_invalid(channels_1[i].get()));
        EXPECT_EQ(zx_handle_close(channels_0[i]), ZX_ERR_BAD_HANDLE);
    }

    auto message_handles = reinterpret_cast<zx_handle_t*>(message.inline_struct.vector.data);
    for (int i = 0; i < kTooBigNumHandles; i++) {
        EXPECT_EQ(message_handles[i], ZX_HANDLE_INVALID);
    }

    delete[] channels_0;

    END_TEST;
}
Пример #17
0
static void javaScriptCallback(WKSerializedScriptValueRef resultSerializedScriptValue, WKErrorRef error, void* ctx)
{
    ASSERT_NOT_NULL(resultSerializedScriptValue);

    JavaScriptCallbackContext* context = static_cast<JavaScriptCallbackContext*>(ctx);

    JSGlobalContextRef scriptContext = JSGlobalContextCreate(0);
    ASSERT_NOT_NULL(scriptContext);

    JSValueRef scriptValue = WKSerializedScriptValueDeserialize(resultSerializedScriptValue, scriptContext, 0);
    ASSERT_NOT_NULL(scriptValue);

    context->actualString.adopt(JSValueToStringCopy(scriptContext, scriptValue, 0));
    ASSERT_NOT_NULL(context->actualString.get());

    context->didFinish = true;

    JSGlobalContextRelease(scriptContext);

    EXPECT_NULL(error);
}
static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef body, const void*)
{
    didReceiveMessage = true;

    EXPECT_WK_STREQ("DidReceiveWillSendSubmitEvent", messageName);

    EXPECT_EQ(WKDictionaryGetTypeID(), WKGetTypeID(body));
    WKDictionaryRef values = static_cast<WKDictionaryRef>(body);

    WKRetainPtr<WKStringRef> textFieldKey(AdoptWK, WKStringCreateWithUTF8CString("textField"));
    WKStringRef textFieldValueWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(values, textFieldKey.get()));
    EXPECT_WK_STREQ("text field", textFieldValueWK);

    WKRetainPtr<WKStringRef> passwordFieldKey(AdoptWK, WKStringCreateWithUTF8CString("passwordField"));
    WKStringRef passwordFieldValueWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(values, passwordFieldKey.get()));
    EXPECT_WK_STREQ("password field", passwordFieldValueWK);

    // <input type="hidden"> fields are not sent.
    WKRetainPtr<WKStringRef> hiddenFieldKey(AdoptWK, WKStringCreateWithUTF8CString("hiddenField"));
    WKStringRef hiddenFieldValueWK = static_cast<WKStringRef>(WKDictionaryGetItemForKey(values, hiddenFieldKey.get()));
    EXPECT_NULL(hiddenFieldValueWK);
}
Пример #19
0
int main(int argc, char **argv)
{
    BEGIN_TEST();

    EXPECT_SUCCESS(setenv("S2N_ENABLE_CLIENT_MODE", "1", 0));
    EXPECT_SUCCESS(setenv("S2N_DONT_MLOCK", "1", 0));
    EXPECT_SUCCESS(s2n_init());

    /* Client doens't use the server name extension. */
    {
        struct s2n_connection *client_conn;
        struct s2n_connection *server_conn;
        struct s2n_config *server_config;
        s2n_blocked_status client_blocked;
        s2n_blocked_status server_blocked;
        int server_to_client[2];
        int client_to_server[2];

        /* Create nonblocking pipes */
        EXPECT_SUCCESS(pipe(server_to_client));
        EXPECT_SUCCESS(pipe(client_to_server));
        for (int i = 0; i < 2; i++) {
           EXPECT_NOT_EQUAL(fcntl(server_to_client[i], F_SETFL, fcntl(server_to_client[i], F_GETFL) | O_NONBLOCK), -1);
           EXPECT_NOT_EQUAL(fcntl(client_to_server[i], F_SETFL, fcntl(client_to_server[i], F_GETFL) | O_NONBLOCK), -1);
        }

        EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT));
        EXPECT_SUCCESS(s2n_connection_set_read_fd(client_conn, server_to_client[0]));
        EXPECT_SUCCESS(s2n_connection_set_write_fd(client_conn, client_to_server[1]));

        EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER));
        EXPECT_SUCCESS(s2n_connection_set_read_fd(server_conn, client_to_server[0]));
        EXPECT_SUCCESS(s2n_connection_set_write_fd(server_conn, server_to_client[1]));

        EXPECT_NOT_NULL(server_config = s2n_config_new());
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key(server_config, certificate, private_key));
        EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config));

        do {
            int ret;
            ret = s2n_negotiate(client_conn, &client_blocked);
            EXPECT_TRUE(ret == 0 || (client_blocked && errno == EAGAIN));
            ret = s2n_negotiate(server_conn, &server_blocked);
            EXPECT_TRUE(ret == 0 || (server_blocked && errno == EAGAIN));
        } while (client_blocked || server_blocked);

        /* Verify that the server didn't receive the server name. */
        EXPECT_NULL(s2n_get_server_name(server_conn));

        EXPECT_SUCCESS(s2n_shutdown(client_conn, &client_blocked));
        EXPECT_SUCCESS(s2n_connection_free(client_conn));
        EXPECT_SUCCESS(s2n_shutdown(server_conn, &server_blocked));
        EXPECT_SUCCESS(s2n_connection_free(server_conn));

        EXPECT_SUCCESS(s2n_config_free(server_config));

        for (int i = 0; i < 2; i++) {
           EXPECT_SUCCESS(close(server_to_client[i]));
           EXPECT_SUCCESS(close(client_to_server[i]));
        }
    }

    /* Client uses the server name extension. */
    {
        struct s2n_connection *client_conn;
        struct s2n_connection *server_conn;
        struct s2n_config *server_config;
        s2n_blocked_status client_blocked;
        s2n_blocked_status server_blocked;
        int server_to_client[2];
        int client_to_server[2];

        const char *sent_server_name = "awesome.amazonaws.com";
        const char *received_server_name;

        /* Create nonblocking pipes */
        EXPECT_SUCCESS(pipe(server_to_client));
        EXPECT_SUCCESS(pipe(client_to_server));
        for (int i = 0; i < 2; i++) {
            EXPECT_NOT_EQUAL(fcntl(server_to_client[i], F_SETFL, fcntl(server_to_client[i], F_GETFL) | O_NONBLOCK), -1);
            EXPECT_NOT_EQUAL(fcntl(client_to_server[i], F_SETFL, fcntl(client_to_server[i], F_GETFL) | O_NONBLOCK), -1);
        }

        EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT));
        EXPECT_SUCCESS(s2n_connection_set_read_fd(client_conn, server_to_client[0]));
        EXPECT_SUCCESS(s2n_connection_set_write_fd(client_conn, client_to_server[1]));

        /* Set the server name */
        EXPECT_SUCCESS(s2n_set_server_name(client_conn, sent_server_name));

        EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER));
        EXPECT_SUCCESS(s2n_connection_set_read_fd(server_conn, client_to_server[0]));
        EXPECT_SUCCESS(s2n_connection_set_write_fd(server_conn, server_to_client[1]));

        EXPECT_NOT_NULL(server_config = s2n_config_new());
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key(server_config, certificate, private_key));
        EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config));

        do {
            int ret;
            ret = s2n_negotiate(client_conn, &client_blocked);
            EXPECT_TRUE(ret == 0 || (client_blocked && errno == EAGAIN));
            ret = s2n_negotiate(server_conn, &server_blocked);
            EXPECT_TRUE(ret == 0 || (server_blocked && errno == EAGAIN));
        } while (client_blocked || server_blocked);

        /* Verify that the server name was received intact. */
        EXPECT_NOT_NULL(received_server_name = s2n_get_server_name(server_conn));
        EXPECT_EQUAL(strlen(received_server_name), strlen(sent_server_name));
        EXPECT_BYTEARRAY_EQUAL(received_server_name, sent_server_name, strlen(received_server_name));

        EXPECT_SUCCESS(s2n_shutdown(client_conn, &client_blocked));
        EXPECT_SUCCESS(s2n_connection_free(client_conn));
        EXPECT_SUCCESS(s2n_shutdown(server_conn, &server_blocked));
        EXPECT_SUCCESS(s2n_connection_free(server_conn));

        EXPECT_SUCCESS(s2n_config_free(server_config));
        for (int i = 0; i < 2; i++) {
            EXPECT_SUCCESS(close(server_to_client[i]));
            EXPECT_SUCCESS(close(client_to_server[i]));
        }
    }

    /* Client sends multiple server names. */
    {
        struct s2n_connection *server_conn;
        struct s2n_config *server_config;
        s2n_blocked_status server_blocked;
        int server_to_client[2];
        int client_to_server[2];
        const char *sent_server_name = "svr";
        const char *received_server_name;

        uint8_t client_extensions[] = {
            /* Extension type TLS_EXTENSION_SERVER_NAME */
            0x00, 0x00,
            /* Extension size */
            0x00, 0x0C,
            /* All server names len */
            0x00, 0x0A,
            /* First server name type - host name */
            0x00,
            /* First server name len */
            0x00, 0x03,
            /* First server name, matches sent_server_name */
            's', 'v', 'r',
            /* Second server name type - host name */
            0x00,
            /* Second server name len */
            0x00, 0x01,
            /* Second server name */
            0xFF,
        };
        int client_extensions_len = sizeof(client_extensions);
        uint8_t client_hello_message[] = {
            /* Protocol version TLS 1.2 */
            0x03, 0x03,
            /* Client random */
            ZERO_TO_THIRTY_ONE,
            /* SessionID len - 32 bytes */
            0x20,
            /* Session ID */
            ZERO_TO_THIRTY_ONE,
            /* Cipher suites len */
            0x00, 0x02,
            /* Cipher suite - TLS_RSA_WITH_AES_128_CBC_SHA256 */
            0x00, 0x3C,
            /* Compression methods len */
            0x01,
            /* Compression method - none */
            0x00,
            /* Extensions len */
            (client_extensions_len >> 8) & 0xff, (client_extensions_len & 0xff),
        };
        int body_len = sizeof(client_hello_message) + client_extensions_len;
        uint8_t message_header[] = {
            /* Handshake message type CLIENT HELLO */
            0x01,
            /* Body len */
            (body_len >> 16) & 0xff, (body_len >> 8) & 0xff, (body_len & 0xff),
        };
        int message_len = sizeof(message_header) + body_len;
        uint8_t record_header[] = {
            /* Record type HANDSHAKE */
            0x16,
            /* Protocol version TLS 1.2 */
            0x03, 0x03,
            /* Message len */
            (message_len >> 8) & 0xff, (message_len & 0xff),
        };

        /* Create nonblocking pipes */
        EXPECT_SUCCESS(pipe(server_to_client));
        EXPECT_SUCCESS(pipe(client_to_server));
        for (int i = 0; i < 2; i++) {
            EXPECT_NOT_EQUAL(fcntl(server_to_client[i], F_SETFL, fcntl(server_to_client[i], F_GETFL) | O_NONBLOCK), -1);
            EXPECT_NOT_EQUAL(fcntl(client_to_server[i], F_SETFL, fcntl(client_to_server[i], F_GETFL) | O_NONBLOCK), -1);
        }

        EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER));
        EXPECT_SUCCESS(s2n_connection_set_read_fd(server_conn, client_to_server[0]));
        EXPECT_SUCCESS(s2n_connection_set_write_fd(server_conn, server_to_client[1]));

        EXPECT_NOT_NULL(server_config = s2n_config_new());
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key(server_config, certificate, private_key));
        EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config));

        /* Send the client hello */
        EXPECT_EQUAL(write(client_to_server[1], record_header, sizeof(record_header)), sizeof(record_header));
        EXPECT_EQUAL(write(client_to_server[1], message_header, sizeof(message_header)), sizeof(message_header));
        EXPECT_EQUAL(write(client_to_server[1], client_hello_message, sizeof(client_hello_message)), sizeof(client_hello_message));
        EXPECT_EQUAL(write(client_to_server[1], client_extensions, sizeof(client_extensions)), sizeof(client_extensions));

        /* Verify that the CLIENT HELLO is accepted */
        s2n_negotiate(server_conn, &server_blocked);
        EXPECT_EQUAL(server_blocked, 1);
        EXPECT_EQUAL(server_conn->handshake.state, CLIENT_KEY);

        /* Verify that the server name was received intact. */
        EXPECT_NOT_NULL(received_server_name = s2n_get_server_name(server_conn));
        EXPECT_EQUAL(strlen(received_server_name), strlen(sent_server_name));
        EXPECT_BYTEARRAY_EQUAL(received_server_name, sent_server_name, strlen(received_server_name));

        EXPECT_SUCCESS(s2n_shutdown(server_conn, &server_blocked));
        EXPECT_SUCCESS(s2n_connection_free(server_conn));

        EXPECT_SUCCESS(s2n_config_free(server_config));
        for (int i = 0; i < 2; i++) {
            EXPECT_SUCCESS(close(server_to_client[i]));
            EXPECT_SUCCESS(close(client_to_server[i]));
        }
    }

    /* Client doesn't use the OCSP extension. */
    {
        struct s2n_connection *client_conn;
        struct s2n_connection *server_conn;
        struct s2n_config *server_config;
        s2n_blocked_status client_blocked;
        s2n_blocked_status server_blocked;
        int server_to_client[2];
        int client_to_server[2];
        uint32_t length;

        /* Create nonblocking pipes */
        EXPECT_SUCCESS(pipe(server_to_client));
        EXPECT_SUCCESS(pipe(client_to_server));
        for (int i = 0; i < 2; i++) {
           EXPECT_NOT_EQUAL(fcntl(server_to_client[i], F_SETFL, fcntl(server_to_client[i], F_GETFL) | O_NONBLOCK), -1);
           EXPECT_NOT_EQUAL(fcntl(client_to_server[i], F_SETFL, fcntl(client_to_server[i], F_GETFL) | O_NONBLOCK), -1);
        }

        EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT));
        EXPECT_SUCCESS(s2n_connection_set_read_fd(client_conn, server_to_client[0]));
        EXPECT_SUCCESS(s2n_connection_set_write_fd(client_conn, client_to_server[1]));

        EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER));
        EXPECT_SUCCESS(s2n_connection_set_read_fd(server_conn, client_to_server[0]));
        EXPECT_SUCCESS(s2n_connection_set_write_fd(server_conn, server_to_client[1]));

        EXPECT_NOT_NULL(server_config = s2n_config_new());
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_with_status(server_config, certificate, private_key, server_ocsp_status, sizeof(server_ocsp_status)));
        EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config));

        do {
            int ret;
            ret = s2n_negotiate(client_conn, &client_blocked);
            EXPECT_TRUE(ret == 0 || client_blocked);
            ret = s2n_negotiate(server_conn, &server_blocked);
            EXPECT_TRUE(ret == 0 || server_blocked);
        } while (client_blocked || server_blocked);

        /* Verify that the client didn't receive an OCSP response. */
        EXPECT_NULL(s2n_connection_get_ocsp_response(client_conn, &length));
        EXPECT_EQUAL(length, 0);

        EXPECT_SUCCESS(s2n_shutdown(client_conn, &client_blocked));
        EXPECT_SUCCESS(s2n_connection_free(client_conn));
        EXPECT_SUCCESS(s2n_shutdown(server_conn, &server_blocked));
        EXPECT_SUCCESS(s2n_connection_free(server_conn));

        EXPECT_SUCCESS(s2n_config_free(server_config));

        for (int i = 0; i < 2; i++) {
           EXPECT_SUCCESS(close(server_to_client[i]));
           EXPECT_SUCCESS(close(client_to_server[i]));
        }
    }

    /* Server doesn't support the OCSP extension. */
    {
        struct s2n_connection *client_conn;
        struct s2n_connection *server_conn;
        struct s2n_config *server_config;
        struct s2n_config *client_config;
        s2n_blocked_status client_blocked;
        s2n_blocked_status server_blocked;
        int server_to_client[2];
        int client_to_server[2];
        uint32_t length;

        /* Create nonblocking pipes */
        EXPECT_SUCCESS(pipe(server_to_client));
        EXPECT_SUCCESS(pipe(client_to_server));
        for (int i = 0; i < 2; i++) {
           EXPECT_NOT_EQUAL(fcntl(server_to_client[i], F_SETFL, fcntl(server_to_client[i], F_GETFL) | O_NONBLOCK), -1);
           EXPECT_NOT_EQUAL(fcntl(client_to_server[i], F_SETFL, fcntl(client_to_server[i], F_GETFL) | O_NONBLOCK), -1);
        }

        EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT));
        EXPECT_SUCCESS(s2n_connection_set_read_fd(client_conn, server_to_client[0]));
        EXPECT_SUCCESS(s2n_connection_set_write_fd(client_conn, client_to_server[1]));

        EXPECT_NOT_NULL(client_config = s2n_config_new());
        EXPECT_SUCCESS(s2n_config_set_status_request_type(client_config, S2N_STATUS_REQUEST_OCSP));
        EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config));

        EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER));
        EXPECT_SUCCESS(s2n_connection_set_read_fd(server_conn, client_to_server[0]));
        EXPECT_SUCCESS(s2n_connection_set_write_fd(server_conn, server_to_client[1]));

        EXPECT_NOT_NULL(server_config = s2n_config_new());
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key(server_config, certificate, private_key));
        EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config));

        do {
            int ret;
            ret = s2n_negotiate(client_conn, &client_blocked);
            EXPECT_TRUE(ret == 0 || client_blocked);
            ret = s2n_negotiate(server_conn, &server_blocked);
            EXPECT_TRUE(ret == 0 || server_blocked);
        } while (client_blocked || server_blocked);

        /* Verify that the client didn't receive an OCSP response. */
        EXPECT_NULL(s2n_connection_get_ocsp_response(client_conn, &length));
        EXPECT_EQUAL(length, 0);

        EXPECT_SUCCESS(s2n_shutdown(client_conn, &client_blocked));
        EXPECT_SUCCESS(s2n_connection_free(client_conn));
        EXPECT_SUCCESS(s2n_shutdown(server_conn, &server_blocked));
        EXPECT_SUCCESS(s2n_connection_free(server_conn));

        EXPECT_SUCCESS(s2n_config_free(server_config));
        EXPECT_SUCCESS(s2n_config_free(client_config));

        for (int i = 0; i < 2; i++) {
           EXPECT_SUCCESS(close(server_to_client[i]));
           EXPECT_SUCCESS(close(client_to_server[i]));
        }
    }

    /* Server and client support the OCSP extension. */
    {
        struct s2n_connection *client_conn;
        struct s2n_connection *server_conn;
        struct s2n_config *server_config;
        struct s2n_config *client_config;
        s2n_blocked_status client_blocked;
        s2n_blocked_status server_blocked;
        int server_to_client[2];
        int client_to_server[2];
        uint32_t length;

        /* Create nonblocking pipes */
        EXPECT_SUCCESS(pipe(server_to_client));
        EXPECT_SUCCESS(pipe(client_to_server));
        for (int i = 0; i < 2; i++) {
           EXPECT_NOT_EQUAL(fcntl(server_to_client[i], F_SETFL, fcntl(server_to_client[i], F_GETFL) | O_NONBLOCK), -1);
           EXPECT_NOT_EQUAL(fcntl(client_to_server[i], F_SETFL, fcntl(client_to_server[i], F_GETFL) | O_NONBLOCK), -1);
        }

        EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT));
        EXPECT_SUCCESS(s2n_connection_set_read_fd(client_conn, server_to_client[0]));
        EXPECT_SUCCESS(s2n_connection_set_write_fd(client_conn, client_to_server[1]));

        EXPECT_NOT_NULL(client_config = s2n_config_new());
        EXPECT_SUCCESS(s2n_config_set_status_request_type(client_config, S2N_STATUS_REQUEST_OCSP));
        EXPECT_SUCCESS(s2n_connection_set_config(client_conn, client_config));

        EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER));
        EXPECT_SUCCESS(s2n_connection_set_read_fd(server_conn, client_to_server[0]));
        EXPECT_SUCCESS(s2n_connection_set_write_fd(server_conn, server_to_client[1]));

        EXPECT_NOT_NULL(server_config = s2n_config_new());
        EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_with_status(server_config, certificate, private_key, server_ocsp_status, sizeof(server_ocsp_status)));
        EXPECT_SUCCESS(s2n_connection_set_config(server_conn, server_config));

        do {
            int ret;
            ret = s2n_negotiate(client_conn, &client_blocked);
            EXPECT_TRUE(ret == 0 || client_blocked);
            ret = s2n_negotiate(server_conn, &server_blocked);
            EXPECT_TRUE(ret == 0 || server_blocked);
        } while (client_blocked || server_blocked);

        /* Verify that the client didn't receive an OCSP response. */
        EXPECT_NULL(s2n_connection_get_ocsp_response(client_conn, &length));
        EXPECT_EQUAL(length, 0);

        EXPECT_SUCCESS(s2n_shutdown(client_conn, &client_blocked));
        EXPECT_SUCCESS(s2n_connection_free(client_conn));
        EXPECT_SUCCESS(s2n_shutdown(server_conn, &server_blocked));
        EXPECT_SUCCESS(s2n_connection_free(server_conn));

        EXPECT_SUCCESS(s2n_config_free(server_config));
        EXPECT_SUCCESS(s2n_config_free(client_config));

        for (int i = 0; i < 2; i++) {
           EXPECT_SUCCESS(close(server_to_client[i]));
           EXPECT_SUCCESS(close(client_to_server[i]));
        }
    }

    END_TEST();
    return 0;
}
void test_macro_args() {
  int i = 0;
  int *Ptr;

  IS_EQ(static_cast<int*>(0), Ptr);
  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: use nullptr
  // CHECK-FIXES: IS_EQ(static_cast<int*>(nullptr), Ptr);

  IS_EQ(0, Ptr);    // literal
  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
  // CHECK-FIXES: IS_EQ(nullptr, Ptr);

  IS_EQ(NULL, Ptr); // macro
  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
  // CHECK-FIXES: IS_EQ(nullptr, Ptr);

  // These are ok since the null literal is not spelled within a macro.
#define myassert(x) if (!(x)) return;
  myassert(0 == Ptr);
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr
  // CHECK-FIXES: myassert(nullptr == Ptr);

  myassert(NULL == Ptr);
  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use nullptr
  // CHECK-FIXES: myassert(nullptr == Ptr);

  // These are bad as the null literal is buried in a macro.
#define BLAH(X) myassert(0 == (X));
#define BLAH2(X) myassert(NULL == (X));
  BLAH(Ptr);
  BLAH2(Ptr);

  // Same as above but testing extra macro expansion.
#define EXPECT_NULL(X) IS_EQ(0, X);
#define EXPECT_NULL2(X) IS_EQ(NULL, X);
  EXPECT_NULL(Ptr);
  EXPECT_NULL2(Ptr);

  // Almost the same as above but now null literal is not in a macro so ok
  // to transform.
#define EQUALS_PTR(X) IS_EQ(X, Ptr);
  EQUALS_PTR(0);
  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use nullptr
  // CHECK-FIXES: EQUALS_PTR(nullptr);
  EQUALS_PTR(NULL);
  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use nullptr
  // CHECK-FIXES: EQUALS_PTR(nullptr);

  // Same as above but testing extra macro expansion.
#define EQUALS_PTR_I(X) EQUALS_PTR(X)
  EQUALS_PTR_I(0);
  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
  // CHECK-FIXES: EQUALS_PTR_I(nullptr);
  EQUALS_PTR_I(NULL);
  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use nullptr
  // CHECK-FIXES: EQUALS_PTR_I(nullptr);

  // Ok since null literal not within macro. However, now testing macro
  // used as arg to another macro.
#define decorate(EXPR) side_effect(); EXPR;
  decorate(IS_EQ(NULL, Ptr));
  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
  // CHECK-FIXES: decorate(IS_EQ(nullptr, Ptr));
  decorate(IS_EQ(0, Ptr));
  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
  // CHECK-FIXES: decorate(IS_EQ(nullptr, Ptr));

  // This macro causes a NullToPointer cast to happen where 0 is assigned to z
  // but the 0 literal cannot be replaced because it is also used as an
  // integer in the comparison.
#define INT_AND_PTR_USE(X) do { int *z = X; if (X == 4) break; } while(false)
  INT_AND_PTR_USE(0);

  // Both uses of X in this case result in NullToPointer casts so replacement
  // is possible.
#define PTR_AND_PTR_USE(X) do { int *z = X; if (X != z) break; } while(false)
  PTR_AND_PTR_USE(0);
  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr
  // CHECK-FIXES: PTR_AND_PTR_USE(nullptr);
  PTR_AND_PTR_USE(NULL);
  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr
  // CHECK-FIXES: PTR_AND_PTR_USE(nullptr);

#define OPTIONAL_CODE(...) __VA_ARGS__
#define NOT_NULL dummy(0)
#define CALL(X) X
  OPTIONAL_CODE(NOT_NULL);
  CALL(NOT_NULL);

#define ENTRY(X) {X}
  struct A {
    int *Ptr;
  } a[2] = {ENTRY(0), {0}};
  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: use nullptr
  // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: use nullptr
  // CHECK-FIXES: a[2] = {ENTRY(nullptr), {nullptr}};
#undef ENTRY
}
TEST(WebKit2, PendingAPIRequestURL)
{
    WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate());
    PlatformWebView webView(context.get());

    WKPageLoaderClientV0 loaderClient;
    memset(&loaderClient, 0, sizeof(loaderClient));
    loaderClient.base.version = 0;
    loaderClient.didFinishLoadForFrame = [](WKPageRef, WKFrameRef, WKTypeRef, const void*) { done = true; };
    WKPageSetPageLoaderClient(webView.page(), &loaderClient.base);

    WKRetainPtr<WKURLRef> activeURL = adoptWK(WKPageCopyActiveURL(webView.page()));
    EXPECT_NULL(activeURL.get());

    WKRetainPtr<WKURLRef> url = adoptWK(Util::createURLForResource("simple", "html"));
    WKPageLoadURL(webView.page(), url.get());
    activeURL = adoptWK(WKPageCopyActiveURL(webView.page()));
    ASSERT_NOT_NULL(activeURL.get());
    EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get()));
    Util::run(&done);
    done = false;

    WKPageReload(webView.page());
    activeURL = adoptWK(WKPageCopyActiveURL(webView.page()));
    ASSERT_NOT_NULL(activeURL.get());
    EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get()));
    Util::run(&done);
    done = false;

    WKRetainPtr<WKStringRef> htmlString = Util::toWK("<body>Hello, World</body>");
    WKRetainPtr<WKURLRef> blankURL = adoptWK(WKURLCreateWithUTF8CString("about:blank"));
    WKPageLoadHTMLString(webView.page(), htmlString.get(), nullptr);
    activeURL = adoptWK(WKPageCopyActiveURL(webView.page()));
    ASSERT_NOT_NULL(activeURL.get());
    EXPECT_TRUE(WKURLIsEqual(activeURL.get(), blankURL.get()));
    Util::run(&done);
    done = false;

    WKPageReload(webView.page());
    activeURL = adoptWK(WKPageCopyActiveURL(webView.page()));
    ASSERT_NOT_NULL(activeURL.get());
    EXPECT_TRUE(WKURLIsEqual(activeURL.get(), blankURL.get()));
    Util::run(&done);
    done = false;

    url = adoptWK(Util::createURLForResource("simple2", "html"));
    WKPageLoadHTMLString(webView.page(), htmlString.get(), url.get());
    activeURL = adoptWK(WKPageCopyActiveURL(webView.page()));
    ASSERT_NOT_NULL(activeURL.get());
    EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get()));
    Util::run(&done);
    done = false;

    WKPageReload(webView.page());
    activeURL = adoptWK(WKPageCopyActiveURL(webView.page()));
    ASSERT_NOT_NULL(activeURL.get());
    EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get()));
    Util::run(&done);
    done = false;

    WKRetainPtr<WKDataRef> data = adoptWK(WKDataCreate(nullptr, 0));
    WKPageLoadData(webView.page(), data.get(), nullptr, nullptr, nullptr);
    activeURL = adoptWK(WKPageCopyActiveURL(webView.page()));
    ASSERT_NOT_NULL(activeURL.get());
    EXPECT_TRUE(WKURLIsEqual(activeURL.get(), blankURL.get()));
    Util::run(&done);
    done = false;

    WKPageReload(webView.page());
    activeURL = adoptWK(WKPageCopyActiveURL(webView.page()));
    ASSERT_NOT_NULL(activeURL.get());
    EXPECT_TRUE(WKURLIsEqual(activeURL.get(), blankURL.get()));
    Util::run(&done);
    done = false;

    WKPageLoadData(webView.page(), data.get(), nullptr, nullptr, url.get());
    activeURL = adoptWK(WKPageCopyActiveURL(webView.page()));
    ASSERT_NOT_NULL(activeURL.get());
    EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get()));
    Util::run(&done);
    done = false;

    WKPageReload(webView.page());
    activeURL = adoptWK(WKPageCopyActiveURL(webView.page()));
    ASSERT_NOT_NULL(activeURL.get());
    EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get()));
    Util::run(&done);
    done = false;

    WKPageLoadAlternateHTMLString(webView.page(), htmlString.get(), nullptr, url.get());
    activeURL = adoptWK(WKPageCopyActiveURL(webView.page()));
    ASSERT_NOT_NULL(activeURL.get());
    EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get()));
    Util::run(&done);
    done = false;

    WKPageReload(webView.page());
    activeURL = adoptWK(WKPageCopyActiveURL(webView.page()));
    ASSERT_NOT_NULL(activeURL.get());
    EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get()));
    Util::run(&done);
    done = false;

    WKRetainPtr<WKStringRef> plainTextString = Util::toWK("Hello, World");
    WKPageLoadPlainTextString(webView.page(), plainTextString.get());
    activeURL = adoptWK(WKPageCopyActiveURL(webView.page()));
    ASSERT_NOT_NULL(activeURL.get());
    EXPECT_TRUE(WKURLIsEqual(activeURL.get(), blankURL.get()));
    Util::run(&done);
    done = false;

    WKPageReload(webView.page());
    activeURL = adoptWK(WKPageCopyActiveURL(webView.page()));
    ASSERT_NOT_NULL(activeURL.get());
    EXPECT_TRUE(WKURLIsEqual(activeURL.get(), blankURL.get()));
    Util::run(&done);
    done = false;

    url = adoptWK(WKURLCreateWithUTF8CString("file:///tmp/index.html"));
    WKPageLoadFile(webView.page(), url.get(), nullptr);
    activeURL = adoptWK(WKPageCopyActiveURL(webView.page()));
    ASSERT_NOT_NULL(activeURL.get());
    EXPECT_TRUE(WKURLIsEqual(activeURL.get(), url.get()));
    WKPageStopLoading(webView.page());
}
Пример #22
0
static void
parse_valid_test(void)
{
	struct iscsi_param *params;
	int rc;

	params = NULL;
	char *data;
	int len;
	char *partial_parameter = NULL;

	/* simple test with a single key=value */
	PARSE("Abc=def\0", false, NULL);
	CU_ASSERT(rc == 0);
	EXPECT_VAL("Abc", "def");

	/* multiple key=value pairs */
	PARSE("Aaa=bbbbbb\0Xyz=test\0", false, NULL);
	CU_ASSERT(rc == 0);
	EXPECT_VAL("Aaa", "bbbbbb");
	EXPECT_VAL("Xyz", "test");

	/* value with embedded '=' */
	PARSE("A=b=c\0", false, NULL);
	CU_ASSERT(rc == 0);
	EXPECT_VAL("A", "b=c");

	/* CHAP_C=AAAA.... with value length 8192 */
	len = strlen("CHAP_C=") + ISCSI_TEXT_MAX_VAL_LEN + 1/* null terminators */;
	data = malloc(len);
	SPDK_CU_ASSERT_FATAL(data != NULL);
	memset(data, 'A', len);
	strcpy(data, "CHAP_C");
	data[6] = '=';
	data[len - 1] = '\0';
	rc = spdk_iscsi_parse_params(&params, data, len, false, NULL);
	CU_ASSERT(rc == 0);
	free(data);

	/* partial parameter: value is partial*/
	PARSE("C=AAA\0D=B", true, &partial_parameter);
	SPDK_CU_ASSERT_FATAL(partial_parameter != NULL);
	CU_ASSERT_STRING_EQUAL(partial_parameter, "D=B");
	CU_ASSERT(rc == 0);
	EXPECT_VAL("C", "AAA");
	EXPECT_NULL("D");
	PARSE("XXXX\0E=UUUU\0", false, &partial_parameter);
	CU_ASSERT(rc == 0);
	EXPECT_VAL("D", "BXXXX");
	EXPECT_VAL("E", "UUUU");
	CU_ASSERT_PTR_NULL(partial_parameter);

	/* partial parameter: key is partial*/
	PARSE("IAMAFAK", true, &partial_parameter);
	CU_ASSERT_STRING_EQUAL(partial_parameter, "IAMAFAK");
	CU_ASSERT(rc == 0);
	EXPECT_NULL("IAMAFAK");
	PARSE("EDKEY=TTTT\0F=IIII", false, &partial_parameter);
	CU_ASSERT(rc == 0);
	EXPECT_VAL("IAMAFAKEDKEY", "TTTT");
	EXPECT_VAL("F", "IIII");
	CU_ASSERT_PTR_NULL(partial_parameter);

	/* Second partial parameter is the only parameter */
	PARSE("OOOO", true, &partial_parameter);
	CU_ASSERT_STRING_EQUAL(partial_parameter, "OOOO");
	CU_ASSERT(rc == 0);
	EXPECT_NULL("OOOO");
	PARSE("LL=MMMM", false, &partial_parameter);
	CU_ASSERT(rc == 0);
	EXPECT_VAL("OOOOLL", "MMMM");
	CU_ASSERT_PTR_NULL(partial_parameter);

	spdk_iscsi_param_free(params);
}
static void didForceRepaint(WKErrorRef error, void*)
{
    EXPECT_NULL(error);
    test2Done = true;
}
Пример #24
0
static int doTestHdfsOperations(struct tlhThreadInfo *ti, hdfsFS fs,
                                const struct tlhPaths *paths)
{
    char tmp[4096];
    hdfsFile file;
    int ret, expected, numEntries;
    hdfsFileInfo *fileInfo;
    struct hdfsReadStatistics *readStats = NULL;

    if (hdfsExists(fs, paths->prefix) == 0) {
        EXPECT_ZERO(hdfsDelete(fs, paths->prefix, 1));
    }
    EXPECT_ZERO(hdfsCreateDirectory(fs, paths->prefix));

    EXPECT_ZERO(doTestGetDefaultBlockSize(fs, paths->prefix));

    /* There should be no entry in the directory. */
    errno = EACCES; // see if errno is set to 0 on success
    EXPECT_NULL_WITH_ERRNO(hdfsListDirectory(fs, paths->prefix, &numEntries), 0);
    if (numEntries != 0) {
        fprintf(stderr, "hdfsListDirectory set numEntries to "
                "%d on empty directory.", numEntries);
    }

    /* There should not be any file to open for reading. */
    EXPECT_NULL(hdfsOpenFile(fs, paths->file1, O_RDONLY, 0, 0, 0));

    /* hdfsOpenFile should not accept mode = 3 */
    EXPECT_NULL(hdfsOpenFile(fs, paths->file1, 3, 0, 0, 0));

    file = hdfsOpenFile(fs, paths->file1, O_WRONLY, 0, 0, 0);
    EXPECT_NONNULL(file);

    /* TODO: implement writeFully and use it here */
    expected = (int)strlen(paths->prefix);
    ret = hdfsWrite(fs, file, paths->prefix, expected);
    if (ret < 0) {
        ret = errno;
        fprintf(stderr, "hdfsWrite failed and set errno %d\n", ret);
        return ret;
    }
    if (ret != expected) {
        fprintf(stderr, "hdfsWrite was supposed to write %d bytes, but "
                "it wrote %d\n", ret, expected);
        return EIO;
    }
    EXPECT_ZERO(hdfsFlush(fs, file));
    EXPECT_ZERO(hdfsHSync(fs, file));
    EXPECT_ZERO(hdfsCloseFile(fs, file));

    /* There should be 1 entry in the directory. */
    EXPECT_NONNULL(hdfsListDirectory(fs, paths->prefix, &numEntries));
    if (numEntries != 1) {
        fprintf(stderr, "hdfsListDirectory set numEntries to "
                "%d on directory containing 1 file.", numEntries);
    }

    /* Let's re-open the file for reading */
    file = hdfsOpenFile(fs, paths->file1, O_RDONLY, 0, 0, 0);
    EXPECT_NONNULL(file);

    EXPECT_ZERO(hdfsFileGetReadStatistics(file, &readStats));
    errno = 0;
    EXPECT_UINT64_EQ(UINT64_C(0), readStats->totalBytesRead);
    EXPECT_UINT64_EQ(UINT64_C(0), readStats->totalLocalBytesRead);
    EXPECT_UINT64_EQ(UINT64_C(0), readStats->totalShortCircuitBytesRead);
    hdfsFileFreeReadStatistics(readStats);
    /* TODO: implement readFully and use it here */
    ret = hdfsRead(fs, file, tmp, sizeof(tmp));
    if (ret < 0) {
        ret = errno;
        fprintf(stderr, "hdfsRead failed and set errno %d\n", ret);
        return ret;
    }
    if (ret != expected) {
        fprintf(stderr, "hdfsRead was supposed to read %d bytes, but "
                "it read %d\n", ret, expected);
        return EIO;
    }
    EXPECT_ZERO(hdfsFileGetReadStatistics(file, &readStats));
    errno = 0;
    EXPECT_UINT64_EQ((uint64_t)expected, readStats->totalBytesRead);
    hdfsFileFreeReadStatistics(readStats);
    EXPECT_ZERO(hdfsFileClearReadStatistics(file));
    EXPECT_ZERO(hdfsFileGetReadStatistics(file, &readStats));
    EXPECT_UINT64_EQ((uint64_t)0, readStats->totalBytesRead);
    hdfsFileFreeReadStatistics(readStats);
    EXPECT_ZERO(memcmp(paths->prefix, tmp, expected));
    EXPECT_ZERO(hdfsCloseFile(fs, file));

    // TODO: Non-recursive delete should fail?
    //EXPECT_NONZERO(hdfsDelete(fs, prefix, 0));
    EXPECT_ZERO(hdfsCopy(fs, paths->file1, fs, paths->file2));

    EXPECT_ZERO(hdfsChown(fs, paths->file2, NULL, NULL));
    EXPECT_ZERO(hdfsChown(fs, paths->file2, NULL, "doop"));
    fileInfo = hdfsGetPathInfo(fs, paths->file2);
    EXPECT_NONNULL(fileInfo);
    EXPECT_ZERO(strcmp("doop", fileInfo->mGroup));
    EXPECT_ZERO(hdfsFileIsEncrypted(fileInfo));
    hdfsFreeFileInfo(fileInfo, 1);

    EXPECT_ZERO(hdfsChown(fs, paths->file2, "ha", "doop2"));
    fileInfo = hdfsGetPathInfo(fs, paths->file2);
    EXPECT_NONNULL(fileInfo);
    EXPECT_ZERO(strcmp("ha", fileInfo->mOwner));
    EXPECT_ZERO(strcmp("doop2", fileInfo->mGroup));
    hdfsFreeFileInfo(fileInfo, 1);

    EXPECT_ZERO(hdfsChown(fs, paths->file2, "ha2", NULL));
    fileInfo = hdfsGetPathInfo(fs, paths->file2);
    EXPECT_NONNULL(fileInfo);
    EXPECT_ZERO(strcmp("ha2", fileInfo->mOwner));
    EXPECT_ZERO(strcmp("doop2", fileInfo->mGroup));
    hdfsFreeFileInfo(fileInfo, 1);

    snprintf(tmp, sizeof(tmp), "%s/nonexistent-file-name", paths->prefix);
    EXPECT_NEGATIVE_ONE_WITH_ERRNO(hdfsChown(fs, tmp, "ha3", NULL), ENOENT);
    return 0;
}
Пример #25
0
static void
parse_invalid_test(void)
{
	struct iscsi_param *params;
	int rc;

	params = NULL;
	char *data;
	int len;

	/* key without '=' */
	PARSE("Abc\0", false, NULL);
	CU_ASSERT(rc != 0);
	EXPECT_NULL("Abc");

	/* multiple key=value pairs, one missing '=' */
	PARSE("Abc=def\0Xyz\0Www=test\0", false, NULL);
	CU_ASSERT(rc != 0);
	EXPECT_VAL("Abc", "def");
	EXPECT_NULL("Xyz");
	EXPECT_NULL("Www");

	/* empty key */
	PARSE("=abcdef", false, NULL);
	CU_ASSERT(rc != 0);
	EXPECT_NULL("");

	/* CHAP_C=AAAA.... with value length 8192 + 1 */
	len = strlen("CHAP_C=") + ISCSI_TEXT_MAX_VAL_LEN + 1 /* max value len + 1 */ +
	      1 /* null terminators */;
	data = malloc(len);
	SPDK_CU_ASSERT_FATAL(data != NULL);
	memset(data, 'A', len);
	strcpy(data, "CHAP_C");
	data[6] = '=';
	data[len - 1] = '\0';
	rc = spdk_iscsi_parse_params(&params, data, len, false, NULL);
	free(data);
	CU_ASSERT(rc != 0);
	EXPECT_NULL("CHAP_C");

	/* Test simple value, length of value bigger than 255*/
	len = strlen("A=") + ISCSI_TEXT_MAX_SIMPLE_VAL_LEN + 1 /* max simple value len + 1 */ +
	      1 /* null terminators */;
	data = malloc(len);
	SPDK_CU_ASSERT_FATAL(data != NULL);
	memset(data, 'A', len);
	data[1] = '=';
	data[len - 1] = '\0';
	rc = spdk_iscsi_parse_params(&params, data, len, false, NULL);
	free(data);
	CU_ASSERT(rc != 0);
	EXPECT_NULL("A");

	/* key length bigger than 63 */
	len = ISCSI_TEXT_MAX_KEY_LEN + 1 /*max key length + 1*/ + 1 /* = */ + 1 /* A */ +
	      1/* null terminators */;
	data = malloc(len);
	SPDK_CU_ASSERT_FATAL(data != NULL);
	memset(data, 'A', len);
	data[64] = '=';
	data[len - 1] = '\0';
	rc = spdk_iscsi_parse_params(&params, data, len, false, NULL);
	free(data);
	CU_ASSERT(rc != 0);
	EXPECT_NULL("A");

	/* duplicated key */
	PARSE("B=BB", false, NULL);
	CU_ASSERT(rc == 0);
	PARSE("B=BBBB", false, NULL);
	CU_ASSERT(rc != 0);
	EXPECT_VAL("B", "BB");

	spdk_iscsi_param_free(params);
}
Пример #26
0
static int doTestZeroCopyReads(hdfsFS fs, const char *fileName)
{
    hdfsFile file = NULL;
    struct hadoopRzOptions *opts = NULL;
    struct hadoopRzBuffer *buffer = NULL;
    uint8_t *block;

    file = hdfsOpenFile(fs, fileName, O_RDONLY, 0, 0, 0);
    EXPECT_NONNULL(file);
    opts = hadoopRzOptionsAlloc();
    EXPECT_NONNULL(opts);
    EXPECT_ZERO(hadoopRzOptionsSetSkipChecksum(opts, 1));
    /* haven't read anything yet */
    EXPECT_ZERO(expectFileStats(file, 0LL, 0LL, 0LL, 0LL));
    block = getZeroCopyBlockData(0);
    EXPECT_NONNULL(block);
    /* first read is half of a block. */
    buffer = hadoopReadZero(file, opts, TEST_ZEROCOPY_FULL_BLOCK_SIZE / 2);
    EXPECT_NONNULL(buffer);
    EXPECT_INT_EQ(TEST_ZEROCOPY_FULL_BLOCK_SIZE / 2,
          hadoopRzBufferLength(buffer));
    EXPECT_ZERO(memcmp(hadoopRzBufferGet(buffer), block,
          TEST_ZEROCOPY_FULL_BLOCK_SIZE / 2));
    hadoopRzBufferFree(file, buffer);
    /* read the next half of the block */
    buffer = hadoopReadZero(file, opts, TEST_ZEROCOPY_FULL_BLOCK_SIZE / 2);
    EXPECT_NONNULL(buffer);
    EXPECT_INT_EQ(TEST_ZEROCOPY_FULL_BLOCK_SIZE / 2,
          hadoopRzBufferLength(buffer));
    EXPECT_ZERO(memcmp(hadoopRzBufferGet(buffer),
          block + (TEST_ZEROCOPY_FULL_BLOCK_SIZE / 2),
          TEST_ZEROCOPY_FULL_BLOCK_SIZE / 2));
    hadoopRzBufferFree(file, buffer);
    free(block);
    EXPECT_ZERO(expectFileStats(file, TEST_ZEROCOPY_FULL_BLOCK_SIZE, 
              TEST_ZEROCOPY_FULL_BLOCK_SIZE,
              TEST_ZEROCOPY_FULL_BLOCK_SIZE,
              TEST_ZEROCOPY_FULL_BLOCK_SIZE));
    /* Now let's read just a few bytes. */
    buffer = hadoopReadZero(file, opts, SMALL_READ_LEN);
    EXPECT_NONNULL(buffer);
    EXPECT_INT_EQ(SMALL_READ_LEN, hadoopRzBufferLength(buffer));
    block = getZeroCopyBlockData(1);
    EXPECT_NONNULL(block);
    EXPECT_ZERO(memcmp(block, hadoopRzBufferGet(buffer), SMALL_READ_LEN));
    hadoopRzBufferFree(file, buffer);
    EXPECT_INT64_EQ(
          (int64_t)TEST_ZEROCOPY_FULL_BLOCK_SIZE + (int64_t)SMALL_READ_LEN,
          hdfsTell(fs, file));
    EXPECT_ZERO(expectFileStats(file,
          TEST_ZEROCOPY_FULL_BLOCK_SIZE + SMALL_READ_LEN,
          TEST_ZEROCOPY_FULL_BLOCK_SIZE + SMALL_READ_LEN,
          TEST_ZEROCOPY_FULL_BLOCK_SIZE + SMALL_READ_LEN,
          TEST_ZEROCOPY_FULL_BLOCK_SIZE + SMALL_READ_LEN));

    /* Clear 'skip checksums' and test that we can't do zero-copy reads any
     * more.  Since there is no ByteBufferPool set, we should fail with
     * EPROTONOSUPPORT.
     */
    EXPECT_ZERO(hadoopRzOptionsSetSkipChecksum(opts, 0));
    EXPECT_NULL(hadoopReadZero(file, opts, TEST_ZEROCOPY_FULL_BLOCK_SIZE));
    EXPECT_INT_EQ(EPROTONOSUPPORT, errno);

    /* Verify that setting a NULL ByteBufferPool class works. */
    EXPECT_ZERO(hadoopRzOptionsSetByteBufferPool(opts, NULL));
    EXPECT_ZERO(hadoopRzOptionsSetSkipChecksum(opts, 0));
    EXPECT_NULL(hadoopReadZero(file, opts, TEST_ZEROCOPY_FULL_BLOCK_SIZE));
    EXPECT_INT_EQ(EPROTONOSUPPORT, errno);

    /* Now set a ByteBufferPool and try again.  It should succeed this time. */
    EXPECT_ZERO(hadoopRzOptionsSetByteBufferPool(opts,
          ELASTIC_BYTE_BUFFER_POOL_CLASS));
    buffer = hadoopReadZero(file, opts, TEST_ZEROCOPY_FULL_BLOCK_SIZE);
    EXPECT_NONNULL(buffer);
    EXPECT_INT_EQ(TEST_ZEROCOPY_FULL_BLOCK_SIZE, hadoopRzBufferLength(buffer));
    EXPECT_ZERO(expectFileStats(file,
          (2 * TEST_ZEROCOPY_FULL_BLOCK_SIZE) + SMALL_READ_LEN,
          (2 * TEST_ZEROCOPY_FULL_BLOCK_SIZE) + SMALL_READ_LEN,
          (2 * TEST_ZEROCOPY_FULL_BLOCK_SIZE) + SMALL_READ_LEN,
          TEST_ZEROCOPY_FULL_BLOCK_SIZE + SMALL_READ_LEN));
    EXPECT_ZERO(memcmp(block + SMALL_READ_LEN, hadoopRzBufferGet(buffer),
        TEST_ZEROCOPY_FULL_BLOCK_SIZE - SMALL_READ_LEN));
    free(block);
    block = getZeroCopyBlockData(2);
    EXPECT_NONNULL(block);
    EXPECT_ZERO(memcmp(block, (uint8_t*)hadoopRzBufferGet(buffer) +
        (TEST_ZEROCOPY_FULL_BLOCK_SIZE - SMALL_READ_LEN), SMALL_READ_LEN));
    hadoopRzBufferFree(file, buffer);

    /* Check the result of a zero-length read. */
    buffer = hadoopReadZero(file, opts, 0);
    EXPECT_NONNULL(buffer);
    EXPECT_NONNULL(hadoopRzBufferGet(buffer));
    EXPECT_INT_EQ(0, hadoopRzBufferLength(buffer));
    hadoopRzBufferFree(file, buffer);

    /* Check the result of reading past EOF */
    EXPECT_INT_EQ(0, hdfsSeek(fs, file, TEST_ZEROCOPY_FILE_LEN));
    buffer = hadoopReadZero(file, opts, 1);
    EXPECT_NONNULL(buffer);
    EXPECT_NULL(hadoopRzBufferGet(buffer));
    hadoopRzBufferFree(file, buffer);

    /* Cleanup */
    free(block);
    hadoopRzOptionsFree(opts);
    EXPECT_ZERO(hdfsCloseFile(fs, file));
    return 0;
}
Пример #27
0
static bool ralloc_pools_c_api_test(void) {
    BEGIN_TEST;

    // Make a pool for the bookkeeping.  Do not allow it to be very large.
    // Require that this succeeds, we will not be able to run the tests without
    // it.
    ralloc_pool_t* pool;
    ASSERT_EQ(ZX_OK, ralloc_create_pool(REGION_POOL_MAX_SIZE, &pool), "");
    ASSERT_NONNULL(pool, "");

    // Create an allocator.
    ralloc_allocator_t* alloc;
    ASSERT_EQ(ZX_OK, ralloc_create_allocator(&alloc), "");
    ASSERT_NONNULL(alloc, "");

    {
        // Make sure that it refuses to perform any operations because it has no
        // RegionPool assigned to it yet.
        const ralloc_region_t tmp = { .base = 0u, .size = 1u };
        const ralloc_region_t* out;

        EXPECT_EQ(ZX_ERR_BAD_STATE, ralloc_add_region(alloc, &tmp, false), "");
        EXPECT_EQ(ZX_ERR_BAD_STATE, ralloc_get_sized_region_ex(alloc, 1u, 1u, &out), "");
        EXPECT_EQ(ZX_ERR_BAD_STATE, ralloc_get_specific_region_ex(alloc, &tmp, &out), "");
        EXPECT_NULL(ralloc_get_sized_region(alloc, 1u, 1u), "");
        EXPECT_NULL(ralloc_get_specific_region(alloc, &tmp), "");
    }

    // Assign our pool to our allocator, but hold onto the pool for now.
    EXPECT_EQ(ZX_OK, ralloc_set_region_pool(alloc, pool), "");

    // Release our pool reference.  The allocator should be holding onto its own
    // reference at this point.
    ralloc_release_pool(pool);
    pool = NULL;

    // Add some regions to our allocator.
    for (size_t i = 0; i < countof(GOOD_REGIONS); ++i)
        EXPECT_EQ(ZX_OK, ralloc_add_region(alloc, &GOOD_REGIONS[i], false), "");

    // Make a new pool and try to assign it to the allocator.  This should fail
    // because the allocator is currently using resources from its currently
    // assigned pool.
    ASSERT_EQ(ZX_OK, ralloc_create_pool(REGION_POOL_MAX_SIZE, &pool), "");
    ASSERT_NONNULL(pool, "");
    EXPECT_EQ(ZX_ERR_BAD_STATE, ralloc_set_region_pool(alloc, pool), "");

    // Add a bunch of adjacent regions to our pool.  Try to add so many
    // that we would normally run out of bookkeeping space.  We should not
    // actually run out, however, because the regions should get merged as they
    // get added.
    {
        ralloc_region_t tmp = { .base = GOOD_MERGE_REGION_BASE,
                                     .size = GOOD_MERGE_REGION_SIZE };
        for (size_t i = 0; i < OOM_RANGE_LIMIT; ++i) {
            ASSERT_EQ(ZX_OK, ralloc_add_region(alloc, &tmp, false), "");
            tmp.base += tmp.size;
        }
    }

    // Attempt (and fail) to add some bad regions (regions which overlap,
    // regions which wrap the address space)
    for (size_t i = 0; i < countof(BAD_REGIONS); ++i)
        EXPECT_EQ(ZX_ERR_INVALID_ARGS, ralloc_add_region(alloc, &BAD_REGIONS[i], false), "");

    // Force the region bookkeeping pool to run out of memory by adding more and
    // more regions until we eventuall run out of room.  Make sure that the
    // regions are not adjacent, or the internal bookkeeping will just merge
    // them.
    {
        size_t i;
        ralloc_region_t tmp = { .base = BAD_MERGE_REGION_BASE,
                                .size = BAD_MERGE_REGION_SIZE };
        for (i = 0; i < OOM_RANGE_LIMIT; ++i) {
            zx_status_t res;

            res = ralloc_add_region(alloc, &tmp, false);
            if (res != ZX_OK) {
                EXPECT_EQ(ZX_ERR_NO_MEMORY, res, "");
                break;
            }

            tmp.base += tmp.size + 1;
        }

        EXPECT_LT(i, OOM_RANGE_LIMIT, "");
    }

    // Reset allocator.  All of the existing available regions we had previously
    // added will be returned to the pool.
    ralloc_reset_allocator(alloc);

    // Now assign the second pool to the allocator.  Now that the allocator is
    // no longer using any resources, this should succeed.
    EXPECT_EQ(ZX_OK, ralloc_set_region_pool(alloc, pool), "");

    // Release our pool reference.
    ralloc_release_pool(pool);

    // Destroy our allocator.
    ralloc_destroy_allocator(alloc);

    END_TEST;
}

static bool ralloc_by_size_c_api_test(void) {
    BEGIN_TEST;

    // Make a pool and attach it to an allocator.  Then add the test regions to it.
    ralloc_allocator_t* alloc = NULL;
    {
        ralloc_pool_t* pool;
        ASSERT_EQ(ZX_OK, ralloc_create_pool(REGION_POOL_MAX_SIZE, &pool), "");
        ASSERT_NONNULL(pool, "");

        // Create an allocator and add our region pool to it.
        ASSERT_EQ(ZX_OK, ralloc_create_allocator(&alloc), "");
        ASSERT_NONNULL(alloc, "");
        ASSERT_EQ(ZX_OK, ralloc_set_region_pool(alloc, pool), "");

        // Release our pool reference.  The allocator should be holding onto its own
        // reference at this point.
        ralloc_release_pool(pool);
    }

    for (size_t i = 0; i < countof(ALLOC_BY_SIZE_REGIONS); ++i)
        EXPECT_EQ(ZX_OK, ralloc_add_region(alloc, &ALLOC_BY_SIZE_REGIONS[i], false), "");

    // Run the alloc by size tests.  Hold onto the regions it allocates so they
    // can be cleaned up properly when the test finishes.
    const ralloc_region_t* regions[countof(ALLOC_BY_SIZE_TESTS)];
    memset(regions, 0, sizeof(regions));

    for (size_t i = 0; i < countof(ALLOC_BY_SIZE_TESTS); ++i) {
        const alloc_by_size_alloc_test_t* TEST = ALLOC_BY_SIZE_TESTS + i;
        zx_status_t res = ralloc_get_sized_region_ex(alloc,
                                                     TEST->size,
                                                     TEST->align,
                                                     regions + i);

        // Make sure we get the test result we were expecting.
        EXPECT_EQ(TEST->res, res, "");

        // If the allocation claimed to succeed, we should have gotten
        // back a non-null region.  Otherwise, we should have gotten a
        // null region back.
        if (res == ZX_OK) {
            ASSERT_NONNULL(regions[i], "");
        } else {
            EXPECT_NULL(regions[i], "");
        }

        // If the allocation succeeded, and we expected it to succeed,
        // the allocation should have come from the test region we
        // expect and be aligned in the way we asked.
        if ((res == ZX_OK) && (TEST->res == ZX_OK)) {
            ASSERT_LT(TEST->region, countof(ALLOC_BY_SIZE_TESTS), "");
            EXPECT_TRUE(region_contains_region(ALLOC_BY_SIZE_REGIONS + TEST->region,
                                               regions[i]), "");
            EXPECT_EQ(0u, regions[i]->base & (TEST->align - 1), "");
        }
    }

    // Put the regions we have allocated back in the allocator.
    for (size_t i = 0; i < countof(regions); ++i)
        if (regions[i])
            ralloc_put_region(regions[i]);

    // Destroy our allocator.
    ralloc_destroy_allocator(alloc);

    END_TEST;
}