summaryrefslogtreecommitdiff
path: root/spec/unit/util/command_line_spec.rb
blob: 9eb61b07756ceff93ddcd44cfe183eeead7f5f59 (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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#! /usr/bin/env ruby
require 'spec_helper'

require 'puppet/face'
require 'puppet/util/command_line'

describe Puppet::Util::CommandLine do
  include PuppetSpec::Files

  context "#initialize" do
    it "should pull off the first argument if it looks like a subcommand" do
      command_line = Puppet::Util::CommandLine.new("puppet", %w{ client --help whatever.pp })

      command_line.subcommand_name.should == "client"
      command_line.args.should            == %w{ --help whatever.pp }
    end

    it "should return nil if the first argument looks like a .pp file" do
      command_line = Puppet::Util::CommandLine.new("puppet", %w{ whatever.pp })

      command_line.subcommand_name.should == nil
      command_line.args.should            == %w{ whatever.pp }
    end

    it "should return nil if the first argument looks like a .rb file" do
      command_line = Puppet::Util::CommandLine.new("puppet", %w{ whatever.rb })

      command_line.subcommand_name.should == nil
      command_line.args.should            == %w{ whatever.rb }
    end

    it "should return nil if the first argument looks like a flag" do
      command_line = Puppet::Util::CommandLine.new("puppet", %w{ --debug })

      command_line.subcommand_name.should == nil
      command_line.args.should            == %w{ --debug }
    end

    it "should return nil if the first argument is -" do
      command_line = Puppet::Util::CommandLine.new("puppet", %w{ - })

      command_line.subcommand_name.should == nil
      command_line.args.should            == %w{ - }
    end

    it "should return nil if the first argument is --help" do
      command_line = Puppet::Util::CommandLine.new("puppet", %w{ --help })

      command_line.subcommand_name.should == nil
    end


    it "should return nil if there are no arguments" do
      command_line = Puppet::Util::CommandLine.new("puppet", [])

      command_line.subcommand_name.should == nil
      command_line.args.should            == []
    end

    it "should pick up changes to the array of arguments" do
      args = %w{subcommand}
      command_line = Puppet::Util::CommandLine.new("puppet", args)
      args[0] = 'different_subcommand'
      command_line.subcommand_name.should == 'different_subcommand'
    end
  end

  context "#execute" do
    %w{--version -V}.each do |arg|
      it "should print the version and exit if #{arg} is given" do
        expect do
          described_class.new("puppet", [arg]).execute
        end.to have_printed(/^#{Regexp.escape(Puppet.version)}$/)
      end
    end
  end

  describe "when dealing with puppet commands" do
    it "should return the executable name if it is not puppet" do
      command_line = Puppet::Util::CommandLine.new("puppetmasterd", [])
      command_line.subcommand_name.should == "puppetmasterd"
    end

    describe "when the subcommand is not implemented" do
      it "should find and invoke an executable with a hyphenated name" do
        commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'])
        Puppet::Util.expects(:which).with('puppet-whatever').
          returns('/dev/null/puppet-whatever')

        Kernel.expects(:exec).with('/dev/null/puppet-whatever', 'argument')

        commandline.execute
      end

      describe "and an external implementation cannot be found" do
        before :each do
          Puppet::Util::CommandLine::UnknownSubcommand.any_instance.stubs(:console_has_color?).returns false
        end

        it "should abort and show the usage message" do
          Puppet::Util.expects(:which).with('puppet-whatever').returns(nil)
          commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'])
          commandline.expects(:exec).never

          expect {
            commandline.execute
          }.to have_printed(/Unknown Puppet subcommand 'whatever'/).and_exit_with(1)
        end

        it "should abort and show the help message" do
          Puppet::Util.expects(:which).with('puppet-whatever').returns(nil)
          commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', 'argument'])
          commandline.expects(:exec).never

          expect {
            commandline.execute
          }.to have_printed(/See 'puppet help' for help on available puppet subcommands/).and_exit_with(1)
        end

        %w{--version -V}.each do |arg|
          it "should abort and display #{arg} information" do
            Puppet::Util.expects(:which).with('puppet-whatever').returns(nil)
            commandline = Puppet::Util::CommandLine.new("puppet", ['whatever', arg])
            commandline.expects(:exec).never

            expect {
              commandline.execute
            }.to have_printed(%r[^#{Regexp.escape(Puppet.version)}$]).and_exit_with(1)
          end
        end
      end
    end

    describe 'when loading commands' do
      it "should deprecate the available_subcommands instance method" do
        Puppet::Application.expects(:available_application_names)
        Puppet.expects(:deprecation_warning).with("Puppet::Util::CommandLine#available_subcommands is deprecated; please use Puppet::Application.available_application_names instead.")

        command_line = Puppet::Util::CommandLine.new("foo", %w{ client --help whatever.pp })
        command_line.available_subcommands
      end

      it "should deprecate the available_subcommands class method" do
        Puppet::Application.expects(:available_application_names)
        Puppet.expects(:deprecation_warning).with("Puppet::Util::CommandLine.available_subcommands is deprecated; please use Puppet::Application.available_application_names instead.")

        Puppet::Util::CommandLine.available_subcommands
      end
    end

    describe 'when setting process priority' do
      let(:command_line) do
        Puppet::Util::CommandLine.new("puppet", %w{ agent })
      end

      before :each do
        Puppet::Util::CommandLine::ApplicationSubcommand.any_instance.stubs(:run)
      end

      it 'should never set priority by default' do
        Process.expects(:setpriority).never

        command_line.execute
      end

      it 'should lower the process priority if one has been specified' do
        Puppet[:priority] = 10

        Process.expects(:setpriority).with(0, Process.pid, 10)
        command_line.execute
      end

      it 'should warn if trying to raise priority, but not privileged user' do
        Puppet[:priority] = -10

        Process.expects(:setpriority).raises(Errno::EACCES, 'Permission denied')
        Puppet.expects(:warning).with("Failed to set process priority to '-10'")

        command_line.execute
      end

      it "should warn if the platform doesn't support `Process.setpriority`" do
        Puppet[:priority] = 15

        Process.expects(:setpriority).raises(NotImplementedError, 'NotImplementedError: setpriority() function is unimplemented on this machine')
        Puppet.expects(:warning).with("Failed to set process priority to '15'")

        command_line.execute
      end
    end
  end
end