test-kitchen/test-kitchen — pull request #358 by fnichol (2014-02-12 18:24:43+00:00)
Title: Load needed (dynamic) dependencies for provisioners at creation time.

The need for this change was initated with #293 which runs every
instance action in a thread of execution, even in serial mode. The issue
is that on the Mac platform MRI Ruby 1.9 and 2.0 (not confirmed for
2.1), dynamic (i.e. native) code needs to be loaded in the main thread
otherwise causing a "Trace/BPT trap: 5" crash.

References:

* http://stackoverflow.com/questions/9933969/matlab-ruby-gem-doesnt-work-when-called-from-thread#answer-12319780
* https://bugs.launchpad.net/sbcl/+bug/1014409

For Berkshelf 2.0.x at least, there are multiple transitive dependencies
that *could* load native code, meaning that `require 'berkshelf'` could
very well lead to a VM crash if performed in a thread other than main.

This commit pushes library loading code ahead to Provisioner creation
time. In other words, by the time you have a Provisioner object
reference either Berkshelf, Librarian-Chef, or nothing has been required
(assuming a Chef provisioner).

A drawback to this approach is that these dynamic dependencies will be
eagerly loaded when Test Kitchen is booting for trivial CLI commands
such as `kitchen list` and `kitchen diagnose`. Further work is needed to
ensure that `kitchen diagnose` remains viable even in the face of a
failure to load these dependencies.

Finally, the loaded version of Berkshelf or Librarian-Chef will be
displayed to the user on INFO for converge action and DEBUG on code
loading for troubleshooting.

Closes #357

/cc @reset, @ivey, @sethvargo