Ejemplo n.º 1
0
TEST_F(ServerStartup, after_server_sigkilled_can_start_new_instance)
{
    ASSERT_FALSE(mtf::detect_server(mtf::test_socket_file(), std::chrono::milliseconds(0)));

    run_in_server([]{});

    if (is_test_process())
    {
        /* Under valgrind, raise(SIGKILL) results in a memcheck orphan process
         * we kill the server process from the test process instead
         */
        EXPECT_TRUE(sigkill_server_process());

        run_in_server([]{});
    }

    run_in_client([]
        {
            EXPECT_TRUE(mtf::detect_server(mtf::test_socket_file(),
                                           std::chrono::milliseconds(100)));
        });
}
Ejemplo n.º 2
0
int find_test_symbol(Context * ctx, const char * name, void ** addr, int * sym_class) {
    /* This code allows to run TCF diagnostic tests when symbols info is not available */
    if (is_test_process(ctx) && strncmp(name, "tcf_test_", 9) == 0) {
        *addr = NULL;
        if (strcmp(name, "tcf_test_array") == 0) {
            *sym_class = SYM_CLASS_REFERENCE;
            *addr = &tcf_test_array;
        }
        else if (strcmp(name, "tcf_test_char") == 0) {
            *sym_class = SYM_CLASS_REFERENCE;
            *addr = &tcf_test_char;
        }
        else {
            *sym_class = SYM_CLASS_FUNCTION;
            if (strcmp(name, "tcf_test_func0") == 0) *addr = (void *)&tcf_test_func0;
            else if (strcmp(name, "tcf_test_func1") == 0) *addr = (void *)&tcf_test_func1;
            else if (strcmp(name, "tcf_test_func2") == 0) *addr = (void *)&tcf_test_func2;
            else if (strcmp(name, "tcf_test_func3") == 0) *addr = (void *)&tcf_test_func3;
        }
        if (*addr != NULL) return 0;
    }
    errno = ERR_SYM_NOT_FOUND;
    return -1;
}
TEST_F(UnresponsiveClient, does_not_hang_server)
{
    mt::CrossProcessAction server_send_events;
    mt::CrossProcessAction client_connect;
    mt::CrossProcessAction client_release;
    mt::CrossProcessAction server_finish;

    SessionListener sessions;

    init_server([&]
         {
            server.override_the_session_listener([&]
                { return mt::fake_shared(sessions); });
         });

    run_in_server([&]
        {
            mt::AutoJoinThread t{
                [&] {
                    server_send_events.exec([&]
                        {
                            for (int i = 0; i < 1000; ++i)
                            {
                                sessions.for_each(
                                    [i] (std::shared_ptr<ms::Session> const& session)
                                    {
                                        session->default_surface()->resize({i + 1, i + 1});
                                    });
                            }
                        });
                }};

            server_finish.exec([]{});
        });

    auto const client_code = [&]
    {
        MirConnection* connection = nullptr;
        MirSurface* surface = nullptr;

        client_connect.exec([&]
            {
                connection = mir_connect_sync(mir_test_socket, __PRETTY_FUNCTION__);

                surface = mtf::make_any_surface(connection);
            });

        client_release.exec([&]
            {
                // We would normally explicitly release the surface at this
                // point. However, because we have been filling the server
                // send socket buffer, releasing the surface may cause the
                // server to try to write to a full socket buffer when
                // responding, leading the server to believe that the client
                // is blocked, and causing a premature client disconnection.
                mir_connection_release(connection);
            });
    };

    auto client_process = new_client_process(client_code);

    if (is_test_process())
    {
        client_connect();
        kill(client_pid(), SIGSTOP);
        try 
        { 
            server_send_events(std::chrono::seconds{10});
        }
        catch(...)
        { 
            ADD_FAILURE() << "Server blocked while sending events";
        }
        kill(client_pid(), SIGCONT);
        client_release();
        server_finish();

        auto const result = client_process->wait_for_termination();
        EXPECT_THAT(result.exit_code, testing::Eq(EXIT_SUCCESS));
    }
}