chefspec:设置要在配方中的所有测试中使用的全局节点属性

chefspec: setting global node attributes to be used in all tests in recipe

我目前正在编写一个 chefspec 食谱,它设置了完成我的单元测试所必需的某些节点属性。我目前在每次测试中都设置这些属性,这看起来很浪费。我希望以不重复代码的方式执行此操作,即 "global attributes?"。

我目前的工作配方如下:

# 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' 语句(在测试之外),然后在后续测试中重用它们。

我设置这些属性的努力 "globally" 看起来像这样:

# 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

它returns出现以下错误:

...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 的新手,所以我可能遗漏了一些东西。任何帮助是极大的赞赏。谢谢

在你的第二种形式中,你永远不会融合任何配方,所以显然没有 resource_collection 可以测试。

在你的跑步者定义的末尾添加一个 converge(described_recipe)。

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