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

Proposed by Chase Douglas
Status: Merged
Merged at revision: 3
Proposed branch: lp://staging/~chasedouglas/xorg-gtest/fixes
Merge into: lp://staging/~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://staging/~chasedouglas/xorg-gtest/fixes
Reviewer Review Type Date Requested Status
Thomas Voß (community) Approve
Stephen M. Webb (community) Approve
Review via email: mp+84896@code.staging.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.
Revision history for this message
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
Revision history for this message
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!

Revision history for this message
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.

Revision history for this message
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}) {
}

Revision history for this message
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
Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
Stephen M. Webb (bregma) wrote :

I think this is Good Enough.

review: Approve
Revision history for this message
Thomas Voß (thomas-voss) wrote :

Looks good to me.

review: Approve
3. By Chase Douglas

Merge cleanup and fixes branch

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
The diff is not available at this time. You can reload the page or download it.

Subscribers

People subscribed via source and target branches