summaryrefslogtreecommitdiffstats
path: root/spec/unit/file_bucket/file_spec.rb
blob: 82063c2e318ac8d32b52083442c60e9c122d5401 (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
#!/usr/bin/env ruby

require ::File.dirname(__FILE__) + '/../../spec_helper'

require 'puppet/file_bucket/file'
require 'digest/md5'
require 'digest/sha1'

describe Puppet::FileBucket::File do
  include PuppetSpec::Files

  before do
    # this is the default from spec_helper, but it keeps getting reset at odd times
    @bucketdir = tmpdir('bucket')
    Puppet[:bucketdir] = @bucketdir

    @digest = "4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
    @checksum = "{md5}4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
    @dir = File.join(@bucketdir, '4/a/8/e/c/4/f/a/4a8ec4fa5f01b4ab1a0ab8cbccb709f0')

    @contents = "file contents"
  end

  it "should have a to_s method to return the contents" do
    Puppet::FileBucket::File.new(@contents).to_s.should == @contents
  end

  it "should raise an error if changing content" do
    x = Puppet::FileBucket::File.new("first")
    proc { x.contents = "new" }.should raise_error
  end

  it "should require contents to be a string" do
    proc { Puppet::FileBucket::File.new(5) }.should raise_error(ArgumentError)
  end

  it "should set the contents appropriately" do
    Puppet::FileBucket::File.new(@contents).contents.should == @contents
  end

  it "should default to 'md5' as the checksum algorithm if the algorithm is not in the name" do
    Puppet::FileBucket::File.new(@contents).checksum_type.should == "md5"
  end

  it "should calculate the checksum" do
    Puppet::FileBucket::File.new(@contents).checksum.should == @checksum
  end

  describe "when using back-ends" do
    it "should redirect using Puppet::Indirector" do
      Puppet::Indirector::Indirection.instance(:file_bucket_file).model.should equal(Puppet::FileBucket::File)
    end

    it "should have a :save instance method" do
      Puppet::FileBucket::File.new("mysum").should respond_to(:save)
    end

    it "should respond to :find" do
      Puppet::FileBucket::File.should respond_to(:find)
    end

    it "should respond to :destroy" do
      Puppet::FileBucket::File.should respond_to(:destroy)
    end
  end

  describe "when saving files" do
    it "should save the contents to the calculated path" do
      ::File.stubs(:directory?).with(@dir).returns(true)
      ::File.expects(:exist?).with("#{@dir}/contents").returns false

      mockfile = mock "file"
      mockfile.expects(:print).with(@contents)
      ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440).yields(mockfile)

      Puppet::FileBucket::File.new(@contents).save
    end

    it "should make any directories necessary for storage" do
      FileUtils.expects(:mkdir_p).with do |arg|
        ::File.umask == 0007 and arg == @dir
      end
      ::File.expects(:directory?).with(@dir).returns(false)
      ::File.expects(:open).with("#{@dir}/contents", ::File::WRONLY|::File::CREAT, 0440)
      ::File.expects(:exist?).with("#{@dir}/contents").returns false

      Puppet::FileBucket::File.new(@contents).save
    end
  end

  it "should return a url-ish name" do
    Puppet::FileBucket::File.new(@contents).name.should == "md5/4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
  end

  it "should reject a url-ish name with an invalid checksum" do
    bucket = Puppet::FileBucket::File.new(@contents)
    lambda { bucket.name = "sha1/4a8ec4fa5f01b4ab1a0ab8cbccb709f0/new/path" }.should raise_error
  end

  it "should convert the contents to PSON" do
    Puppet::FileBucket::File.new(@contents).to_pson.should == '{"contents":"file contents"}'
  end

  it "should load from PSON" do
    Puppet::FileBucket::File.from_pson({"contents"=>"file contents"}).contents.should == "file contents"
  end

  it "should save a file" do
    ::File.expects(:exist?).with("#{@dir}/contents").returns false
    ::File.expects(:directory?).with(@dir).returns false
    ::FileUtils.expects(:mkdir_p).with(@dir)
    ::File.expects(:open).with("#{@dir}/contents",  ::File::WRONLY|::File::CREAT, 0440)

    bucketfile = Puppet::FileBucket::File.new(@contents)
    bucketfile.save

  end

  def make_bucketed_file
    FileUtils.mkdir_p(@dir)
    File.open("#{@dir}/contents", 'w') { |f| f.write @contents }
  end

  describe "using the indirector's find method" do
    it "should return nil if a file doesn't exist" do
      bucketfile = Puppet::FileBucket::File.find("md5/#{@digest}")
      bucketfile.should == nil
    end

    it "should find a filebucket if the file exists" do
      make_bucketed_file
      bucketfile = Puppet::FileBucket::File.find("md5/#{@digest}")
      bucketfile.should_not == nil
    end

    describe "using RESTish digest notation" do
      it "should return nil if a file doesn't exist" do
        bucketfile = Puppet::FileBucket::File.find("md5/#{@digest}")
        bucketfile.should == nil
      end

      it "should find a filebucket if the file exists" do
        make_bucketed_file
        bucketfile = Puppet::FileBucket::File.find("md5/#{@digest}")
        bucketfile.should_not == nil
      end

    end
  end
end