Skip to content

Commit a2a30ce

Browse files
author
Matthew Sackman
committed
Merging bug 22821 onto default
2 parents 3ac74f7 + 65f62c7 commit a2a30ce

File tree

5 files changed

+399
-1
lines changed

5 files changed

+399
-1
lines changed

test/src/com/rabbitmq/client/test/functional/FunctionalTests.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,13 @@ public static TestSuite suite() {
4747
suite.addTestSuite(PersistentTransactions.class);
4848
suite.addTestSuite(RequeueOnConnectionClose.class);
4949
suite.addTestSuite(RequeueOnChannelClose.class);
50+
suite.addTestSuite(DurableOnTransient.class);
5051
suite.addTestSuite(NoRequeueOnCancel.class);
5152
suite.addTestSuite(Bug20004Test.class);
5253
suite.addTestSuite(QosTests.class);
5354
suite.addTestSuite(AlternateExchange.class);
55+
suite.addTestSuite(QueueLifecycle.class);
56+
suite.addTestSuite(QueueExclusivity.class);
5457
return suite;
5558
}
5659
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
// The contents of this file are subject to the Mozilla Public License
2+
// Version 1.1 (the "License"); you may not use this file except in
3+
// compliance with the License. You may obtain a copy of the License at
4+
// http://www.mozilla.org/MPL/
5+
//
6+
// Software distributed under the License is distributed on an "AS IS"
7+
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
8+
// License for the specific language governing rights and limitations
9+
// under the License.
10+
//
11+
// The Original Code is RabbitMQ.
12+
//
13+
// The Initial Developers of the Original Code are LShift Ltd,
14+
// Cohesive Financial Technologies LLC, and Rabbit Technologies Ltd.
15+
//
16+
// Portions created before 22-Nov-2008 00:00:00 GMT by LShift Ltd,
17+
// Cohesive Financial Technologies LLC, or Rabbit Technologies Ltd
18+
// are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial
19+
// Technologies LLC, and Rabbit Technologies Ltd.
20+
//
21+
// Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift
22+
// Ltd. Portions created by Cohesive Financial Technologies LLC are
23+
// Copyright (C) 2007-2010 Cohesive Financial Technologies
24+
// LLC. Portions created by Rabbit Technologies Ltd are Copyright
25+
// (C) 2007-2010 Rabbit Technologies Ltd.
26+
//
27+
// All Rights Reserved.
28+
//
29+
// Contributor(s): ______________________________________.
30+
//
31+
32+
package com.rabbitmq.client.test.functional;
33+
34+
import java.io.IOException;
35+
import java.util.HashMap;
36+
37+
import com.rabbitmq.client.Channel;
38+
import com.rabbitmq.client.Connection;
39+
import com.rabbitmq.client.QueueingConsumer;
40+
import com.rabbitmq.client.test.BrokerTestCase;
41+
42+
// Test queue auto-delete and exclusive semantics.
43+
public class QueueExclusivity extends BrokerTestCase {
44+
45+
HashMap<String, Object> noArgs = new HashMap<String, Object>();
46+
47+
public Connection altConnection;
48+
public Channel altChannel;
49+
String q = "exclusiveQ";
50+
51+
protected void createResources() throws IOException {
52+
altConnection = connectionFactory.newConnection();
53+
altChannel = altConnection.createChannel();
54+
altChannel.queueDeclare(q,
55+
// not durable, exclusive, not auto-delete
56+
false, true, false, noArgs);
57+
}
58+
59+
protected void releaseResources() throws IOException {
60+
if (altConnection != null && altConnection.isOpen()) {
61+
altConnection.close();
62+
}
63+
}
64+
65+
public void testQueueExclusiveForPassiveDeclare() throws Exception {
66+
try {
67+
channel.queueDeclarePassive(q);
68+
} catch (IOException ioe) {
69+
return;
70+
}
71+
fail("Passive queue declaration of an exclusive queue from another connection should fail");
72+
}
73+
74+
// This is a different scenario because active declare takes notice of
75+
// the all the arguments
76+
public void testQueueExclusiveForDeclare() throws Exception {
77+
try {
78+
channel.queueDeclare(q, false, true, false, noArgs);
79+
} catch (IOException ioe) {
80+
return;
81+
}
82+
fail("Active queue declaration of an exclusive queue from another connection should fail");
83+
}
84+
85+
public void testQueueExclusiveForConsume() throws Exception {
86+
QueueingConsumer c = new QueueingConsumer(channel);
87+
try {
88+
channel.basicConsume(q, c);
89+
} catch (IOException ioe) {
90+
return;
91+
}
92+
fail("Exclusive queue should be locked for basic consume from another connection");
93+
}
94+
95+
public void testQueueExclusiveForPurge() throws Exception {
96+
try {
97+
channel.queuePurge(q);
98+
} catch (IOException ioe) {
99+
return;
100+
}
101+
fail("Exclusive queue should be locked for queue purge from another connection");
102+
}
103+
104+
public void testQueueExclusiveForDelete() throws Exception {
105+
try {
106+
channel.queueDelete(q);
107+
} catch (IOException ioe) {
108+
return;
109+
}
110+
fail("Exclusive queue should be locked for queue delete from another connection");
111+
}
112+
113+
public void testQueueExclusiveForBind() throws Exception {
114+
try {
115+
channel.queueBind(q, "", ""); // NB uses default exchange
116+
} catch (IOException ioe) {
117+
return;
118+
}
119+
fail("Exclusive queue should be locked for queue bind from another connection");
120+
}
121+
122+
// NB The spec XML doesn't mention queue.unbind, basic.cancel, or
123+
// basic.get in the exclusive rule. It seems the most sensible
124+
// interpretation to include queue.unbind and basic.get in the
125+
// prohibition.
126+
// basic.cancel is inherently local to a channel, so it
127+
// *doesn't* make sense to include it.
128+
129+
public void testQueueExclusiveForUnbind() throws Exception {
130+
altChannel.queueBind(q, "", ""); // NB uses default exchange
131+
try {
132+
channel.queueUnbind(q, "", "");
133+
} catch (IOException ioe) {
134+
return;
135+
}
136+
fail("Exclusive queue should be locked for queue unbind from another connection");
137+
}
138+
139+
public void testQueueExclusiveForGet() throws Exception {
140+
try {
141+
channel.basicGet(q, true);
142+
} catch (IOException ioe) {
143+
return;
144+
}
145+
fail("Exclusive queue should be locked for basic get from another connection");
146+
}
147+
148+
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
// The contents of this file are subject to the Mozilla Public License
2+
// Version 1.1 (the "License"); you may not use this file except in
3+
// compliance with the License. You may obtain a copy of the License at
4+
// http://www.mozilla.org/MPL/
5+
//
6+
// Software distributed under the License is distributed on an "AS IS"
7+
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
8+
// License for the specific language governing rights and limitations
9+
// under the License.
10+
//
11+
// The Original Code is RabbitMQ.
12+
//
13+
// The Initial Developers of the Original Code are LShift Ltd,
14+
// Cohesive Financial Technologies LLC, and Rabbit Technologies Ltd.
15+
//
16+
// Portions created before 22-Nov-2008 00:00:00 GMT by LShift Ltd,
17+
// Cohesive Financial Technologies LLC, or Rabbit Technologies Ltd
18+
// are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial
19+
// Technologies LLC, and Rabbit Technologies Ltd.
20+
//
21+
// Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift
22+
// Ltd. Portions created by Cohesive Financial Technologies LLC are
23+
// Copyright (C) 2007-2010 Cohesive Financial Technologies
24+
// LLC. Portions created by Rabbit Technologies Ltd are Copyright
25+
// (C) 2007-2010 Rabbit Technologies Ltd.
26+
//
27+
// All Rights Reserved.
28+
//
29+
// Contributor(s): ______________________________________.
30+
//
31+
32+
package com.rabbitmq.client.test.functional;
33+
34+
import java.io.IOException;
35+
import java.util.HashMap;
36+
import java.util.Map;
37+
38+
import com.rabbitmq.client.QueueingConsumer;
39+
import com.rabbitmq.client.test.BrokerTestCase;
40+
41+
// Test queue auto-delete and exclusive semantics.
42+
public class QueueLifecycle extends BrokerTestCase {
43+
44+
void verifyQueueExists(String name) throws IOException {
45+
channel.queueDeclarePassive(name);
46+
}
47+
48+
void verifyQueueMissing(String name) throws IOException {
49+
// we can't in general check with a passive declare, since that
50+
// may return an IOException because of exclusivity. But we can
51+
// check that we can happily declare another with the same name:
52+
// the only circumstance in which this won't result in an error is
53+
// if it doesn't exist.
54+
try {
55+
channel.queueDeclare(name, false, false, false, null);
56+
} catch (IOException ioe) {
57+
fail("Queue.Declare threw an exception, probably meaning that the queue already exists");
58+
}
59+
// clean up
60+
channel.queueDelete(name);
61+
}
62+
63+
/**
64+
* Verify that a queue both exists and has the properties as given
65+
*
66+
* @throws IOException
67+
* if one of these conditions is not true
68+
*/
69+
void verifyQueue(String name, boolean durable, boolean exclusive,
70+
boolean autoDelete, Map<String, Object> args) throws IOException {
71+
verifyQueueExists(name);
72+
// use passive/equivalent rule to check that it has the same properties
73+
channel.queueDeclare(name, durable, exclusive, autoDelete, args);
74+
}
75+
76+
// NB the exception will close the connection
77+
void verifyNotEquivalent(boolean durable, boolean exclusive,
78+
boolean autoDelete) throws IOException {
79+
String q = "queue";
80+
channel.queueDeclare(q, false, false, false, null);
81+
try {
82+
verifyQueue(q, durable, exclusive, autoDelete, null);
83+
} catch (IOException ioe) {
84+
return;
85+
}
86+
fail("Queue.declare should have been rejected as not equivalent");
87+
}
88+
89+
// From amqp-0-9-1.xml, for "passive" property, "equivalent" rule:
90+
// "If not set and the queue exists, the server MUST check that the
91+
// existing queue has the same values for durable, exclusive,
92+
// auto-delete, and arguments fields. The server MUST respond with
93+
// Declare-Ok if the requested queue matches these fields, and MUST
94+
// raise a channel exception if not."
95+
public void testQueueEquivalence() throws IOException {
96+
String q = "queue";
97+
channel.queueDeclare(q, false, false, false, null);
98+
// equivalent
99+
verifyQueue(q, false, false, false, null);
100+
101+
// the spec says that the arguments table is matched on
102+
// being semantically equivalent.
103+
HashMap<String, Object> args = new HashMap<String, Object>();
104+
args.put("assumed-to-be-semantically-void", "bar");
105+
verifyQueue(q, false, false, false, args);
106+
107+
}
108+
109+
// not equivalent in various ways
110+
// We don't enforce this for 0-8
111+
// public void testQueueNonEquivalenceDurable() throws IOException {
112+
// verifyNotEquivalent(true, false, false);
113+
// }
114+
115+
public void testQueueNonEquivalenceExclusive() throws IOException {
116+
verifyNotEquivalent(false, true, false);
117+
}
118+
119+
// We don't enforce this for 0-8
120+
// public void testQueueNonEquivalenceAutoDelete() throws IOException {
121+
// verifyNotEquivalent(false, false, true);
122+
// }
123+
124+
// Note that this assumes that auto-deletion is synchronous with
125+
// basic.cancel,
126+
// which is not actually in the spec. (If it isn't, there's a race here).
127+
public void testQueueAutoDelete() throws IOException {
128+
String name = "tempqueue";
129+
channel.queueDeclare(name, false, false, true, null);
130+
// now it's there
131+
verifyQueue(name, false, false, true, null);
132+
QueueingConsumer consumer = new QueueingConsumer(channel);
133+
channel.basicConsume(name, consumer);
134+
channel.basicCancel(consumer.getConsumerTag());
135+
// now it's not .. we hope
136+
try {
137+
verifyQueueExists(name);
138+
} catch (IOException ioe) {
139+
return;
140+
}
141+
fail("Queue should have been auto-deleted after we removed its only consumer");
142+
}
143+
144+
public void testExclusiveNotAutoDelete() throws IOException {
145+
String name = "exclusivequeue";
146+
channel.queueDeclare(name, false, true, false, null);
147+
// now it's there
148+
verifyQueue(name, false, true, false, null);
149+
QueueingConsumer consumer = new QueueingConsumer(channel);
150+
channel.basicConsume(name, consumer);
151+
channel.basicCancel(consumer.getConsumerTag());
152+
// and still there, because exclusive no longer implies autodelete
153+
verifyQueueExists(name);
154+
}
155+
156+
public void testExclusiveGoesWithConnection() throws IOException {
157+
String name = "exclusivequeue2";
158+
channel.queueDeclare(name, false, true, false, null);
159+
// now it's there
160+
verifyQueue(name, false, true, false, null);
161+
closeConnection();
162+
openConnection();
163+
openChannel();
164+
verifyQueueMissing(name);
165+
}
166+
167+
}

0 commit comments

Comments
 (0)