Class: Puppet::Application::Spec

Inherits:
Puppet::Application
  • Object
show all
Includes:
Util::Colors
Defined in:
lib/puppet/application/spec.rb

Instance Method Summary collapse

Instance Method Details

#catalog(path) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/puppet/application/spec.rb', line 49

def catalog(path)
  Puppet::Test::TestHelper.before_each_test
  Puppet[:code] = File.read(path)

  node = Puppet::Node.new("spec")
  modulepath = get_modulepath(node)
  link_module(modulepath)
  catalog = Puppet::Resource::Catalog.indirection.find(node.name, :use_node => node)
  catalog.to_ral

  Puppet::Test::TestHelper.after_each_test
  catalog
end

#get_modulepath(node) ⇒ Object

Given a node object, return the first modulepath



127
128
129
# File 'lib/puppet/application/spec.rb', line 127

def get_modulepath(node)
  node.environment.full_modulepath[0]
end

Ensure that a symlink is present pointing from the node’s env to the current directory



134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/puppet/application/spec.rb', line 134

def link_module(modulepath)
  pwd = Dir.pwd
  name = File.basename(pwd)
  symlink = File.join(modulepath, name)

  # Ensure that the modulepath exists
  # within the temp environment
  FileUtils.mkdir_p(modulepath) unless Dir.exist?(modulepath)

  # Ensure that a symlink to the
  # cwd exists
  FileUtils.ln_s(pwd, symlink) unless File.symlink?(symlink)
end

#notify_compiledObject

Print an rspec style dot to signify spec compilation



121
122
123
# File 'lib/puppet/application/spec.rb', line 121

def notify_compiled
  print colorize(:green, '.')
end

Given the resulting hash from .visit_assertions, present the output to the user.



99
100
101
102
103
104
105
106
107
108
# File 'lib/puppet/application/spec.rb', line 99

def print_results(results)
  print "\n\n"
  print results[:msg] if results[:msg]

  if results[:count] == 1
    print colorize(:yellow, "Evaluated #{results[:count]} assertion\n")
  else
    print colorize(:yellow, "Evaluated #{results[:count]} assertions\n")
  end
end

#process_spec(path) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/puppet/application/spec.rb', line 34

def process_spec(path)
  catalog = catalog(path)
  notify_compiled

  assertions = catalog.resources.select {|res| res.type == 'Assertion' }

  # Get the subject resource from the catalog rather than the
  # reference provided from the parser. The reference's resource
  # object does not contain any parameters for whatever reason.
  assertions.map do |res|
    res[:subject] = catalog.resource(res[:subject].to_s)
    res
  end
end

#process_spec_directory(specdir) ⇒ Object



27
28
29
30
31
32
# File 'lib/puppet/application/spec.rb', line 27

def process_spec_directory(specdir)
  results = Dir.glob("#{specdir}/**/*_spec.pp").map { |spec| process_spec(spec) }.flatten
  output = visit_assertions(results)
  print_results(output)
  output
end

#run_commandObject



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/puppet/application/spec.rb', line 9

def run_command
  output = Hash.new

  begin
    Puppet::Test::TestHelper.initialize
    output = process_spec_directory(specdir)
  rescue Exception => e
    print colorize(:red, "#{e.message}\n")
    exit 1
  end

  if output[:failed] == 0
    exit 0
  else
    exit 1
  end
end

#specdirObject

Return the specdir under the CWD or raise an error if not found.



151
152
153
154
155
156
157
158
# File 'lib/puppet/application/spec.rb', line 151

def specdir
  pwd = Dir.pwd
  specdir = File.join(pwd, 'spec')
  unless Dir.exist?(specdir)
    raise 'No spec directory was found under the CWD. You can optionally specifiy one with --specdir'
  end
  specdir
end

#validate_assertion(assertion) ⇒ Object

Validate assertion raises an error if the assertion does not contain a subject, or if it contains a expectation without attribute.

Raises:

  • (Puppet::Error)


114
115
116
117
# File 'lib/puppet/application/spec.rb', line 114

def validate_assertion(assertion)
  raise Puppet::Error, "#{assertion} requires a subject" unless assertion[:subject]
  raise Puppet::Error, "#{assertion} requires an attribute when an expectation is given" if assertion[:expectation] and not assertion[:attribute]
end

#visit_assertions(assertions) ⇒ Object

Return a hash that contains data to be displayed to the user which represents the results of the assertions.



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
# File 'lib/puppet/application/spec.rb', line 67

def visit_assertions(assertions)
  count = 0
  failed_count = 0

  msg = assertions.map do |assertion|
    count += 1
    validate_assertion(assertion)

    unless assertion[:expectation] == assertion[:subject][assertion[:attribute]]
      failed_count += 1
      file = assertion[:subject].file.split('manifests/').last

      msg = colorize(:red, "#{failed_count}) Assertion #{assertion[:name]} failed on #{assertion[:subject].to_s}\n")
      msg += colorize(:yellow, "  On line #{assertion[:subject].line} of #{file}\n")
      msg += colorize(:blue, "  Wanted: ")
      msg += "#{assertion[:attribute]} => '#{assertion[:expectation]}'\n"
      msg += colorize(:blue, "  Got:    ")
      msg += "#{assertion[:attribute]} => '#{assertion[:subject][assertion[:attribute]]}'\n\n"
    end
  end

  {
    :msg    => msg.join,
    :count  => count,
    :failed => failed_count,
  }
end