summaryrefslogtreecommitdiffstats
path: root/spec/unit/util/autoload/file_cache.rb
blob: 333ddb545d94360758ef154d5f2d59d53b676f61 (plain)
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/env ruby

require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/util/autoload/file_cache'

class FileCacheTester
    include Puppet::Util::Autoload::FileCache
end

describe Puppet::Util::Autoload::FileCache do
    before do
        @cacher = FileCacheTester.new
    end

    after do
        Puppet::Util::Autoload::FileCache.clear
    end

    describe "when checking whether files exist" do
        it "should have a method for testing whether a file exists" do
            @cacher.should respond_to(:file_exist?)
        end

        it "should use lstat to determine whether a file exists" do
            File.expects(:lstat).with("/my/file")
            @cacher.file_exist?("/my/file")
        end

        it "should consider a file as absent if its lstat fails" do
            File.expects(:lstat).with("/my/file").raises Errno::ENOENT
            @cacher.should_not be_file_exist("/my/file")
        end

        it "should consider a file as present if its lstat succeeds" do
            File.expects(:lstat).with("/my/file").returns mock("stat")
            @cacher.should be_file_exist("/my/file")
        end

        it "should not stat a file twice in quick succession when the file is missing" do
            File.expects(:lstat).with("/my/file").once.raises Errno::ENOENT
            @cacher.should_not be_file_exist("/my/file")
            @cacher.should_not be_file_exist("/my/file")
        end

        it "should not stat a file twice in quick succession when the file is present" do
            File.expects(:lstat).with("/my/file").once.returns mock("stat")
            @cacher.should be_file_exist("/my/file")
            @cacher.should be_file_exist("/my/file")
        end

        it "should expire cached data after 15 seconds" do
            now = Time.now

            later = now + 16

            Time.expects(:now).times(3).returns(now).then.returns(later).then.returns(later)
            File.expects(:lstat).with("/my/file").times(2).returns(mock("stat")).then.raises Errno::ENOENT
            @cacher.should be_file_exist("/my/file")
            @cacher.should_not be_file_exist("/my/file")
        end

        it "should share cached data across autoload instances" do
            File.expects(:lstat).with("/my/file").once.returns mock("stat")
            other = Puppet::Util::Autoload.new("bar", "tmp")

            @cacher.should be_file_exist("/my/file")
            other.should be_file_exist("/my/file")
        end
    end

    describe "when checking whether files exist" do
        before do
            @stat = stub 'stat', :directory? => true
        end

        it "should have a method for determining whether a directory exists" do
            @cacher.should respond_to(:directory_exist?)
        end

        it "should use lstat to determine whether a directory exists" do
            File.expects(:lstat).with("/my/file").returns @stat
            @cacher.directory_exist?("/my/file")
        end

        it "should consider a directory as absent if its lstat fails" do
            File.expects(:lstat).with("/my/file").raises Errno::ENOENT
            @cacher.should_not be_directory_exist("/my/file")
        end

        it "should consider a directory as present if its lstat succeeds and the stat is of a directory" do
            @stat.expects(:directory?).returns true
            File.expects(:lstat).with("/my/file").returns @stat
            @cacher.should be_directory_exist("/my/file")
        end

        it "should consider a directory as absent if its lstat succeeds and the stat is not of a directory" do
            @stat.expects(:directory?).returns false
            File.expects(:lstat).with("/my/file").returns @stat
            @cacher.should_not be_directory_exist("/my/file")
        end

        it "should not stat a directory twice in quick succession when the file is missing" do
            File.expects(:lstat).with("/my/file").once.raises Errno::ENOENT
            @cacher.should_not be_directory_exist("/my/file")
            @cacher.should_not be_directory_exist("/my/file")
        end

        it "should not stat a directory twice in quick succession when the file is present" do
            File.expects(:lstat).with("/my/file").once.returns @stat
            @cacher.should be_directory_exist("/my/file")
            @cacher.should be_directory_exist("/my/file")
        end

        it "should not consider a file to be a directory based on cached data" do
            @stat.stubs(:directory?).returns false
            File.stubs(:lstat).with("/my/file").returns @stat
            @cacher.file_exist?("/my/file")
            @cacher.should_not be_directory_exist("/my/file")
        end

        it "should share cached data across autoload instances" do
            File.expects(:lstat).with("/my/file").once.returns @stat
            other = Puppet::Util::Autoload.new("bar", "tmp")

            @cacher.should be_directory_exist("/my/file")
            other.should be_directory_exist("/my/file")
        end
    end

    describe "when checking whether a named file exists" do
        it "should have a method for testing whether a named file is missing" do
            @cacher.should respond_to(:named_file_missing?)
        end

        it "should have a method for registering that a named file is missing" do
            @cacher.should respond_to(:named_file_is_missing)
        end

        it "should cache that a file is missing for 15 seconds" do
            now = Time.now

            later = now + 16

            Time.expects(:now).times(2).returns(now).then.returns(later)
            @cacher.named_file_is_missing("foo")
            @cacher.should_not be_named_file_missing("foo")
        end

        it "should return false when registering a file as missing" do
            @cacher.named_file_is_missing("foo").should be_false
        end
    end
end