【问题标题】:chefspec: setting global node attributes to be used in all tests in recipechefspec:设置要在配方中的所有测试中使用的全局节点属性
【发布时间】:2015-07-22 16:49:50
【问题描述】:

我目前正在编写一个 chefspec 配方,它设置某些节点属性,这些属性是完成我的单元测试所必需的。我目前在每个测试中都设置这些属性,这似乎很浪费。我希望以不重复代码的方式执行此操作,即“全局属性?”。

我目前的工作配方如下:

# encoding: UTF-8
require_relative '../spec_helper'

osd_device = '/ceph-1-osd'

describe 'ceph::per-host-osd' do
   let(:runner) { ChefSpec::Runner.new }
   let(:chef_run) { runner.converge(described_recipe) }
   let(:node) { runner.node }

    # Test whether directory is created with specifed attributes
    # Node attributes are necessary to satisfy logic of parent recipe
    it 'creates a directory with root ownership and permissions' do
     node.automatic['fqdn'] = 'ceph-1'
     node.set['ceph']['hosts']['ceph-1']
     node.set['ceph']['hosts']['ceph-1']['osd_devices'] = [{device: "/ceph-1-osd", journal: "/ceph-1-journal/journal", type: "directory"}]
    expect(chef_run).to create_directory("#{osd_device}").with(
      user:   'root',
      group:  'root',
    )
    end

   it 'executes ceph-disk-prepare and ceph-disk-activate' do
      node.automatic['fqdn'] = 'ceph-1'
      node.set['ceph']['hosts']['ceph-1']
      node.set['ceph']['hosts']['ceph-1']['osd_devices'] = [{device: "/ceph-1-osd", journal: "/ceph-1-journal/journal", type: "directory"}]
      expect(chef_run).to run_execute("ceph-disk-prepare on #{osd_device}")
      expect(chef_run).to run_execute("ceph-disk-activate #{osd_device}")
   end
end

此 chefspec 测试顺利通过:

.....

Finished in 4.99 seconds (files took 8.13 seconds to load)
5 examples, 0 failures
Coverage report generated for RSpec to /Users/joe.bloggs/workspace/cookbook_ceph/build/report/coverage/coverage.xml

但是,我希望只设置一次“node.automatic”和“node.set”语句(在测试之外),然后在后续测试中重复使用它们。

我为“全局”设置这些属性所做的努力如下所示:

# encoding: UTF-8
require_relative '../spec_helper'

osd_device = '/ceph-1-osd'

describe 'ceph::per-host-osd' do
   let(:chef_run) do
     ChefSpec::Runner.new do |node|
       node.automatic['fqdn'] = 'ceph-1'
       node.set['ceph']['hosts']['ceph-1']
       node.set['ceph']['hosts']['ceph-1']['osd_devices'] = [{device: "/ceph-1-osd", journal: "/ceph-1-journal/journal", type: "directory"}]
     end
   end
    # Test whether directory is created with specifed attributes
    # Node attributes are necessary to satisfy logic of parent recipe
    it 'creates a directory with root ownership and permissions' do
      expect(chef_run).to create_directory("#{osd_device}").with(
        user:   'root',
        group:  'root',
      )
    end
    it 'executes ceph-disk-prepare and ceph-disk-activate' do
       expect(chef_run).to run_execute("ceph-disk-prepare on #{osd_device}")
       expect(chef_run).to run_execute("ceph-disk-activate #{osd_device}")
    end
end

它返回以下错误:

...FF

Failures:

  1) ceph::per-host-osd creates a directory with root ownership and permissions
     Failure/Error: expect(chef_run).to create_directory("#{osd_device}").with(
     NoMethodError:
       undefined method `resource_collection' for nil:NilClass
     # ./spec/unit/per-host-osd_spec.rb:17:in `block (2 levels) in <top (required)>'

  2) ceph::per-host-osd executes ceph-disk-prepare and ceph-disk-activate
     Failure/Error: expect(chef_run).to run_execute("ceph-disk-prepare on #{osd_device}")
     NoMethodError:
       undefined method `resource_collection' for nil:NilClass
     # ./spec/unit/per-host-osd_spec.rb:23:in `block (2 levels) in <top (required)>'

Finished in 3.12 seconds (files took 8.46 seconds to load)
5 examples, 2 failures

Failed examples:

rspec ./spec/unit/per-host-osd_spec.rb:16 # ceph::per-host-osd creates a directory with root ownership and permissions
rspec ./spec/unit/per-host-osd_spec.rb:22 # ceph::per-host-osd executes ceph-disk-prepare and ceph-disk-activate
Coverage report generated for RSpec to /Users/joe.bloggs/workspace/cookbook_ceph/build/report/coverage/coverage.xml

我是 chefspec 的新手,所以也许我遗漏了一些东西。任何帮助是极大的赞赏。谢谢。

【问题讨论】:

    标签: ruby rspec chef-infra chefspec


    【解决方案1】:

    在您的第二种形式中,您永远不会收敛任何配方,因此显然没有要测试的 resource_collection。

    在跑步者定义的末尾添加一个收敛(描述的食谱)。

    let(:chef_run) do
         ChefSpec::Runner.new do |node|
           node.automatic['fqdn'] = 'ceph-1'
           node.set['ceph']['hosts']['ceph-1']
           node.set['ceph']['hosts']['ceph-1']['osd_devices'] = [{device: "/ceph-1-osd", journal: "/ceph-1-journal/journal", type: "directory"}]
         end.converge(described_recipe)
    end
    

    【讨论】:

    • 这确实是问题所在。我试过你的建议,它奏效了。非常感谢。
    最近更新 更多