diff options
Diffstat (limited to 'spec/unit/util/symbolic_file_mode_spec.rb')
-rwxr-xr-x | spec/unit/util/symbolic_file_mode_spec.rb | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/spec/unit/util/symbolic_file_mode_spec.rb b/spec/unit/util/symbolic_file_mode_spec.rb new file mode 100755 index 000000000..a6e9509f7 --- /dev/null +++ b/spec/unit/util/symbolic_file_mode_spec.rb @@ -0,0 +1,182 @@ +#!/usr/bin/env rspec +require 'spec_helper' + +require 'puppet/util/symbolic_file_mode' + +describe Puppet::Util::SymbolicFileMode do + include Puppet::Util::SymbolicFileMode + + describe "#valid_symbolic_mode?" do + %w{ + 0 0000 1 1 7 11 77 111 777 11 + 0 00000 01 01 07 011 077 0111 0777 011 + = - + u= g= o= a= u+ g+ o+ a+ u- g- o- a- ugo= ugoa= ugugug= + a=,u=,g= a=,g+ + =rwx +rwx -rwx + 644 go-w =rw,+X +X 755 u=rwx,go=rx u=rwx,go=u-w go= g=u-w + 755 0755 + }.each do |input| + it "should treat #{input.inspect} as valid" do + valid_symbolic_mode?(input).should be_true + end + end + + [0000, 0111, 0640, 0755, 0777].each do |input| + it "should treat the int #{input.to_s(8)} as value" do + valid_symbolic_mode?(input).should be_true + end + end + + %w{ + -1 -8 8 9 18 19 91 81 000000 11111 77777 + 0-1 0-8 08 09 018 019 091 081 0000000 011111 077777 + u g o a ug uo ua ag + }.each do |input| + it "should treat #{input.inspect} as invalid" do + valid_symbolic_mode?(input).should be_false + end + end + end + + describe "#normalize_symbolic_mode" do + it "should turn an int into a string" do + normalize_symbolic_mode(12).should be_an_instance_of String + end + + it "should not add a leading zero to an int" do + normalize_symbolic_mode(12).should_not =~ /^0/ + end + + it "should not add a leading zero to a string with a number" do + normalize_symbolic_mode("12").should_not =~ /^0/ + end + + it "should string a leading zero from a number" do + normalize_symbolic_mode("012").should == '12' + end + + it "should pass through any other string" do + normalize_symbolic_mode("u=rwx").should == 'u=rwx' + end + end + + describe "#symbolic_mode_to_int" do + { + "0654" => 00654, + "u+r" => 00400, + "g+r" => 00040, + "a+r" => 00444, + "a+x" => 00111, + "o+t" => 01000, + "o+t" => 01000, + ["o-t", 07777] => 06777, + ["a-x", 07777] => 07666, + ["a-rwx", 07777] => 07000, + ["ug-rwx", 07777] => 07007, + "a+x,ug-rwx" => 00001, + # My experimentation on debian suggests that +g ignores the sgid flag + ["a+g", 02060] => 02666, + # My experimentation on debian suggests that -g ignores the sgid flag + ["a-g", 02666] => 02000, + "g+x,a+g" => 00111, + # +X without exec set in the original should not set anything + "u+x,g+X" => 00100, + "g+X" => 00000, + # +X only refers to the original, *unmodified* file mode! + ["u+x,a+X", 0600] => 00700, + # Examples from the MacOS chmod(1) manpage + "0644" => 00644, + ["go-w", 07777] => 07755, + ["=rw,+X", 07777] => 07777, + ["=rw,+X", 07766] => 07777, + ["=rw,+X", 07676] => 07777, + ["=rw,+X", 07667] => 07777, + ["=rw,+X", 07666] => 07666, + "0755" => 00755, + "u=rwx,go=rx" => 00755, + "u=rwx,go=u-w" => 00755, + ["go=", 07777] => 07700, + ["g=u-w", 07777] => 07757, + ["g=u-w", 00700] => 00750, + ["g=u-w", 00600] => 00640, + ["g=u-w", 00500] => 00550, + ["g=u-w", 00400] => 00440, + ["g=u-w", 00300] => 00310, + ["g=u-w", 00200] => 00200, + ["g=u-w", 00100] => 00110, + ["g=u-w", 00000] => 00000, + # Cruel, but legal, use of the action set. + ["g=u+r-w", 0300] => 00350, + # Empty assignments. + ["u=", 00000] => 00000, + ["u=", 00600] => 00000, + ["ug=", 00000] => 00000, + ["ug=", 00600] => 00000, + ["ug=", 00660] => 00000, + ["ug=", 00666] => 00006, + ["=", 00000] => 00000, + ["=", 00666] => 00000, + ["+", 00000] => 00000, + ["+", 00124] => 00124, + ["-", 00000] => 00000, + ["-", 00124] => 00124, + }.each do |input, result| + from = input.is_a?(Array) ? "#{input[0]}, 0#{input[1].to_s(8)}" : input + it "should map #{from.inspect} to #{result.inspect}" do + symbolic_mode_to_int(*input).should == result + end + end + + # Now, test some failure modes. + it "should fail if no mode is given" do + expect { symbolic_mode_to_int('') }. + to raise_error Puppet::Error, /empty mode string/ + end + + %w{u g o ug uo go ugo a uu u/x u!x u=r,,g=r}.each do |input| + it "should fail if no (valid) action is given: #{input.inspect}" do + expect { symbolic_mode_to_int(input) }. + to raise_error Puppet::Error, /Missing action/ + end + end + + %w{u+q u-rwF u+rw,g+rw,o+RW}.each do |input| + it "should fail with unknown op #{input.inspect}" do + expect { symbolic_mode_to_int(input) }. + to raise_error Puppet::Error, /Unknown operation/ + end + end + + it "should refuse to subtract the conditional execute op" do + expect { symbolic_mode_to_int("o-rwX") }. + to raise_error Puppet::Error, /only works with/ + end + + it "should refuse to set to the conditional execute op" do + expect { symbolic_mode_to_int("o=rwX") }. + to raise_error Puppet::Error, /only works with/ + end + + %w{8 08 9 09 118 119}.each do |input| + it "should fail for decimal modes: #{input.inspect}" do + expect { symbolic_mode_to_int(input) }. + to raise_error Puppet::Error, /octal/ + end + end + + it "should set the execute bit on a directory, without exec in original" do + symbolic_mode_to_int("u+X", 0444, true).to_s(8).should == "544" + symbolic_mode_to_int("g+X", 0444, true).to_s(8).should == "454" + symbolic_mode_to_int("o+X", 0444, true).to_s(8).should == "445" + symbolic_mode_to_int("+X", 0444, true).to_s(8).should == "555" + end + + it "should set the execute bit on a file with exec in the original" do + symbolic_mode_to_int("+X", 0544).to_s(8).should == "555" + end + + it "should not set the execute bit on a file without exec on the original even if set by earlier DSL" do + symbolic_mode_to_int("u+x,go+X", 0444).to_s(8).should == "544" + end + end +end |