Mir

Merge lp:~vanvugt/mir/system-performance into lp:mir

Proposed by Daniel van Vugt
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 3708
Proposed branch: lp:~vanvugt/mir/system-performance
Merge into: lp:mir
Diff against target: 478 lines (+253/-164)
4 files modified
tests/performance-tests/CMakeLists.txt (+5/-0)
tests/performance-tests/system_performance_test.cpp (+191/-0)
tests/performance-tests/system_performance_test.h (+46/-0)
tests/performance-tests/test_compositor.cpp (+11/-164)
To merge this branch: bzr merge lp:~vanvugt/mir/system-performance
Reviewer Review Type Date Requested Status
Mir CI Bot continuous-integration Approve
Cemil Azizoglu (community) Approve
Review via email: mp+305923@code.launchpad.net

Commit message

Generalise CompositorTest into "SystemPerformanceTest" so we can reuse
it for non-compositor system performance testing.

To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3707
https://mir-jenkins.ubuntu.com/job/mir-ci/1744/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/2184
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/2247
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/2238
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/2238
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/2238
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/2212
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/2212/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/2212
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/2212/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/2212
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/2212/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/2212
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/2212/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/2212
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/2212/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/1744/rebuild

review: Approve (continuous-integration)
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

ok

review: Approve
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Autolanding.
More details in the following jenkins job:
https://mir-jenkins.ubuntu.com/job/mir-autolanding/595/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/2189/console
    None: https://mir-jenkins.ubuntu.com/job/generic-land-mp/634/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/2252
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/2243
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/2243
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/2243
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/2217
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/2217/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/2217
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/2217/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/2217
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/2217/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/2217
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/2217/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/2217/console

review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

^^^
Bug 1523621, unrelated.

Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Autolanding.
More details in the following jenkins job:
https://mir-jenkins.ubuntu.com/job/mir-autolanding/596/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/2192/console
    None: https://mir-jenkins.ubuntu.com/job/generic-land-mp/635/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/2255
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/2246
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/2246
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/2246
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/2220
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/2220/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/2220
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/2220/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/2220/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/2220
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/2220/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/2220
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/2220/artifact/output/*zip*/output.zip

review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

^^^
Bug 1616312 now

Revision history for this message
Mir CI Bot (mir-ci-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/performance-tests/CMakeLists.txt'
2--- tests/performance-tests/CMakeLists.txt 2016-08-24 02:09:08 +0000
3+++ tests/performance-tests/CMakeLists.txt 2016-09-16 10:11:25 +0000
4@@ -27,11 +27,16 @@
5 ${GTEST_BOTH_LIBRARIES}
6 )
7
8+add_library(mir_system_performance_test STATIC
9+ system_performance_test.cpp
10+)
11+
12 mir_add_wrapped_executable(mir_compositor_performance_test
13 test_compositor.cpp
14 )
15 target_link_libraries(mir_compositor_performance_test
16 ${GTEST_BOTH_LIBRARIES}
17+ mir_system_performance_test
18 )
19
20 mir_add_wrapped_executable(mir_client_startup_performance_test
21
22=== added file 'tests/performance-tests/system_performance_test.cpp'
23--- tests/performance-tests/system_performance_test.cpp 1970-01-01 00:00:00 +0000
24+++ tests/performance-tests/system_performance_test.cpp 2016-09-16 10:11:25 +0000
25@@ -0,0 +1,191 @@
26+/*
27+ * Copyright © 2016 Canonical Ltd.
28+ *
29+ * This program is free software: you can redistribute it and/or modify it
30+ * under the terms of the GNU General Public License version 3,
31+ * as published by the Free Software Foundation.
32+ *
33+ * This program is distributed in the hope that it will be useful,
34+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
35+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36+ * GNU General Public License for more details.
37+ *
38+ * You should have received a copy of the GNU General Public License
39+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
40+ *
41+ * Author: Daniel van Vugt <daniel.van.vugt@canonical.com>
42+ */
43+
44+#include "system_performance_test.h"
45+#include <cstdio>
46+#include <cstdlib>
47+#include <cstring>
48+#include <unistd.h>
49+#include <string>
50+#include <thread>
51+
52+using namespace std::literals::chrono_literals;
53+
54+namespace
55+{
56+
57+std::string mir_bin_dir()
58+{
59+ char path[256];
60+ auto len = readlink("/proc/self/exe", path, sizeof(path)-1);
61+ if (len < 0)
62+ len = 0;
63+ path[len] = '\0';
64+ if (auto slash = strrchr(path, '/'))
65+ *slash = '\0';
66+ return path;
67+}
68+
69+void kill_nicely(pid_t pid)
70+{
71+ if (kill(pid, SIGTERM) < 0)
72+ return;
73+ int const timeout = 5;
74+ int status, count = 0;
75+ while (0 == waitpid(pid, &status, WNOHANG) && count < timeout)
76+ {
77+ sleep(1);
78+ ++count;
79+ }
80+ kill(pid, SIGKILL);
81+}
82+
83+int exec_cmd(char const* cmd)
84+{
85+ auto buf = strdup(cmd);
86+ size_t argc = 1;
87+ char* argv[256] = {buf};
88+ char *c = buf;
89+ while (*c)
90+ {
91+ if (*c == ' ')
92+ {
93+ *c = '\0';
94+ if (argc < (sizeof(argv)/sizeof(argv[0]) - 1))
95+ {
96+ argv[argc] = c + 1;
97+ ++argc;
98+ }
99+ }
100+ ++c;
101+ }
102+ argv[argc] = NULL;
103+ return execv(argv[0], argv);
104+}
105+
106+FILE* popen_with_pid(char const* cmd, pid_t& pid)
107+{
108+ int pipefd[2];
109+ if (pipe(pipefd))
110+ return NULL;
111+
112+ int const& pipe_out = pipefd[0];
113+ int const& pipe_in = pipefd[1];
114+
115+ pid = fork();
116+ if (pid < 0)
117+ {
118+ close(pipe_in);
119+ close(pipe_out);
120+ return NULL;
121+ }
122+ else if (pid == 0)
123+ {
124+ close(pipe_out);
125+ dup2(pipe_in, 1); // Child stdout goes into pipe_in
126+ close(pipe_in);
127+ exec_cmd(cmd);
128+ exit(errno);
129+ }
130+ else
131+ {
132+ close(pipe_in);
133+ }
134+
135+ return fdopen(pipe_out, "r");
136+}
137+
138+bool spawn_and_forget(char const* cmd)
139+{
140+ int pid = fork();
141+ if (pid == 0)
142+ {
143+ // Silence stdout/stderr
144+ close(1);
145+ close(2);
146+ exec_cmd(cmd);
147+ exit(errno);
148+ }
149+ return (pid > 0);
150+}
151+
152+bool spawn_and_forget(std::string const& cmd)
153+{
154+ return spawn_and_forget(cmd.c_str());
155+}
156+
157+bool wait_for_file(char const* path, std::chrono::seconds timeout)
158+{
159+ struct stat s;
160+ int count = 0, max = timeout.count();
161+ int ret;
162+ while ((ret = stat(path, &s)) < 0 && errno == ENOENT && count < max)
163+ {
164+ ++count;
165+ std::this_thread::sleep_for(1s);
166+ }
167+ return ret == 0;
168+}
169+
170+} // anonymous namespace
171+
172+namespace mir { namespace test {
173+
174+SystemPerformanceTest::SystemPerformanceTest() : bin_dir{mir_bin_dir()}
175+{
176+}
177+
178+void SystemPerformanceTest::SetUp(std::string const server_args)
179+{
180+ auto const mir_sock = "/tmp/mir_test_socket_"+std::to_string(getpid());
181+ auto const server_cmd =
182+ bin_dir+"/mir_demo_server -f "+mir_sock+" "+server_args;
183+
184+ server_output = popen_with_pid(server_cmd.c_str(), server_pid);
185+ ASSERT_TRUE(server_output) << server_cmd;
186+ ASSERT_TRUE(wait_for_file(mir_sock.c_str(), 5s)) << server_cmd;
187+ setenv("MIR_SOCKET", mir_sock.c_str(), 1);
188+}
189+
190+void SystemPerformanceTest::TearDown()
191+{
192+ kill_nicely(server_pid);
193+ fclose(server_output);
194+}
195+
196+void SystemPerformanceTest::spawn_clients(std::initializer_list<std::string> clients)
197+{
198+ for (auto& client : clients)
199+ {
200+ spawn_and_forget(bin_dir+"/"+client);
201+ std::this_thread::sleep_for(100ms);
202+ }
203+}
204+
205+void SystemPerformanceTest::run_server_for(std::chrono::seconds timeout)
206+{
207+ pid_t pid = server_pid;
208+ std::thread killer([timeout,pid]()
209+ {
210+ std::this_thread::sleep_for(timeout);
211+ kill_nicely(pid);
212+ });
213+ killer.detach();
214+}
215+
216+} } // namespace mir::test
217
218=== added file 'tests/performance-tests/system_performance_test.h'
219--- tests/performance-tests/system_performance_test.h 1970-01-01 00:00:00 +0000
220+++ tests/performance-tests/system_performance_test.h 2016-09-16 10:11:25 +0000
221@@ -0,0 +1,46 @@
222+/*
223+ * Copyright © 2016 Canonical Ltd.
224+ *
225+ * This program is free software: you can redistribute it and/or modify it
226+ * under the terms of the GNU General Public License version 3,
227+ * as published by the Free Software Foundation.
228+ *
229+ * This program is distributed in the hope that it will be useful,
230+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
231+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
232+ * GNU General Public License for more details.
233+ *
234+ * You should have received a copy of the GNU General Public License
235+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
236+ *
237+ * Author: Daniel van Vugt <daniel.van.vugt@canonical.com>
238+ */
239+
240+#ifndef MIR_TEST_SYSTEM_PERFORMANCE_TEST_H_
241+#define MIR_TEST_SYSTEM_PERFORMANCE_TEST_H_
242+
243+#include <gtest/gtest.h>
244+#include <string>
245+#include <chrono>
246+#include <initializer_list>
247+
248+namespace mir { namespace test {
249+
250+class SystemPerformanceTest : public testing::Test
251+{
252+protected:
253+ SystemPerformanceTest();
254+ void SetUp(std::string const server_args);
255+ void TearDown() override;
256+ void spawn_clients(std::initializer_list<std::string> clients);
257+ void run_server_for(std::chrono::seconds timeout);
258+
259+ FILE* server_output;
260+private:
261+ std::string const bin_dir;
262+ pid_t server_pid = 0;
263+};
264+
265+} } // namespace mir::test
266+
267+#endif // MIR_TEST_SYSTEM_PERFORMANCE_TEST_H_
268
269=== modified file 'tests/performance-tests/test_compositor.cpp'
270--- tests/performance-tests/test_compositor.cpp 2016-05-09 02:49:10 +0000
271+++ tests/performance-tests/test_compositor.cpp 2016-09-16 10:11:25 +0000
272@@ -16,174 +16,23 @@
273 * Author: Daniel van Vugt <daniel.van.vugt@canonical.com>
274 */
275
276-#include <gtest/gtest.h>
277-#include <cstdio>
278-#include <cstdlib>
279-#include <cstring>
280-#include <unistd.h>
281-#include <string>
282-#include <thread>
283-#include <initializer_list>
284+#include "system_performance_test.h"
285
286 using namespace std::literals::chrono_literals;
287+using namespace mir::test;
288
289 namespace
290 {
291-
292-std::string mir_bin_dir()
293-{
294- char path[256];
295- auto len = readlink("/proc/self/exe", path, sizeof(path)-1);
296- if (len < 0)
297- len = 0;
298- path[len] = '\0';
299- if (auto slash = strrchr(path, '/'))
300- *slash = '\0';
301- return path;
302-}
303-
304-void kill_nicely(pid_t pid)
305-{
306- if (kill(pid, SIGTERM) < 0)
307- return;
308- int const timeout = 5;
309- int status, count = 0;
310- while (0 == waitpid(pid, &status, WNOHANG) && count < timeout)
311- {
312- sleep(1);
313- ++count;
314- }
315- kill(pid, SIGKILL);
316-}
317-
318-int exec_cmd(char const* cmd)
319-{
320- auto buf = strdup(cmd);
321- size_t argc = 1;
322- char* argv[256] = {buf};
323- char *c = buf;
324- while (*c)
325- {
326- if (*c == ' ')
327- {
328- *c = '\0';
329- if (argc < (sizeof(argv)/sizeof(argv[0]) - 1))
330- {
331- argv[argc] = c + 1;
332- ++argc;
333- }
334- }
335- ++c;
336- }
337- argv[argc] = NULL;
338- return execv(argv[0], argv);
339-}
340-
341-FILE* popen_with_pid(char const* cmd, pid_t& pid)
342-{
343- int pipefd[2];
344- if (pipe(pipefd))
345- return NULL;
346-
347- int const& pipe_out = pipefd[0];
348- int const& pipe_in = pipefd[1];
349-
350- pid = fork();
351- if (pid < 0)
352- {
353- close(pipe_in);
354- close(pipe_out);
355- return NULL;
356- }
357- else if (pid == 0)
358- {
359- close(pipe_out);
360- dup2(pipe_in, 1); // Child stdout goes into pipe_in
361- close(pipe_in);
362- exec_cmd(cmd);
363- exit(errno);
364- }
365- else
366- {
367- close(pipe_in);
368- }
369-
370- return fdopen(pipe_out, "r");
371-}
372-
373-bool spawn_and_forget(char const* cmd)
374-{
375- int pid = fork();
376- if (pid == 0)
377- {
378- // Silence stdout/stderr
379- close(1);
380- close(2);
381- exec_cmd(cmd);
382- exit(errno);
383- }
384- return (pid > 0);
385-}
386-
387-bool spawn_and_forget(std::string const& cmd)
388-{
389- return spawn_and_forget(cmd.c_str());
390-}
391-
392-bool wait_for_file(char const* path, std::chrono::seconds timeout)
393-{
394- struct stat s;
395- int count = 0, max = timeout.count();
396- int ret;
397- while ((ret = stat(path, &s)) < 0 && errno == ENOENT && count < max)
398- {
399- ++count;
400- std::this_thread::sleep_for(1s);
401- }
402- return ret == 0;
403-}
404-
405-struct CompositorPerformance : testing::Test
406+struct CompositorPerformance : SystemPerformanceTest
407 {
408 void SetUp() override
409 {
410 compositor_fps = compositor_render_time = -1.0f;
411-
412- auto const mir_sock = "/tmp/mir_test_socket_"+std::to_string(getpid());
413- auto const server_cmd =
414- bin_dir+"/mir_demo_server --compositor-report=log -f "+mir_sock;
415-
416- server_output = popen_with_pid(server_cmd.c_str(), server_pid);
417- ASSERT_TRUE(server_output) << server_cmd;
418- ASSERT_TRUE(wait_for_file(mir_sock.c_str(), 5s)) << server_cmd;
419- setenv("MIR_SOCKET", mir_sock.c_str(), 1);
420- }
421-
422- void TearDown() override
423- {
424- kill_nicely(server_pid);
425- fclose(server_output);
426- }
427-
428- void spawn_clients(std::initializer_list<std::string> clients)
429- {
430- for (auto& client : clients)
431- {
432- spawn_and_forget(bin_dir+"/"+client);
433- std::this_thread::sleep_for(100ms);
434- }
435- }
436-
437- void wait_for_server(std::chrono::seconds timeout)
438- {
439- pid_t pid = server_pid;
440- std::thread killer([timeout,pid]()
441- {
442- std::this_thread::sleep_for(timeout);
443- kill_nicely(pid);
444- });
445- killer.detach();
446-
447+ SystemPerformanceTest::SetUp("--compositor-report=log");
448+ }
449+
450+ void read_compositor_report()
451+ {
452 char line[256];
453 while (fgets(line, sizeof(line), server_output))
454 {
455@@ -200,12 +49,8 @@
456 }
457 }
458
459- std::string const bin_dir{mir_bin_dir()};
460- pid_t server_pid = 0;
461- FILE* server_output;
462 float compositor_fps, compositor_render_time;
463 };
464-
465 } // anonymous namespace
466
467 TEST_F(CompositorPerformance, regression_test_1563287)
468@@ -216,7 +61,9 @@
469 "mir_demo_client_scroll",
470 "mir_demo_client_egltriangle -b0.5",
471 "mir_demo_client_multiwin"});
472- wait_for_server(10s);
473+ run_server_for(10s);
474+
475+ read_compositor_report();
476 EXPECT_GE(compositor_fps, 58.0f);
477 EXPECT_LT(compositor_render_time, 17.0f);
478 }

Subscribers

People subscribed via source and target branches