Archive for the 'Testing' Category



cfix studio Beta 2 to add support for EXE-based unit tests

N.B. cfix studio was the code name of what has become Visual Assert

The biggest shortcoming of the current cfix studio version certainly is that it requires all tests be implemented in a DLL. Conceptually, keeping test cases separated from the remaining code certainly is a good idea — and implementing tests in a DLL is a way to accomplish this. However, there are many projects in which such separation is either not feasible or just too much effort.

The good news is that with Beta 2, this will finally change: EXEs become first class-citizens in cfix studio and it will not matter any more whether your tests are part of a DLL or EXE project — you can just put them where you think is appropriate.

Take a classic MFC/GUI application project as an example: It is pretty common for these kinds of projects that most, if not all, application logic is part of a single Visual Studio project that compiles into a single EXE. There may be some additional DLLs or LIBs, but by and large, the EXE itself is where most of the interesting things happen.

The upcoming Beta 2 release now allows you to implement all your unit tests as part of the same EXE project. This means that your tests have access to all classes, functions and resources that are part of the project — all of which you would not easily have access to if you implemented the tests in a separate DLL.

Of course, embedding unit tests into an executable raises two questions:

  1. How to strip the tests from the final release?
  2. How on earth will you be able to run these tests without having main() create windows, load files, play sounds, etc each time?

Thankfully, C/C++ has a preprocessor and Visual C++ has the “exclude from build” feature which allows you to exclude certain files whenever the project is built using a specific configuration. Using any of these two features, the first question is easily answered.

The second problem is more tricky — but thankfully, it has already been solved for you: When cfix studio runs unit tests, it is well aware of that running main() might have, let’s say interesting effects — so what it does is simple: It just makes sure that main() is never run! Not only does this ensure that the tests run silently, i.e. without windows popping up etc, it also has the benefit that all unit tests “see” the application in a pristine state: Rather than having to worry about which state main() has brought the application into, you can initialize and clean up any state you need in your Setup and Teardown functions1.

To make a long story short: You can write unit tests in EXE projects in exactly the same manner as you would in a DLL project. No special considerations needed, no project settings that need to be changed, no additional boilerplate code to write. And when you run the EXE outside cfix studio, i.e. hit F5 in Visual Studio or launch the EXE directly, you will not even notice that the EXE houses some unit tests — everything works as normal.

Sounds good? Then wait a few more days and see it in action!

Remarks
1: Needless to say, all global variables are initialized, constructors are run, etc. All CRT initialization happens as normal; only main()/WinMain() is not run. And yes, it also works for apps that link statically to MFC and therefore do not have a “regular” WinMain().

Introducing cfix studio, the Visual Studio AddIn for C/C++ Unit Testing

N.B. cfix studio was the code name of what has become Visual Assert

There is little doubt that native code, and C and C++ in particular, is here to stay. And still, it is pretty obvious that when it comes to tools and IDEs, it is the managed world that has gotten most attention from tool vendors over the past years.

While there are lots and lots of useful tools for native development, many of them probably even better than their managed counterparts, there are some areas where the managed language fraction is far ahead: One of these areas certainly is IDE support for unit testing.

JUnit for Eclipse, TestDriven.Net for Visual Studio and MS Test make test-driven development so much more convenient and efficient that it is almost ridiculous that using command line tools is still state of the art for C/C++ development.

That said, there is great news: With cfix studio, there finally is a solution filling in this gap! cfix studio, based on the cfix unit testing framework, is a Visual Studio-AddIn that allows you to easily write, manage, run, and debug your unit tests from within Visual Studio. No fiddling with command line tools, complex configuration, or boilerplate code required!

Among lots of other features, cfix studio also has first-class support for multi-architecture development – you can easily switch back and forth between 32-bit and 64-bit and can even mix tests of different architectures in a single test run. Needless to say, cfix studio, like cfix, is also fully compatible to WinUnit.

If that has caught your interest, you are invited to check out the first beta version of cfix studio:

Download cfix studio Beta 1
Version 1.0.0.3458

It is free, quick to install and comes with a set of example projects. Give it a try — and please let me know about all your crticism, suggestions and other feedback!

Here are some screenshots of cfix studio in action:

Test Explorer
The Test Explorer allows you to start a single or set of tests, the Run Window shows the results

Run Window
Run Window: Viewing test progress

Failed Assertion
Run Window: Viewing test results and details of a failed assertion

Debgging a failed assertion
When running in the debugger, a failed assertion will hit a breakpoint and the Run Window will show additional details

cfix 1.4 released

Today, a new version of cfix, the open source unit testing framework for user and kernel mode C and C++, has been released. cfix 1.4, in addition to the existing feature of allowing test runs to be restricted to specific fixtures, now also allows single testcases to be run in isolation, which can be a great aid in debugging. Besides several minor fixes, the cfix API has been slightly enhanced and cfix now degrades more gracefully in case of dbghelp-issues.

Updated cfix binaries and source code are now available for download

cfix 1.3.0 Released, Introducing WinUnit Compatibility

cfix 1.3, the latest version of the unit testing framework for C/C++ on Windows, has just been released. As announced in the last blog post, the major new feature of this release is WinUnit compatibility, i.e. the ability to recompile existing WinUnit test suites into cfix test suites without having to change a single line of code.

To demonstrate that this compatibility indeed works, consider the following simple example:

#include "WinUnit.h"

BEGIN_TEST(DummyTest)
{
  WIN_ASSERT_STRING_EQUAL( "foo", "bar" "Descriptive message");
}
END_TEST

Compile it:

cl /I %CFIX_HOME%\include /LD /EHa /Zi winunittest.cpp /link /LIBPATH:%CFIX_HOME%\lib\i386

Or, in case %INCLUDE% and %LIB% already happen to be set properly:

cl /LD /EHa winunittest.cpp

Note that the only difference to compiling the test for WinUnit ist that a different include path is used — rather than the original winunit.h, cfix’ own winunit.h is used, which in turn implements the WinUnit API on top of the existing API.

The resulting DLL is a valid cfix DLL and its tests can be run in the usual manner. As the example contains a failing test, cfix will print the stack trace and error description to the console:

D:\sample>cfix32 -ts -z winunittest.dll
cfix version 1.3.0.3340 (fre)
(C) 2008-2009 - Johannes Passing - http://www.cfix-testing.org/
[Failure]      winunittest.DummyTest.DummyTest
      winunittest.cpp(5): DummyTest

      Expression: Descriptive message: [foo] == [bar] (Expression: "foo" == "bar")
      Last Error: 0 (The operation completed successfully. )

      cfix!CfixpCaptureStackTrace +0x40
      cfix!CfixPeReportFailedAssertion +0xd2
      winunittest!cfixcc::Assertion::Fail<std::...
      winunittest!cfixcc::Assertion::Relate<std...
      winunittest!cfixcc::Assertion::Relate ...
      winunittest!cfixcc::Assertion::RelateStri...
      winunittest!DummyTest +0x9c
      cfix!CfixsRunTestRoutine +0x33
      cfix!CfixsRunTestCaseMethod +0x27
      cfix!CfixsRunTestCase +0x25
      ...

Of course, cfix also supports WinUnit fixtures, as the following example, taken from the original WinUnit article on MSDN demonstrates:

#include "WinUnit.h"
#include <windows.h>

// Fixture must be declared.
FIXTURE(DeleteFileFixture);

namespace
{
  TCHAR s_tempFileName[MAX_PATH] = _T("");
  bool IsFileValid(TCHAR* fileName);
}

// Both SETUP and TEARDOWN must be present. 
SETUP(DeleteFileFixture)
{
  // This is the maximum size of the directory passed to GetTempFileName.
  const unsigned int maxTempPath = MAX_PATH - 14; 
  TCHAR tempPath[maxTempPath + 1] = _T("");
  DWORD charsWritten = GetTempPath(maxTempPath + 1, tempPath);
  // (charsWritten does not include null character)
  WIN_ASSERT_TRUE(charsWritten  0, 
    _T("GetTempPath failed."));

  // Create a temporary file
  UINT tempFileNumber = GetTempFileName(tempPath, _T("WUT"), 
    0, // This means the file will get created and closed.
    s_tempFileName);

  // Make sure that the file actually exists
  WIN_ASSERT_WINAPI_SUCCESS(IsFileValid(s_tempFileName), 
    _T("File %s is invalid or does not exist."), s_tempFileName);
}

// TEARDOWN does the inverse of SETUP, as well as undoing 
// any side effects the tests could have caused.
TEARDOWN(DeleteFileFixture)
{
  // Delete the temp file if it still exists.
  if (IsFileValid(s_tempFileName))
  {
    // Ensure file is not read-only
    DWORD fileAttributes = GetFileAttributes(s_tempFileName);
    if (fileAttributes & FILE_ATTRIBUTE_READONLY)
    {
      WIN_ASSERT_WINAPI_SUCCESS(
        SetFileAttributes(s_tempFileName, 
          fileAttributes ^ FILE_ATTRIBUTE_READONLY),
          _T("Unable to undo read-only attribute of file %s."),
          s_tempFileName);
    }

    // Since I'm testing DeleteFile, I use the alternative CRT file
    // deletion function in my cleanup.
    WIN_ASSERT_ZERO(_tremove(s_tempFileName), 
      _T("Unable to delete file %s."), s_tempFileName);
  }

  // Clear the temp file name.
  ZeroMemory(s_tempFileName, 
    ARRAYSIZE(s_tempFileName) * sizeof(s_tempFileName[0]));
}

BEGIN_TESTF(DeleteFileShouldDeleteFileIfNotReadOnly, DeleteFileFixture)
{
  WIN_ASSERT_WINAPI_SUCCESS(DeleteFile(s_tempFileName));
  WIN_ASSERT_FALSE(IsFileValid(s_tempFileName), 
    _T("DeleteFile did not delete %s correctly."),
    s_tempFileName);
}
END_TESTF

BEGIN_TESTF(DeleteFileShouldFailIfFileIsReadOnly, DeleteFileFixture)
{
  // Set file to read-only
  DWORD fileAttributes = GetFileAttributes(s_tempFileName);
  WIN_ASSERT_WINAPI_SUCCESS(
    SetFileAttributes(s_tempFileName, 
    fileAttributes | FILE_ATTRIBUTE_READONLY));

  // Verify that DeleteFile fails with ERROR_ACCESS_DENIED
  // (according to spec)
  WIN_ASSERT_FALSE(DeleteFile(s_tempFileName));
  WIN_ASSERT_EQUAL(ERROR_ACCESS_DENIED, GetLastError());
}
END_TESTF

namespace
{
  bool IsFileValid(TCHAR* fileName)
  {
    return (GetFileAttributes(fileName) != INVALID_FILE_ATTRIBUTES);
  }
}

Compiling and running this test yields the expected output:

d:\sample>cl /I %CFIX_HOME%\include /LD /EHa /Zi fixture.cpp /link /LIBPATH:%CFIX_HOME%\lib\i386
d:\sample>cfix32 -ts -z fixture.dll
cfix version 1.3.0.3340 (fre)
(C) 2008-2009 - Johannes Passing - http://www.cfix-testing.org/
[Success]      fixture.DeleteFileFixture.DeleteFileShouldDeleteFileIfNotReadOnly
[Success]      fixture.DeleteFileFixture.DeleteFileShouldFailIfFileIsReadOnly


       1 Fixtures
       2 Test cases
           2 succeeded
           0 failed
           0 inconclusive

Limitations

All compatibility has its limitations — although cfix supports all major WinUnit constructs and assertions, there are a small number of known limitations, which are listed in the documentation. And although I am confident that most WinUnit code should compile and run just fine, it is, of course, possible, that further limitations pop up. In such cases, I would welcome an appropriate bug report and will try to fix cfix accordingly.

Documentation

In order to have cfix be a fully adequate replacement for cfix, the cfix documentation has additionally been augmented to include a documentation of the entire WinUnit API.

Technical background

Technically, implementing the compatibility layer went rather smoothly. On the one hand, WinUnit and cfix have similar architectures, which makes many things easier. On the other hand, WinUnit has a clean, single public header file (contrast that to CppUnit!), which also simplified things. And as WinUnit is limited to C++, I was able to use C++ templates (in combination with some preprocessor macros) to implement the entire WinUnit compatibility layer without having to change a single line of cfix itself. Rather, the WinUnit macros/classes are all mapped onto the existing cfix C++ API, which already includes most of what was neccessary to implement the WinUnit functionality.

Conclusion

In case have been using WinUnit the past and have a set of existing WinUnit-based test suites, give cfix a try — Not only should it be a full-featured replacement for WinUnit, you can also expect to see, and benefit from new features in upcoming releases!

Last but not least, the release contains a number of minor bugfixes. So upgrading is recommended even if you do not intend to use the new WinUnit compatibility feature.

cfix can be downloaded here.

Embracing WinUnit

Around two years ago, in early 2007, after having read about, having tried, and finally having dismissed numerous existing unit testing frameworks for C, I resigned and started thinking about creating a new unit testing framework. Having been accustomed to NUnit and JUnit, I found most frameworks clumsy to use — some “frameworks” like MinUnit are a joke, some frameworks like CUnit require lots of boilerplate code to be written, some frameworks only support C++ but not C, and some manage to combine the worst properties of them all (CppUnit).

However, it was not before end of 2007 until I finally found the time to actually start working on what would later become cfix. About half way through the initial coding phase, in the February 2007 issue, MSDN magazine featured the article Simplified Unit Testing for Native C++ Applications, introducing WinUnit, a unit testing framework for unmanaged C++.

Enter WinUnit

On the one hand, it was nice to see someone thinking the same about current unit testing frameworks and coming up with a new solution. But given the effort that had already gone into cfix, I was not exactly amused about this article — after all, WinUnit implements one of the core ideas of cfix, namely, to separate the test runner (winunit.exe/cfix32.exe) from the actual tests (DLLs) and using PE file introspection to identify fixtures and test cases. So although WinUnit already generated significant positive feedback, I continued development of cfix — not only would cfix at least add the benefit of supporting C in addition to C++, after investigating WinUnit a bit, I still saw lots of room for improvement.

Now, one year later, the situation has changed. Contrary to what one might have expected, WinUnit has not evolved into a serious project — it has not gotten past the MSDN article and the accomanying download link: No new features, no fixes, no blog, no community — by now, WinUnit seems pretty much dead to me. Sure, nothing prevents you from keep using WinUnit, but using tools for which no further development seems to take place is somewhat dissatisfying to me.

Good News

Given this situation and the architectural simlarity of both testing frameworks, it therefore just makes sense to take the next logical step and have cfix embrace WinUnit!

That is, the upcoming cfix 1.3 release will be compatible to WinUnit by allowing developers to take existing test cases written against the WinUnit API and recompile them into cfix test cases without requiring any code to be changed.

With such compatibility in place, transitioning from WinUnit to cfix will thus become a snap. Better yet, because no code has to be changed, the option to switch back and forth between cfix and WinUnit is retained, giving existing WinUnit users maximum flexibility at minimal risk.

The 1.3 release of cfix is due in a couple of days. Once released, I will get a bit more into detail about WinUnit compatibility.

By the way…

today is the first anniversary of cfix :)

Working Around TlbImp’s Cleverness

TlbImp, the .Net tool to create Interop assemblies from COM type libraries, contains an optimization that presumably aims at making the consumption of the Interop assembly easier, but ultimately is a nuisance. Consider the following IDL code:

import "oaidl.idl";
import "ocidl.idl";

[
  uuid( a657ef35-fea1-40ad-86d8-bb7b6085a0a3 ),
  version( 1.0 )
]
library Test
{
  
  [
    object,
    uuid( 84b2f017-b8fe-4c2c-87b8-0587b4bf5507 ),
    version( 1.0 ),
    oleautomation
  ]
  interface IFoo : IUnknown 
  {
    HRESULT Foo();
  }

  [
    object,
    uuid( 13d950d6-beb3-4dd3-957b-88b0e5eb5e3f ),
    version( 1.0 ),
    oleautomation
  ]
  interface IBar : IUnknown 
  {
    HRESULT CreateFoo( 
      [out, retval] IFoo **Foo
      );
  }

  [
    uuid( e01ea769-410c-4915-a48c-3522a8087a52 ),
    noncreatable 
  ]
  coclass Foo
  {
    interface IFoo;
  }

  [
    uuid( dca66832-fe3b-4658-a975-442b5678a9ec )
  ]
  coclass Bar
  {
    interface IBar;
  }
}

Two things are worth noting about this IDL code: First, IBar::CreateFoo is declared to “return” an IFoo*, and second, there is only one coclass implementing IFoo, namely Foo. As a consequence, TlbImp attempts to be clever and assumes that if IBar::CreateFoo “returns” an IFoo*, it relly must be an Foo* that is returned. So in the resulting Interop assembly, the IBar interface will look as follows:

[
  ComImport, InterfaceType((short) 1), 
  Guid("13D950D6-BEB3-4DD3-957B-88B0E5EB5E3F"), 
  TypeLibType((short) 0x100)
]
public interface IBar
{
  [return: MarshalAs(UnmanagedType.Interface)]
  [MethodImpl(MethodImplOptions.InternalCall, 
   MethodCodeType=MethodCodeType.Runtime)]
  Foo CreateFoo();
}

Contrary to what the IDL defines, IBar::CreateFoo returns Foo, i.e. a concrete class.

First of all, the assumption underlying this optimization certainly is somewhat flaky as it is not quite in accord with the rules of COM — after all, the implementation of Bar is free to return whatever coclass implementing IFoo seems appropriate and is not limited to returning Foo coclass instances.

While this might not be a real problem in practice, the optimization has another an unpleasant effect on the testability of the library consuming the interface: To properly test this library, it might be a good idea to implement mock or stub implementations of IFoo and IBar. Unfortunately, due to the “optimized” return type of IBar::CreateFoo(), this turns out to be not quite easy, as the following code suggests:

class FooStub : IFoo
{
  public void Foo() 
  {}
}

class BarStub : IBar
{
  public Foo CreateFoo()
  {
    // XXX: FooStub implements IFoo, but Foo is required!
    return new FooStub()
  }
}

Workarounds

As pointless as TlbImp’s behavior in this regard might be, it is quite easy to work around this issue.

The first workaround is to define a dummy coclass in the IDL and declare it to implement IFoo as well:

[
  uuid( ed93b3e6-104b-43d6-be34-972d7519bc62 )
]
coclass Dummy
{
  interface IFoo;
}

Now that there are two candidate coclasses, TlbImp will not be able to infer the coclass from the interface and will not be able to apply its optimization. The drawback of this approach is, of course, that the additional Dummy coclass consitutes additional baggage in the IDL and the Interop assembly.

The second option is to forego declaring the interfaces of Foo in the coclass. These declarations mainly serve informative purposes and are not mandatory, so we can omit them. To satisfy MIDL’s requirement of naming at least one interface, we can just put in IUnknown:

[
  uuid( e01ea769-410c-4915-a48c-3522a8087a52 ),
  noncreatable 
]
coclass Foo
{
  interface IUnknown;
}

Again, TlbImp will not be able to apply its optimization and the resulting Interop assembly will contain a proper, mockable, interface IBar.

Needless to say, this approach has its own drawbacks. As a consequence of the missing interface implementation declarations, class Foo (in the Interop assembly) will not contain any methods and is basically useless — you are obliged to use the interface.

More importantly, however, the .Net class Foo will not implement IFoo — so although QueryInterface’ing IFoo from Foo would work, a statement like IBar bar = new BarClass() will now lead to a compiler error:

Cannot implicitly convert type ‘Test.BarClass’ to ‘Test.IBar’. An explicit conversion exists (are you missing a cast?)

Although I consider the second option to be the cleaner approach, it is therefore best used for noncreatable coclasses only.

cfix 1.2 Installer Fixed for AMD64

The cfix 1.2 package as released last week contained a rather stupid bug that the new build, 1.2.0.3244, now fixes: the amd64 binaries cfix64.exe and cfixkr64.sys were wrongly installed as cfix32.exe and cfixkr32.sys, respectively. Not only did this stand in contrast to what the documenation stated, it also resulted in cfix being unable to load the cfixkr driver on AMD64 platforms.

The new MSI package is now available for download on Sourceforge.

cfix 1.2 introduces improved C++ support

cfix 1.2, which has been released today, introduces a number of new features, the most prominent being improved support for C++ and additional execution options.

New C++ API

To date, cfix has primarily focussed on C as the programming language to write unit tests in. Although C++ has always been supported, cfix has not made use of the additional capabilities C++ provides. With version 1.2, cfix makes C++ a first class citizen and introduces an additional API that leverages the benefits of C++ and allows writing test cases in a more convenient manner.

Being implemented on top of the existing C API, the C++ API is not a replacement, but rather an addition to the existing API set.

As the following example suggests, fixtures can now be written as classes, with test cases being implemented as methods:

#include <cfixcc.h>

class ExampleTest : public cfixcc::TestFixture
{
public:
  void TestOne() 
  {}
  
  void TestTwo() 
  {}
};

CFIXCC_BEGIN_CLASS( ExampleTest )
  CFIXCC_METHOD( TestOne )
  CFIXCC_METHOD( TestTwo )
CFIXCC_END_CLASS()

To learn more about the definition of fixtures, have a look at the respective TestFixture chapter in the cfix documentation.

Regarding the implementation of test cases, cfix adds a new set of type-safe, template-driven assertions that, for instance, allow convenient equality checks:

void TestOne() 
{
  const wchar_t* testString = L"test";
  
  //
  // Use typesafe assertions...
  //
  CFIXCC_ASSERT_EQUALS( 1, 1 );
  CFIXCC_ASSERT_EQUALS( L"test", testString );
  CFIXCC_ASSERT_EQUALS( wcslen( testString ), ( size_t ) 4 );
  
  //
  // ...log messages...
  //
  CFIX_LOG( L"Test string is %s", testString );
  
  //
  // ...or use the existing "C" assertions.
  //
  CFIX_ASSERT( wcslen( testString ) == 4 );
  CFIX_ASSERT_MESSAGE( testString[ 0 ] == 't', 
    L"Test string should start with a 't'" );
}

Again, have a look at the updated API reference for an overview of the new API additions.

Customizing Test Runs

Another important new feature is the addition of the new switches -fsf (Shortcut Fixture), -fsr (Shortcut Run), and -fss (Shortcut Run On Failing Setup). Using these switches allows you to specify how a test run should resume when a test case fails.

When a test case fails, the default behavior of cfix is to report the failure, and resume at the next test case. By specifying -fsf, however, the remaining test cases of the same fixture will be skipped and execution resumes at the next fixture. With -fsr, cfix can be requirested to abort the entire run as soon as a single test case fails.

What else is new in 1.2?

Download

As always, cfix 1.2 is source and binary compatible to previous versions. The new MSI package and source code can now be downloaded on Sourceforge.

cfix is open source and licensed under the GNU Lesser General Public License.

cfix 1.1.1 released

As discussed last week, cfix 1.1.0 has suffered from a potential deadlocking issue when run in the VisualStudio 2008 debugger. cfix 1.1.1 mitigates this problem and should now work equally well with Visual Studio 2005 and 2008.

When run in a debugger, cfix now will not try to capture a stack trace for a failed assertion any more. These stack traces usually have been redundant to what the debugger provides, yet the logic to implement this has been the reason for the interference with the VS 2008 debugger. When run outside the debugger, cfix will capture and display a stack trace as before.

As always, binaries and source code can be obtained on Sourceforge.

cfix 1.1 goes LGPL

cfix 1.0 had been licensed under the GNU General Public License. One of the characteristics of the GPL is that it disallows proprietary binaries to be linked against GPL-licensed binaries.

In the context of cfix, linking is quite a concern — after all, every test-DLL has to be linked against cfix.dll. As cfix.dll is GPL-licensed, this means that it would be illegal to redistribute the test-DLL, along with the cfix test runner, commercially. Granted, it is rather uncommon to redistribute testing code with your proprietary software — however, as it turned out, this case exists.

For this reason, cfix 1.1 switches over to the slightly more liberal GNU Lesser General Public License. The LGPL explicitly allows proprietary binaries to link against LGPL-licensed binaries. As such, redistributing your cfix test-DLLs will not be an issue any more.

« Previous PageNext Page »


Categories

Try Visual Assert, the unit testing add-in for Visual Studio (R)


NTrace: Function Boundary Tracing for Windows on IA-32

About me

Johannes Passing, M.Sc., living in Berlin, Germany.

Besides his consulting work, Johannes mainly focusses on Win32, COM, and NT kernel mode development, along with Java and .Net. He also is the author of cfix, a C/C++ unit testing framework for Win32 and NT kernel mode, Visual Assert, a Visual Studio Unit Testing-AddIn, and NTrace, a dynamic function boundary tracing toolkit for Windows NT/x86 kernel/user mode code.

Contact Johannes: jpassing (at) acm org

Johannes' GPG fingerprint is BBB1 1769 B82D CD07 D90A 57E8 9FE1 D441 F7A0 1BB1.

LinkedIn LinkedIn Profile
Xing Xing Profile
Twitter Follow me on Twitter (new)

Follow

Get every new post delivered to your Inbox.