Conversation
b6d76b5 to
6647c69
Compare
|
Nice catch. For a bit of context: we actually stumbled upon this issue while switching from Bolt to OpenBolt on macOS. The same code path started failing with:
That led us to notice that OpenURI.open_uri returns an IO-like object (StringIO), not a String, and that the implementation was relying on an implicit conversion that doesn’t always happen. Our assumption is that OpenBolt bundles a different Ruby version / stdlib than Bolt, which exposed this behavior more strictly. The test suite didn’t catch it because OpenURI.open_uri was mocked to return a String, masking the real-world behavior. |
Starting with Puppet 8, stdlib use the JSON class instead of the PSON class that was used before to load JSON content downloaded from an URL. The PSON class allowed to pass an IO object and #read its content for parsing, but the JSON class mandates passing a String. The loadjson() functions, when passed an URL, download the document with OpenURI.open_uri (which return a StringIO object) and try to parse it. On Puppet 7, this works because PSON accept IO objects, but with Puppet 8 an exception is raised: ``` Error: Evaluation Error: Error while evaluating a Function Call, no implicit conversion of StringIO into String ``` As the test suite inadequately mocked OpenURI.open_uri to return a String, this was not catch. Fix this by adjusting the return value in the test suite to match the actual behavior of OpenURI and calling #read on the IO object returned by OpenURI.open_uri. While here, add an acceptance tests to check loadjson when using an URL.
6647c69 to
b90f878
Compare
So, after more digging the failure reason is now straightforward:
I adjusted the commit / PR to include this information, and added a basic integration test to assert catalog compiles. |
Starting with Puppet 8, stdlib use the
JSONclass instead of thePSONclass that was used before to load JSON content downloaded from an URL.The
PSONclass allowed to pass anIOobject and#readits content for parsing, but theJSONclass mandates passing aString.The
loadjson()functions, when passed an URL, download the document withOpenURI.open_uri(which return aStringIOobject) and try to parse it. On Puppet 7, this works becausePSONacceptIOobjects, but with Puppet 8 an exception is raised:As the test suite inadequately mocked
OpenURI.open_urito return aString, this was not catch.Fix this by adjusting the return value in the test suite to match the actual behavior of OpenURI and calling
#readon theIOobject returned byOpenURI.open_uri.While here, add an acceptance tests to check
loadjsonwhen using an URL.