Robert’s rules of Boost testing

By the way of trying to figure out how to make tests building faster? (I will post about it later), I have learned some interesting practices regarding Boost testing in general. Especially, Robert Ramey shared his best practices, worth to look at really. New release of Boost will be released next week, so I’m testing Boost.Geometry library and it is a good opportunity to apply some of Robert’s rules.

I’m testing against “known good” components – the next release branch.

How to run tests of current development line of a library (a Boost library, e.g. Boost.Geometry) against Boost release branch? Assuming all the library development happens in Boost trunk, let’s say in ${DEV}/boost/_svn/trunk where ${DEV} is your base workshop location, do this:

  • Checkout Boost release branch
    mkdir -p ${DEV}/boost/_svn/branches/release
    cd ${DEV}/boost/_svn/branches/release
    svn co https://svn.boost.org/svn/boost/branches/release/ .
    

  • Stay in ${DEV}/boost/_svn/branches/release
  • Build and install Boost.Build v2 from the release branch:
    cd tools/build/v2
    # On Windows, run bootstrap.bat
    ./bootstrap.sh
    # On Windows, I use C:\usr as prefix for my Boost installation
    ./b2 --prefix=/usr/local install
    # Note, this command will also install b2 utility in ${prefix}/bin
    
  • Switch Boost.Geometry directories to trunk:
    svn switch https://svn.boost.org/svn/boost/trunk/boost/geometry boost/geometry
    svn switch https://svn.boost.org/svn/boost/trunk/libs/geometry libs/geometry
    
  • Run tests and generate full log in file:
    export BGLOG=boost-geometry-test.log
    date > $BGLOG & b2 >> $BGLOG 2<&1 & date >> $BGLOG
    
    # On Windows, I run this with logging this way:
    set BGLOG=%CD%\boost-geometry-test.log
    dateu.exe > %BGLOG% & b2 >> %BGLOG% 2<&1 & dateu.exe >> %BGLOG%
    

    Note, the dateu.exe is renamed Unix utility date.exe installed from GnuWin32 packages. I just like it.

Inspect the log file for test failures, for example by quick check of number of passed tests:

$ grep "\*passed\*" boost-geometry-test.log | wc -l
111

That’s it.

Try this out – it will help a lot.

Boost.Geometry mailing list moved

I have moved mailing list of the Boost.Geometry library from server at OSGeo to Boost mailing list server. All existing subscribers and archives have been moved to the new server.

The new list is available at geometry at lists dot boost dot org. It is also mirrored at Nabble as Boost.Geometry.

The old ggl at lists dot osgeo dot org will be wiped out soon.

If anyone experiences any problems with the new geometry at lists.boost.org, please contact me directly.

Big thanks to the OSGeo Foundation for hosting the ggl mailing list and thanks to Boost admins for help with the new server.

pygit-svn-mirror 0.1 released

I have been looking for easy and quick solution to mirror Subversion repositories in Git at GitHub. With bit of reading and testing, I came up with some quite usable workflow. But, most likely due to my lack of Git fu, I wasn’t happy with it. Especially, could not find how to update Git mirrors from various locations and computers, also to allow others to do that.

Lately, I have found a tool written in Ruby by Eloy Durán. It is git-svn-mirrora command-line tool that automates the task of creating a Git mirror for a SVN repository, and keeping it up-to-date. I installed Eloy’s tool from Ruby gems and played with it for a while. I really liked it.

I skimmed the Ruby code of git-svn-mirror and found out it makes use of bare repositories in Git. A Git bare repository stores just the contents of the .git directory, without any files checked out around it. Long story short, this script does almost exactly what I need and if there is something it does not do, then I can add it.

I have never written a single line of code in Ruby and I don’t feel like I need to learn it now. So, I decided to port git-svn-mirror to Python. I have just pushed pygit-svn-mirror 0.1 based on git-svn-mirror 0.1 to the repository at GitHub. I have tried to follow command line interface and overall code structure of the original version in Ruby. I have also preserved the original license and Eloy’s copyright.

There is README.md file included with detailed guide on how to use the pygit-svn-mirror. Basically, there are two commands: init and update. For each command, --help option will display required and supported arguments.

For example, creating mirror of Subversion repository of PROJ.4 project at GitHub involves the following commands:

mkdir /path/to/proj4/mirror
cd /path/to/proj4/mirror
git-svn-mirror.py init \
  --from=https://svn.osgeo.org/metacrs/proj/ \
  --to=git@github.com:<USRNAME>/proj.4.git

and to update the mirror from its workbench directory:

cd /path/to/proj4/mirror
git-svn-mirror.py update

or from any folder but with workbench location pointed explicitly:

git-svn-mirror.py update -w /path/to/proj4/mirror

Feedback, bug reports and patches highly appreciated.

Finally, big thanks to Eloy Durán for the original git-svn-mirror written in Ruby.

Python sys.stdout redirection in C++

Lately, I have been embedding Python interpreter and implementing plenty of Python extensions in C++ using plain C API provided by Python 3. One of common challenges at C/C++ level is to intercept output sent to sys.stdout or sys.stderr by Python functions like print. Python Embedding/Extending FAQ suggests common solution based on Python code:

# catcher code
import sys
class StdoutCatcher:
   def __init__(self):
      self.data = ''
   def write(self, stuff):
      self.data = self.data + stuff
catcher = StdoutCatcher()
sys.stdout = catcher

This Python code can be executed by embedded Python interpreter using PyRun_SimpleString, then the output can be accessed by fetching __main__ module attributes:

PyObject* m = PyImport_AddModule("__main__");
char const* code = "... catcher code here...";
PyRun_SimpleString(code);
PyRun_SimpleString("print(3.14)");
PyObject* catcher = PyObject_GetAttrString(m, "catcher");
PyObject* output = PyObject_GetAttrString(catcher, "data");
// get textual data contained in output

Such mix of Python and C code is neither convenient to use nor states a flexible solution. I simply don’t like this prosthesis, especially if I need to frequently switch between number output sinks.

So, I have come up with better solution which allows me to directly bind any callable C++ entity. The syntax I mean looks and feels like this:

int main()
{
    PyImport_AppendInittab("emb", emb::PyInit_emb);
    Py_Initialize();
    PyImport_ImportModule("emb");

    PyRun_SimpleString("print(\'hello to console\')");

    // here comes the ***magic***
    std::string buffer;
    {
        // switch sys.stdout to custom handler
        emb::stdout_write_type write =
            [&buffer] (std::string s) { buffer += s; };

        emb::set_stdout(write);
        PyRun_SimpleString("print(\'hello to buffer\')");
        PyRun_SimpleString("print(3.14)");
        PyRun_SimpleString("print(\'still talking to buffer\')");
        emb::reset_stdout();
    }

    PyRun_SimpleString("print(\'hello to console again\')");
    Py_Finalize();

    // output what was written to buffer object
    std::clog << buffer << std::endl;
}

This allows me to handle sys.stdout.write with C++ free function, class member function, named function objects or even anonymous functions as in the example above where I use C++11 lambda.

Complete implementation of the emb module in C/C++ using plain Python C API is available from my Python workshop at GitHub:

git clone git://github.com/mloskot/workshop.git

The complete code is enclosed in python/emb/emb.cpp file. Note, this is a minimal example to present the essential concept. In production-ready code, it certainly needs more attention around reference counting of PyObject, getting rid of global state, and so one.

OSGeo Charter Nomination for Martin Daly

This month, OSGeo Foundation is conducting annual election of new OSGeo Charter Members.

I have nominated Martin Daly (CTO of Cadcorp) for Charter Member of the OSGeo Foundation.

Martin has long-standing experience in development of geospatial software and development, and adoption of open standards for geospatial under his belt.

Martin has used and supported numerous open source software projects. Martin led Cadcorp to offer first implementation of PostGIS by a GIS vendor, to become a GDAL/OGR Silver Sponsor, to contribute funds and time of Cadcorp development team to make the wheels of PostGIS Raster project (aka WKT Raster) spinning. Improvements in PostgreSQL are also on not-a-short list of contributions to the Free and Open Source Software projects, as is GEOS.

Martin was one of the original members of the OGC Architecture Board (OAB). He was also the main author of the OpenGIS Coordinate Transformation Services Specification as well as participated in developing several other OpenGIS specifications. Martin is one of authors of the GeoJSON Format Specification and actively participates in future development of GeoJSON.

Martin is a member of the Advisory Board of the Open Source Geospatial Lab (OSGL) at the University of Nottingham Centre for Geospatial Science.

Martin also participates and leads Cadcorp involvement in the annual FOSS4G WMS Benchmark.

I believe Martin Daly’s experience and contributions make him a valuable candidate for the OSGeo Charter Member.

Microsoft Announces SQL Server ODBC Driver for Linux!

Thanks to my, hopefully, open minded attitude, I sometimes let myself to dive into unknown with honest hope to find unexpected.

Today at lunchtime I let myself loose across Twitter archives and I came across an interesting account, or I rather should say: I fell into evil ways. It is @OpenAtMicrosoft. Hmm, another marketing specialist at Microsoft buzz’ing about the NKTOB ™, means new keyword on the block. Or, it is just Microsoft twitting daily menu from their newly opened cafeteria. But now, they presumably say what they mean:

source for info on Microsoft and interoperability, open source and open standards

By the way, it is a foothold of Interoperability @ Microsoft. (For those who may have problems with interpreting the @ sign, like my grandfather for example, it means the same as English word “at” as in Kids at the House.)

In spite of that my eyes nearly dried out of the openness, I went for it and skimmed and voil?: Microsoft Announces SQL Server ODBC Driver for Linux!. It will soon be widely available to customers. Yay!

Yes, you read that right

It’s an evil good news of the day and I’m keen in trying it out as soon as I polish the ODBC backend in SOCI. I hope to stop worrying about which one to use, unixODBC or iODBC, for SQL Server at least. Life may become easier for OGR SQL Server driver users too.

I also hope, Microsoft will consider to offer the fastest development environment for C/C++ programmers for Linux. Namely, Visual Studio.

Yes, I am radically open minded. I can take on the most incredible of challenges, even surfing an inflatable crocodile.

Update on SqlGeometry and POINT EMPTY in WKB

Long time ago I discussed about how SqlGeometry handles POINT EMPTY in WKB format. The SqlGeometry states the definition of OGC GEOMETRY type for Microsoft SQL Server. Shortly, the message was that SqlGeometry implicitly casts POINT EMPTY to MULTIPOINT EMPTY geometry when generating WKB output. PostGIS casts as well, but does it in a consistent way, in my opinion, outputting GEOMETRYCOLLECTION.

Following those findings, I assumed it is not quite correct, or I didn’t like the inconsistency, and I had reported it to Microsoft Connect as a bug: SqlGeometry reports invalid type of WKB of POINT EMPTY.

Recently, I have received a couple of comments from Microsoft to my report. The comments are attached to the report linked above, but I paste them below for completeness and archive:

Our development team for the spatial data types tells me that it is not possible to use a single value for the WKB format of any spatial data type. For the POINT EMPTY, the WKB format does not allow empty points, so we are outputting a MULTIPOINT with zero elements.
In a MULTIPOINT EMPTY, we are stripping out empty points.

The reasoning is technically correct. It’s just Microsoft does it differently. However, as second comment suggests, the current behaviour may change in future:

But we might consider changing it to get consistent behavior.