public inbox for mauve-discuss@sourceware.org
 help / color / mirror / Atom feed
* New SocketChannel test that requires testing
@ 2006-09-18 11:30 Jeroen Frijters
  2006-09-18 22:45 ` Casey Marshall
  0 siblings, 1 reply; 8+ messages in thread
From: Jeroen Frijters @ 2006-09-18 11:30 UTC (permalink / raw)
  To: mauve-discuss

[-- Attachment #1: Type: text/plain, Size: 703 bytes --]

Hi,

I've written a new test case for SocketChannel and I require some
assistance testing it on different platforms (and/or opinions on it)
because it uses a trick and I would like to know if the trick is
reliable or not.

The trick is that it creates a server socket with a backlog of 1 and
then it fills up that backlog queue by initiating a connection to make
sure that a subsequent connection attempt will block (to test if
asynchronous connections work correctly).

I tested this on Windows (JDK 1.5 and IKVM) and I would appreciate it if
people would run this test on their platform of choice. Other feedback
on the validity of this approach is also appreciated.

Thanks,
Jeroen

[-- Attachment #2: tests.java.txt --]
[-- Type: text/plain, Size: 3086 bytes --]

// Tags: JDK1.4

// Copyright (C) 2006 Jeroen Frijters

// This file is part of Mauve.

// Mauve is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.

// Mauve is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Mauve; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.  */

package gnu.testlet.java.nio.channels.SocketChannel;

import gnu.testlet.Testlet;
import gnu.testlet.TestHarness;

import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class tests implements Testlet
{
  public void test(TestHarness harness)
  {
    try
    {
      harness.checkPoint("test states");
      testStates(harness);
    }
    catch (Exception x)
    {
      harness.check(false);
      harness.debug(x);
    }
  }

  private void testStates(TestHarness harness) throws Exception
  {
    ServerSocket srv = new ServerSocket(0, 1);
    Socket consumeSocket = new Socket(InetAddress.getLocalHost(), srv.getLocalPort());

    SocketChannel ch = SocketChannel.open();

    harness.checkPoint("initial state");
    harness.check(ch.isOpen());
    harness.check(!ch.isConnected());
    harness.check(!ch.isConnectionPending());

    harness.checkPoint("initiate async connect");
    ch.configureBlocking(false);
    harness.check(!ch.connect(new InetSocketAddress(InetAddress.getLocalHost(), srv.getLocalPort())));
    harness.check(!ch.isConnected());
    harness.check(ch.isConnectionPending());
    harness.check(!ch.finishConnect());

    harness.checkPoint("establish the connection");
    // free up the backlog
    srv.accept().close();
    ch.configureBlocking(true);
    harness.check(ch.finishConnect());
    harness.check(ch.isOpen());
    harness.check(ch.isConnected());
    harness.check(!ch.isConnectionPending());

    harness.checkPoint("receive some data");
    ch.configureBlocking(false);
    ByteBuffer buf = ByteBuffer.allocate(4);
    harness.check(ch.read(buf) == 0);
    Socket otherSide = srv.accept();
    otherSide.getOutputStream().write("TEST".getBytes(), 0, 4);
    ch.configureBlocking(true);
    harness.check(ch.read(buf) == 4);
    harness.check(new String(buf.array()).equals("TEST"));

    harness.checkPoint("close");
    ch.close();
    harness.check(!ch.isOpen());
    harness.check(!ch.isConnected());
    harness.check(!ch.isConnectionPending());

    // clean up
    consumeSocket.close();
    srv.close();
  }
}

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: New SocketChannel test that requires testing
  2006-09-18 11:30 New SocketChannel test that requires testing Jeroen Frijters
@ 2006-09-18 22:45 ` Casey Marshall
  2006-09-19  5:32   ` Jeroen Frijters
  0 siblings, 1 reply; 8+ messages in thread
From: Casey Marshall @ 2006-09-18 22:45 UTC (permalink / raw)
  To: Jeroen Frijters; +Cc: mauve-discuss

Jeroen Frijters wrote:
> Hi,
> 
> I've written a new test case for SocketChannel and I require some
> assistance testing it on different platforms (and/or opinions on it)
> because it uses a trick and I would like to know if the trick is
> reliable or not.
> 
> The trick is that it creates a server socket with a backlog of 1 and
> then it fills up that backlog queue by initiating a connection to make
> sure that a subsequent connection attempt will block (to test if
> asynchronous connections work correctly).
> 
> I tested this on Windows (JDK 1.5 and IKVM) and I would appreciate it if
> people would run this test on their platform of choice. Other feedback
> on the validity of this approach is also appreciated.
> 

It doesn't quite work for me (jamvm+classpath CVS and java 1.5; both on
OSX/x86). I get two fails with classpath:

  FAIL: java.nio.channels.SocketChannel.tests
    line 65: initiate async connect [2] -- boolean passed to check was false
    line 67: initiate async connect [4] -- boolean passed to check was false

And one with Sun/Apple Java:

  FAIL: java.nio.channels.SocketChannel.tests
    line 67: initiate async connect [4] -- boolean passed to check was false

I think this is because that connect is, indeed, eating up a slot in the
backlog, but the kernel allowed the connection anyway. So as far as the
client SocketChannel is concerned, it's connected, and the socket is
writable.

Maybe we are wrong for returning true for `isConnected' that early after
trying to establish the connection; the test we're using is whether or
not the socket has a remote address or not, which may not be the
criteria we're interested in.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: New SocketChannel test that requires testing
  2006-09-18 22:45 ` Casey Marshall
@ 2006-09-19  5:32   ` Jeroen Frijters
  2006-09-19  8:08     ` Casey Marshall
  0 siblings, 1 reply; 8+ messages in thread
From: Jeroen Frijters @ 2006-09-19  5:32 UTC (permalink / raw)
  To: Casey Marshall; +Cc: mauve-discuss

Casey Marshall wrote:
> Jeroen Frijters wrote:
> > Hi,
> > 
> > I've written a new test case for SocketChannel and I require some
> > assistance testing it on different platforms (and/or opinions on it)
> > because it uses a trick and I would like to know if the trick is
> > reliable or not.
> > 
> > The trick is that it creates a server socket with a backlog of 1 and
> > then it fills up that backlog queue by initiating a 
> connection to make
> > sure that a subsequent connection attempt will block (to test if
> > asynchronous connections work correctly).
> > 
> > I tested this on Windows (JDK 1.5 and IKVM) and I would 
> appreciate it if
> > people would run this test on their platform of choice. 
> Other feedback
> > on the validity of this approach is also appreciated.
> > 
> 
> It doesn't quite work for me (jamvm+classpath CVS and java 
> 1.5; both on
> OSX/x86). I get two fails with classpath:
> 
>   FAIL: java.nio.channels.SocketChannel.tests
>     line 65: initiate async connect [2] -- boolean passed to 
> check was false
>     line 67: initiate async connect [4] -- boolean passed to 
> check was false
> 
> And one with Sun/Apple Java:
> 
>   FAIL: java.nio.channels.SocketChannel.tests
>     line 67: initiate async connect [4] -- boolean passed to 
> check was false

Hmm, that's unfortunate. I don't know of any other way to reliably build
a test for these things. Thanks for testing this.

> I think this is because that connect is, indeed, eating up a 
> slot in the backlog, but the kernel allowed the connection anyway.
> So as far as the client SocketChannel is concerned, it's connected,
> and the socket is writable.
> 
> Maybe we are wrong for returning true for `isConnected' that 
> early after trying to establish the connection; the test we're using
> is whether or not the socket has a remote address or not, which may
> not be the criteria we're interested in.

Yes, I believe that's incorrect. I think you can only transition into
the connected state by calling finishConnect (if connect was called in
non-blocking mode).

Regards,
Jeroen

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: New SocketChannel test that requires testing
  2006-09-19  5:32   ` Jeroen Frijters
@ 2006-09-19  8:08     ` Casey Marshall
  2006-09-19  8:21       ` Jeroen Frijters
  0 siblings, 1 reply; 8+ messages in thread
From: Casey Marshall @ 2006-09-19  8:08 UTC (permalink / raw)
  To: Jeroen Frijters; +Cc: mauve-discuss

Jeroen Frijters wrote:
> Casey Marshall wrote:
>> Maybe we are wrong for returning true for `isConnected' that 
>> early after trying to establish the connection; the test we're using
>> is whether or not the socket has a remote address or not, which may
>> not be the criteria we're interested in.
> 
> Yes, I believe that's incorrect. I think you can only transition into
> the connected state by calling finishConnect (if connect was called in
> non-blocking mode).
> 

That's not necessarily true; on some systems, even a non-blocking call
to connect() can succeed immediately, if you are connecting to the local
machine. It doesn't sound right that you get this condition even when
the server process hasn't pulled the connection off the queue, but that
may be how it works.

I wonder, now, if this is an artifact of our (new) RI: we call a
nonblocking connect() every time, then select() on the server's FD to
handle the blocking case, with timeout. This may be doing the wrong
thing with nonblocking sockets.

Thanks.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: New SocketChannel test that requires testing
  2006-09-19  8:08     ` Casey Marshall
@ 2006-09-19  8:21       ` Jeroen Frijters
  2006-09-19 18:36         ` Casey Marshall
  0 siblings, 1 reply; 8+ messages in thread
From: Jeroen Frijters @ 2006-09-19  8:21 UTC (permalink / raw)
  To: Casey Marshall; +Cc: mauve-discuss

Casey Marshall wrote:
> Jeroen Frijters wrote:
> > Casey Marshall wrote:
> >> Maybe we are wrong for returning true for `isConnected' that 
> >> early after trying to establish the connection; the test 
> we're using
> >> is whether or not the socket has a remote address or not, which may
> >> not be the criteria we're interested in.
> > 
> > Yes, I believe that's incorrect. I think you can only 
> transition into
> > the connected state by calling finishConnect (if connect 
> was called in
> > non-blocking mode).
> > 
> 
> That's not necessarily true; on some systems, even a non-blocking call
> to connect() can succeed immediately, if you are connecting 
> to the local machine. It doesn't sound right that you get this
> condition even when the server process hasn't pulled the connection
> off the queue, but that may be how it works.

I don't think it has nothing to do with the underlying socket mechanics,
it is simply an invariant of the SocketChannel API.

Regards,
Jeroen

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: New SocketChannel test that requires testing
  2006-09-19  8:21       ` Jeroen Frijters
@ 2006-09-19 18:36         ` Casey Marshall
  2006-09-20  4:34           ` Jeroen Frijters
  0 siblings, 1 reply; 8+ messages in thread
From: Casey Marshall @ 2006-09-19 18:36 UTC (permalink / raw)
  To: Jeroen Frijters; +Cc: mauve-discuss

Jeroen Frijters wrote:
> Casey Marshall wrote:
>> Jeroen Frijters wrote:
>>> Casey Marshall wrote:
>>>> Maybe we are wrong for returning true for `isConnected' that 
>>>> early after trying to establish the connection; the test 
>> we're using
>>>> is whether or not the socket has a remote address or not, which may
>>>> not be the criteria we're interested in.
>>> Yes, I believe that's incorrect. I think you can only 
>> transition into
>>> the connected state by calling finishConnect (if connect 
>> was called in
>>> non-blocking mode).
>>>
>> That's not necessarily true; on some systems, even a non-blocking call
>> to connect() can succeed immediately, if you are connecting 
>> to the local machine. It doesn't sound right that you get this
>> condition even when the server process hasn't pulled the connection
>> off the queue, but that may be how it works.
> 
> I don't think it has nothing to do with the underlying socket mechanics,
> it is simply an invariant of the SocketChannel API.
> 

Nope:

"If this channel is in non-blocking mode then an invocation of this
method initiates a non-blocking connection operation. If the connection
is established immediately, as can happen with a local connection, then
this method returns true. Otherwise this method returns false and the
connection operation must later be completed by invoking the
finishConnect method." [1]

1.
http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/SocketChannel.html#connect(java.net.SocketAddress)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: New SocketChannel test that requires testing
  2006-09-19 18:36         ` Casey Marshall
@ 2006-09-20  4:34           ` Jeroen Frijters
  2006-09-20  5:14             ` Casey Marshall
  0 siblings, 1 reply; 8+ messages in thread
From: Jeroen Frijters @ 2006-09-20  4:34 UTC (permalink / raw)
  To: Casey Marshall; +Cc: mauve-discuss

Casey Marshall wrote:
> > I don't think it has nothing to do with the underlying 
> > socket mechanics,
> > it is simply an invariant of the SocketChannel API.
> 
> Nope:
> 
> "If this channel is in non-blocking mode then an invocation of this
> method initiates a non-blocking connection operation. If the 
> connection is established immediately, as can happen with a local 
> connection, then this method returns true. Otherwise this method
> returns false and the connection operation must later be completed
> by invoking the finishConnect method." [1]
> 
> 1.
> http://java.sun.com/j2se/1.4.2/docs/api/java/nio/channels/Sock
> etChannel.html#connect(java.net.SocketAddress)

May be I misunderstood what you meant, we were talking about
isConnected() changing its return value right? The only way I can read
the text you quoted is that it confirms that isConnected() will only
return true iff either connect() or finishConnect() previously returned
true.

Regards,
Jeroen

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: New SocketChannel test that requires testing
  2006-09-20  4:34           ` Jeroen Frijters
@ 2006-09-20  5:14             ` Casey Marshall
  0 siblings, 0 replies; 8+ messages in thread
From: Casey Marshall @ 2006-09-20  5:14 UTC (permalink / raw)
  To: Jeroen Frijters; +Cc: mauve-discuss

Jeroen Frijters wrote:
> May be I misunderstood what you meant, we were talking about
> isConnected() changing its return value right? The only way I can read
> the text you quoted is that it confirms that isConnected() will only
> return true iff either connect() or finishConnect() previously returned
> true.
> 

Oops, yeah. I was thinking of connect()'s return value.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2006-09-20  5:14 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-09-18 11:30 New SocketChannel test that requires testing Jeroen Frijters
2006-09-18 22:45 ` Casey Marshall
2006-09-19  5:32   ` Jeroen Frijters
2006-09-19  8:08     ` Casey Marshall
2006-09-19  8:21       ` Jeroen Frijters
2006-09-19 18:36         ` Casey Marshall
2006-09-20  4:34           ` Jeroen Frijters
2006-09-20  5:14             ` Casey Marshall

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).