File: locker_spec.rb

package info (click to toggle)
puppet-agent 7.23.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 19,092 kB
  • sloc: ruby: 245,074; sh: 456; makefile: 38; xml: 33
file content (99 lines) | stat: -rw-r--r-- 3,490 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
require 'spec_helper'
require 'puppet/agent'
require 'puppet/agent/locker'

class LockerTester
  include Puppet::Agent::Locker
end

describe Puppet::Agent::Locker do
  before do
    @locker = LockerTester.new
  end

  ## These tests are currently very implementation-specific, and they rely heavily on
  ##  having access to the lockfile object.  However, I've made this method private
  ##  because it really shouldn't be exposed outside of our implementation... therefore
  ##  these tests have to use a lot of ".send" calls.  They should probably be cleaned up
  ##  but for the moment I wanted to make sure not to lose any of the functionality of
  ##  the tests.   --cprice 2012-04-16

  it "should use a Pidlock instance as its lockfile" do
    expect(@locker.send(:lockfile)).to be_instance_of(Puppet::Util::Pidlock)
  end

  it "should use puppet's agent_catalog_run_lockfile' setting to determine its lockfile path" do
    lockfile = File.expand_path("/my/lock")
    Puppet[:agent_catalog_run_lockfile] = lockfile
    lock = Puppet::Util::Pidlock.new(lockfile)
    expect(Puppet::Util::Pidlock).to receive(:new).with(lockfile).and_return(lock)

    @locker.send(:lockfile)
  end

  it "#lockfile_path provides the path to the lockfile" do
    lockfile = File.expand_path("/my/lock")
    Puppet[:agent_catalog_run_lockfile] = lockfile
    expect(@locker.lockfile_path).to eq(File.expand_path("/my/lock"))
  end

  it "should reuse the same lock file each time" do
    expect(@locker.send(:lockfile)).to equal(@locker.send(:lockfile))
  end

  it "should have a method that yields when a lock is attained" do
    expect(@locker.send(:lockfile)).to receive(:lock).and_return(true)

    yielded = false
    @locker.lock do
      yielded = true
    end
    expect(yielded).to be_truthy
  end

  it "should return the block result when the lock method successfully locked" do
    expect(@locker.send(:lockfile)).to receive(:lock).and_return(true)

    expect(@locker.lock { :result }).to eq(:result)
  end

  it "should raise LockError when the lock method does not receive the lock" do
    expect(@locker.send(:lockfile)).to receive(:lock).and_return(false)

    expect { @locker.lock {} }.to raise_error(Puppet::LockError)
  end

  it "should not yield when the lock method does not receive the lock" do
    expect(@locker.send(:lockfile)).to receive(:lock).and_return(false)

    yielded = false
    expect { @locker.lock { yielded = true } }.to raise_error(Puppet::LockError)
    expect(yielded).to be_falsey
  end

  it "should not unlock when a lock was not received" do
    expect(@locker.send(:lockfile)).to receive(:lock).and_return(false)
    expect(@locker.send(:lockfile)).not_to receive(:unlock)

    expect { @locker.lock {} }.to raise_error(Puppet::LockError)
  end

  it "should unlock after yielding upon obtaining a lock" do
    allow(@locker.send(:lockfile)).to receive(:lock).and_return(true)
    expect(@locker.send(:lockfile)).to receive(:unlock)

    @locker.lock {}
  end

  it "should unlock after yielding upon obtaining a lock, even if the block throws an exception" do
    allow(@locker.send(:lockfile)).to receive(:lock).and_return(true)
    expect(@locker.send(:lockfile)).to receive(:unlock)

    expect { @locker.lock { raise "foo" } }.to raise_error(RuntimeError)
  end

  it "should be considered running if the lockfile is locked" do
    expect(@locker.send(:lockfile)).to receive(:locked?).and_return(true)
    expect(@locker).to be_running
  end
end