~kdub/unity-system-compositor/unblock-silo0

« back to all changes in this revision

Viewing changes to tests/integration-tests/test_external_spinner.cpp

  • Committer: Andreas Pokorny
  • Date: 2015-07-31 14:11:27 UTC
  • mfrom: (200.4.6 unity-system-compositor)
  • Revision ID: andreas.pokorny@canonical.com-20150731141127-pkvvz9ppwiyrt03c
update to recent unity-system-compositor changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
#include "src/external_spinner.h"
20
20
#include "run_command.h"
 
21
#include "spin_wait.h"
21
22
 
22
23
#include <fstream>
23
24
#include <chrono>
70
71
    return pids;
71
72
}
72
73
 
 
74
bool is_zombie(pid_t pid)
 
75
{
 
76
    std::ifstream stat("/proc/" + std::to_string(pid) + "/stat");
 
77
 
 
78
    std::stringstream ss;
 
79
    ss << stat.rdbuf();
 
80
 
 
81
    return ss.str().find(" Z ") != std::string::npos;
 
82
}
 
83
 
73
84
struct AnExternalSpinner : testing::Test
74
85
{
75
86
    std::vector<pid_t> spinner_pids()
76
87
    {
77
 
        return pidof(spinner_cmd);
 
88
        std::vector<pid_t> pids;
 
89
 
 
90
        usc::test::spin_wait_for_condition_or_timeout(
 
91
            [&pids, this] { pids = pidof(spinner_cmd); return !pids.empty(); },
 
92
            timeout);
 
93
 
 
94
        if (pids.empty())
 
95
            BOOST_THROW_EXCEPTION(std::runtime_error("spinner_pids timed out"));
 
96
 
 
97
        return pids;
78
98
    }
79
99
 
80
100
    std::vector<std::string> environment_of_spinner()
81
101
    {
82
 
        auto const pids = pidof(spinner_cmd);
 
102
        auto const pids = spinner_pids();
83
103
        if (pids.size() > 1)
84
104
            BOOST_THROW_EXCEPTION(std::runtime_error("Detected multiple spinner processes"));
85
105
        std::vector<std::string> env;
96
116
 
97
117
    void wait_for_spinner_to_terminate()
98
118
    {
99
 
        auto const timeout = std::chrono::milliseconds{3000};
100
 
        auto const expire = std::chrono::steady_clock::now() + timeout;
101
 
 
102
 
        while (spinner_pids().size() > 0)
103
 
        {
104
 
            if (std::chrono::steady_clock::now() > expire)
105
 
                BOOST_THROW_EXCEPTION(std::runtime_error("wait_for_no_spinner timed out"));
106
 
            std::this_thread::sleep_for(std::chrono::milliseconds{10});
107
 
        }
 
119
        usc::test::spin_wait_for_condition_or_timeout(
 
120
            [this] { return pidof(spinner_cmd).empty(); },
 
121
            timeout);
108
122
    }
109
123
 
110
124
    std::string const spinner_cmd{executable_path() + "/usc_test_helper_wait_for_signal"};
111
125
    std::string const mir_socket{"usc_mir_socket"};
 
126
    std::chrono::milliseconds const timeout{3000};
112
127
    usc::ExternalSpinner spinner{spinner_cmd, mir_socket};
113
128
};
114
129
 
165
180
 
166
181
    EXPECT_THAT(environment_of_spinner(), Contains("MIR_SOCKET=" + mir_socket));
167
182
}
 
183
 
 
184
TEST_F(AnExternalSpinner, does_not_leave_zombie_process)
 
185
{
 
186
    using namespace testing;
 
187
 
 
188
    spinner.ensure_running();
 
189
    auto const spinner_pid = spinner_pids()[0];
 
190
    spinner.kill();
 
191
 
 
192
    wait_for_spinner_to_terminate();
 
193
 
 
194
    // Wait a bit for zombie to be reaped by parent
 
195
    bool const spinner_is_not_zombie = usc::test::spin_wait_for_condition_or_timeout(
 
196
        [spinner_pid] { return !is_zombie(spinner_pid); },
 
197
        timeout);
 
198
 
 
199
    EXPECT_TRUE(spinner_is_not_zombie);
 
200
}