File: test_connection_driver.rb

package info (click to toggle)
qpid-proton 0.37.0-7
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 18,384 kB
  • sloc: ansic: 37,828; cpp: 37,140; python: 15,302; ruby: 6,018; xml: 477; sh: 320; pascal: 52; makefile: 18
file content (134 lines) | stat: -rw-r--r-- 5,412 bytes parent folder | download | duplicates (5)
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
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.


require 'test_tools'
require 'minitest/unit'

include Qpid::Proton

# Test delivery of raw proton events

class RawDriverTest < MiniTest::Test

  # Raw handler to record all on_xxx calls
  class RecordingHandler
    def initialize() @calls =[]; end
    def proton_adapter_class() nil; end # Raw adapter
    attr_reader :calls

    def method_missing(name, *args) respond_to_missing?(name) ? @calls << name : super; end
    def respond_to_missing?(name, private=false); (/^on_/ =~ name); end
    def respond_to?(name, all=false) super || respond_to_missing?(name); end # For ruby < 1.9.2
  end

  def test_send_recv
    send_class = Class.new do
      def proton_adapter_class() nil; end # Raw adapter
      attr_reader :outcome
      def on_link_flow(event) event.sender.send Message.new("foo"); end
      def on_delivery(event)
        @outcome = event.delivery.state
        event.connection.close;
      end
    end

    recv_class = Class.new do
      def proton_adapter_class() nil; end # Raw adapter
      attr_reader :message
      def on_connection_remote_open(event) event.context.open; end
      def on_session_remote_open(event) event.context.open; end
      def on_link_remote_open(event) event.link.open; event.link.flow(1); end
      def on_delivery(event) @message = event.message; event.delivery.accept; end
    end

    d = DriverPair.new(send_class.new, recv_class.new)
    d.client.connection.open(:container_id => __method__);
    d.client.connection.open_sender()
    d.run
    assert_equal(d.server.handler.message.body, "foo")
    assert_equal Transfer::ACCEPTED, d.client.handler.outcome
  end

  def test_idle

    d = DriverPair.new(RecordingHandler.new, RecordingHandler.new)
    ms = 444
    secs = Rational(ms, 1000)   # Use rationals to keep it accurate
    opts = {:idle_timeout => secs}
    d.client.transport.apply(opts)
    assert_equal(ms, d.client.transport.idle_timeout) # Transport converts to ms
    d.server.transport.set_server
    d.client.connection.open(opts)

    start = Time.at(1)          # Dummy timeline
    tick = d.run start          # Process all IO events
    assert_equal(secs/4, tick - start)
    assert_equal [:on_connection_init, :on_connection_local_open, :on_connection_bound], d.client.handler.calls
    assert_equal [:on_connection_init, :on_connection_bound, :on_connection_remote_open, :on_transport], d.server.handler.calls
    assert_equal (ms), d.client.transport.idle_timeout
    assert_equal (ms/2), d.server.transport.remote_idle_timeout # proton changes the value
    assert_equal (secs/2), d.server.connection.idle_timeout

    # Now update the time till we get connections closing
    d.each { |x| x.handler.calls.clear }
    d.run(start + secs - 0.001) # Should nothing, timeout not reached
    assert_equal [[],[]], d.collect { |x| x.handler.calls }
    d.run(start + secs*2)   # After 2x timeout, connections should close
    assert_equal [[:on_transport_error, :on_transport_tail_closed, :on_transport_head_closed, :on_transport_closed], [:on_connection_remote_close, :on_transport_tail_closed, :on_transport_head_closed, :on_transport_closed]], d.collect { |x| x.handler.calls }
  end

  # Test each_session/each_link methods both with a block and returning Enumerator
  def test_enumerators
    connection = Connection.new()
    (3.times.collect { connection.open_session }).each { |s|
      s.open_sender; s.open_receiver
    }

    assert_equal 3, connection.each_session.to_a.size
    assert_equal 6, connection.each_link.to_a.size

    # Build Session => Set<Links> map using connection link enumerator
    map1 = {}
    connection.each_link { |l| map1[l.session] ||= Set.new; map1[l.session] << l }
    assert_equal 3, map1.size
    map1.each do |session,links|
      assert_equal 2, links.size
      links.each { |l| assert_equal session, l.session }
    end

    # Build Session => Set<Links> map using connection and session blocks
    map2 = {}
    connection.each_session do |session|
      map2[session] = Set.new
      session.each_link { |l| map2[session] << l }
    end
    assert_equal map1, map2

    # Build Session => Set<Links> map using connection session and session enumerators
    map3 = Hash[connection.each_session.collect { |s| [s, Set.new(s.each_link)] }]
    assert_equal map1, map3

    assert_equal [true, true, true], connection.each_sender.collect { |l| l.is_a? Sender }
    assert_equal [true, true, true], connection.each_receiver.collect { |l| l.is_a? Receiver }
    connection.each_session { |session|
      assert_equal [true], session.each_sender.collect { |l| l.is_a? Sender }
      assert_equal [true], session.each_receiver.collect { |l| l.is_a? Receiver }
    }


  end
end