From a86965c34068f351f840d1a7bab04084539404bd Mon Sep 17 00:00:00 2001 From: Paul Hinze Date: Fri, 28 Jan 2022 14:01:32 -0600 Subject: [PATCH] ruby mappers: Unwrap wrapper types in Hashes and Arrays Boolean types (and possibly a few others) are returned as wrapper classes when coming out from proto mapping; these need to be unwrapped otherwise the caller who is expecting a nice clean boolean value ends up with an icky protobuf class. This fixes the shell provisioner, which relies on a communicator receiving a settings hash `{error_check: false}` for a command that usually fails but it sent just in case before provisioning starts. --- plugins/commands/serve/mappers/known_types.rb | 7 +++- .../plugins/commands/serve/mappers_test.rb | 39 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 test/unit/plugins/commands/serve/mappers_test.rb diff --git a/plugins/commands/serve/mappers/known_types.rb b/plugins/commands/serve/mappers/known_types.rb index 42d5af9a1..de09692fb 100644 --- a/plugins/commands/serve/mappers/known_types.rb +++ b/plugins/commands/serve/mappers/known_types.rb @@ -77,7 +77,10 @@ module VagrantPlugins def converter(proto, mapper) begin proto.list.map do |v| - mapper.map(v) + r = mapper.map(v) + # unwrap any wrapper classes here before assigning + r = r.value if r.is_a?(Type) + r end rescue => err logger.error("proto mapping to array failed: #{err}") @@ -169,6 +172,8 @@ module VagrantPlugins Hash.new.tap do |result| proto.fields.each do |k, v| r = mapper.map(v) + # unwrap any wrapper classes here before assigning + r = r.value if r.is_a?(Type) result[k.to_sym] = r end end diff --git a/test/unit/plugins/commands/serve/mappers_test.rb b/test/unit/plugins/commands/serve/mappers_test.rb new file mode 100644 index 000000000..951bfb381 --- /dev/null +++ b/test/unit/plugins/commands/serve/mappers_test.rb @@ -0,0 +1,39 @@ +require File.expand_path("../../../base", __dir__) + +require Vagrant.source_root.join("plugins/commands/serve/command") + +describe VagrantPlugins::CommandServe::Mappers do + include_context "unit" + + subject { described_class.new } + + context "Hash" do + it "unwraps wrapper types when they show up in the Hash" do + input = Hashicorp::Vagrant::Sdk::Args::Hash.new( + fields: { + "error_check" => Google::Protobuf::Any.pack( + Google::Protobuf::BoolValue.new(value: false) + ) + } + ) + output = subject.map(input, to: Hash) + + expect(output).to eq({error_check: false}) + end + end + + context "Array" do + it "unwraps wrapper types when they show up in the Array" do + input = Hashicorp::Vagrant::Sdk::Args::Array.new( + list: [ + Google::Protobuf::Any.pack( + Google::Protobuf::BoolValue.new(value: false) + ), + ], + ) + output = subject.map(input, to: Array) + + expect(output).to eq([false]) + end + end +end