xmpp4r 0.4 → 0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +8 -0
- data/README.rdoc +4 -1
- data/Rakefile +10 -20
- data/data/doc/xmpp4r/examples/advanced/versionpoll.rb +20 -1
- data/lib/xmpp4r/bytestreams/helper/ibb/target.rb +7 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb +7 -1
- data/lib/xmpp4r/callbacks.rb +9 -0
- data/lib/xmpp4r/caps/c.rb +14 -0
- data/lib/xmpp4r/caps/helper/helper.rb +1 -4
- data/lib/xmpp4r/client.rb +42 -15
- data/lib/xmpp4r/connection.rb +7 -3
- data/lib/xmpp4r/debuglog.rb +22 -1
- data/lib/xmpp4r/discovery.rb +1 -0
- data/lib/xmpp4r/discovery/helper/helper.rb +58 -0
- data/lib/xmpp4r/discovery/iq/discoinfo.rb +2 -2
- data/lib/xmpp4r/discovery/iq/discoitems.rb +2 -2
- data/lib/xmpp4r/errors.rb +5 -2
- data/lib/xmpp4r/httpbinding/client.rb +9 -19
- data/lib/xmpp4r/last.rb +2 -0
- data/lib/xmpp4r/last/helper/helper.rb +37 -0
- data/lib/xmpp4r/last/iq/last.rb +67 -0
- data/lib/xmpp4r/location.rb +2 -0
- data/lib/xmpp4r/location/helper/helper.rb +56 -0
- data/lib/xmpp4r/location/location.rb +179 -0
- data/lib/xmpp4r/message.rb +32 -0
- data/lib/xmpp4r/presence.rb +1 -1
- data/lib/xmpp4r/pubsub/children/configuration.rb +1 -1
- data/lib/xmpp4r/pubsub/children/items.rb +11 -2
- data/lib/xmpp4r/pubsub/children/publish.rb +14 -0
- data/lib/xmpp4r/pubsub/children/retract.rb +41 -0
- data/lib/xmpp4r/pubsub/helper/nodebrowser.rb +2 -3
- data/lib/xmpp4r/pubsub/helper/nodehelper.rb +4 -4
- data/lib/xmpp4r/pubsub/helper/oauth_service_helper.rb +90 -0
- data/lib/xmpp4r/pubsub/helper/servicehelper.rb +58 -19
- data/lib/xmpp4r/reliable.rb +168 -0
- data/lib/xmpp4r/rexmladdons.rb +6 -0
- data/lib/xmpp4r/roster/helper/roster.rb +5 -2
- data/lib/xmpp4r/sasl.rb +19 -8
- data/lib/xmpp4r/stream.rb +133 -31
- data/lib/xmpp4r/streamparser.rb +9 -1
- data/lib/xmpp4r/test/listener_mocker.rb +118 -0
- data/lib/xmpp4r/xmpp4r.rb +3 -1
- data/test/bytestreams/tc_ibb.rb +6 -4
- data/test/bytestreams/tc_socks5bytestreams.rb +3 -2
- data/test/caps/tc_helper.rb +4 -2
- data/test/dataforms/tc_data.rb +1 -1
- data/test/last/tc_helper.rb +75 -0
- data/test/lib/clienttester.rb +43 -14
- data/test/muc/tc_muc_mucclient.rb +6 -2
- data/test/pubsub/tc_helper.rb +131 -8
- data/test/pubsub/tc_nodeconfig.rb +7 -0
- data/test/reliable/tc_disconnect_cleanup.rb +334 -0
- data/test/reliable/tc_disconnect_exception.rb +37 -0
- data/test/reliable/tc_listener_mocked_test.rb +68 -0
- data/test/reliable/tc_reliable_connection.rb +31 -0
- data/test/roster/tc_helper.rb +21 -11
- data/test/rpc/tc_helper.rb +2 -2
- data/test/tc_callbacks.rb +3 -3
- data/test/tc_message.rb +15 -0
- data/test/tc_stream.rb +59 -121
- data/test/tc_streamError.rb +2 -4
- data/test/tc_streamparser.rb +26 -13
- data/test/ts_xmpp4r.rb +0 -9
- data/test/tune/tc_helper_recv.rb +0 -2
- data/test/vcard/tc_helper.rb +1 -1
- data/xmpp4r.gemspec +31 -84
- metadata +116 -167
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb.orig +0 -62
data/test/pubsub/tc_helper.rb
CHANGED
@@ -107,7 +107,7 @@ class PubSub::ServiceHelperTest < Test::Unit::TestCase
|
|
107
107
|
<subscription node='#{iq.pubsub.children.first.attributes['node']}' jid='#{iq.from.strip}'
|
108
108
|
subid='ba49252aaa4f5d320c24d3766f0bdcade78c78d3'
|
109
109
|
subscription='pending'/>
|
110
|
-
|
110
|
+
|
111
111
|
</pubsub>
|
112
112
|
</iq>")
|
113
113
|
}
|
@@ -336,7 +336,7 @@ class PubSub::ServiceHelperTest < Test::Unit::TestCase
|
|
336
336
|
assert_equal(1, iq.pubsub.children[0].children.size)
|
337
337
|
assert_equal('item', iq.pubsub.children[0].children[0].name)
|
338
338
|
assert_equal(1, iq.pubsub.children[0].children[0].children.size)
|
339
|
-
assert_equal(item1.children.to_s, iq.pubsub.children[0].children[0].children[0].to_s)
|
339
|
+
assert_equal(item1.children[0].to_s, iq.pubsub.children[0].children[0].children[0].to_s)
|
340
340
|
send("<iq type='result' to='#{iq.from}' from='#{iq.to}' id='#{iq.id}'/>")
|
341
341
|
}
|
342
342
|
assert_nothing_raised { h.publish_item_to(node, item1) }
|
@@ -362,7 +362,7 @@ class PubSub::ServiceHelperTest < Test::Unit::TestCase
|
|
362
362
|
assert_equal('item', iq.pubsub.children[0].children[0].name)
|
363
363
|
assert_equal('blubb', iq.pubsub.children[0].children[0].attributes['id'] )
|
364
364
|
assert_equal(1, iq.pubsub.children[0].children[0].children.size)
|
365
|
-
assert_equal(item1.children.to_s, iq.pubsub.children[0].children[0].children[0].to_s)
|
365
|
+
assert_equal(item1.children[0].to_s, iq.pubsub.children[0].children[0].children[0].to_s)
|
366
366
|
send("<iq type='result' to='#{iq.from}' from='#{iq.to}' id='#{iq.id}'/>")
|
367
367
|
}
|
368
368
|
assert_nothing_raised { h.publish_item_with_id_to('mynode', item1,"blubb") }
|
@@ -379,7 +379,7 @@ class PubSub::ServiceHelperTest < Test::Unit::TestCase
|
|
379
379
|
|
380
380
|
assert_raise RuntimeError do h.publish_item_with_id_to('mynode', item1,"blubb") end
|
381
381
|
end
|
382
|
-
|
382
|
+
|
383
383
|
##
|
384
384
|
# publish item and trap server-side error
|
385
385
|
# examples 88 from
|
@@ -401,7 +401,7 @@ class PubSub::ServiceHelperTest < Test::Unit::TestCase
|
|
401
401
|
assert_equal('item', iq.pubsub.children[0].children[0].name)
|
402
402
|
assert_equal('blubb', iq.pubsub.children[0].children[0].attributes['id'] )
|
403
403
|
assert_equal(1, iq.pubsub.children[0].children[0].children.size)
|
404
|
-
assert_equal(item1.children.to_s, iq.pubsub.children[0].children[0].children[0].to_s)
|
404
|
+
assert_equal(item1.children[0].to_s, iq.pubsub.children[0].children[0].children[0].to_s)
|
405
405
|
send("<iq type='error' to='#{iq.from}' from='#{iq.to}' id='#{iq.id}'/>
|
406
406
|
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
407
407
|
<publish node='#{iq.pubsub.children[0].attributes['node']}'>
|
@@ -419,7 +419,7 @@ class PubSub::ServiceHelperTest < Test::Unit::TestCase
|
|
419
419
|
##
|
420
420
|
# retrieve all items
|
421
421
|
# examples 70 and 71 from
|
422
|
-
# http://www.xmpp.org/extensions/xep-0060.html#subscriber-retrieve-returnall
|
422
|
+
# http://www.xmpp.org/extensions/xep-0060.html#subscriber-retrieve-returnall
|
423
423
|
def test_items
|
424
424
|
item1 = Jabber::PubSub::Item.new("1")
|
425
425
|
item1.text = 'foobar'
|
@@ -427,7 +427,7 @@ class PubSub::ServiceHelperTest < Test::Unit::TestCase
|
|
427
427
|
item2.text = 'barfoo'
|
428
428
|
|
429
429
|
h = PubSub::ServiceHelper.new(@client,'pubsub.example.org')
|
430
|
-
|
430
|
+
|
431
431
|
state { |iq|
|
432
432
|
assert_kind_of(Jabber::Iq, iq)
|
433
433
|
assert_equal(:get, iq.type)
|
@@ -453,6 +453,30 @@ class PubSub::ServiceHelperTest < Test::Unit::TestCase
|
|
453
453
|
wait_state
|
454
454
|
end
|
455
455
|
|
456
|
+
##
|
457
|
+
# retrieve some items
|
458
|
+
# example 76 from
|
459
|
+
# http://xmpp.org/extensions/xep-0060.html#subscriber-retrieve-requestsome
|
460
|
+
def test_items_with_max_items
|
461
|
+
node_name = "mynode"
|
462
|
+
max_items = 2
|
463
|
+
h = PubSub::ServiceHelper.new(@client,'pubsub.example.org')
|
464
|
+
|
465
|
+
state { |iq|
|
466
|
+
assert_kind_of(Jabber::Iq, iq)
|
467
|
+
assert_equal(:get, iq.type)
|
468
|
+
assert_equal(1, iq.pubsub.children.size)
|
469
|
+
assert_equal('items', iq.pubsub.children.first.name)
|
470
|
+
assert_equal(node_name, iq.pubsub.children.first.attributes['node'])
|
471
|
+
assert_equal(max_items.to_s, iq.pubsub.children.first.attributes['max_items'])
|
472
|
+
# response doesn't matter; was previously tested, so send a simple result
|
473
|
+
send("<iq type='result' to='#{iq.from}' from='#{iq.to}' id='#{iq.id}' />")
|
474
|
+
}
|
475
|
+
|
476
|
+
h.get_items_from(node_name, max_items)
|
477
|
+
wait_state
|
478
|
+
end
|
479
|
+
|
456
480
|
##
|
457
481
|
# get affiliation
|
458
482
|
# example 184 and 185 from
|
@@ -487,6 +511,25 @@ class PubSub::ServiceHelperTest < Test::Unit::TestCase
|
|
487
511
|
wait_state
|
488
512
|
end
|
489
513
|
|
514
|
+
# http://xmpp.org/extensions/xep-0060.html#owner-affiliations-modify
|
515
|
+
def test_set_affiliations
|
516
|
+
h = PubSub::ServiceHelper.new(@client,'pubsub.shakespeare.lit')
|
517
|
+
|
518
|
+
state { |iq|
|
519
|
+
assert_kind_of(Jabber::Iq, iq)
|
520
|
+
assert_equal(:set, iq.type)
|
521
|
+
assert_equal(1, iq.pubsub.children.size)
|
522
|
+
assert_equal('affiliations', iq.pubsub.children[0].name)
|
523
|
+
assert_equal('affiliation', iq.pubsub.children[0].children[0].name)
|
524
|
+
assert_equal('bard@shakespeare.lit', iq.pubsub.children[0].children[0].attributes['jid'])
|
525
|
+
assert_equal('publisher', iq.pubsub.children[0].children[0].attributes['affiliation'])
|
526
|
+
send("<iq type='result' to='#{iq.from}' from='#{iq.to}' id='#{iq.id}'/>")
|
527
|
+
}
|
528
|
+
|
529
|
+
a = h.set_affiliations('princely_musings', 'bard@shakespeare.lit', :publisher)
|
530
|
+
wait_state
|
531
|
+
end
|
532
|
+
|
490
533
|
##
|
491
534
|
# get_subscriptions_from
|
492
535
|
# example 171 and 172 from
|
@@ -596,7 +639,7 @@ class PubSub::ServiceHelperTest < Test::Unit::TestCase
|
|
596
639
|
end
|
597
640
|
|
598
641
|
##
|
599
|
-
# get all subscriptions with no subscriptions
|
642
|
+
# get all subscriptions with no subscriptions
|
600
643
|
def test_get_all_subscriptions_with_no_subscriptions
|
601
644
|
h = PubSub::ServiceHelper.new(@client,'pubsub.example.org')
|
602
645
|
|
@@ -655,6 +698,86 @@ class PubSub::ServiceHelperTest < Test::Unit::TestCase
|
|
655
698
|
wait_state
|
656
699
|
end
|
657
700
|
|
701
|
+
##
|
702
|
+
# owner set configuration for a node
|
703
|
+
# example 133
|
704
|
+
# http://xmpp.org/extensions/xep-0060.html#owner-configure
|
705
|
+
def test_set_node_config
|
706
|
+
node = 'princely_musings'
|
707
|
+
pubsub = 'pubsub.shakespeare.lit'
|
708
|
+
h = PubSub::ServiceHelper.new(@client,pubsub)
|
709
|
+
|
710
|
+
state { |iq|
|
711
|
+
assert_kind_of(Jabber::Iq,iq)
|
712
|
+
assert_equal(:set, iq.type)
|
713
|
+
assert_equal(pubsub, iq.to.to_s)
|
714
|
+
|
715
|
+
config = iq.pubsub.first_element('configure')
|
716
|
+
assert_kind_of(Jabber::PubSub::OwnerNodeConfig, config)
|
717
|
+
assert_kind_of(Jabber::Dataforms::XData, config.form)
|
718
|
+
|
719
|
+
assert_equal(config.options["pubsub#title"], "Princely Musings (Atom)")
|
720
|
+
assert_equal(config.options["pubsub#deliver_notifications"], "1")
|
721
|
+
assert_equal(config.options["pubsub#deliver_payloads"], "1")
|
722
|
+
assert_equal(config.options["pubsub#persist_items"], "1")
|
723
|
+
assert_equal(config.options["pubsub#max_items"], "10")
|
724
|
+
assert_equal(config.options["pubsub#access_model"], "open")
|
725
|
+
assert_equal(config.options["pubsub#publish_model"], "publishers")
|
726
|
+
assert_equal(config.options["pubsub#send_last_published_item"], "never")
|
727
|
+
assert_equal(config.options["pubsub#presence_based_delivery"], "false")
|
728
|
+
assert_equal(config.options["pubsub#notify_config"], "0")
|
729
|
+
assert_equal(config.options["pubsub#notify_delete"], "0")
|
730
|
+
assert_equal(config.options["pubsub#notify_retract"], "0")
|
731
|
+
assert_equal(config.options["pubsub#notify_sub"], "0")
|
732
|
+
assert_equal(config.options["pubsub#max_payload_size"], "1028")
|
733
|
+
assert_equal(config.options["pubsub#type"], "http://www.w3.org/2005/Atom")
|
734
|
+
assert_equal(config.options["pubsub#body_xslt"], "http://jabxslt.jabberstudio.org/atom_body.xslt")
|
735
|
+
|
736
|
+
send("<iq type='result' from='#{iq.to}' to='#{iq.from}' id='#{iq.id}'/>")
|
737
|
+
}
|
738
|
+
|
739
|
+
config = Jabber::PubSub::OwnerNodeConfig.new(node)
|
740
|
+
config.options = {
|
741
|
+
"pubsub#title" => "Princely Musings (Atom)",
|
742
|
+
"pubsub#deliver_notifications" => "1",
|
743
|
+
"pubsub#deliver_payloads" => "1",
|
744
|
+
"pubsub#persist_items" => "1",
|
745
|
+
"pubsub#max_items" => "10",
|
746
|
+
"pubsub#access_model" => "open",
|
747
|
+
"pubsub#publish_model" => "publishers",
|
748
|
+
"pubsub#send_last_published_item" => "never",
|
749
|
+
"pubsub#presence_based_delivery" => "false",
|
750
|
+
"pubsub#notify_config" => "0",
|
751
|
+
"pubsub#notify_delete" => "0",
|
752
|
+
"pubsub#notify_retract" => "0",
|
753
|
+
"pubsub#notify_sub" => "0",
|
754
|
+
"pubsub#max_payload_size" => "1028",
|
755
|
+
"pubsub#type" => "http://www.w3.org/2005/Atom",
|
756
|
+
"pubsub#body_xslt" => "http://jabxslt.jabberstudio.org/atom_body.xslt"
|
757
|
+
}
|
758
|
+
|
759
|
+
assert_kind_of(Jabber::PubSub::OwnerNodeConfig, config)
|
760
|
+
h.set_config_for(node, config)
|
761
|
+
wait_state
|
762
|
+
end
|
763
|
+
|
764
|
+
def test_delete_item
|
765
|
+
pubsub = 'pubsub.example.org'
|
766
|
+
h = PubSub::ServiceHelper.new(@client, pubsub)
|
767
|
+
|
768
|
+
state { |iq|
|
769
|
+
assert_kind_of(Jabber::Iq, iq)
|
770
|
+
assert_kind_of(Jabber::PubSub::IqPubSub, iq.pubsub)
|
771
|
+
assert_kind_of(Jabber::PubSub::Retract, iq.pubsub.first_element('retract'))
|
772
|
+
assert_equal(1, iq.pubsub.first_element('retract').items.size)
|
773
|
+
assert_equal('ae890ac52d0df67ed7cfdf51b644e901', iq.pubsub.first_element('retract').items[0].id)
|
774
|
+
send(iq.answer.set_type(:result))
|
775
|
+
}
|
776
|
+
|
777
|
+
h.delete_item_from('princely_musings', 'ae890ac52d0df67ed7cfdf51b644e901')
|
778
|
+
wait_state
|
779
|
+
end
|
780
|
+
|
658
781
|
def test_to_s
|
659
782
|
h = PubSub::ServiceHelper.new(@client,'pubsub.example.org')
|
660
783
|
assert_equal('pubsub.example.org',h.to_s)
|
@@ -51,4 +51,11 @@ class PubSub::NodeConfigTest < Test::Unit::TestCase
|
|
51
51
|
assert_kind_of(Jabber::Dataforms::XData, config.form)
|
52
52
|
assert_equal(options, config.options)
|
53
53
|
end
|
54
|
+
|
55
|
+
def test_create_with_array_in_options
|
56
|
+
options = {'pubsub#collection'=>['parent1','parent2']}
|
57
|
+
config = PubSub::OwnerNodeConfig.new(nil, options)
|
58
|
+
|
59
|
+
assert_equal(options, config.options)
|
60
|
+
end
|
54
61
|
end
|
@@ -0,0 +1,334 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
$:.unshift "#{File.dirname(__FILE__)}/../../lib"
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require 'xmpp4r'
|
7
|
+
|
8
|
+
# Jabber::debug = true
|
9
|
+
# Jabber::warnings = true
|
10
|
+
|
11
|
+
class ClientDisconnectCleanupTest < Test::Unit::TestCase
|
12
|
+
class ControledClient < Jabber::Client
|
13
|
+
attr_accessor :tcpserver, :socket_override
|
14
|
+
def connect
|
15
|
+
begin
|
16
|
+
@port = 1024 + rand(32768 - 1024)
|
17
|
+
@tcpserver = TCPServer.new("127.0.0.1", @port)
|
18
|
+
rescue Errno::EADDRINUSE, Errno::EACCES
|
19
|
+
@tcpserver.close rescue nil
|
20
|
+
retry
|
21
|
+
end
|
22
|
+
super("127.0.0.1", @port)
|
23
|
+
end
|
24
|
+
def start
|
25
|
+
@socket = socket_override
|
26
|
+
super
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_regular_stream_end
|
31
|
+
rd, wr = IO.pipe
|
32
|
+
rd.instance_eval do
|
33
|
+
def write(*args)
|
34
|
+
end
|
35
|
+
def flush
|
36
|
+
end
|
37
|
+
end
|
38
|
+
client = ControledClient.new("test@localhost")
|
39
|
+
@exceptions_caught = 0
|
40
|
+
client.on_exception do |e, connection, where_failed|
|
41
|
+
@exceptions_caught += 1
|
42
|
+
end
|
43
|
+
|
44
|
+
Thread.new do
|
45
|
+
client.socket_override = rd
|
46
|
+
client.instance_eval{ @keepalive_interval = 0.1 }
|
47
|
+
client.connect
|
48
|
+
client.auth_nonsasl("password", false)
|
49
|
+
end
|
50
|
+
sleep(0.1)
|
51
|
+
assert client.is_connected?
|
52
|
+
|
53
|
+
wr.write('<stream:stream xmlns:stream="http://etherx.jabber.org/streams">')
|
54
|
+
wr.write("</stream:stream>")
|
55
|
+
sleep(0.2)
|
56
|
+
|
57
|
+
assert !client.is_connected?
|
58
|
+
assert client.instance_eval{ @parser_thread.nil? || !@parser_thread.alive? }
|
59
|
+
assert client.instance_eval{ @keepaliveThread.nil? || !@keepaliveThread.alive? }
|
60
|
+
assert @exceptions_caught > 0
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_error_on_send
|
64
|
+
rd, wr = IO.pipe
|
65
|
+
rd.instance_eval do
|
66
|
+
def write(*args)
|
67
|
+
end
|
68
|
+
def flush
|
69
|
+
end
|
70
|
+
end
|
71
|
+
client = ControledClient.new("test@localhost")
|
72
|
+
@exceptions_caught = 0
|
73
|
+
client.on_exception do |e, connection, where_failed|
|
74
|
+
@exceptions_caught += 1
|
75
|
+
end
|
76
|
+
|
77
|
+
Thread.new do
|
78
|
+
client.socket_override = rd
|
79
|
+
client.connect
|
80
|
+
client.auth_nonsasl("password", false)
|
81
|
+
end
|
82
|
+
sleep(0.1)
|
83
|
+
assert client.is_connected?
|
84
|
+
|
85
|
+
rd.instance_eval do
|
86
|
+
def write(*args)
|
87
|
+
raise "No writting for you, you disconnect now"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
wr.write(%Q{<stream:stream from='localhost' id="acecf234be084aecdc16509077573c7d7200912f" version='1.0' xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client"><stream:features><auth xmlns='http://jabber.org/features/iq-auth'/></stream:features> })
|
91
|
+
sleep(0.1)
|
92
|
+
|
93
|
+
assert !client.is_connected?
|
94
|
+
assert client.instance_eval{ @parser_thread.nil? || !@parser_thread.alive? }
|
95
|
+
assert client.instance_eval{ @keepaliveThread.nil? || !@keepaliveThread.alive? }
|
96
|
+
assert @exceptions_caught > 0
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_client_disconnect
|
100
|
+
rd, wr = IO.pipe
|
101
|
+
rd.instance_eval do
|
102
|
+
def write(*args)
|
103
|
+
end
|
104
|
+
def flush
|
105
|
+
end
|
106
|
+
end
|
107
|
+
client = ControledClient.new("test@localhost")
|
108
|
+
@exceptions_caught = 0
|
109
|
+
client.on_exception do |e, connection, where_failed|
|
110
|
+
@exceptions_caught += 1
|
111
|
+
end
|
112
|
+
|
113
|
+
Thread.new do
|
114
|
+
client.socket_override = rd
|
115
|
+
client.connect
|
116
|
+
client.auth_nonsasl("password", false)
|
117
|
+
end
|
118
|
+
wr.write(%Q{<stream:stream from='localhost' id="acecf234be084aecdc16509077573c7d7200912f" version='1.0' xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client"><stream:features><auth xmlns='http://jabber.org/features/iq-auth'/></stream:features> })
|
119
|
+
sleep(0.1)
|
120
|
+
assert client.is_connected?
|
121
|
+
assert client.instance_eval{ @parser_thread.alive? }
|
122
|
+
assert client.instance_eval{ @keepaliveThread.alive? }
|
123
|
+
|
124
|
+
wr.close
|
125
|
+
sleep(0.1)
|
126
|
+
|
127
|
+
assert !client.is_connected?
|
128
|
+
assert client.instance_eval{ @parser_thread.nil? || !@parser_thread.alive? }
|
129
|
+
assert client.instance_eval{ @keepaliveThread.nil? || !@keepaliveThread.alive? }
|
130
|
+
assert @exceptions_caught > 0
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
class ConnectionDisconnectCleanupTest < Test::Unit::TestCase
|
136
|
+
class PipeConnection < Jabber::Connection
|
137
|
+
attr_accessor :socket_override
|
138
|
+
def connect
|
139
|
+
begin
|
140
|
+
@port = 1024 + rand(32768 - 1024)
|
141
|
+
tcpsocket = TCPServer.new("127.0.0.1", @port)
|
142
|
+
rescue Errno::EADDRINUSE, Errno::EACCES
|
143
|
+
tcpsocket.close rescue nil
|
144
|
+
retry
|
145
|
+
end
|
146
|
+
super("127.0.0.1", @port)
|
147
|
+
end
|
148
|
+
def accept_features
|
149
|
+
#do nothing
|
150
|
+
end
|
151
|
+
def start
|
152
|
+
@socket = self.socket_override
|
153
|
+
super
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_cleanup_when_disconnected_during_keepalive
|
158
|
+
rd, wr = IO.pipe
|
159
|
+
conn = PipeConnection.new
|
160
|
+
@exceptions_caught = 0
|
161
|
+
conn.on_exception do |e, connection, where_failed|
|
162
|
+
@exceptions_caught += 1
|
163
|
+
end
|
164
|
+
|
165
|
+
Thread.new do
|
166
|
+
conn.socket_override = rd
|
167
|
+
#this will raise exception in keepalive thread, when attempts to send blank space shortly after connect
|
168
|
+
conn.instance_eval{ @keepalive_interval = 0.1 }
|
169
|
+
conn.connect
|
170
|
+
end
|
171
|
+
|
172
|
+
sleep(0.2)
|
173
|
+
|
174
|
+
assert rd.closed?
|
175
|
+
assert !conn.is_connected?
|
176
|
+
assert !conn.instance_eval{ @parser_thread }.alive?
|
177
|
+
assert !conn.instance_eval{ @keepaliveThread }.alive?
|
178
|
+
assert @exceptions_caught > 0
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_cleanup_after_stream_close
|
182
|
+
rd, wr = IO.pipe
|
183
|
+
conn = PipeConnection.new
|
184
|
+
@exceptions_caught = 0
|
185
|
+
conn.on_exception do |e, connection, where_failed|
|
186
|
+
@exceptions_caught += 1
|
187
|
+
end
|
188
|
+
|
189
|
+
Thread.new do
|
190
|
+
conn.socket_override = rd
|
191
|
+
conn.connect
|
192
|
+
end
|
193
|
+
|
194
|
+
wr.write("<hi/>")
|
195
|
+
wr.close
|
196
|
+
sleep(0.1)
|
197
|
+
|
198
|
+
assert rd.closed?
|
199
|
+
assert !conn.is_connected?
|
200
|
+
assert !conn.instance_eval{ @parser_thread }.alive?
|
201
|
+
assert !conn.instance_eval{ @keepaliveThread }.alive?
|
202
|
+
assert @exceptions_caught > 0
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_cleanup_after_stream_end
|
206
|
+
rd, wr = IO.pipe
|
207
|
+
conn = PipeConnection.new
|
208
|
+
@exceptions_caught = 0
|
209
|
+
conn.on_exception do |e, connection, where_failed|
|
210
|
+
@exceptions_caught += 1
|
211
|
+
end
|
212
|
+
|
213
|
+
Thread.new do
|
214
|
+
conn.socket_override = rd
|
215
|
+
conn.connect
|
216
|
+
end
|
217
|
+
|
218
|
+
wr.write('<stream:stream xmlns:stream="http://etherx.jabber.org/streams">')
|
219
|
+
wr.write("</stream:stream>")
|
220
|
+
# wr.close
|
221
|
+
sleep(0.1)
|
222
|
+
|
223
|
+
assert rd.closed?
|
224
|
+
assert !conn.is_connected?
|
225
|
+
assert !conn.instance_eval{ @parser_thread }.alive?
|
226
|
+
assert !conn.instance_eval{ @keepaliveThread }.alive?
|
227
|
+
assert @exceptions_caught > 0
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|
231
|
+
|
232
|
+
class StreamDisconnectCleanupTest < Test::Unit::TestCase
|
233
|
+
|
234
|
+
def test_cleanup_when_errors_on_send
|
235
|
+
rd, wr = IO.pipe
|
236
|
+
|
237
|
+
stream = Jabber::Stream.new
|
238
|
+
@exceptions_caught = 0
|
239
|
+
stream.on_exception do |e, connection, where_failed|
|
240
|
+
@exceptions_caught += 1
|
241
|
+
end
|
242
|
+
|
243
|
+
assert !stream.is_connected?
|
244
|
+
|
245
|
+
stream.start(rd)
|
246
|
+
wr.write("<hi/>")
|
247
|
+
assert stream.is_connected?
|
248
|
+
#should raise error trying to write to stream that can't be written to, and catch should close it.
|
249
|
+
begin
|
250
|
+
stream.send("<hi/>")
|
251
|
+
rescue
|
252
|
+
end
|
253
|
+
sleep(0.1)
|
254
|
+
|
255
|
+
assert rd.closed?
|
256
|
+
assert !stream.is_connected?
|
257
|
+
assert !stream.instance_eval{ @parser_thread }.alive?
|
258
|
+
assert @exceptions_caught > 0
|
259
|
+
end
|
260
|
+
|
261
|
+
def test_cleanup_after_stream_close
|
262
|
+
rd, wr = IO.pipe
|
263
|
+
|
264
|
+
stream = Jabber::Stream.new
|
265
|
+
@exceptions_caught = 0
|
266
|
+
stream.on_exception do |e, connection, where_failed|
|
267
|
+
@exceptions_caught += 1
|
268
|
+
end
|
269
|
+
|
270
|
+
assert !stream.is_connected?
|
271
|
+
|
272
|
+
stream.start(rd)
|
273
|
+
wr.write("<hi/>")
|
274
|
+
assert stream.is_connected?
|
275
|
+
|
276
|
+
wr.close
|
277
|
+
sleep(0.1)
|
278
|
+
|
279
|
+
assert rd.closed?
|
280
|
+
assert !stream.is_connected?
|
281
|
+
assert !stream.instance_eval{ @parser_thread }.alive?
|
282
|
+
assert @exceptions_caught > 0
|
283
|
+
end
|
284
|
+
|
285
|
+
def test_cleanup_after_stream_end
|
286
|
+
rd, wr = IO.pipe
|
287
|
+
|
288
|
+
stream = Jabber::Stream.new
|
289
|
+
@exceptions_caught = 0
|
290
|
+
stream.on_exception do |e, connection, where_failed|
|
291
|
+
@exceptions_caught += 1
|
292
|
+
end
|
293
|
+
|
294
|
+
assert !stream.is_connected?
|
295
|
+
|
296
|
+
stream.start(rd)
|
297
|
+
wr.write('<stream:stream xmlns:stream="http://etherx.jabber.org/streams">')
|
298
|
+
wr.write("</stream:stream>")
|
299
|
+
assert stream.is_connected?
|
300
|
+
|
301
|
+
# wr.close
|
302
|
+
sleep(0.1)
|
303
|
+
|
304
|
+
assert rd.closed?
|
305
|
+
assert !stream.is_connected?
|
306
|
+
assert !stream.instance_eval{ @parser_thread }.alive?
|
307
|
+
assert @exceptions_caught > 0
|
308
|
+
end
|
309
|
+
|
310
|
+
def test_cleanup_after_parse_failure
|
311
|
+
rd, wr = IO.pipe
|
312
|
+
|
313
|
+
stream = Jabber::Stream.new
|
314
|
+
@exceptions_caught = 0
|
315
|
+
stream.on_exception do |e, connection, where_failed|
|
316
|
+
@exceptions_caught += 1
|
317
|
+
end
|
318
|
+
|
319
|
+
assert !stream.is_connected?
|
320
|
+
|
321
|
+
stream.start(rd)
|
322
|
+
wr.write('<this is bad xml>>')
|
323
|
+
wr.close
|
324
|
+
assert stream.is_connected?
|
325
|
+
|
326
|
+
sleep(0.1)
|
327
|
+
|
328
|
+
assert rd.closed?
|
329
|
+
assert !stream.is_connected?
|
330
|
+
assert !stream.instance_eval{ @parser_thread }.alive?
|
331
|
+
assert @exceptions_caught > 0
|
332
|
+
end
|
333
|
+
|
334
|
+
end
|