You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by Michael Ossareh <os...@gmail.com> on 2009/06/08 21:25:15 UTC
Exceptions in MINA
Hi,
Firstly I'm cross posting because there is, in my mind at least, two
discussions which can come out of this. If you feel your reply is only
pertinent to one group please remove the other from your reply!
I've uncovered what I believe to be a problem in the framework of
MINA. I'm using 2.0.0-m5. As it currently stands any classes that
subclass IoHandlerAdapter are crippled by the methods throwing
Exception and the framework catching it. In my case I cannot write
JUnit test cases because the Exception thrown by Assert.fail() is
caught up in the framework therefore not allowing me to verify
failures.
Dev's Is there a strong reason for this? Exceptions need to take place
in business logic, not just test cases, and right now they cannot.
These methods, I feel, shouldn't have Exception in their method def.
Perhaps a subclass of Exception such as BusinessException or something
which we can treat differently?
Perhaps I've missed something? Is there some part of the filter chain
that you can add an exception handler? That only unhandled exceptions
then result in bubbling to the top?
Thoughts? Depending what we come up with I'm happy to implement a fix.
Cheers,
mike
--
god loves atheists, Fact: http://www.mrwiggleslovesyou.com/comics/rehab477.jpg
Re: Exceptions in MINA
Posted by Michael Ossareh <os...@gmail.com>.
On Mon, Jun 8, 2009 at 12:25 PM, Michael Ossareh<os...@gmail.com> wrote:
> Hi,
>
> Firstly I'm cross posting because there is, in my mind at least, two
> discussions which can come out of this. If you feel your reply is only
> pertinent to one group please remove the other from your reply!
>
> I've uncovered what I believe to be a problem in the framework of
> MINA. I'm using 2.0.0-m5. As it currently stands any classes that
> subclass IoHandlerAdapter are crippled by the methods throwing
> Exception and the framework catching it. In my case I cannot write
> JUnit test cases because the Exception thrown by Assert.fail() is
> caught up in the framework therefore not allowing me to verify
> failures.
>
> Dev's Is there a strong reason for this? Exceptions need to take place
> in business logic, not just test cases, and right now they cannot.
> These methods, I feel, shouldn't have Exception in their method def.
> Perhaps a subclass of Exception such as BusinessException or something
> which we can treat differently?
>
> Perhaps I've missed something? Is there some part of the filter chain
> that you can add an exception handler? That only unhandled exceptions
> then result in bubbling to the top?
>
> Thoughts? Depending what we come up with I'm happy to implement a fix.
I've had some more time to digest my initial thoughts on this -
interested to know what you dev's think.
What is the result of an Exception being thrown at the IoHandler
level? This isn't documented; I appreciate why it is not documented.
The closest I can think of is spring's transaction management - when
you throw an exception it triggers a rollback. At this layer the
packet has already been read from the network, in my case it has
already been identified by the demux decodable method, so what benefit
is there to my exception being tracked here?
This is beyond the JUnit example I gave, this is more a 'spiritual'
thought regarding exception handling.
>
> Cheers,
>
> mike
>
>
> --
> god loves atheists, Fact: http://www.mrwiggleslovesyou.com/comics/rehab477.jpg
>
--
god loves atheists, Fact: http://www.mrwiggleslovesyou.com/comics/rehab477.jpg
Re: Exceptions in MINA
Posted by David Rosenstrauch <da...@darose.net>.
David Rosenstrauch wrote:
> A couple of suggestions:
>
> 1) I'd think you really shouldn't need to go through the whole process
> of fully starting up the server (with a socket listener listening on a
> port) and a client (opening a socket to the server) just to do testing.
> I don't know your code so well so perhaps I'm wrong here. But I'd
> think it should be sufficient to just *simulate* network communication
> by using a DummySession and sending a message down the server's filter
> chain and seeing what response - or lack thereof - gets generated.
>
> 2) If you follow along with that approach, then you won't be in the
> situation where your client is performing assertions inside the
> messageReceived method (which are obviously getting swallowed). If you
> look carefully at the code I posted, you'll see that what I'm doing is
> to add an "OutputListener" - a class that I use only to assist with
> testing - at the end of my filter chain when I test. The output
> listener, true to its name, listens to whatever output/response the
> server's filter chain processing generates, and saves it. Once that
> whole server filter chain interaction is complete, and I've "saved" the
> output from my "communication with the server", only THEN do I go about
> issuing Asserts to verify that the output was what I expected. And
> since these asserts get done outside of the MINA filter chain processing
> they never get swallowed.
Or, more succinctly:
You're trying to do "white-box" testing on your server. Do "black-box"
testing instead. Treat the server as a black box: Send it a message,
get a response, perform assertions to verify that the response is
correct. Do this all from *outside* the server and client, not inside
the client. And if you approach it this way, you don't need to involve
a client in your testing at all.
HTH,
DR
Re: Exceptions in MINA
Posted by Emmanuel Lecharny <el...@apache.org>.
Michael Ossareh wrote:
> On Tue, Jun 9, 2009 at 8:08 AM, David Rosenstrauch<da...@darose.net> wrote:
>
>> Michael Ossareh wrote:
>>
>>> Hi David,
>>>
>>> Thanks for your feedback. I noted your example and my reference to
>>> "solution to this" looks not to dissimilar from what you're doing
>>> (except I don't want to change the filter chain for fear of creating a
>>> difference between prod and dev). The same goes for dummy session. As
>>> I get more to grips with MINA I'm sure my assertions as to how to
>>> build the tests will change.
>>>
>>> Cheers,
>>>
>>> mike
>>>
>> I understand your concerns about not wanting to make a difference between
>> dev and prod. But I'd offer 2 pieces of feedback:
>>
>> 1) Just adding a listener at the end of your filter chain isn't really
>> introducing any real change in behavior in your test filter chain.
>>
>> 2) Is it really necessary to have identical conditions between dev and prod
>> for every single test? I'd argue no. You can have some tests that test for
>> correct behavior, others that test network I/O, etc.. Given that, you can
>> set up one set of tests that just do black-box testing directly against your
>> server's filter chain (as in my example), in order to verify that specific
>> inputs generate expected outputs. Then, separately, you can write
>> additional tests against the full server (and thus the prod filter chain)
>> via a socket to test the server's network I/O, performance, etc. If you
>> handle the two kinds of tests separately it makes your testing job simpler.
>>
>
> Thanks for your continuing thoughts, David.
>
> Do you have any suggestions on how to verify that encoding and decoding work?
>
> I'm taking a POJO sending it - it gets encoded into a series of bytes.
> The decoding (logically required for verifying that things encoded
> correctly) is triggered by the framework so not entirely sure how to
> harness them.
>
Pretty easy : just call your encoder on a POJO and decode the result,
checking that it's equals to the initial POJO.
Just call the Encoder and Decoder without adding them in a chain whatsoever.
You have to do one more thing : check that the decoder works well by
sending the bytes one by one, as you may receive the data in small chunks.
This is what we do for the Ldap codec :
/**
* Test the decoding of a full DelRequest
*/
@Test
public void testDecodeDelRequestSuccess()
{
Asn1Decoder ldapDecoder = new LdapDecoder();
ByteBuffer stream = ByteBuffer.allocate( 0x27 );
stream.put( new byte[]
{
0x30, 0x25, // LDAPMessage ::= SEQUENCE {
0x02, 0x01, 0x01, // messageID MessageID
// CHOICE { ..., delRequest
DelRequest, ...
// DelRequest ::= [APPLICATION
10] LDAPDN;
0x4A, 0x20,
'c', 'n', '=', 't', 'e', 's', 't', 'M', 'o', 'd', 'i',
'f', 'y', ',', 'o', 'u', '=', 'u',
's', 'e', 'r', 's', ',', 'o', 'u', '=', 's', 'y', 's',
't', 'e', 'm'
} );
String decodedPdu = StringTools.dumpBytes( stream.array() );
stream.flip();
// Allocate a LdapMessage Container
IAsn1Container ldapMessageContainer = new LdapMessageContainer();
// Decode a DelRequest PDU
try
{
ldapDecoder.decode( stream, ldapMessageContainer );
}
catch ( DecoderException de )
{
de.printStackTrace();
fail( de.getMessage() );
}
// Check the decoded DelRequest PDU
LdapMessageCodec message = ( ( LdapMessageContainer )
ldapMessageContainer ).getLdapMessage();
DelRequestCodec delRequest = message.getDelRequest();
assertEquals( 1, message.getMessageId() );
assertEquals( "cn=testModify,ou=users,ou=system",
delRequest.getEntry().toString() );
// Check the length
assertEquals( 0x27, message.computeLength() );
// Check the encoding
try
{
ByteBuffer bb = message.encode( null );
String encodedPdu = StringTools.dumpBytes( bb.array() );
assertEquals( encodedPdu, decodedPdu );
}
catch ( EncoderException ee )
{
ee.printStackTrace();
fail( ee.getMessage() );
}
}
--
--
cordialement, regards,
Emmanuel Lécharny
www.iktek.com
directory.apache.org
Re: Exceptions in MINA
Posted by Michael Ossareh <os...@gmail.com>.
On Tue, Jun 9, 2009 at 8:08 AM, David Rosenstrauch<da...@darose.net> wrote:
> Michael Ossareh wrote:
>>
>> Hi David,
>>
>> Thanks for your feedback. I noted your example and my reference to
>> "solution to this" looks not to dissimilar from what you're doing
>> (except I don't want to change the filter chain for fear of creating a
>> difference between prod and dev). The same goes for dummy session. As
>> I get more to grips with MINA I'm sure my assertions as to how to
>> build the tests will change.
>>
>> Cheers,
>>
>> mike
>
> I understand your concerns about not wanting to make a difference between
> dev and prod. But I'd offer 2 pieces of feedback:
>
> 1) Just adding a listener at the end of your filter chain isn't really
> introducing any real change in behavior in your test filter chain.
>
> 2) Is it really necessary to have identical conditions between dev and prod
> for every single test? I'd argue no. You can have some tests that test for
> correct behavior, others that test network I/O, etc.. Given that, you can
> set up one set of tests that just do black-box testing directly against your
> server's filter chain (as in my example), in order to verify that specific
> inputs generate expected outputs. Then, separately, you can write
> additional tests against the full server (and thus the prod filter chain)
> via a socket to test the server's network I/O, performance, etc. If you
> handle the two kinds of tests separately it makes your testing job simpler.
Thanks for your continuing thoughts, David.
Do you have any suggestions on how to verify that encoding and decoding work?
I'm taking a POJO sending it - it gets encoded into a series of bytes.
The decoding (logically required for verifying that things encoded
correctly) is triggered by the framework so not entirely sure how to
harness them.
FWIW I'm using the demuxing stuff for all the various packet types that I have.
>
> HTH,
>
> DR
>
--
god loves atheists, Fact: http://www.mrwiggleslovesyou.com/comics/rehab477.jpg
RE: Exceptions in MINA
Posted by Yongxing Wang <yw...@sharpcast.com>.
I would second David's second point. If you are writing your Unit Test,
then focus on what Unit Test should do. Starting a full server is a good
way to unit test your code? I'd say no. If you do that, you will make
your maven build process to have another dependency. If your test server
dies, you won't be able to build (unless you skip test, which just beats
the whole purpose).
Starting a full sever and going through something like prod env belongs
to PSR type of domain. Don't get me wrong, it is critical. But you
should separate them out.
Thanks,
Yong
-----Original Message-----
From: David Rosenstrauch [mailto:darose@darose.net]
Sent: Tuesday, June 09, 2009 8:08 AM
To: users@mina.apache.org
Subject: Re: Exceptions in MINA
Michael Ossareh wrote:
> Hi David,
>
> Thanks for your feedback. I noted your example and my reference to
> "solution to this" looks not to dissimilar from what you're doing
> (except I don't want to change the filter chain for fear of creating a
> difference between prod and dev). The same goes for dummy session. As
> I get more to grips with MINA I'm sure my assertions as to how to
> build the tests will change.
>
> Cheers,
>
> mike
I understand your concerns about not wanting to make a difference
between dev and prod. But I'd offer 2 pieces of feedback:
1) Just adding a listener at the end of your filter chain isn't really
introducing any real change in behavior in your test filter chain.
2) Is it really necessary to have identical conditions between dev and
prod for every single test? I'd argue no. You can have some tests that
test for correct behavior, others that test network I/O, etc.. Given
that, you can set up one set of tests that just do black-box testing
directly against your server's filter chain (as in my example), in order
to verify that specific inputs generate expected outputs. Then,
separately, you can write additional tests against the full server (and
thus the prod filter chain) via a socket to test the server's network
I/O, performance, etc. If you handle the two kinds of tests separately
it makes your testing job simpler.
HTH,
DR
Re: Exceptions in MINA
Posted by David Rosenstrauch <da...@darose.net>.
Michael Ossareh wrote:
> Hi David,
>
> Thanks for your feedback. I noted your example and my reference to
> "solution to this" looks not to dissimilar from what you're doing
> (except I don't want to change the filter chain for fear of creating a
> difference between prod and dev). The same goes for dummy session. As
> I get more to grips with MINA I'm sure my assertions as to how to
> build the tests will change.
>
> Cheers,
>
> mike
I understand your concerns about not wanting to make a difference
between dev and prod. But I'd offer 2 pieces of feedback:
1) Just adding a listener at the end of your filter chain isn't really
introducing any real change in behavior in your test filter chain.
2) Is it really necessary to have identical conditions between dev and
prod for every single test? I'd argue no. You can have some tests that
test for correct behavior, others that test network I/O, etc.. Given
that, you can set up one set of tests that just do black-box testing
directly against your server's filter chain (as in my example), in order
to verify that specific inputs generate expected outputs. Then,
separately, you can write additional tests against the full server (and
thus the prod filter chain) via a socket to test the server's network
I/O, performance, etc. If you handle the two kinds of tests separately
it makes your testing job simpler.
HTH,
DR
Re: Exceptions in MINA
Posted by Emmanuel Lecharny <el...@apache.org>.
Michael Ossareh wrote:
> On Mon, Jun 8, 2009 at 3:10 PM, Emmanuel Lecharny<el...@apache.org> wrote:
>
>> Michael Ossareh wrote:
>>
>>> On Mon, Jun 8, 2009 at 2:13 PM, David Rosenstrauch<da...@darose.net>
>>> wrote:
>>>
>>>
>>>> Michael Ossareh wrote:
>>>>
>>>>
>>>>> In the case above the code in messageReceived() cannot trigger
>>>>> assertion failures, the exception they throw is trapped by the
>>>>> framework and JUnit thinks the test passed. I'm using Assert.fail()
>>>>> because the test I'm doing isn't part of JUnit's base tests (though I
>>>>> understand I should start checking out the hamcrest matchers for my
>>>>> tests:
>>>>>
>>>>> http://stackoverflow.com/questions/958460/creating-a-assertclass-method-in-junit
>>>>> ) however using "normal" assertion fails suffer the same issue, for
>>>>> example assertEquals(1, 2) results in the test passing beacause junit
>>>>> doesn't ever see the exception.
>>>>>
>>>>> Clearly you'll see the power of this type of testing, the 20 or tests
>>>>> I have to write are all structured the same. Connect client to server,
>>>>> either client or server send data, ensure data is rendered same on the
>>>>> receiving side.
>>>>>
>>>>> I'm midway through building a solution to this, however some of it
>>>>> really reinventing the wheel and all because
>>>>> IoHandlerAdapter.messageReceived / sessionOpened / sessionCreated all
>>>>> throw Exception and/or the framework doesn't allow the ability to
>>>>> distinguish different Exceptions from this layer.
>>>>>
>>>>> mike
>>>>>
>>>>>
>>>>>
>>>> A couple of suggestions:
>>>>
>>>> 1) I'd think you really shouldn't need to go through the whole process of
>>>> fully starting up the server (with a socket listener listening on a port)
>>>> and a client (opening a socket to the server) just to do testing. I
>>>> don't
>>>> know your code so well so perhaps I'm wrong here. But I'd think it
>>>> should
>>>> be sufficient to just *simulate* network communication by using a
>>>> DummySession and sending a message down the server's filter chain and
>>>> seeing
>>>> what response - or lack thereof - gets generated.
>>>>
>>>> 2) If you follow along with that approach, then you won't be in the
>>>> situation where your client is performing assertions inside the
>>>> messageReceived method (which are obviously getting swallowed). If you
>>>> look
>>>> carefully at the code I posted, you'll see that what I'm doing is to add
>>>> an
>>>> "OutputListener" - a class that I use only to assist with testing - at
>>>> the
>>>> end of my filter chain when I test. The output listener, true to its
>>>> name,
>>>> listens to whatever output/response the server's filter chain processing
>>>> generates, and saves it. Once that whole server filter chain interaction
>>>> is
>>>> complete, and I've "saved" the output from my "communication with the
>>>> server", only THEN do I go about issuing Asserts to verify that the
>>>> output
>>>> was what I expected. And since these asserts get done outside of the
>>>> MINA
>>>> filter chain processing they never get swallowed.
>>>>
>>>>
>>>> Bottom line: I think you can do any type of JUnit testing you want
>>>> against
>>>> your MINA server, but you need to write your tests differently.
>>>>
>>>> HTH,
>>>>
>>>> DR
>>>>
>>>>
>>>>
>>> Hi David,
>>>
>>> Thanks for your feedback. I noted your example and my reference to
>>> "solution to this" looks not to dissimilar from what you're doing
>>> (except I don't want to change the filter chain for fear of creating a
>>> difference between prod and dev). The same goes for dummy session. As
>>> I get more to grips with MINA I'm sure my assertions as to how to
>>> build the tests will change.
>>>
>>>
>> I would add to the very sensitive proposals David have suggested that
>> whatever you do in your unit tests, trying to keep them close to what you
>> will have in prod by simulating the full stack (ie, with sockets and server)
>> is probably impossible : it will just test that the loopback interface works
>> well, with time conditions totally different to what you will have in prod
>> anyway.
>>
>
> This is a valid point for sure.
>
> In particular I'm trying to test some decoders and encoders that I've
> written to implement a custom binary protocol. It wasn't clear to me,
> and I appreciate that MINA is work in progress, how to get an entity
> to send an object through a filter chain, and then another entity
> decode that object.
>
> As an easier way of doing this I decided to fire up a server and a
> client. As far as my testing goes I now have a nice black box
> solution, the server and client deal with call backs where the
> assertions are trapped in the case of a failure and reported back once
> outside of the MINA framework.
>
>
>> This is what is difficult when it comes to test a server : unit tests are
>> just good enough to check the internal logic (ie, the encoder/decoder, the
>> handler), but you need to build a bench with a real server, real injectors,
>> etc.
>>
>> Note that testing your application with real sockets is also good to have,
>> as you may encounter some weird conditions too.
>>
>> Thanks for using MINA, btw !
>>
>
> I'm extremely thankful for MINA! A number of years ago I tried to
> write an opensource java dhcpd - the point being to have web service
> calls at particular parts of the state machine to do things like mac
> address authentication, etc. Now with MINA I'm sure I can ressurect
> that project when I find some spare time!
>
There is already a -minimal- DHCP server implemented on top of MINA in
the Apache Directory Server project. It's probably not completed, but
this is a good start, for sure !
--
--
cordialement, regards,
Emmanuel Lécharny
www.iktek.com
directory.apache.org
Re: Exceptions in MINA
Posted by Michael Ossareh <os...@gmail.com>.
On Mon, Jun 8, 2009 at 3:10 PM, Emmanuel Lecharny<el...@apache.org> wrote:
> Michael Ossareh wrote:
>>
>> On Mon, Jun 8, 2009 at 2:13 PM, David Rosenstrauch<da...@darose.net>
>> wrote:
>>
>>>
>>> Michael Ossareh wrote:
>>>
>>>>
>>>> In the case above the code in messageReceived() cannot trigger
>>>> assertion failures, the exception they throw is trapped by the
>>>> framework and JUnit thinks the test passed. I'm using Assert.fail()
>>>> because the test I'm doing isn't part of JUnit's base tests (though I
>>>> understand I should start checking out the hamcrest matchers for my
>>>> tests:
>>>>
>>>> http://stackoverflow.com/questions/958460/creating-a-assertclass-method-in-junit
>>>> ) however using "normal" assertion fails suffer the same issue, for
>>>> example assertEquals(1, 2) results in the test passing beacause junit
>>>> doesn't ever see the exception.
>>>>
>>>> Clearly you'll see the power of this type of testing, the 20 or tests
>>>> I have to write are all structured the same. Connect client to server,
>>>> either client or server send data, ensure data is rendered same on the
>>>> receiving side.
>>>>
>>>> I'm midway through building a solution to this, however some of it
>>>> really reinventing the wheel and all because
>>>> IoHandlerAdapter.messageReceived / sessionOpened / sessionCreated all
>>>> throw Exception and/or the framework doesn't allow the ability to
>>>> distinguish different Exceptions from this layer.
>>>>
>>>> mike
>>>>
>>>>
>>>
>>> A couple of suggestions:
>>>
>>> 1) I'd think you really shouldn't need to go through the whole process of
>>> fully starting up the server (with a socket listener listening on a port)
>>> and a client (opening a socket to the server) just to do testing. I
>>> don't
>>> know your code so well so perhaps I'm wrong here. But I'd think it
>>> should
>>> be sufficient to just *simulate* network communication by using a
>>> DummySession and sending a message down the server's filter chain and
>>> seeing
>>> what response - or lack thereof - gets generated.
>>>
>>> 2) If you follow along with that approach, then you won't be in the
>>> situation where your client is performing assertions inside the
>>> messageReceived method (which are obviously getting swallowed). If you
>>> look
>>> carefully at the code I posted, you'll see that what I'm doing is to add
>>> an
>>> "OutputListener" - a class that I use only to assist with testing - at
>>> the
>>> end of my filter chain when I test. The output listener, true to its
>>> name,
>>> listens to whatever output/response the server's filter chain processing
>>> generates, and saves it. Once that whole server filter chain interaction
>>> is
>>> complete, and I've "saved" the output from my "communication with the
>>> server", only THEN do I go about issuing Asserts to verify that the
>>> output
>>> was what I expected. And since these asserts get done outside of the
>>> MINA
>>> filter chain processing they never get swallowed.
>>>
>>>
>>> Bottom line: I think you can do any type of JUnit testing you want
>>> against
>>> your MINA server, but you need to write your tests differently.
>>>
>>> HTH,
>>>
>>> DR
>>>
>>>
>>
>>
>> Hi David,
>>
>> Thanks for your feedback. I noted your example and my reference to
>> "solution to this" looks not to dissimilar from what you're doing
>> (except I don't want to change the filter chain for fear of creating a
>> difference between prod and dev). The same goes for dummy session. As
>> I get more to grips with MINA I'm sure my assertions as to how to
>> build the tests will change.
>>
>
> I would add to the very sensitive proposals David have suggested that
> whatever you do in your unit tests, trying to keep them close to what you
> will have in prod by simulating the full stack (ie, with sockets and server)
> is probably impossible : it will just test that the loopback interface works
> well, with time conditions totally different to what you will have in prod
> anyway.
This is a valid point for sure.
In particular I'm trying to test some decoders and encoders that I've
written to implement a custom binary protocol. It wasn't clear to me,
and I appreciate that MINA is work in progress, how to get an entity
to send an object through a filter chain, and then another entity
decode that object.
As an easier way of doing this I decided to fire up a server and a
client. As far as my testing goes I now have a nice black box
solution, the server and client deal with call backs where the
assertions are trapped in the case of a failure and reported back once
outside of the MINA framework.
>
> This is what is difficult when it comes to test a server : unit tests are
> just good enough to check the internal logic (ie, the encoder/decoder, the
> handler), but you need to build a bench with a real server, real injectors,
> etc.
>
> Note that testing your application with real sockets is also good to have,
> as you may encounter some weird conditions too.
>
> Thanks for using MINA, btw !
I'm extremely thankful for MINA! A number of years ago I tried to
write an opensource java dhcpd - the point being to have web service
calls at particular parts of the state machine to do things like mac
address authentication, etc. Now with MINA I'm sure I can ressurect
that project when I find some spare time!
>
> --
> --
> cordialement, regards,
> Emmanuel Lécharny
> www.iktek.com
> directory.apache.org
>
>
>
--
god loves atheists, Fact: http://www.mrwiggleslovesyou.com/comics/rehab477.jpg
Re: Exceptions in MINA
Posted by Emmanuel Lecharny <el...@apache.org>.
Michael Ossareh wrote:
> On Mon, Jun 8, 2009 at 2:13 PM, David Rosenstrauch<da...@darose.net> wrote:
>
>> Michael Ossareh wrote:
>>
>>> In the case above the code in messageReceived() cannot trigger
>>> assertion failures, the exception they throw is trapped by the
>>> framework and JUnit thinks the test passed. I'm using Assert.fail()
>>> because the test I'm doing isn't part of JUnit's base tests (though I
>>> understand I should start checking out the hamcrest matchers for my
>>> tests:
>>> http://stackoverflow.com/questions/958460/creating-a-assertclass-method-in-junit
>>> ) however using "normal" assertion fails suffer the same issue, for
>>> example assertEquals(1, 2) results in the test passing beacause junit
>>> doesn't ever see the exception.
>>>
>>> Clearly you'll see the power of this type of testing, the 20 or tests
>>> I have to write are all structured the same. Connect client to server,
>>> either client or server send data, ensure data is rendered same on the
>>> receiving side.
>>>
>>> I'm midway through building a solution to this, however some of it
>>> really reinventing the wheel and all because
>>> IoHandlerAdapter.messageReceived / sessionOpened / sessionCreated all
>>> throw Exception and/or the framework doesn't allow the ability to
>>> distinguish different Exceptions from this layer.
>>>
>>> mike
>>>
>>>
>> A couple of suggestions:
>>
>> 1) I'd think you really shouldn't need to go through the whole process of
>> fully starting up the server (with a socket listener listening on a port)
>> and a client (opening a socket to the server) just to do testing. I don't
>> know your code so well so perhaps I'm wrong here. But I'd think it should
>> be sufficient to just *simulate* network communication by using a
>> DummySession and sending a message down the server's filter chain and seeing
>> what response - or lack thereof - gets generated.
>>
>> 2) If you follow along with that approach, then you won't be in the
>> situation where your client is performing assertions inside the
>> messageReceived method (which are obviously getting swallowed). If you look
>> carefully at the code I posted, you'll see that what I'm doing is to add an
>> "OutputListener" - a class that I use only to assist with testing - at the
>> end of my filter chain when I test. The output listener, true to its name,
>> listens to whatever output/response the server's filter chain processing
>> generates, and saves it. Once that whole server filter chain interaction is
>> complete, and I've "saved" the output from my "communication with the
>> server", only THEN do I go about issuing Asserts to verify that the output
>> was what I expected. And since these asserts get done outside of the MINA
>> filter chain processing they never get swallowed.
>>
>>
>> Bottom line: I think you can do any type of JUnit testing you want against
>> your MINA server, but you need to write your tests differently.
>>
>> HTH,
>>
>> DR
>>
>>
>
>
> Hi David,
>
> Thanks for your feedback. I noted your example and my reference to
> "solution to this" looks not to dissimilar from what you're doing
> (except I don't want to change the filter chain for fear of creating a
> difference between prod and dev). The same goes for dummy session. As
> I get more to grips with MINA I'm sure my assertions as to how to
> build the tests will change.
>
I would add to the very sensitive proposals David have suggested that
whatever you do in your unit tests, trying to keep them close to what
you will have in prod by simulating the full stack (ie, with sockets and
server) is probably impossible : it will just test that the loopback
interface works well, with time conditions totally different to what you
will have in prod anyway.
This is what is difficult when it comes to test a server : unit tests
are just good enough to check the internal logic (ie, the
encoder/decoder, the handler), but you need to build a bench with a real
server, real injectors, etc.
Note that testing your application with real sockets is also good to
have, as you may encounter some weird conditions too.
Thanks for using MINA, btw !
--
--
cordialement, regards,
Emmanuel Lécharny
www.iktek.com
directory.apache.org
Re: Exceptions in MINA
Posted by Michael Ossareh <os...@gmail.com>.
On Mon, Jun 8, 2009 at 2:13 PM, David Rosenstrauch<da...@darose.net> wrote:
> Michael Ossareh wrote:
>>
>> In the case above the code in messageReceived() cannot trigger
>> assertion failures, the exception they throw is trapped by the
>> framework and JUnit thinks the test passed. I'm using Assert.fail()
>> because the test I'm doing isn't part of JUnit's base tests (though I
>> understand I should start checking out the hamcrest matchers for my
>> tests:
>> http://stackoverflow.com/questions/958460/creating-a-assertclass-method-in-junit
>> ) however using "normal" assertion fails suffer the same issue, for
>> example assertEquals(1, 2) results in the test passing beacause junit
>> doesn't ever see the exception.
>>
>> Clearly you'll see the power of this type of testing, the 20 or tests
>> I have to write are all structured the same. Connect client to server,
>> either client or server send data, ensure data is rendered same on the
>> receiving side.
>>
>> I'm midway through building a solution to this, however some of it
>> really reinventing the wheel and all because
>> IoHandlerAdapter.messageReceived / sessionOpened / sessionCreated all
>> throw Exception and/or the framework doesn't allow the ability to
>> distinguish different Exceptions from this layer.
>>
>> mike
>>
>
> A couple of suggestions:
>
> 1) I'd think you really shouldn't need to go through the whole process of
> fully starting up the server (with a socket listener listening on a port)
> and a client (opening a socket to the server) just to do testing. I don't
> know your code so well so perhaps I'm wrong here. But I'd think it should
> be sufficient to just *simulate* network communication by using a
> DummySession and sending a message down the server's filter chain and seeing
> what response - or lack thereof - gets generated.
>
> 2) If you follow along with that approach, then you won't be in the
> situation where your client is performing assertions inside the
> messageReceived method (which are obviously getting swallowed). If you look
> carefully at the code I posted, you'll see that what I'm doing is to add an
> "OutputListener" - a class that I use only to assist with testing - at the
> end of my filter chain when I test. The output listener, true to its name,
> listens to whatever output/response the server's filter chain processing
> generates, and saves it. Once that whole server filter chain interaction is
> complete, and I've "saved" the output from my "communication with the
> server", only THEN do I go about issuing Asserts to verify that the output
> was what I expected. And since these asserts get done outside of the MINA
> filter chain processing they never get swallowed.
>
>
> Bottom line: I think you can do any type of JUnit testing you want against
> your MINA server, but you need to write your tests differently.
>
> HTH,
>
> DR
>
Hi David,
Thanks for your feedback. I noted your example and my reference to
"solution to this" looks not to dissimilar from what you're doing
(except I don't want to change the filter chain for fear of creating a
difference between prod and dev). The same goes for dummy session. As
I get more to grips with MINA I'm sure my assertions as to how to
build the tests will change.
Cheers,
mike
--
god loves atheists, Fact: http://www.mrwiggleslovesyou.com/comics/rehab477.jpg
Re: Exceptions in MINA
Posted by David Rosenstrauch <da...@darose.net>.
Michael Ossareh wrote:
> In the case above the code in messageReceived() cannot trigger
> assertion failures, the exception they throw is trapped by the
> framework and JUnit thinks the test passed. I'm using Assert.fail()
> because the test I'm doing isn't part of JUnit's base tests (though I
> understand I should start checking out the hamcrest matchers for my
> tests: http://stackoverflow.com/questions/958460/creating-a-assertclass-method-in-junit
> ) however using "normal" assertion fails suffer the same issue, for
> example assertEquals(1, 2) results in the test passing beacause junit
> doesn't ever see the exception.
>
> Clearly you'll see the power of this type of testing, the 20 or tests
> I have to write are all structured the same. Connect client to server,
> either client or server send data, ensure data is rendered same on the
> receiving side.
>
> I'm midway through building a solution to this, however some of it
> really reinventing the wheel and all because
> IoHandlerAdapter.messageReceived / sessionOpened / sessionCreated all
> throw Exception and/or the framework doesn't allow the ability to
> distinguish different Exceptions from this layer.
>
> mike
>
A couple of suggestions:
1) I'd think you really shouldn't need to go through the whole process
of fully starting up the server (with a socket listener listening on a
port) and a client (opening a socket to the server) just to do testing.
I don't know your code so well so perhaps I'm wrong here. But I'd
think it should be sufficient to just *simulate* network communication
by using a DummySession and sending a message down the server's filter
chain and seeing what response - or lack thereof - gets generated.
2) If you follow along with that approach, then you won't be in the
situation where your client is performing assertions inside the
messageReceived method (which are obviously getting swallowed). If you
look carefully at the code I posted, you'll see that what I'm doing is
to add an "OutputListener" - a class that I use only to assist with
testing - at the end of my filter chain when I test. The output
listener, true to its name, listens to whatever output/response the
server's filter chain processing generates, and saves it. Once that
whole server filter chain interaction is complete, and I've "saved" the
output from my "communication with the server", only THEN do I go about
issuing Asserts to verify that the output was what I expected. And
since these asserts get done outside of the MINA filter chain processing
they never get swallowed.
Bottom line: I think you can do any type of JUnit testing you want
against your MINA server, but you need to write your tests differently.
HTH,
DR
Re: Exceptions in MINA
Posted by Maarten Bosteels <mb...@gmail.com>.
Hi
Can't you save whatever data you need in your asserts. and do your asserts
outside of messageReceived ?
Something like:
@Test
public void ensureCorrectPacketSent() {
final List<Contact> contacts = ... create list and put contacts in
it...;
final List<Whatever> received = ...
final CountDownLatch latch = new CountDownLatch(1);*
*
IoAcceptor server = startServer(9090, new IoHandlerAdapter() {
@Override
public void sessionOpened(IoSession session) throws Exception {
session.write(new ContactListPacket(contacts));
}
});
IoConnector client = startClient(9090, new IoHandlerAdapter() {
@Override
public void messageRecieved(IoSession session, Object message) {
Whatever whatever = extractWhateverFrom(message);
received.add(whatever);
latch.countDown();
}
});
latch.await();
assertTrue( received.contains(...));
}
Maarten
On Mon, Jun 8, 2009 at 10:10 PM, Michael Ossareh <os...@gmail.com> wrote:
> On Mon, Jun 8, 2009 at 12:40 PM, David Rosenstrauch<da...@darose.net>
> wrote:
> > Michael Ossareh wrote:
> >>
> >> I've uncovered what I believe to be a problem in the framework of
> >> MINA. I'm using 2.0.0-m5. As it currently stands any classes that
> >> subclass IoHandlerAdapter are crippled by the methods throwing
> >> Exception and the framework catching it. In my case I cannot write
> >> JUnit test cases because the Exception thrown by Assert.fail() is
> >> caught up in the framework therefore not allowing me to verify
> >> failures.
>
> .. snip..
>
> >> Thoughts? Depending what we come up with I'm happy to implement a fix.
> >>
> >> Cheers,
> >>
> >> mike
> >
> > Can you elaborate (or give an example) of exactly what the problem is?
> I've
> > written numerous junit tests for my MINA server, though I suppose I did
> have
> > to do it in a somewhat roundabout way: I sent a simulated received
> message
> > down the filter chain, and then verify that it triggers sending a
> particular
> > response. Code attached.
> >
> > HTH,
> >
> > DR
> >
> > ----
>
> Hi David, In my case
>
> public class SomeTest() {
>
>
> @Test
> public void ensureCorrectPacketSent() {
>
> final List<Contact> contacts = ... create list and put
> contacts in it...;
>
> IoAcceptor server = startServer(9090, new IoHandlerAdapter() {
> @Override
> public void sessionOpened(IoSession session) throws Exception {
> session.write(new ContactListPacket(contacts));
> }
> });
>
> IoConnector client = startClient(9090, new IoHandlerAdapter() {
> @Override
> public void messageRecieved(IoSession session, Object message) {
> // tests to ensure list contents are the same as sent.
> }
> });
>
>
> }
>
> public IoAcceptor startServer(int port, IoHandlerAdapter serverLogic) {
> IoAcceptor ia = new NioSocketAcceptor();
>
>
> ia.getFilterChain().addLast(... add protocol codec filter for
> our protocol ...);
> ia.setHandler(serverLogic);
>
> // bind and return ia
> }
>
> public IoConnector startClient(int port, IoHandlerAdapter clientLogic) {
> // start client, set handler, etc.
> }
> }
>
> In the case above the code in messageReceived() cannot trigger
> assertion failures, the exception they throw is trapped by the
> framework and JUnit thinks the test passed. I'm using Assert.fail()
> because the test I'm doing isn't part of JUnit's base tests (though I
> understand I should start checking out the hamcrest matchers for my
> tests:
> http://stackoverflow.com/questions/958460/creating-a-assertclass-method-in-junit
> ) however using "normal" assertion fails suffer the same issue, for
> example assertEquals(1, 2) results in the test passing beacause junit
> doesn't ever see the exception.
>
> Clearly you'll see the power of this type of testing, the 20 or tests
> I have to write are all structured the same. Connect client to server,
> either client or server send data, ensure data is rendered same on the
> receiving side.
>
> I'm midway through building a solution to this, however some of it
> really reinventing the wheel and all because
> IoHandlerAdapter.messageReceived / sessionOpened / sessionCreated all
> throw Exception and/or the framework doesn't allow the ability to
> distinguish different Exceptions from this layer.
>
> mike
>
> --
> god loves atheists, Fact:
> http://www.mrwiggleslovesyou.com/comics/rehab477.jpg
>
Re: Exceptions in MINA
Posted by Michael Ossareh <os...@gmail.com>.
On Mon, Jun 8, 2009 at 12:40 PM, David Rosenstrauch<da...@darose.net> wrote:
> Michael Ossareh wrote:
>>
>> I've uncovered what I believe to be a problem in the framework of
>> MINA. I'm using 2.0.0-m5. As it currently stands any classes that
>> subclass IoHandlerAdapter are crippled by the methods throwing
>> Exception and the framework catching it. In my case I cannot write
>> JUnit test cases because the Exception thrown by Assert.fail() is
>> caught up in the framework therefore not allowing me to verify
>> failures.
.. snip..
>> Thoughts? Depending what we come up with I'm happy to implement a fix.
>>
>> Cheers,
>>
>> mike
>
> Can you elaborate (or give an example) of exactly what the problem is? I've
> written numerous junit tests for my MINA server, though I suppose I did have
> to do it in a somewhat roundabout way: I sent a simulated received message
> down the filter chain, and then verify that it triggers sending a particular
> response. Code attached.
>
> HTH,
>
> DR
>
> ----
Hi David, In my case
public class SomeTest() {
@Test
public void ensureCorrectPacketSent() {
final List<Contact> contacts = ... create list and put
contacts in it...;
IoAcceptor server = startServer(9090, new IoHandlerAdapter() {
@Override
public void sessionOpened(IoSession session) throws Exception {
session.write(new ContactListPacket(contacts));
}
});
IoConnector client = startClient(9090, new IoHandlerAdapter() {
@Override
public void messageRecieved(IoSession session, Object message) {
// tests to ensure list contents are the same as sent.
}
});
}
public IoAcceptor startServer(int port, IoHandlerAdapter serverLogic) {
IoAcceptor ia = new NioSocketAcceptor();
ia.getFilterChain().addLast(... add protocol codec filter for
our protocol ...);
ia.setHandler(serverLogic);
// bind and return ia
}
public IoConnector startClient(int port, IoHandlerAdapter clientLogic) {
// start client, set handler, etc.
}
}
In the case above the code in messageReceived() cannot trigger
assertion failures, the exception they throw is trapped by the
framework and JUnit thinks the test passed. I'm using Assert.fail()
because the test I'm doing isn't part of JUnit's base tests (though I
understand I should start checking out the hamcrest matchers for my
tests: http://stackoverflow.com/questions/958460/creating-a-assertclass-method-in-junit
) however using "normal" assertion fails suffer the same issue, for
example assertEquals(1, 2) results in the test passing beacause junit
doesn't ever see the exception.
Clearly you'll see the power of this type of testing, the 20 or tests
I have to write are all structured the same. Connect client to server,
either client or server send data, ensure data is rendered same on the
receiving side.
I'm midway through building a solution to this, however some of it
really reinventing the wheel and all because
IoHandlerAdapter.messageReceived / sessionOpened / sessionCreated all
throw Exception and/or the framework doesn't allow the ability to
distinguish different Exceptions from this layer.
mike
--
god loves atheists, Fact: http://www.mrwiggleslovesyou.com/comics/rehab477.jpg
Re: Exceptions in MINA
Posted by David Rosenstrauch <da...@darose.net>.
Michael Ossareh wrote:
> I've uncovered what I believe to be a problem in the framework of
> MINA. I'm using 2.0.0-m5. As it currently stands any classes that
> subclass IoHandlerAdapter are crippled by the methods throwing
> Exception and the framework catching it. In my case I cannot write
> JUnit test cases because the Exception thrown by Assert.fail() is
> caught up in the framework therefore not allowing me to verify
> failures.
>
> Dev's Is there a strong reason for this? Exceptions need to take place
> in business logic, not just test cases, and right now they cannot.
> These methods, I feel, shouldn't have Exception in their method def.
> Perhaps a subclass of Exception such as BusinessException or something
> which we can treat differently?
>
> Perhaps I've missed something? Is there some part of the filter chain
> that you can add an exception handler? That only unhandled exceptions
> then result in bubbling to the top?
>
> Thoughts? Depending what we come up with I'm happy to implement a fix.
>
> Cheers,
>
> mike
Can you elaborate (or give an example) of exactly what the problem is?
I've written numerous junit tests for my MINA server, though I suppose I
did have to do it in a somewhat roundabout way: I sent a simulated
received message down the filter chain, and then verify that it triggers
sending a particular response. Code attached.
HTH,
DR
----
public class TestTextProtocolHandler extends TestCase {
protected void setUp() throws IOException {
...
session = new DummySession();
session.setHandler(new TextProtocolHandler(serverControl, cacheNode));
filterChain = session.getFilterChain();
outputListener = new OutputListener();
filterChain.addLast("listener", outputListener);
}
...
public void testQuery() throws IOException, InterruptedException,
ExecutionException {
...
filterChain.fireMessageReceived("query 1234/I");
ProtocolResponse response = outputListener.getResponse();
assertTrue(response.isSuccess());
AssertHelper.assertNotNullOrEmpty(TextProtocolHandler.argsToString(response.getArgs(),
unsquasher));
}
...
}
class OutputListener extends IoFilterAdapter {
public void messageSent(NextFilter nextFilter, IoSession session,
WriteRequest writeRequest) {
String responseStr = (String) writeRequest.getMessage();
response = TextProtocolHandler.protocolResponseFromString(responseStr);
nextFilter.messageSent(session, writeRequest);
}
public ProtocolResponse getResponse() {
return response;
}
private ProtocolResponse response;
}
Re: Exceptions in MINA
Posted by Michael Ossareh <os...@gmail.com>.
On Tue, Jun 9, 2009 at 1:38 AM, Irving,
Dave<da...@bankofamerica.com> wrote:
>
> Hi,
>
> ..
>
>> In my case I cannot write JUnit test cases because the Exception
> thrown
>> by Assert.fail() is caught up in the framework therefore not allowing
>> me to verify failures.
>
> Sorry if my response is complete nonsense - its been a while since I've
> used Mina in anger :)
> Can't you just set an ExceptionMonitor instance which doesn't swallow
> exceptions (or captures them for relaying back to your test if you're
> not running off the main thread)?
>
> org.apache.mina.util.ExceptionMonitor#setInstance(ExceptionMonitor
> instance)
>
> http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mi
> na/util/ExceptionMonitor.java?view=co
Aha, I'd not come across this exception monitoring.
Cheers for the heads up.
>
>
>> Cheers,
>
>> mike
>
> Dave
>
>
>
> Notice to recipient:
> The information in this internet e-mail and any attachments is confidential and may be privileged. It is intended solely for the addressee. If you are not the intended addressee please notify the sender immediately by telephone. If you are not the intended recipient, any disclosure, copying, distribution or any action taken or omitted to be taken in reliance on it, is prohibited and may be unlawful.
>
> When addressed to external clients any opinions or advice contained in this internet e-mail are subject to the terms and conditions expressed in any applicable governing terms of business or client engagement letter issued by the pertinent Bank of America group entity.
>
> If this email originates from the U.K. please note that Bank of America, N.A., London Branch, Banc of America Securities Limited and MBNA Europe Bank Limited are authorised and regulated by the Financial Services Authority. For all U.K. corporate disclosures, please refer to www.bankofamerica.com/ukcompanies
>
--
god loves atheists, Fact: http://www.mrwiggleslovesyou.com/comics/rehab477.jpg
Re: Exceptions in MINA
Posted by Michael Ossareh <os...@gmail.com>.
On Tue, Jun 9, 2009 at 1:38 AM, Irving,
Dave<da...@bankofamerica.com> wrote:
>
> Hi,
>
> ..
>
>> In my case I cannot write JUnit test cases because the Exception
> thrown
>> by Assert.fail() is caught up in the framework therefore not allowing
>> me to verify failures.
>
> Sorry if my response is complete nonsense - its been a while since I've
> used Mina in anger :)
> Can't you just set an ExceptionMonitor instance which doesn't swallow
> exceptions (or captures them for relaying back to your test if you're
> not running off the main thread)?
>
> org.apache.mina.util.ExceptionMonitor#setInstance(ExceptionMonitor
> instance)
>
> http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mi
> na/util/ExceptionMonitor.java?view=co
Aha, I'd not come across this exception monitoring.
Cheers for the heads up.
>
>
>> Cheers,
>
>> mike
>
> Dave
>
>
>
> Notice to recipient:
> The information in this internet e-mail and any attachments is confidential and may be privileged. It is intended solely for the addressee. If you are not the intended addressee please notify the sender immediately by telephone. If you are not the intended recipient, any disclosure, copying, distribution or any action taken or omitted to be taken in reliance on it, is prohibited and may be unlawful.
>
> When addressed to external clients any opinions or advice contained in this internet e-mail are subject to the terms and conditions expressed in any applicable governing terms of business or client engagement letter issued by the pertinent Bank of America group entity.
>
> If this email originates from the U.K. please note that Bank of America, N.A., London Branch, Banc of America Securities Limited and MBNA Europe Bank Limited are authorised and regulated by the Financial Services Authority. For all U.K. corporate disclosures, please refer to www.bankofamerica.com/ukcompanies
>
--
god loves atheists, Fact: http://www.mrwiggleslovesyou.com/comics/rehab477.jpg
RE: Exceptions in MINA
Posted by "Irving, Dave" <da...@bankofamerica.com>.
Hi,
..
> In my case I cannot write JUnit test cases because the Exception
thrown
> by Assert.fail() is caught up in the framework therefore not allowing
> me to verify failures.
Sorry if my response is complete nonsense - its been a while since I've
used Mina in anger :)
Can't you just set an ExceptionMonitor instance which doesn't swallow
exceptions (or captures them for relaying back to your test if you're
not running off the main thread)?
org.apache.mina.util.ExceptionMonitor#setInstance(ExceptionMonitor
instance)
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mi
na/util/ExceptionMonitor.java?view=co
> Cheers,
> mike
Dave
Notice to recipient:
The information in this internet e-mail and any attachments is confidential and may be privileged. It is intended solely for the addressee. If you are not the intended addressee please notify the sender immediately by telephone. If you are not the intended recipient, any disclosure, copying, distribution or any action taken or omitted to be taken in reliance on it, is prohibited and may be unlawful.
When addressed to external clients any opinions or advice contained in this internet e-mail are subject to the terms and conditions expressed in any applicable governing terms of business or client engagement letter issued by the pertinent Bank of America group entity.
If this email originates from the U.K. please note that Bank of America, N.A., London Branch, Banc of America Securities Limited and MBNA Europe Bank Limited are authorised and regulated by the Financial Services Authority. For all U.K. corporate disclosures, please refer to www.bankofamerica.com/ukcompanies
RE: Exceptions in MINA
Posted by "Irving, Dave" <da...@bankofamerica.com>.
Hi,
..
> In my case I cannot write JUnit test cases because the Exception
thrown
> by Assert.fail() is caught up in the framework therefore not allowing
> me to verify failures.
Sorry if my response is complete nonsense - its been a while since I've
used Mina in anger :)
Can't you just set an ExceptionMonitor instance which doesn't swallow
exceptions (or captures them for relaying back to your test if you're
not running off the main thread)?
org.apache.mina.util.ExceptionMonitor#setInstance(ExceptionMonitor
instance)
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mi
na/util/ExceptionMonitor.java?view=co
> Cheers,
> mike
Dave
Notice to recipient:
The information in this internet e-mail and any attachments is confidential and may be privileged. It is intended solely for the addressee. If you are not the intended addressee please notify the sender immediately by telephone. If you are not the intended recipient, any disclosure, copying, distribution or any action taken or omitted to be taken in reliance on it, is prohibited and may be unlawful.
When addressed to external clients any opinions or advice contained in this internet e-mail are subject to the terms and conditions expressed in any applicable governing terms of business or client engagement letter issued by the pertinent Bank of America group entity.
If this email originates from the U.K. please note that Bank of America, N.A., London Branch, Banc of America Securities Limited and MBNA Europe Bank Limited are authorised and regulated by the Financial Services Authority. For all U.K. corporate disclosures, please refer to www.bankofamerica.com/ukcompanies