Implement (most of) JRuby command execution support.

This is a basic implementation of the execution API for JRuby systems.  It is
complete except for support of UID and GID switching.

As written it allows us to get the test suite running at all, which is more
than we previously had.  UID and GID switching can wait until the rest of the
suite passes...

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
JRuby 1.9 Pathname vs File: convert to string

JRuby requires that the pathname be explicitly turned into a string, or it
fails on trying to rename.  (Claiming, oddly, that it can't convert Pathname
to a string, despite it being manifestly possible.)

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
JRuby OSCP constants are not available.

Other Ruby implementations make the (optional, low priority) constants for CRL
revocation reason available under the OpenSSL::OSCP namespace, for some
reason, despite their being standardized in RFC 3280, the CRL itself.

The details are at http://tools.ietf.org/html/rfc3280#section-5.3.1

Because this is a standard we can just use the constant number rather than the
named constant, and make JRuby happy - it emulates other parts of the OpenSSL
stack for us, but not the OSCP portion.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Disable CA operation on JRuby.

The CRL implementation in JRuby 1.6.7, at least, causes a failure when
managing the CRL - it either adds a duplicate `crlNumber` extension, or the
provider does and we don't manipulate it as expected.

Either way this blocks correct operation as a CA on JRuby for the moment, so
we should honestly disable it and refuse to operate on an unsupported
platform.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Use more realistic certificates for testing.

JRuby demanded that a genuine key be available on any X.509 certificate that
was used.  This revealed that we had a half completed issuer certificate in
our testing here - we didn't give it a key.

This creates the key, since we should test in as realistic an environment as
possible for code contained within our current object.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Don't duplicate CHILD_STATUS: it can't be modified.

The object in $CHILD_STATUS can't be modified except by executing an external
command; it is literally impossible for anyone to change it in any other way.
(A fact that causes us pain in other parts of the code.)

Given that, duplicating it is useless in most places, rather than just
returning a reference to the same object.  The runtime also doesn't mutate in
place, it points the top level variable somewhere else.

In MRI the extraneous dup was just a waste of CPU cycles allocating the
object.  JRuby literally can't allocate a new Process::Status object in Ruby
code, and caused a hard failure in consequence.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Avoid dangling symlinks for the sake of JRuby

JRuby 1.6.7.2 (and 1.7.0-preview1) have a bug where they are unable to
`readlink` on a dangling symlink.  This isn't actually needed in this
particular test - it was just a happenstance of implementation.

So, if we create the second target file as well as the first we can have the
suite pass on both platforms before the upstream problem is resolved.

See https://github.com/jruby/jruby/issues/210 for the upstream bug report.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Rewrite binwrite emulation again, this time for JRuby.

This emulation is an ongoing source of pain: every obscure platform has a
different set of things that go wrong, or are not implemented, or are
not abstracted.

In this case the IO.new mode operation on JRuby doesn't support POSIX numeric
modes, only string modes.  That blows up the last way we tried to work around
this stuff.

On the plus side, now we have a slow, ugly, but portable implementation that
passes on Windows, JRuby, and MRI 1.8.  This is good, finally.

Writing portable Ruby is just like writing portable C, only slower.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
JRuby < 1.7.0 fails on recursive YAML loading

Expanding YAML that contains a reference to a reference cycle - a child that
references a parent, for example - is mishandled by JRuby 1.6.7.2 and earlier.

JRuby 1.7 does the right thing, so we can just mark the test pending (with a
block to catch unexpected success) for the interim.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Disable `safe_posix_fork` tests on JRuby.

JRuby doesn't implement fork, but does explode if you close off an FD that it
uses; other platforms have tests that stub out fork itself, but let the other
behaviour alone, and that work exactly and only by chance.

JRuby doesn't - but we can disable the tests, as it doesn't break anything
deeper in the system that wouldn't already be broken.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Disable `posix_execute` tests on JRuby.

These tests assume the standard fork/exec execution environment, and suffer
the same fate as other fork related tests - they can break JRuby, and couldn't
succeed at execution anyhow.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Skip ~ expansion failure test that passes on JRuby

JRuby actually goes out and does the right thing  when faced with expanding a
path containing a tilde, but when 'HOME' is not set in the environment.
This is unlike MRI, which just fails in that case.

This is actually desirable behaviour, so just skip the test that asserts we
warn in that failure case.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Avoid stubbing methods on `nil`

Recent versions of Mocha treat stubbing something on the `nil` object as an
error, which is reasonable, but we did that in the queue application spec.

Since it makes no great difference, we can just put a stub object in place
where nil was sitting, and let that save us the trouble instead.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
JRuby mishandles Time.local with a timezone.

When passed the ten argument variant of Time.local, Ruby should take the
passed timezone as input.  JRuby mishandles that, and generates a UTC time
instead, leading to failures in our schedule handling.

See https://github.com/jruby/jruby/issues/215 for upstream bug.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
JRuby doesn't mangle pathnames exactly like MRI.

One of the corner cases of handling pathnames is that a leading `//` should be
preserved for POSIX compatibility - it is treated as a special value
indicating "another server" in favour of DomainOS (and Windows) qualifying
for POSIX.

MRI gets this wrong in places, but JRuby gets it right - so skip testing that
failure mode is preserved on that platform.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
`expand_path` eliminates `..` directories under JRuby.

The generate function test used `File.expand_path` to fully qualify a command
name that included the `..` sequence, for Windows.  Unfortunately, this
actually washes out the sequence entirely on JRuby - leading to a test failure
because the command was pre-cleaned of the failing input.

We can limit the "make absolute" part to only Windows, in which case we get
the correct behaviour as well as more clarity on why it is done.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Fix bad stubbing in dpkg package provider spec.

The tests depended on stubbing the internal implementation of the Tempfile
class to work - they depended on `Tempfile.new` being invoked inside
`Tempfile.open` to behave correctly.

Unfortunately, JRuby doesn't expose that level of implementation detail in a
way that the stubbing works as intended - so we either need to rethink our
testing strategy, or stub the actual call the implementation makes.

This follows the later path: it is simpler, and no worse, than the previous
code was.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Handle JRuby `Etc` implementation differences.

JRuby implements `Etc` to return `nil` when a record can't be found, rather
than by raising an exception.  Since that communicates the same information we
can just handle both cases and have success regardless of the platform.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Comparing object-identity of object_id's is redundant.

The JRuby runtime has a quirk - well, bug, honestly - where
`foo.object_id.equals? foo.object_id` returns false incorrectly.

It is kind of redundant to compare object equality on an integer that
explicitly determines object equality, so we can just work around the bug by
performance a standard integer equality comparison there.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
Rewrite poorly stubbed tests that fail on JRuby.

Some of the certificate request tests were poorly stubbed, and ended up
failing in strange ways under JRuby.  Rewriting them to pass also makes them a
little more solid in testing what they set out to test, too.

Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>