On 7/11/06, Paulex Yang <[EMAIL PROTECTED]> wrote:

Andrew,

The AsyncCloseException is actually thrown by
AbstractInterruptibleChannel.end(), so probably you actually want to
test is if DatagramChannel.read() invokes begin()/end() as below:

try{
   begin();
   complete = doSomeIO();
}finally{
   end(complete);
}

To test this, you may want to inject some synchronization/check point
into this procedure:
1. Extend DatagramChannel and override begin()/end(), but because
begin()/end() are final, so this way doesn't work
2. Inject something into certain part of doSomeIO(), but this makes the
tests implementation dependent if no SPI methods defined.

So if you have strong feeling to test this, you may consider the option
2, and check if there is some "injection point" you can leverage, for
example, mock a INetworkSystem and inject it into DatagramChannel or so.


Thank you Paulex. I see your solution.

Solution 2 works :) but it's implementation dependent.

Additionally, for this specific case, such implementation test does not make
sense. Here're my reasons:

If we could ASSUME there are some "injection point", what is the assumption
based on?

Just by reading the code or design doc?  If it's so, we could definitely
ASSUME end() is always called because we could easily find "end()" in
finally block.

Again for this specific case, mock a INetworkSystem is quite complicated, we
have to overcome "finally method","static method"... lots of troubles.

The reason I posted this case on mailing list is that there are so many
blocking operation tests which are impossible (maybe impossible is
nothing:)) tested by their api.

So shall we keep these tests in Harmony?

If they are not valuable to be existing, I'll clean these potentially
unstable tests from NIO module.

Any comments are welcome :)


Andrew Zhang wrote:
> Hello Tim,
>
> Thank you for your suggestion. :)
>
> Of course, "fix" is the best choice. I also have tried to use
> "wait/notify",
> but found it didn't work for this case.
>
> Please note that "channel1.read(targetBuf); // Label 3" is a blocking
> operation. And we want code at label 1,2 to execute after label 3.
>
> There is the question:
>
> Where should I put "notify"?
>
> 1. before "read"? NO. If nofity is put before read, then we still can't
> guarantee "configureBlocking" is executed after read.
> 2. after "read"? NO. read is a blocking operatoin. It will never be
> executed
> if put notify after read.
> 3. in "read"?  Obviously NO.
>
> Please correct me if I'm wrong.
>
> Thanks!
>
>
> On 7/11/06, Tim Ellison <[EMAIL PROTECTED]> wrote:
>>
>> Andrew Zhang wrote:
>> > Hello everybody,
>> >
>> > I noticed such tests in DatagramChannel, which is useful, but
>> potentially
>> > unstable.  Consider:
>> >
>> > public void testReadWrite_configureBlock() throws Exception {
>> >        byte[] targetArray = new byte[2];
>> >        // bind and connect
>> >        this.channel1.socket().bind(localAddr2);
>> >        this.channel1.connect(localAddr1);
>> >        this.channel2.socket().bind(localAddr1);
>> >        this.channel2.connect(localAddr2);
>> >        ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
>> >
>> >        new Thread() {
>> >            public void run() {
>> >                try {
>> >                    Thread.sleep(TIME_UNIT);
>> >                    channel1.configureBlocking(false); // Label 1
>> >                    channel1.close(); // Label 2
>> >                } catch (Exception e) {
>> >                    //ignore
>> >                }
>> >            }
>> >        }.start();
>> >        try {
>> >            this.channel1.read(targetBuf); // Label 3
>> >            fail("should throw AsynchronousCloseException");
>> >        } catch (AsynchronousCloseException e) {
>> >            // ok
>> >        }
>> >    }
>> > This test assumes Label 3  code should execute before Label 1 and
>> Label
>> 2,
>> > which is right in most cases, because the code invokes "Thread.sleep
>> > (TIME_UNIT)".
>> >
>> > However, it's potentially unstable. It heavily depends on TIME_UNIT
>> value,
>> > test environment (Hardware, OS ...)
>>
>> Urgh.  There are *very* few occasions when you need to use
>> Thread.sleep(); and 'thread synchronization' is definitely not one of
>> them!
>>
>> If you have order dependencies between two or more threads then use
>> wait/notify, or synchronized, and make them explicit.
>>
>> There are any number of books on multi-threaded programming in Java.
>>
>> > Indubitably, the test is very useful for testing
>> > "AsynchronousCloseException" of DatagramChannel.read(ByteBuffer)
>> method.
>> >
>> > How shall we deal with such issue?  Deleting such valuable tests is
>> not
>> a
>> > wise decision, while keeping them may cause build system fail.
>> >
>> > One solution I could image is TestNG. :) i.e. Use "@dev" or
>> something to
>> > mark such tests, say, the tests are only for developing purpose.
>> >
>> > Any suggestions?
>>
>> Fix it!  :-)
>>
>> Regards,
>> Tim
>>
>> --
>>
>> Tim Ellison ([EMAIL PROTECTED])
>> IBM Java technology centre, UK.
>>
>> ---------------------------------------------------------------------
>> Terms of use : http://incubator.apache.org/harmony/mailing.html
>> To unsubscribe, e-mail: [EMAIL PROTECTED]
>> For additional commands, e-mail: [EMAIL PROTECTED]
>>
>>
>
>


--
Paulex Yang
China Software Development Lab
IBM



---------------------------------------------------------------------
Terms of use : http://incubator.apache.org/harmony/mailing.html
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




--
Andrew Zhang
China Software Development Lab, IBM

Reply via email to