File: calling_all_functions.rb

package info (click to toggle)
puppet-agent 8.10.0-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 27,404 kB
  • sloc: ruby: 286,820; sh: 492; xml: 116; makefile: 88; cs: 68
file content (235 lines) | stat: -rw-r--r-- 15,624 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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
test_name 'Calling all functions.. test in progress!'

tag 'audit:high',
    'audit:acceptance'

# create single manifest calling all functions
step 'Apply manifest containing all function calls'
def manifest_call_each_function_from_array(functions)
  manifest = ''
  # use index to work around puppet's immutable variables
  # use variables so we can concatenate strings
  functions.each_with_index do |function,index|
    if function[:rvalue]
      manifest << "$pre#{index} = \"sayeth #{function[:name].capitalize}: Scope(Class[main]): \" "
      manifest << "$output#{index} = #{function[:name]}(#{function[:args]}) "
      manifest << "#{function[:lambda]} notice \"${pre#{index}}${output#{index}}\"\n"
    else
      manifest << "$pre#{index} = \"sayeth #{function[:name].capitalize}: \" "
      manifest << "notice \"${pre#{index}}\"\n"
      manifest << "#{function[:name]}(#{function[:args]}) "
      manifest << "#{function[:lambda]}\n"
    end
  end
  manifest
end


agents.each do |agent|
  testdir = agent.tmpdir('calling_all_functions')
  # if agent["platform"] =~ /win/
  #   generator = {:args => '"c:/windows/system32/tasklist.exe"', :expected => /\nImage Name/}
  # else
  #   generator = {:args => '"/bin/date"',                        :expected => /\w\w\w.*?\d\d:\d\d\:\d\d/}
  # end

  # create list of 3x functions and args
  # notes: hiera functions are well tested elsewhere, included for completeness
  #   special cases: contain (call this from call_em_all)
  #   do fail last because it errors out

  functions_3x = [
    {:name => :alert,            :args => '"consider yourself on alert"',      :lambda => nil, :expected => 'consider yourself on alert', :rvalue => false},
    {:name => :binary_file,      :args => '"call_em_all/rickon.txt"',          :lambda => nil, :expected => '', :rvalue => true},
    #{:name => :break,            :args => '',                                  :lambda => nil, :expected => '', :rvalue => false},
    # this is explicitly called from call_em_all module which is included below
    #{:name => :contain,          :args => 'call_em_all',                       :lambda => nil, :expected => '', :rvalue => true},
    # below doens't instance the resource. no output
    {:name => :create_resources, :args => 'notify, {"w"=>{message=>"winter is coming"}}',      :lambda => nil, :expected => '', :rvalue => false},
    {:name => :crit,             :args => '"consider yourself critical"',      :lambda => nil, :expected => 'consider yourself critical', :rvalue => false},
    {:name => :debug,            :args => '"consider yourself bugged"',        :lambda => nil, :expected => '', :rvalue => false}, # no output expected unless run with debug
    {:name => :defined,          :args => 'File["/tmp"]',                      :lambda => nil, :expected => 'false', :rvalue => true},
    {:name => :dig,              :args => '[100]',                             :lambda => nil, :expected => '[100]', :rvalue => true},
    # Expect sha256 hash value for the digest
    {:name => :digest,           :args => '"Sansa"',                           :lambda => nil, :expected => '4ebf3a5527313f06c7965749d7764c15cba6fe86da11691ca9bd0ce448563979', :rvalue => true},
    {:name => :emerg,            :args => '"consider yourself emergent"',      :lambda => nil, :expected => 'consider yourself emergent', :rvalue => false},
    {:name => :err,              :args => '"consider yourself in err"',        :lambda => nil, :expected => 'consider yourself in err', :rvalue => false},
    {:name => :file,             :args => '"call_em_all/rickon.txt"',          :lambda => nil, :expected => 'who?', :rvalue => true},
    {:name => :fqdn_rand,        :args => '100000',                            :lambda => nil, :expected => /Fqdn_rand: Scope\(Class\[main\]\): \d{1,5}/, :rvalue => true},
    # generate requires a fully qualified exe; which requires specifics for windows vs posix
    #{:name => :generate,         :args => generator[:args],                    :lambda => nil, :expected => generator[:expected], :rvalue => true},
    {:name => :hiera_array,      :args => 'date,default_array',                :lambda => nil, :expected => 'default_array', :rvalue => true},
    {:name => :hiera_hash,       :args => 'date,default_hash',                 :lambda => nil, :expected => 'default_hash', :rvalue => true},
    {:name => :hiera_include,    :args => 'date,call_em_all',                  :lambda => nil, :expected => '', :rvalue => false},
    {:name => :hiera,            :args => 'date,default_date',                 :lambda => nil, :expected => 'default_date', :rvalue => true},
    {:name => :include,          :args => 'call_em_all',                       :lambda => nil, :expected => '', :rvalue => false},
    {:name => :info,             :args => '"consider yourself informed"',      :lambda => nil, :expected => '', :rvalue => false}, # no ouput unless in debug mode
    {:name => :inline_template,  :args => '\'empty<%= @x %>space\'',           :lambda => nil, :expected => 'emptyspace', :rvalue => true},
    # test the living life out of this thing in lookup.rb, and it doesn't allow for a default value
    #{:name => :lookup,           :args => 'date,lookup_date',                  :lambda => nil, :expected => '', :rvalue => true},  # well tested elsewhere
    {:name => :sha256,           :args => '"Bran"',                            :lambda => nil, :expected => '824264f7f73d6026550b52a671c50ad0c4452af66c24f3784e30f515353f2ce0', :rvalue => true},
    # Integer.new
    {:name => :Integer,          :args => '"100"',                             :lambda => nil, :expected => '100', :rvalue => true},
    {:name => :notice,           :args => '"consider yourself under notice"',  :lambda => nil, :expected => 'consider yourself under notice', :rvalue => false},
    {:name => :realize,          :args => 'User[arya]',                        :lambda => nil, :expected => '', :rvalue => false},  # TODO: create a virtual first
    {:name => :regsubst,         :args => '"Cersei","Cer(\\\\w)ei","Daenery\\\\1"',:lambda => nil, :expected => 'Daenerys', :rvalue => true},
    # explicitly called in call_em_all; implicitly called by the include above
    #{:name => :require,          :args => '[4,5,6]',                          :lambda => nil, :expected => '', :rvalue => true},
    # 4x output contains brackets around scanf output
    {:name => :scanf,            :args => '"Eddard Stark","%6s"',              :lambda => nil, :expected => '[Eddard]', :rvalue => true},
    {:name => :sha1,             :args => '"Sansa"',                           :lambda => nil, :expected => '4337ce5e4095e565d51e0ef4c80df1fecf238b29', :rvalue => true},
    {:name => :shellquote,       :args => '["-1", "--two"]',                   :lambda => nil, :expected => '-1 --two', :rvalue => true},
    # 4x output contains brackets around split output and commas btwn values
    {:name => :split,            :args => '"9,8,7",","',                       :lambda => nil, :expected => '[9, 8, 7]', :rvalue => true},
    {:name => :sprintf,          :args => '"%b","123"',                        :lambda => nil, :expected => '1111011', :rvalue => true},
    {:name => :step,             :args => '[100,99],1',                        :lambda => nil, :expected => 'Iterator[Integer]-Value', :rvalue => true},
    # explicitly called in call_em_all
    #{:name => :tag,              :args => '[4,5,6]',                          :lambda => nil, :expected => '', :rvalue => true},
    {:name => :tagged,           :args => '"yer_it"',                          :lambda => nil, :expected => 'false', :rvalue => true},
    {:name => :template,         :args => '"call_em_all/template.erb"',        :lambda => nil, :expected => 'no defaultsno space', :rvalue => true},
    {:name => :type,             :args => '42',                                :lambda => nil, :expected => 'Integer[42, 42]', :rvalue => true},
    {:name => :versioncmp,       :args => '"1","2"',                           :lambda => nil, :expected => '-1', :rvalue => true},
    {:name => :warning,          :args => '"consider yourself warned"',        :lambda => nil, :expected => 'consider yourself warned', :rvalue => false},
    # do this one last or it will not allow the others to run.
    {:name => :fail,             :args => '"Jon Snow"',                        :lambda => nil, :expected => /Error:.*Jon Snow/, :rvalue => false},
  ]

  puppet_version = on(agent, puppet('--version')).stdout.chomp

  functions_4x = [
    {:name => :assert_type,      :args => '"String[1]", "Valar morghulis"',    :lambda => nil, :expected => 'Valar morghulis', :rvalue => true},
    {:name => :each,             :args => '[1,2,3]',                           :lambda => '|$x| {$x}', :expected => '[1, 2, 3]', :rvalue => true},
    {:name => :epp,              :args => '"call_em_all/template.epp",{x=>droid}', :lambda => nil, :expected => 'This is the droid you are looking for!', :rvalue => true},
    {:name => :filter,           :args => '[4,5,6]',                           :lambda => '|$x| {true}', :expected => '[4, 5, 6]', :rvalue => true},
    # find_file() called by binary_file
    #{:name => :find_file,           :args => '[4,5,6]',                           :lambda => '|$x| {true}', :expected => '[4, 5, 6]', :rvalue => true},
    {:name => :inline_epp,       :args => '\'<%= $x %>\',{x=>10}',             :lambda => nil, :expected => '10', :rvalue => true},
    #{:name => :lest,             :args => '100',                               :lambda => '"100"', :expected => '100', :rvalue => true},
    {:name => :map,              :args => '[7,8,9]',                           :lambda => '|$x| {$x * $x}', :expected => '[49, 64, 81]', :rvalue => true},
    {:name => :match,            :args => '"abc", /b/',                        :lambda => nil, :expected => '[b]', :rvalue => true},
    #{:name => :next,             :args => '100',                               :lambda => nil, :expected => '100', :rvalue => true},
    {:name => :reduce,           :args => '[4,5,6]',                           :lambda => '|$sum, $n| { $sum+$n }', :expected => '15', :rvalue => true},
    #{:name => :return,           :args => '100',                               :lambda => nil, :expected => '100', :rvalue => true},
    {:name => :reverse_each,     :args => '[100,99]',                          :lambda => nil, :expected => 'Iterator[Integer]-Value', :rvalue => true},
    #         :reuse,:recycle
    {:name => :slice,            :args => '[1,2,3,4,5,6], 2',                  :lambda => nil, :expected => '[[1, 2], [3, 4], [5, 6]]', :rvalue => true},
    {:name => :strftime,         :args => 'Timestamp("4216-09-23T13:14:15.123 UTC"), "%C"',    :lambda => nil, :expected => '42', :rvalue => true},
    {:name => :then,             :args => '100',                               :lambda => '|$x| {$x}', :expected => '100', :rvalue => true},
    {:name => :with,             :args => '1, "Catelyn"',                      :lambda => '|$x, $y| {"$x, $y"}', :expected => '1, Catelyn', :rvalue => true},
  ]

  module_manifest = <<PP
File {
  ensure => directory,
}
file {
  '#{testdir}':;
  '#{testdir}/environments':;
  '#{testdir}/environments/production':;
  '#{testdir}/environments/production/modules':;
  '#{testdir}/environments/production/modules/tagged':;
  '#{testdir}/environments/production/modules/tagged/manifests':;
  '#{testdir}/environments/production/modules/contained':;
  '#{testdir}/environments/production/modules/contained/manifests':;
  '#{testdir}/environments/production/modules/required':;
  '#{testdir}/environments/production/modules/required/manifests':;
  '#{testdir}/environments/production/modules/call_em_all':;
  '#{testdir}/environments/production/modules/call_em_all/manifests':;
  '#{testdir}/environments/production/modules/call_em_all/templates':;
  '#{testdir}/environments/production/modules/call_em_all/files':;
}
file { '#{testdir}/environments/production/modules/tagged/manifests/init.pp':
  ensure  => file,
  content => 'class tagged {
    notice tagged
    tag     yer_it
    }',
}
file { '#{testdir}/environments/production/modules/required/manifests/init.pp':
  ensure  => file,
  content => 'class required {
    notice required
    }',
}
file { '#{testdir}/environments/production/modules/contained/manifests/init.pp':
  ensure  => file,
  content => 'class contained {
    notice contained
    }',
}
file { '#{testdir}/environments/production/modules/call_em_all/manifests/init.pp':
  ensure  => file,
  content => 'class call_em_all {
    notice call_em_all
    contain contained
    require required
    tag     yer_it
    }',
}
file { '#{testdir}/environments/production/modules/call_em_all/files/rickon.txt':
  ensure  => file,
  content => 'who?',
}
file { '#{testdir}/environments/production/modules/call_em_all/templates/template.epp':
  ensure  => file,
  content => 'This is the <%= $x %> you are looking for!',
}
file { '#{testdir}/environments/production/modules/call_em_all/templates/template.erb':
  ensure  => file,
  content => 'no defaults<%= @x %>no space',
}
PP

  apply_manifest_on(agent, module_manifest, :catch_failures => true)

  scope = 'Scope(Class[main]):'
  # apply the 4x function manifest with future parser
  puppet_apply_options = {:modulepath => "#{testdir}/environments/production/modules/",
     :acceptable_exit_codes => 1}
  puppet_apply_options[:future_parser] = true if puppet_version =~ /\A3\./
  apply_manifest_on(agent, manifest_call_each_function_from_array(functions_4x), puppet_apply_options) do |result|
       functions_4x.each do |function|
         expected = "#{function[:name].capitalize}: #{scope} #{function[:expected]}"
         unless agent['locale'] == 'ja'
           assert_match(expected, result.output,
                        "#{function[:name]} output didn't match expected value")
         end
       end
     end

   file_path = agent.tmpfile('apply_manifest.pp')

   create_remote_file(agent, file_path, manifest_call_each_function_from_array(functions_3x))

   trusted_3x = puppet_version =~ /\A3\./ ? '--trusted_node_data ' : ''
   on(agent, puppet("apply #{trusted_3x} --color=false  --modulepath #{testdir}/environments/production/modules/ #{file_path}"),
      :acceptable_exit_codes => 1 ) do |result|
        functions_3x.each do |function|
          # append the function name to the matcher so it's more expressive
          if function[:expected].is_a?(String)
            if function[:name] == :fail
              expected = function[:expected]
            elsif function[:name] == :crit
              expected = "#{function[:name].capitalize}ical: #{scope} #{function[:expected]}"
            elsif function[:name] == :emerg
              expected = "#{function[:name].capitalize}ency: #{scope} #{function[:expected]}"
            elsif function[:name] == :err
              expected = "#{function[:name].capitalize}or: #{scope} #{function[:expected]}"
            elsif function[:expected] == ''
              expected = "#{function[:name].capitalize}: #{function[:expected]}"
            else
              expected = "#{function[:name].capitalize}: #{scope} #{function[:expected]}"
            end
          elsif function[:expected].is_a?(Regexp)
            expected = function[:expected]
          else
            raise 'unhandled function expectation type (we allow String or Regexp)'
          end

          unless agent['locale'] == 'ja'
            assert_match(expected, result.output, "#{function[:name]} output didn't match expected value")
          end
        end
     end

end