Merge lp:~chasedouglas/xorg-gtest/fixes into lp:~oif-team/xorg-gtest/trunk

Proposed by Chase Douglas on 2011-12-08
Status: Merged
Merged at revision: 3
Proposed branch: lp:~chasedouglas/xorg-gtest/fixes
Merge into: lp:~oif-team/xorg-gtest/trunk
Diff against target: 595 lines (+377/-87)
8 files modified
Makefile.am (+10/-5)
include/xorg/gtest/environment.h (+14/-5)
include/xorg/gtest/process.h (+59/-0)
include/xorg/gtest/test.h (+57/-0)
src/environment.cpp (+53/-60)
src/main.cpp (+37/-17)
src/process.cpp (+98/-0)
src/test.cpp (+49/-0)
To merge this branch: bzr merge lp:~chasedouglas/xorg-gtest/fixes
Reviewer Review Type Date Requested Status
Thomas Voß (community) 2011-12-08 Approve on 2011-12-12
Stephen M. Webb (community) Approve on 2011-12-09
Review via email: mp+84896@code.launchpad.net

Description of the change

A ton of fixes and changes. Highlights:

* Based on Thomas' process class branch
* Fix Process::Start() (variadic args weren't handled properly)
* Use exceptions instead of return codes where it makes sense
* Add server executable path option
* Add basic xorg::testing::Test fixture for opening a connection to the server

I have reworked my utouch-frame v2-tests branch on top of this API, and things seem to work well.

To post a comment you must log in.
Stephen M. Webb (bregma) wrote :

(1) "make install" doesn't install the headers.

(2) in xorg::testing::Environment::SetUp(), the first parameter is a std::string, but std::string::c_str() is passed.

(3) the error messages in xorg::testing::Environment::TearDown() are missing newlines.

(4) xorg::testing::Process::Start() does a lot of simulating the new operator by using malloc() followed by a 'throw bad_alloc' on failure: argv at least should be a std::vector<char*>, eliminating all mallocs and reallocs.

(5) can the pimpls be made std::unique_ptrs instead of using explicit deletes (this is not a big thing).

(6) either a constructor should be added to xorg::testing::Environment::Private or a uniform initializer should be used in the initialization list in the xorg::testing::Environment constructor when initializing Private members (it's bad form to initialize someone else's members). Same goes for xorg::testing::Process::Private.

(7) Why use the C-compatibility headers (eg. string.h, stdlib.h, errno.h) instead of the C++ headers (<cstring>, <cstdlib>, <cerrno>) if this is C++ code? It's not broken, it's just a little inconsistent.

But when all is said and done, this works well.

review: Needs Fixing
Chase Douglas (chasedouglas) wrote :

> (1) "make install" doesn't install the headers.

It does here... Any ideas why it wasn't working on your system?

> (2) in xorg::testing::Environment::SetUp(), the first parameter is a
> std::string, but std::string::c_str() is passed.

Fixed.

> (3) the error messages in xorg::testing::Environment::TearDown() are missing
> newlines.

Fixed.

> (4) xorg::testing::Process::Start() does a lot of simulating the new operator
> by using malloc() followed by a 'throw bad_alloc' on failure: argv at least
> should be a std::vector<char*>, eliminating all mallocs and reallocs.

Unfortunately, I can't find a version of exec* that takes an va_list. The two main versions are execl, which is variadic, and execv, which takes a typical argv list. There isn't a way to programatically call a variadic function, so that leaves us having to create an array.

While it would be nice if we could use std::vector, there's no method that provides a c-style array like std::string::data(). My first attempt was to copy all the arrays into a std::vector, and then use the size of the std::vector to allocate the argv array. This seemed like a bunch of duplicitous effort, so I wrote a pure C version. I'm not sure which is better, but I don't think it makes sense to switch it from one annoying implementation to another.

Any ideas on how to make this better?

> (5) can the pimpls be made std::unique_ptrs instead of using explicit deletes
> (this is not a big thing).

Fixed.

> (6) either a constructor should be added to
> xorg::testing::Environment::Private or a uniform initializer should be used in
> the initialization list in the xorg::testing::Environment constructor when
> initializing Private members (it's bad form to initialize someone else's
> members). Same goes for xorg::testing::Process::Private.

The private members are POD structs. They don't have privacy, and they don't have methods. It seems overkill to make them full classes. And because these are just pimpls, it's not really the same as one normal class initializing another normal class' members.

Do you think we should make them full classes?

> (7) Why use the C-compatibility headers (eg. string.h, stdlib.h, errno.h)
> instead of the C++ headers (<cstring>, <cstdlib>, <cerrno>) if this is C++
> code? It's not broken, it's just a little inconsistent.

Fixed.

> But when all is said and done, this works well.

Great!

Chase Douglas (chasedouglas) wrote :

> > (4) xorg::testing::Process::Start() does a lot of simulating the new
> operator
> > by using malloc() followed by a 'throw bad_alloc' on failure: argv at least
> > should be a std::vector<char*>, eliminating all mallocs and reallocs.
>
> Unfortunately, I can't find a version of exec* that takes an va_list. The two
> main versions are execl, which is variadic, and execv, which takes a typical
> argv list. There isn't a way to programatically call a variadic function, so
> that leaves us having to create an array.
>
> While it would be nice if we could use std::vector, there's no method that
> provides a c-style array like std::string::data(). My first attempt was to
> copy all the arrays into a std::vector, and then use the size of the
> std::vector to allocate the argv array. This seemed like a bunch of
> duplicitous effort, so I wrote a pure C version. I'm not sure which is better,
> but I don't think it makes sense to switch it from one annoying implementation
> to another.
>
> Any ideas on how to make this better?

I used something called Google and found someone stating that the the pointer to the first element in a vector should:

* Be stable until the array is reallocated
* Should act like an array (i.e. (&vector[0] + 1) == &vector[1])

Though I didn't double-check the C++ standard, these rules pass the sniff test. I rewrote the argument handling to take this into account. I also realized that the strings pointed to by the arguments should still be valid, so there's no real need for the strdup'ing I had in there. The code is much cleaner and compact now.

Stephen M. Webb (bregma) wrote :

> The private members are POD structs. They don't have privacy, and they don't have methods. It seems overkill to make
> them full classes. And because these are just pimpls, it's not really the same as one normal class initializing
> another normal class' members.

xorg::testing::Environment::Private is not a POD because it contains 3 members (path_to_conf, path_to_server, and Process) that are not POD. The (default) constructor that's being used does not do the wrong thing, but you're almost always better off initializing members with the correct data on construction than to default-construct them and then immediately reset them with different data.

I would still suggest adding an explicit constructor to that class just to initialize it members. It's not a sin to make it explicit.

xorg::testing::Process::Private is a POD and uniform initialization syntax can be used so that it can be initialized in the Process initializer list. Uniform initialization syntax requires C++11 to be enabled in the compiler.

The Process constructor would then become this.

xorg::testing::Process::Process() : d_(new Private{-1}) {
}

Thomas Voß (thomas-voss) wrote :

I do agree with Stephen's comments.

One minor remark: The file headers still hint to utouch-frame.

review: Needs Fixing
Thomas Voß (thomas-voss) wrote :

> I do agree with Stephen's comments.
>
> One minor remark: The file headers still hint to utouch-frame.

Fixed in https://code.launchpad.net/~thomas-voss/xorg-gtest/Doxygen.

Chase Douglas (chasedouglas) wrote :

> > The private members are POD structs. They don't have privacy, and they don't
> have methods. It seems overkill to make
> > them full classes. And because these are just pimpls, it's not really the
> same as one normal class initializing
> > another normal class' members.
>
> xorg::testing::Environment::Private is not a POD because it contains 3 members
> (path_to_conf, path_to_server, and Process) that are not POD. The (default)
> constructor that's being used does not do the wrong thing, but you're almost
> always better off initializing members with the correct data on construction
> than to default-construct them and then immediately reset them with different
> data.
>
> I would still suggest adding an explicit constructor to that class just to
> initialize it members. It's not a sin to make it explicit.

Fixed.

> xorg::testing::Process::Private is a POD and uniform initialization syntax can
> be used so that it can be initialized in the Process initializer list.
> Uniform initialization syntax requires C++11 to be enabled in the compiler.

I don't want to make this depend on C++11 so that people wanting to test servers on old platforms are excluded. I've left it as is.

Stephen M. Webb (bregma) wrote :

I think this is Good Enough.

review: Approve
Thomas Voß (thomas-voss) wrote :

Looks good to me.

review: Approve
lp:~chasedouglas/xorg-gtest/fixes updated on 2011-12-12
3. By Chase Douglas on 2011-12-12

Merge cleanup and fixes branch

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile.am'
2--- Makefile.am 2011-12-06 00:25:36 +0000
3+++ Makefile.am 2011-12-09 21:07:24 +0000
4@@ -1,16 +1,21 @@
5 lib_LTLIBRARIES = libxorg-gtest.la libxorg-gtest_main.la
6
7 libxorg_gtest_la_SOURCES = \
8- src/environment.cpp
9+ src/environment.cpp \
10+ src/process.cpp \
11+ src/test.cpp
12
13 libxorg_gtest_main_la_SOURCES = \
14 src/main.cpp
15
16-library_includedir=$(includedir)/xorg/gtest
17-library_include_HEADERS = include/xorg/gtest/environment.h
18+library_includedir = $(includedir)/xorg/gtest
19+library_include_HEADERS =
20+ include/xorg/gtest/environment.h \
21+ include/xorg/gtest/process.h \
22+ include/xorg/gtest/test.h
23
24-library_datadir=$(datadir)/xorg/gtest
25-library_data_DATA=conf/dummy.conf
26+library_datadir = $(datadir)/xorg/gtest
27+library_data_DATA = conf/dummy.conf
28
29 libxorg_gtest_main_la_CPPFLAGS = $(AM_CPPFLAGS) -DDUMMY_CONF_PATH="\"$(library_datadir)/dummy.conf\""
30
31
32=== modified file 'include/xorg/gtest/environment.h'
33--- include/xorg/gtest/environment.h 2011-12-06 00:02:22 +0000
34+++ include/xorg/gtest/environment.h 2011-12-09 21:07:24 +0000
35@@ -18,7 +18,10 @@
36 * with this program. If not, see <http://www.gnu.org/licenses/>.
37 *
38 ****************************************************************************/
39+#ifndef XORG_GTEST_ENVIRONMENT_H
40+#define XORG_GTEST_ENVIRONMENT_H
41
42+#include <memory>
43 #include <string>
44
45 #include <gtest/gtest.h>
46@@ -31,19 +34,25 @@
47 *
48 * Starts up a dummy Xorg server for testing purposes on
49 * display :133. Either associate the environment manually
50- * with the overall testing framework or link to libxtestingenvironment_main.a.
51+ * with the overall testing framework or link to libxorg-gtest_main.
52 */
53 class Environment : public ::testing::Environment {
54 public:
55- Environment(const std::string& pathToConf, int display = 133);
56+ Environment(const std::string& path_to_conf,
57+ const std::string& path_to_server = "Xorg", int display = 133);
58
59 virtual void SetUp();
60 virtual void TearDown();
61 private:
62- std::string path_to_conf_;
63- int display_;
64- pid_t child_pid_;
65+ struct Private;
66+ std::auto_ptr<Private> d_;
67+
68+ /* Disable copy c'tor & assignment op. */
69+ Environment(const Environment&);
70+ Environment& operator=(const Environment&);
71 };
72
73 } // namespace testing
74 } // namespace xorg
75+
76+#endif // XORG_GTEST_ENVIRONMENT_H
77
78=== added file 'include/xorg/gtest/process.h'
79--- include/xorg/gtest/process.h 1970-01-01 00:00:00 +0000
80+++ include/xorg/gtest/process.h 2011-12-09 21:07:24 +0000
81@@ -0,0 +1,59 @@
82+/*****************************************************************************
83+ *
84+ * utouch-frame - Touch Frame Library
85+ *
86+ * Copyright (C) 2011 Canonical Ltd.
87+ *
88+ * This program is free software: you can redistribute it and/or modify it
89+ * under the terms of the GNU General Public License as published by the
90+ * Free Software Foundation, either version 3 of the License, or (at your
91+ * option) any later version.
92+ *
93+ * This program is distributed in the hope that it will be useful, but
94+ * WITHOUT ANY WARRANTY; without even the implied warranty of
95+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
96+ * General Public License for more details.
97+ *
98+ * You should have received a copy of the GNU General Public License along
99+ * with this program. If not, see <http://www.gnu.org/licenses/>.
100+ *
101+ ****************************************************************************/
102+#ifndef XORG_GTEST_PROCESS_H
103+#define XORG_GTEST_PROCESS_H
104+
105+#include <stdarg.h>
106+
107+#include <memory>
108+#include <string>
109+
110+namespace xorg {
111+namespace testing {
112+
113+class Process {
114+ public:
115+ Process();
116+
117+ void Start(const std::string& program, va_list args);
118+ void Start(const std::string& program, ...);
119+
120+ bool Terminate();
121+ bool Kill();
122+
123+ void SetEnv(const char* name, const char* value, bool overwrite);
124+ const char * GetEnv(const char* name);
125+
126+ pid_t Pid() const;
127+
128+ private:
129+ struct Private;
130+ std::auto_ptr<Private> d_;
131+
132+ /* Disable copy c'tor, assignment operator */
133+ Process(const Process&);
134+ Process& operator=(const Process&);
135+};
136+
137+} // xorg
138+} // testing
139+
140+#endif // XORG_GTEST_PROCESS_H
141
142=== added file 'include/xorg/gtest/test.h'
143--- include/xorg/gtest/test.h 1970-01-01 00:00:00 +0000
144+++ include/xorg/gtest/test.h 2011-12-09 21:07:24 +0000
145@@ -0,0 +1,57 @@
146+/*****************************************************************************
147+ *
148+ * utouch-frame - Touch Frame Library
149+ *
150+ * Copyright (C) 2011 Canonical Ltd.
151+ *
152+ * This program is free software: you can redistribute it and/or modify it
153+ * under the terms of the GNU General Public License as published by the
154+ * Free Software Foundation, either version 3 of the License, or (at your
155+ * option) any later version.
156+ *
157+ * This program is distributed in the hope that it will be useful, but
158+ * WITHOUT ANY WARRANTY; without even the implied warranty of
159+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
160+ * General Public License for more details.
161+ *
162+ * You should have received a copy of the GNU General Public License along
163+ * with this program. If not, see <http://www.gnu.org/licenses/>.
164+ *
165+ ****************************************************************************/
166+
167+#ifndef XORG_GTEST_TEST_H_
168+#define XORG_GTEST_TEST_H_
169+
170+#include <memory>
171+
172+#include <gtest/gtest.h>
173+#include <X11/Xlib.h>
174+
175+#include "utouch/frame.h"
176+
177+namespace xorg {
178+namespace testing {
179+
180+class Test : public ::testing::Test {
181+ public:
182+ Test();
183+
184+ virtual void SetUp();
185+ virtual void TearDown();
186+
187+ protected:
188+ ::Display* Display() const;
189+
190+ struct Private;
191+ std::auto_ptr<Private> d_;
192+
193+ private:
194+ /* Disable copy c'tor, assignment operator */
195+ Test(const Test&);
196+ Test& operator=(const Test&);
197+};
198+
199+} // namespace testing
200+} // namespace xorg
201+
202+#endif // XORG_GTEST_TEST_H_
203
204=== modified file 'src/environment.cpp'
205--- src/environment.cpp 2011-12-06 00:02:22 +0000
206+++ src/environment.cpp 2011-12-09 21:07:24 +0000
207@@ -20,84 +20,77 @@
208 ****************************************************************************/
209
210 #include "xorg/gtest/environment.h"
211+#include "xorg/gtest/process.h"
212
213-#include <errno.h>
214-#include <signal.h>
215-#include <stdlib.h>
216 #include <sys/types.h>
217 #include <unistd.h>
218
219+#include <cerrno>
220+#include <csignal>
221+#include <cstdlib>
222 #include <cstring>
223 #include <iostream>
224+#include <stdexcept>
225
226 #include <X11/Xlib.h>
227
228-xorg::testing::Environment::Environment(const std::string& path, int display)
229- : path_to_conf_(path),
230- display_(display),
231- child_pid_(-1) {
232-
233+struct xorg::testing::Environment::Private {
234+ Private(const std::string& conf, const std::string& server, int display_num)
235+ : path_to_conf(conf), path_to_server(server), display(display_num) {
236+ }
237+
238+ const std::string path_to_conf;
239+ const std::string path_to_server;
240+ const int display;
241+ Process process;
242+};
243+
244+xorg::testing::Environment::Environment(const std::string& path_to_conf,
245+ const std::string& path_to_server,
246+ int display)
247+ : d_(new Private(path_to_conf, path_to_server, display)) {
248 }
249
250 void xorg::testing::Environment::SetUp() {
251 static char display_string[6];
252- snprintf(display_string, 6, ":%d", display_);
253-
254- child_pid_ = vfork();
255- if (child_pid_ == -1) {
256- FAIL() << "Failed to fork a process for dummy X server: "
257- << std::strerror(errno);
258- } else if (!child_pid_) { /* Child */
259- close(0);
260- close(1);
261- close(2);
262-
263- execlp("Xorg", "Xorg", display_string, "-config", path_to_conf_.c_str(),
264- NULL);
265- perror("Failed to start dummy X server");
266- exit(-1);
267- } else { /* Parent */
268- setenv("DISPLAY", display_string, true);
269-
270- for (int i = 0; i < 10; /*++i*/) {
271- Display* display = XOpenDisplay(NULL);
272-
273- if (display) {
274- XCloseDisplay(display);
275- return;
276- }
277-
278- int status;
279- int pid = waitpid(child_pid_, &status, WNOHANG);
280- if (pid == child_pid_) {
281- child_pid_ = -1;
282- FAIL() << "Dummy X server failed to start, did you run as root?";
283- return;
284- } else if (pid == 0) {
285- sleep(1); /* Give the dummy X server some time to start */
286- continue;
287- } else if (pid == -1) {
288- FAIL() << "Could not get status of dummy X server process: "
289- << std::strerror(errno);
290- return;
291- } else {
292- FAIL() << "Invalid child PID returned by waitpid()";
293- return;
294- }
295+ snprintf(display_string, 6, ":%d", d_->display);
296+
297+ d_->process.Start(d_->path_to_server, d_->path_to_server.c_str(),
298+ display_string, "-config", d_->path_to_conf.c_str(), NULL);
299+
300+ setenv("DISPLAY", display_string, true);
301+
302+ for (int i = 0; i < 10; ++i) {
303+ Display* display = XOpenDisplay(NULL);
304+
305+ if (display) {
306+ XCloseDisplay(display);
307+ return;
308 }
309
310- FAIL() << "Unable to open connection to dummy X server";
311+ int status;
312+ int pid = waitpid(d_->process.Pid(), &status, WNOHANG);
313+ if (pid == d_->process.Pid())
314+ throw std::runtime_error("Dummy X server failed to start, did you run as "
315+ "root?");
316+ else if (pid == 0)
317+ sleep(1); /* Give the dummy X server some time to start */
318+ else if (pid == -1)
319+ throw std::runtime_error("Could not get status of dummy X server "
320+ "process");
321+ else
322+ throw std::runtime_error("Invalid child PID returned by Process::Wait()");
323 }
324+
325+ throw std::runtime_error("Unable to open connection to dummy X server");
326 }
327
328 void xorg::testing::Environment::TearDown() {
329- if (child_pid_ && child_pid_ != -1) {
330- if (kill(child_pid_, SIGTERM) < 0) {
331- FAIL() << "Warning: Failed to terminate dummy Xorg server: "
332- << std::strerror(errno);
333- if (kill(child_pid_, SIGKILL))
334- FAIL() << "Warning: Failed to kill dummy Xorg server: "
335- << std::strerror(errno);
336- }
337+ if (!d_->process.Terminate()) {
338+ std::cerr << "Warning: Failed to terminate dummy Xorg server: "
339+ << std::strerror(errno) << "\n";
340+ if (!d_->process.Kill())
341+ std::cerr << "Warning: Failed to kill dummy Xorg server: "
342+ << std::strerror(errno) << "\n";
343 }
344 }
345
346=== modified file 'src/main.cpp'
347--- src/main.cpp 2011-12-06 00:25:36 +0000
348+++ src/main.cpp 2011-12-09 21:07:24 +0000
349@@ -31,12 +31,14 @@
350 int no_dummy_server = false;
351 int xorg_conf = false;
352 int xorg_display_opt = false;
353+int server = false;
354
355 const struct option longopts[] = {
356 { "help", no_argument, &help, true, },
357 { "no-dummy-server", no_argument, &no_dummy_server, true, },
358- { "xorg-conf", optional_argument, &xorg_conf, true, },
359- { "xorg-display", optional_argument, &xorg_display_opt, true, },
360+ { "xorg-conf", required_argument, &xorg_conf, true, },
361+ { "xorg-display", required_argument, &xorg_display_opt, true, },
362+ { "server", required_argument, &server, true, },
363 { NULL, 0, NULL, 0 }
364 };
365
366@@ -49,32 +51,49 @@
367 /* Default X display */
368 int xorg_display = 133;
369
370+ /* Default Xorg executable */
371+ std::string server("Xorg");
372+
373 testing::InitGoogleTest(&argc, argv);
374
375 /* Reset getopt state */
376 optind = 0;
377
378- int ret;
379- do {
380- ret = getopt_long(argc, argv, "", longopts, NULL);
381-
382- if (xorg_conf) {
383- xorg_conf_path = optarg;
384- }
385-
386- if (xorg_display_opt) {
387- xorg_display = atoi(optarg);
388- }
389- } while (ret == 0);
390-
391- if (ret != -1)
392- exit(-1);
393+ while (true) {
394+ int ret;
395+ int index;
396+ ret = getopt_long(argc, argv, "", longopts, &index);
397+
398+ if (ret == -1)
399+ break;
400+
401+ if (ret == '?')
402+ exit(-1);
403+
404+ switch (index) {
405+ case 2:
406+ xorg_conf_path = optarg;
407+ break;
408+
409+ case 3:
410+ xorg_display = atoi(optarg);
411+ break;
412+
413+ case 4:
414+ server = optarg;
415+ break;
416+
417+ default:
418+ break;
419+ }
420+ }
421
422 if (help) {
423 std::cout << "\nAdditional options:\n";
424 std::cout << " --no-dummy-server: Use the currently running X server "
425 "for testing\n";
426 std::cout << " --xorg-conf: Path to xorg dummy configuration file\n";
427+ std::cout << " --server: Path to X server executable\n";
428 std::cout << " --xorg-display: xorg dummy display port\n";
429 exit(-1);
430 }
431@@ -82,6 +101,7 @@
432 if (!no_dummy_server) {
433 xorg::testing::Environment* environment = new xorg::testing::Environment(
434 xorg_conf_path,
435+ server,
436 xorg_display);
437 testing::AddGlobalTestEnvironment(environment);
438 }
439
440=== added file 'src/process.cpp'
441--- src/process.cpp 1970-01-01 00:00:00 +0000
442+++ src/process.cpp 2011-12-09 21:07:24 +0000
443@@ -0,0 +1,98 @@
444+#include "xorg/gtest/process.h"
445+
446+#include <sys/types.h>
447+#include <sys/wait.h>
448+#include <unistd.h>
449+
450+#include <algorithm>
451+#include <cerrno>
452+#include <csignal>
453+#include <cstdio>
454+#include <cstdlib>
455+#include <cstring>
456+#include <stdexcept>
457+#include <vector>
458+
459+struct xorg::testing::Process::Private {
460+ pid_t pid;
461+};
462+
463+xorg::testing::Process::Process() : d_(new Private) {
464+ d_->pid = -1;
465+}
466+
467+void xorg::testing::Process::Start(const std::string& program, va_list args) {
468+ if (d_->pid != -1)
469+ throw std::runtime_error("Attempting to start an already started process");
470+
471+ d_->pid = vfork();
472+
473+ if (d_->pid == -1) {
474+ throw std::runtime_error("Failed to fork child process");
475+ } else if (d_->pid == 0) { /* Child */
476+ close(0);
477+ close(1);
478+ close(2);
479+
480+ std::vector<char*> argv;
481+
482+ do
483+ argv.push_back(va_arg(args, char*));
484+ while (argv.back());
485+
486+ execvp(program.c_str(), &argv[0]);
487+
488+ throw std::runtime_error("Failed to start process");
489+ }
490+}
491+
492+void xorg::testing::Process::Start(const std::string& program, ...) {
493+ va_list list;
494+ va_start(list, program);
495+ Start(program, list);
496+ va_end(list); /* Shouldn't get here */
497+}
498+
499+bool xorg::testing::Process::Terminate() {
500+ if (d_->pid == -1) {
501+ return false;
502+ } else if (d_->pid == 0) {
503+ /* Child */
504+ throw std::runtime_error("Child process tried to terminate itself");
505+ } else { /* Parent */
506+ if (kill(d_->pid, SIGTERM) < 0) {
507+ return false;
508+ }
509+ }
510+ return true;
511+}
512+
513+bool xorg::testing::Process::Kill() {
514+ if (d_->pid == -1) {
515+ return false;
516+ } else if (d_->pid == 0) {
517+ /* Child */
518+ throw std::runtime_error("Child process tried to kill itself");
519+ } else { /* Parent */
520+ if (kill(d_->pid, SIGKILL) < 0) {
521+ return false;
522+ }
523+ }
524+ return true;
525+}
526+
527+void xorg::testing::Process::SetEnv(const char* name, const char* value,
528+ bool overwrite) {
529+ if (setenv(name, value, overwrite) != 0)
530+ throw std::runtime_error("Failed to set environment variable in process");
531+
532+ return;
533+}
534+
535+const char* xorg::testing::Process::GetEnv(const char* name) {
536+ return getenv(name);
537+}
538+
539+pid_t xorg::testing::Process::Pid() const {
540+ return d_->pid;
541+}
542
543=== added file 'src/test.cpp'
544--- src/test.cpp 1970-01-01 00:00:00 +0000
545+++ src/test.cpp 2011-12-09 21:07:24 +0000
546@@ -0,0 +1,49 @@
547+/*****************************************************************************
548+ *
549+ * utouch-frame - Touch Frame Library
550+ *
551+ * Copyright (C) 2011 Canonical Ltd.
552+ *
553+ * This program is free software: you can redistribute it and/or modify it
554+ * under the terms of the GNU General Public License as published by the
555+ * Free Software Foundation, either version 3 of the License, or (at your
556+ * option) any later version.
557+ *
558+ * This program is distributed in the hope that it will be useful, but
559+ * WITHOUT ANY WARRANTY; without even the implied warranty of
560+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
561+ * General Public License for more details.
562+ *
563+ * You should have received a copy of the GNU General Public License along
564+ * with this program. If not, see <http://www.gnu.org/licenses/>.
565+ *
566+ ****************************************************************************/
567+
568+#include "xorg/gtest/test.h"
569+
570+#include <stdexcept>
571+
572+#include <X11/Xlib.h>
573+
574+struct xorg::testing::Test::Private {
575+ ::Display* display;
576+};
577+
578+xorg::testing::Test::Test() : d_(new Private) {
579+ d_->display = NULL;
580+}
581+
582+void xorg::testing::Test::SetUp() {
583+ d_->display = XOpenDisplay(NULL);
584+ if (!d_->display)
585+ throw std::runtime_error("Failed to open connection to display");
586+}
587+
588+void xorg::testing::Test::TearDown() {
589+ XCloseDisplay(d_->display);
590+ d_->display = NULL;
591+}
592+
593+::Display* xorg::testing::Test::Display() const {
594+ return d_->display;
595+}

Subscribers

People subscribed via source and target branches