Chefspec 剔除 Win32::Service 是 Linux
Chefspec Stubbing out Win32::Service on Linux
我们的食谱在 Linux 和 Windows 机器上使用,当它 runs/converges 时,代码 运行 在两种类型的系统上都完美。然而 rake 单元 测试在 Linux 上失败。在我的食谱中我有:
service 'MyService' do
action %i[enable start]
only_if { ::Win32::Service.exists?("MyService") }
not_if { ::File.exist?("#{install_dir}\scripts\instance-stopped") }
end
我们得到的错误是:
Failures:
perfagent::install_windows When set to install agent on Windows
converges successfully
Failure/Error: expect { chef_run }.to_not raise_error
expected no Exception, got #<NameError: uninitialized constant Win32> with backtrace:
# /tmp/chefspec20200924-2530-350e0zfile_cache_path/cookbooks/perfagent/resources/install_agent.rb:83:in
`block (3 levels) in class_from_file'
是否有可能,对于 Linux 系统,在我的规范文件中为上面的“only_if”虚拟出值,以便我的 rake 单元测试在我们 运行 Linux?
上的耙子
更新:
由于说明书在 Linux 和 Windows 系统上执行,我们在说明书执行的早期进行检查,例如:
if node['platform_family'] == 'windows'
include_recipe 'cookbook::install_windows'
elsif node['platform_family'] == 'rhel'
include_recipe 'cookbook::install_linux'
else
log "This OS family (#{node['platform_family']}) is not supported" do
level :info
end
end
这意味着食谱只根据platform_family调用相关食谱。但是,当我们在 Linux 上 运行 rake 单元时,我们会收到上述错误,而在 Windows 上,rake 成功。
我试过添加:
allow(::Win32::Service).to receive(:exists?).with(windows_service[:name]).and_return(true)
到规范文件,但这在 Linux 上仍然失败并导致 Windows rake 单元也失败。
可以在 Chef 资源中使用 if
条件。我不确定对像 only_if
或 not_if
这样的守卫使用条件是否优雅(它们本身是条件)。
但您可以执行以下操作:
service 'MyService' do
action %i[enable start]
if node['platform'] == 'windows'
only_if { ::Win32::Service.exists?("MyService") }
end
not_if { ::File.exist?("#{install_dir}\scripts\instance-stopped") }
end
如果您的 OS 平台是 windows
只有 only_if
守卫才会被检查。
更新:
其他选项是根据平台设置服务名称并去掉 only_if
守卫。像这样:
# Set the service name appropriate to platform
svc_name = case node['platform']
when 'windows'
'MyService'
when 'linux'
'my-service'
end
# Then use the service name that was set:
service svc_name do
action [ :enable, :start ]
not_if { ::File.exist?("#{install_dir}\scripts\instance-stopped") }
end
在嵌套 classes 的情况下,存根有点复杂。您还需要存根 class 本身。使用 stub_const
from the RSpec for that:
let :subject do
fake_win32 = Class.new
stub_const('Win32::Service', fake_win32)
allow(fake_win32).to receive(:exists?).and_return false
ChefSpec::Runner.new(platform: 'windows', version: '2008R2').converge described_recipe
end
我们的食谱在 Linux 和 Windows 机器上使用,当它 runs/converges 时,代码 运行 在两种类型的系统上都完美。然而 rake 单元 测试在 Linux 上失败。在我的食谱中我有:
service 'MyService' do
action %i[enable start]
only_if { ::Win32::Service.exists?("MyService") }
not_if { ::File.exist?("#{install_dir}\scripts\instance-stopped") }
end
我们得到的错误是:
Failures:
perfagent::install_windows When set to install agent on Windows converges successfully Failure/Error: expect { chef_run }.to_not raise_error
expected no Exception, got #<NameError: uninitialized constant Win32> with backtrace: # /tmp/chefspec20200924-2530-350e0zfile_cache_path/cookbooks/perfagent/resources/install_agent.rb:83:in `block (3 levels) in class_from_file'
是否有可能,对于 Linux 系统,在我的规范文件中为上面的“only_if”虚拟出值,以便我的 rake 单元测试在我们 运行 Linux?
上的耙子更新:
由于说明书在 Linux 和 Windows 系统上执行,我们在说明书执行的早期进行检查,例如:
if node['platform_family'] == 'windows'
include_recipe 'cookbook::install_windows'
elsif node['platform_family'] == 'rhel'
include_recipe 'cookbook::install_linux'
else
log "This OS family (#{node['platform_family']}) is not supported" do
level :info
end
end
这意味着食谱只根据platform_family调用相关食谱。但是,当我们在 Linux 上 运行 rake 单元时,我们会收到上述错误,而在 Windows 上,rake 成功。
我试过添加:
allow(::Win32::Service).to receive(:exists?).with(windows_service[:name]).and_return(true)
到规范文件,但这在 Linux 上仍然失败并导致 Windows rake 单元也失败。
可以在 Chef 资源中使用 if
条件。我不确定对像 only_if
或 not_if
这样的守卫使用条件是否优雅(它们本身是条件)。
但您可以执行以下操作:
service 'MyService' do
action %i[enable start]
if node['platform'] == 'windows'
only_if { ::Win32::Service.exists?("MyService") }
end
not_if { ::File.exist?("#{install_dir}\scripts\instance-stopped") }
end
如果您的 OS 平台是 windows
只有 only_if
守卫才会被检查。
更新:
其他选项是根据平台设置服务名称并去掉 only_if
守卫。像这样:
# Set the service name appropriate to platform
svc_name = case node['platform']
when 'windows'
'MyService'
when 'linux'
'my-service'
end
# Then use the service name that was set:
service svc_name do
action [ :enable, :start ]
not_if { ::File.exist?("#{install_dir}\scripts\instance-stopped") }
end
在嵌套 classes 的情况下,存根有点复杂。您还需要存根 class 本身。使用 stub_const
from the RSpec for that:
let :subject do
fake_win32 = Class.new
stub_const('Win32::Service', fake_win32)
allow(fake_win32).to receive(:exists?).and_return false
ChefSpec::Runner.new(platform: 'windows', version: '2008R2').converge described_recipe
end