summaryrefslogtreecommitdiffstats
path: root/spec/unit/indirector/yaml.rb
blob: 3875d70aa0ad260b6c90b02311f8721f9adf6204 (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
#!/usr/bin/env ruby

require File.dirname(__FILE__) + '/../../spec_helper'

require 'puppet/indirector/yaml'

describe Puppet::Indirector::Yaml, " when choosing file location" do
    before :each do
        @indirection = stub 'indirection', :name => :my_yaml, :register_terminus_type => nil
        Puppet::Indirector::Indirection.stubs(:instance).with(:my_yaml).returns(@indirection)
        @store_class = Class.new(Puppet::Indirector::Yaml) do
            def self.to_s
                "MyYaml::MyType"
            end
        end
        @store = @store_class.new

        @subject = Object.new
        @subject.metaclass.send(:attr_accessor, :name)
        @subject.name = :me

        @dir = "/what/ever"
        Puppet.settings.stubs(:value).returns("fakesettingdata")
        Puppet.settings.stubs(:value).with(:clientyamldir).returns(@dir)

        @request = stub 'request', :key => :me, :instance => @subject
    end

    describe Puppet::Indirector::Yaml, " when choosing file location" do
        it "should use the yamldir if the process name is 'puppetmasterd'" do
            Puppet.settings.expects(:value).with(:name).returns "puppetmasterd"
            Puppet.settings.expects(:value).with(:yamldir).returns "/main/yaml/dir"
            @store.path(:me).should =~ %r{^/main/yaml/dir}
        end

        it "should use the client yamldir if the process name is not 'puppetmasterd'" do
            Puppet.settings.expects(:value).with(:name).returns "cient"
            Puppet.settings.expects(:value).with(:clientyamldir).returns "/client/yaml/dir"
            @store.path(:me).should =~ %r{^/client/yaml/dir}
        end

        it "should store all files in a single file root set in the Puppet defaults" do
            @store.path(:me).should =~ %r{^#{@dir}}
        end

        it "should use the terminus name for choosing the subdirectory" do
            @store.path(:me).should =~ %r{^#{@dir}/my_yaml}
        end

        it "should use the object's name to determine the file name" do
            @store.path(:me).should =~ %r{me.yaml$}
        end
    end

    describe Puppet::Indirector::Yaml, " when storing objects as YAML" do
        it "should only store objects that respond to :name" do
            @request.stubs(:instance).returns Object.new
            proc { @store.save(@request) }.should raise_error(ArgumentError)
        end

        it "should convert Ruby objects to YAML and write them to disk" do
            yaml = @subject.to_yaml
            file = mock 'file'
            path = @store.send(:path, @subject.name)
            FileTest.expects(:exist?).with(File.dirname(path)).returns(true)
            File.expects(:open).with(path, "w", 0660).yields(file)
            file.expects(:print).with(yaml)

            @store.save(@request)
        end

        it "should create the indirection subdirectory if it does not exist" do
            yaml = @subject.to_yaml
            file = mock 'file'
            path = @store.send(:path, @subject.name)
            dir = File.dirname(path)
            FileTest.expects(:exist?).with(dir).returns(false)
            Dir.expects(:mkdir).with(dir)
            File.expects(:open).with(path, "w", 0660).yields(file)
            file.expects(:print).with(yaml)

            @store.save(@request)
        end
    end

    describe Puppet::Indirector::Yaml, " when retrieving YAML" do
        it "should read YAML in from disk and convert it to Ruby objects" do
            path = @store.send(:path, @subject.name)

            yaml = @subject.to_yaml
            FileTest.expects(:exist?).with(path).returns(true)
            File.expects(:read).with(path).returns(yaml)

            @store.find(@request).instance_variable_get("@name").should == :me
        end

        it "should fail coherently when the stored YAML is invalid" do
            path = @store.send(:path, @subject.name)

            # Something that will fail in yaml
            yaml = "--- !ruby/object:Hash"

            FileTest.expects(:exist?).with(path).returns(true)
            File.expects(:read).with(path).returns(yaml)

            proc { @store.find(@request) }.should raise_error(Puppet::Error)
        end
    end
end