File: configurer_spec.rb

package info (click to toggle)
puppet-agent 8.10.0-5
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 27,392 kB
  • sloc: ruby: 286,820; sh: 492; xml: 116; makefile: 88; cs: 68
file content (166 lines) | stat: -rw-r--r-- 6,474 bytes parent folder | download | duplicates (2)
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
require 'spec_helper'

require 'puppet_spec/network'
require 'puppet/configurer'

describe Puppet::Configurer do
  include PuppetSpec::Files
  include PuppetSpec::Network

  describe "when running" do
    before(:each) do
      @catalog = Puppet::Resource::Catalog.new("testing", Puppet.lookup(:environments).get(Puppet[:environment]))
      @catalog.add_resource(Puppet::Type.type(:notify).new(:title => "testing"))

      # Make sure we don't try to persist the local state after the transaction ran,
      # because it will fail during test (the state file is in a not-existing directory)
      # and we need the transaction to be successful to be able to produce a summary report
      @catalog.host_config = false

      @configurer = Puppet::Configurer.new
    end

    it "should send a transaction report with valid data" do
      allow(@configurer).to receive(:save_last_run_summary)
      expect(Puppet::Transaction::Report.indirection).to receive(:save) do |report, x|
        expect(report.time).to be_a(Time)
        expect(report.logs.length).to be > 0
      end.twice

      Puppet[:report] = true

      @configurer.run :catalog => @catalog
    end

    it "should save a correct last run summary" do
      report = Puppet::Transaction::Report.new
      allow(Puppet::Transaction::Report.indirection).to receive(:save)

      Puppet[:lastrunfile] = tmpfile("lastrunfile")
      Puppet.settings.setting(:lastrunfile).mode = 0666
      Puppet[:report] = true

      # We only record integer seconds in the timestamp, and truncate
      # backwards, so don't use a more accurate timestamp in the test.
      # --daniel 2011-03-07
      t1 = Time.now.tv_sec
      @configurer.run :catalog => @catalog, :report => report
      t2 = Time.now.tv_sec

      # sticky bit only applies to directories in windows
      file_mode = Puppet::Util::Platform.windows? ? '666' : '100666'

      expect(Puppet::FileSystem.stat(Puppet[:lastrunfile]).mode.to_s(8)).to eq(file_mode)

      summary = Puppet::Util::Yaml.safe_load_file(Puppet[:lastrunfile])

      expect(summary).to be_a(Hash)
      %w{time changes events resources}.each do |key|
        expect(summary).to be_key(key)
      end
      expect(summary["time"]).to be_key("notify")
      expect(summary["time"]["last_run"]).to be_between(t1, t2)
    end

    it "applies a cached catalog if pluginsync fails when usecacheonfailure is true and environment is valid" do
      expect(@configurer).to receive(:valid_server_environment?).and_return(true)
      Puppet[:ignore_plugin_errors] = false

      Puppet[:use_cached_catalog] = false
      Puppet[:usecacheonfailure] = true

      report = Puppet::Transaction::Report.new
      expect_any_instance_of(Puppet::Configurer::Downloader).to receive(:evaluate).and_raise(Puppet::Error, 'Failed to retrieve: some file')
      expect(Puppet::Resource::Catalog.indirection).to receive(:find).and_return(@catalog)

      @configurer.run(pluginsync: true, report: report)
      expect(report.cached_catalog_status).to eq('on_failure')
    end

    it "applies a cached catalog if pluginsync fails when usecacheonfailure is true and environment is invalid" do
      expect(@configurer).to receive(:valid_server_environment?).and_return(false)
      Puppet[:ignore_plugin_errors] = false

      Puppet[:use_cached_catalog] = false
      Puppet[:usecacheonfailure] = true

      report = Puppet::Transaction::Report.new
      expect(Puppet::Resource::Catalog.indirection).to receive(:find).and_raise(Puppet::Error, 'Cannot compile remote catalog')
      expect(Puppet::Resource::Catalog.indirection).to receive(:find).and_return(@catalog)

      @configurer.run(pluginsync: true, report: report)
      expect(report.cached_catalog_status).to eq('on_failure')
    end

    describe 'resubmitting facts' do
      context 'when resubmit_facts is set to false' do
        it 'should not send data' do
          expect(@configurer).to receive(:resubmit_facts).never

          @configurer.run(catalog: @catalog)
        end
      end

      context 'when resubmit_facts is set to true' do
        let(:test_facts) { Puppet::Node::Facts.new('configurer.test', {test_fact: 'test value'}) }

        before(:each) do
          Puppet[:resubmit_facts] = true

          allow(@configurer).to receive(:find_facts).and_return(test_facts)
        end

        it 'uploads facts as application/json' do
          stub_request(:put, "https://puppet:8140/puppet/v3/facts/configurer.test?environment=production").
            with(
              body: hash_including(
                {
                  "name" => "configurer.test",
                  "values" => {"test_fact" => 'test value',},
                }),
              headers: {
                'Accept'=>acceptable_content_types_string,
                'Content-Type'=>'application/json',
              })

          @configurer.run(catalog: @catalog)
        end

        it 'logs errors that occur during fact generation' do
          allow(@configurer).to receive(:find_facts).and_raise('error generating facts')
          expect(Puppet).to receive(:log_exception).with(instance_of(RuntimeError),
                                                         /^Failed to submit facts/)

          @configurer.run(catalog: @catalog)
        end

        it 'logs errors that occur during fact submission' do
          stub_request(:put, "https://puppet:8140/puppet/v3/facts/configurer.test?environment=production").to_return(status: 502)
          expect(Puppet).to receive(:log_exception).with(Puppet::HTTP::ResponseError,
                                                         /^Failed to submit facts/)

          @configurer.run(catalog: @catalog)
        end

        it 'records time spent resubmitting facts' do
          report = Puppet::Transaction::Report.new

          stub_request(:put, "https://puppet:8140/puppet/v3/facts/configurer.test?environment=production").
            with(
              body: hash_including({
                "name" => "configurer.test",
                "values" => {"test_fact": "test value"},
              }),
              headers: {
                'Accept'=>acceptable_content_types_string,
                'Content-Type'=>'application/json',
              }).to_return(status: 200)

          @configurer.run(catalog: @catalog, report: report)

          expect(report.metrics['time'].values).to include(["resubmit_facts", anything, Numeric])
        end
      end
    end
  end
end