summaryrefslogtreecommitdiffstats
path: root/spec/unit/indirector/queue_spec.rb
blob: 0748b58177b8d67430df602a02fdbf2ffe48f672 (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
#!/usr/bin/env ruby

require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/queue'

class Puppet::Indirector::Queue::TestClient
end

class FooExampleData
    attr_accessor :name

    def self.pson_create(pson)
        new(pson['data'].to_sym)
    end

    def initialize(name = nil)
        @name = name if name
    end

    def render(format = :pson)
        to_pson
    end

    def to_pson(*args)
        {:type => self.class.to_s, :data => name}.to_pson(*args)
    end
end

describe Puppet::Indirector::Queue do
    confine "PSON library is missing; cannot test queueing" => Puppet.features.pson?

    before :each do
        @model = mock 'model'
        @indirection = stub 'indirection', :name => :my_queue, :register_terminus_type => nil, :model => @model
        Puppet::Indirector::Indirection.stubs(:instance).with(:my_queue).returns(@indirection)
        @store_class = Class.new(Puppet::Indirector::Queue) do
            def self.to_s
                'MyQueue::MyType'
            end
        end
        @store = @store_class.new

        @subject_class = FooExampleData
        @subject = @subject_class.new
        @subject.name = :me

        Puppet.settings.stubs(:value).returns("bogus setting data")
        Puppet.settings.stubs(:value).with(:queue_type).returns(:test_client)
        Puppet::Util::Queue.stubs(:queue_type_to_class).with(:test_client).returns(Puppet::Indirector::Queue::TestClient)

        @request = stub 'request', :key => :me, :instance => @subject
    end

    it "should require PSON" do
        Puppet.features.expects(:pson?).returns false

        lambda { @store_class.new }.should raise_error(ArgumentError)
    end

    it 'should use the correct client type and queue' do
        @store.queue.should == :my_queue
        @store.client.should be_an_instance_of(Puppet::Indirector::Queue::TestClient)
    end

    describe "when saving" do
        it 'should render the instance using pson' do
            @subject.expects(:render).with(:pson)
            @store.client.stubs(:send_message)
            @store.save(@request)
        end

        it "should send the rendered message to the appropriate queue on the client" do
            @subject.expects(:render).returns "mypson"

            @store.client.expects(:send_message).with(:my_queue, "mypson")

            @store.save(@request)
        end

        it "should catch any exceptions raised" do
            @store.client.expects(:send_message).raises ArgumentError

            lambda { @store.save(@request) }.should raise_error(Puppet::Error)
        end
    end

    describe "when subscribing to the queue" do
        before do
            @store_class.stubs(:model).returns @model
        end

        it "should use the model's Format support to intern the message from pson" do
            @model.expects(:convert_from).with(:pson, "mymessage")

            @store_class.client.expects(:subscribe).yields("mymessage")
            @store_class.subscribe {|o| o }
        end

        it "should yield each interned received message" do
            @model.stubs(:convert_from).returns "something"

            @subject_two = @subject_class.new
            @subject_two.name = :too

            @store_class.client.expects(:subscribe).with(:my_queue).multiple_yields(@subject, @subject_two)

            received = []
            @store_class.subscribe do |obj|
                received.push(obj)
            end

            received.should == %w{something something}
        end

        it "should log but not propagate errors" do
            @store_class.client.expects(:subscribe).yields("foo")
            @store_class.expects(:intern).raises ArgumentError
            Puppet.expects(:err)
            @store_class.subscribe {|o| o }
        end
    end
end