summaryrefslogtreecommitdiff
path: root/spec/unit/settings/config_file_spec.rb
blob: b071d32e2c23329676c485fb14f7f712d311880a (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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#! /usr/bin/env ruby -S rspec
require 'spec_helper'
require 'puppet/settings/config_file'

describe Puppet::Settings::ConfigFile do
  NOTHING = {}

  def the_parse_of(*lines)
    config.parse_file(filename, lines.join("\n"))
  end

  let(:identity_transformer) { Proc.new { |value| value } }
  let(:config) { Puppet::Settings::ConfigFile.new(identity_transformer) }

  let(:filename) { "a/fake/filename.conf" }

  Conf = Puppet::Settings::ConfigFile::Conf
  Section = Puppet::Settings::ConfigFile::Section
  Meta = Puppet::Settings::ConfigFile::Meta
  NO_META = Puppet::Settings::ConfigFile::NO_META

  it "interprets an empty file to contain a main section with no entries" do
    result = the_parse_of("")

    expect(result).to eq(Conf.new.with_section(Section.new(:main)))
  end

  it "interprets an empty main section the same as an empty file" do
    the_parse_of("").should == config.parse_file(filename, "[main]")
  end

  it "places an entry in no section in main" do
    result = the_parse_of("var = value")

    expect(result).to eq(Conf.new.with_section(Section.new(:main).with_setting(:var, "value", NO_META)))
  end

  it "places an entry after a section header in that section" do
    result = the_parse_of("[section]", "var = value")

    expect(result).to eq(Conf.new.
                         with_section(Section.new(:main)).
                         with_section(Section.new(:section).
                                      with_setting(:var, "value", NO_META)))
  end

  it "does not include trailing whitespace in the value" do
    result = the_parse_of("var = value\t ")

    expect(result).to eq(Conf.new.
                         with_section(Section.new(:main).
                                      with_setting(:var, "value", NO_META)))
  end

  it "does not include leading whitespace in the name" do
    result = the_parse_of("  \t var=value")

    expect(result).to eq(Conf.new.
                         with_section(Section.new(:main).
                                      with_setting(:var, "value", NO_META)))
  end

  it "skips lines that are commented out" do
    result = the_parse_of("#var = value")

    expect(result).to eq(Conf.new.with_section(Section.new(:main)))
  end

  it "skips lines that are entirely whitespace" do
    result = the_parse_of("   \t ")

    expect(result).to eq(Conf.new.with_section(Section.new(:main)))
  end

  it "errors when a line is not a known form" do
    expect { the_parse_of("unknown") }.to raise_error Puppet::Settings::ParseError, /Could not match line/
  end

  it "errors providing correct line number when line is not a known form" do
    multi_line_config = <<-EOF
[main]
foo=bar
badline
    EOF
    expect { the_parse_of(multi_line_config) }.to(
        raise_error(Puppet::Settings::ParseError, /Could not match line/) do |exception|
          expect(exception.line).to eq(3)
        end
      )
  end

  it "stores file meta information in the _meta section" do
    result = the_parse_of("var = value { owner = me, group = you, mode = 0666 }")

    expect(result).to eq(Conf.new.with_section(Section.new(:main).
                                               with_setting(:var, "value",
                                                            Meta.new("me", "you", "0666"))))
  end

  it "errors when there is unknown meta information" do
    expect { the_parse_of("var = value { unknown = no }") }.
      to raise_error ArgumentError, /Invalid file option 'unknown'/
  end

  it "errors when the mode is not numeric" do
    expect { the_parse_of("var = value { mode = no }") }.
      to raise_error ArgumentError, "File modes must be numbers"
  end

  it "errors when the options are not key-value pairs" do
    expect { the_parse_of("var = value { mode }") }.
      to raise_error ArgumentError, "Could not parse 'value { mode }'"
  end

  it "errors when an application_defaults section is created" do
    expect { the_parse_of("[application_defaults]") }.
      to raise_error Puppet::Error,
        "Illegal section 'application_defaults' in config file #{filename} at line 1"
  end

  it "errors when a global_defaults section is created" do
    expect { the_parse_of("[main]\n[global_defaults]") }.
      to raise_error Puppet::Error,
        "Illegal section 'global_defaults' in config file #{filename} at line 2"
  end

  it "issues a single deprecation warning when any section other than main, master, agent or user is parsed" do
    text = "[legacy]
    one = 'e'
    two = 'f'
    [also_deprecated]
    one = 'g'
    "

    config.parse_file(filename, text)

    expect(@logs.map(&:message).grep(/Sections other than/)).to have_exactly(1).item
  end

  it "does not issue a deprecation warning for main, master, agent or user sections" do
    text = "[main]
    one = 'a'
    [master]
    one = 'b'
    [agent]
    one = 'c'
    [user]
    one = 'd'
    "

    Puppet.expects(:deprecation_warning).never

    config.parse_file(filename, text)
  end

  it "transforms values with the given function" do
    config = Puppet::Settings::ConfigFile.new(Proc.new { |value| value + " changed" })

    result = config.parse_file(filename, "var = value")

    expect(result).to eq(Conf.new.
                            with_section(Section.new(:main).
                                         with_setting(:var, "value changed", NO_META)))
  end

  it "does not try to transform an entry named 'mode'" do
    config = Puppet::Settings::ConfigFile.new(Proc.new { raise "Should not transform" })

    result = config.parse_file(filename, "mode = value")

    expect(result).to eq(Conf.new.
                            with_section(Section.new(:main).
                                         with_setting(:mode, "value", NO_META)))
  end
end