Linux上的Chefspec剔除Win32::服务

Linux上的Chefspec剔除Win32::服务,linux,winapi,chef-infra,chefspec,Linux,Winapi,Chef Infra,Chefspec,我们的烹饪书在Linux和Windows机器上都有使用,当它运行/聚合时,代码在这两种类型的系统上都能完美地运行。但是,rake单元测试在Linux上失败。在我的食谱中,我有: service 'MyService' do action %i[enable start] only_if { ::Win32::Service.exists?("MyService") } not_if { ::File.exist?("#{install_dir}\\scr

我们的烹饪书在Linux和Windows机器上都有使用,当它运行/聚合时,代码在这两种类型的系统上都能完美地运行。但是,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
我们得到的错误是:

失败:

  • perfagent::设置为在windows上安装代理时安装\u windows 成功收敛 失败/错误:期望{chef_run}。不要引发错误

    不应出现异常,使用回溯获取#: #/tmp/chefspec20200924-2530-350e0zfile_cache_path/cookbooks/perfagent/resources/install_agent.rb:83:in `从\u文件中的\u类中的块(3级)

  • 对于Linux系统,是否有可能在我的规范文件中为上面的“only_if”虚设值,以便在Linux上运行rake时,我的rake单元测试成功


    更新:

    由于cookbook同时在Linux和Windows系统上执行,我们在执行cookbook的早期会进行检查,例如:

    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
    
    这意味着烹饪书仅根据平台族调用相关食谱。然而,当我们在Linux上运行rake单元时,我们得到了上面的错误,并且在Windows上rake成功了

    我尝试添加:

    allow(::Win32::Service).to receive(:exists?).with(windows_service[:name]).and_return(true)
    

    但这在Linux上仍然失败,并导致Windows rake单元也失败。

    如果在Chef资源中使用
    条件,则可以使用
    。我不确定在警卫中使用条件句是否优雅,比如
    仅当
    不当
    时(自身条件句)

    但是你可以做如下的事情:

    服务“MyService”是什么
    操作%i[启用启动]
    如果节点['platform']='windows'
    仅当{::Win32::Service.exists?(“MyService”)}
    结束
    如果{::File.exist?(“#{install_dir}\\scripts\\instance stopped”)}
    结束
    
    如果您的操作系统平台是
    windows
    only,则将检查
    only\u If
    防护


    更新:

    另一个选项是根据平台设置服务的名称,只有在
    guard时才去掉
    u。大概是这样的:

    #设置适合平台的服务名称
    svc_name=案例节点['platform']
    当“窗口”
    “我的服务”
    什么时候是“linux”
    “我的服务”
    结束
    #然后使用设置的服务名称:
    服务svc_name do
    操作[:启用,:启动]
    如果{::File.exist?(“#{install_dir}\\scripts\\instance stopped”)}
    结束
    
    对于嵌套类,存根稍微复杂一点。您还需要存根类本身。使用存根常数

    let:subject do
    fake_win32=Class.new
    存根常量('Win32::Service',假Win32)
    允许(fake_win32)。接收(:exists?)。并返回false
    ChefSpec::Runner.new(平台:“windows”,版本:“2008R2”)。converge描述了
    结束
    
    不幸的是,我已经尝试过了,但我得到了相同的错误…:(另一个选项是根据平台预先设置服务名称,并在
    service do
    中使用该名称。添加了一个更新以深入了解烹饪书如何运行相关配方。还尝试添加“允许(Win32::service)。接收(:存在?)。使用(windows_服务[:名称])和_返回(true)”到规范文件,但这在Linux上仍然失败。非常好。工作完美。rake单元现在在Linux和Windows上都成功了。非常感谢。