Skip to content

Commit 432ee0d

Browse files
committed
Added more tests
1 parent 45b9418 commit 432ee0d

File tree

4 files changed

+175
-26
lines changed

4 files changed

+175
-26
lines changed

src/main/java/jnr/unixsocket/Common.java

+12-4
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,15 @@ static void setSocketOption(int fd, SocketOption<?> name,
112112
if (null == value) {
113113
throw new IllegalArgumentException("Invalid option value");
114114
}
115+
116+
jnr.constants.platform.SocketOption optname = wMap.get(name);
117+
if (null == optname) {
118+
throw new AssertionError("Option not found or not writable");
119+
}
120+
115121
Class<?> type = name.type();
116122
if (type != Integer.class && type != Boolean.class) {
117-
throw new AssertionError("Should not reach here");
123+
throw new AssertionError("Unsupported option type");
118124
}
119125

120126
int optvalue;
@@ -131,9 +137,11 @@ static void setSocketOption(int fd, SocketOption<?> name,
131137
}
132138
}
133139

134-
jnr.constants.platform.SocketOption optname = wMap.get(name);
135-
if (null == optname) {
136-
throw new AssertionError("Option not found");
140+
if (name == UnixSocketOptions.SO_RCVTIMEO || name == UnixSocketOptions.SO_SNDTIMEO) {
141+
int i = ((Integer)value).intValue();
142+
if (i < 0) {
143+
throw new IllegalArgumentException("Invalid send/receive timeout");
144+
}
137145
}
138146

139147
if (0 != Native.setsockopt(fd, SocketLevel.SOL_SOCKET, optname, optvalue)) {

src/main/java/jnr/unixsocket/UnixDatagramChannel.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ public static final UnixDatagramChannel[] pair() throws IOException {
6464
int[] sockets = { -1, -1 };
6565
Native.socketpair(ProtocolFamily.PF_UNIX, Sock.SOCK_DGRAM, 0, sockets);
6666
return new UnixDatagramChannel[] {
67-
new UnixDatagramChannel(sockets[0], State.CONNECTED),
68-
new UnixDatagramChannel(sockets[1], State.CONNECTED)
67+
new UnixDatagramChannel(sockets[0], State.CONNECTED, true),
68+
new UnixDatagramChannel(sockets[1], State.CONNECTED, true)
6969
};
7070
}
7171

@@ -74,13 +74,14 @@ private UnixDatagramChannel() throws IOException {
7474
}
7575

7676
UnixDatagramChannel(int fd) {
77-
this(fd, State.IDLE);
77+
this(fd, State.IDLE, false);
7878
}
7979

80-
UnixDatagramChannel(int fd, State initialState) {
80+
UnixDatagramChannel(int fd, State initialState, boolean initialBoundState) {
8181
super(fd);
8282
stateLock.writeLock().lock();
8383
state = initialState;
84+
bound.set(initialBoundState);
8485
stateLock.writeLock().unlock();
8586
}
8687

src/test/java/jnr/unixsocket/BasicDatagramFunctionalityTest.java

+15-18
Original file line numberDiff line numberDiff line change
@@ -123,26 +123,23 @@ public void doubleBindTest() throws Exception {
123123
try {
124124
ch.bind(null);
125125
fail("Should have thrown AlreadyBoundException");
126-
} catch (AlreadyBoundException ex) {
127-
}
128-
try {
129-
ch.socket().bind(null);
130-
fail("Should have thrown SocketException");
131-
} catch (SocketException ex) {
132-
assertEquals("exception message", ex.getMessage(), "already bound");
126+
} catch (AlreadyBoundException abx) {
127+
try {
128+
ch.socket().bind(null);
129+
fail("Should have thrown SocketException");
130+
} catch (SocketException sx) {
131+
assertEquals("exception message", sx.getMessage(), "already bound");
132+
}
133133
}
134134
}
135135

136-
// Ignore for now @Test
137-
public void socketBufferTest() throws Exception {
138-
UnixDatagramChannel ch = UnixDatagramChannel.open();
139-
int rxs = ch.getOption(UnixSocketOptions.SO_RCVBUF);
140-
int txs = ch.getOption(UnixSocketOptions.SO_SNDBUF);
141-
System.out.println(String.format("rxbuf=%d, txbuf=%d", rxs, txs));
142-
ch.setOption(UnixSocketOptions.SO_RCVBUF, rxs - 100);
143-
ch.setOption(UnixSocketOptions.SO_SNDBUF, txs - 100);
144-
rxs = ch.getOption(UnixSocketOptions.SO_RCVBUF);
145-
txs = ch.getOption(UnixSocketOptions.SO_SNDBUF);
146-
System.out.println(String.format("rxbuf=%d, txbuf=%d", rxs, txs));
136+
@Test
137+
public void pairTest() throws Exception {
138+
UnixDatagramChannel[] sp = UnixDatagramChannel.pair();
139+
for (final UnixDatagramChannel ch : sp) {
140+
assertTrue("Channel is connected", ch.isConnected());
141+
assertTrue("Channel is bound", ch.isBound());
142+
assertFalse("Channel's socket is not closed", ch.socket().isClosed());
143+
}
147144
}
148145
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
* Copyright (C) 2016 Fritz Elfert
3+
*
4+
* (ported from https://github.com/softprops/unisockets/blob/master/unisockets-core/src/main/scala/Socket.scala)
5+
*
6+
* This file is part of the JNR project.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this file except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*
20+
*/
21+
package jnr.unixsocket;
22+
23+
import java.io.File;
24+
import java.io.IOException;
25+
import java.net.SocketAddress;
26+
import java.net.SocketException;
27+
import java.nio.ByteBuffer;
28+
import java.nio.CharBuffer;
29+
import java.nio.file.Files;
30+
import java.nio.channels.AlreadyBoundException;
31+
import java.nio.channels.DatagramChannel;
32+
import java.nio.charset.StandardCharsets;
33+
34+
import java.util.Set;
35+
36+
import org.junit.Assume;
37+
import org.junit.Ignore;
38+
import org.junit.Test;
39+
40+
import jnr.ffi.Platform;
41+
import jnr.ffi.Platform.OS;
42+
43+
import static junit.framework.Assert.*;
44+
45+
public class ChannelOptionsTest {
46+
47+
@Test
48+
public void readonlyDatagramChannelOptionTest() throws Exception {
49+
UnixDatagramChannel[] sp = UnixDatagramChannel.pair();
50+
UnixDatagramChannel ch = sp[0];
51+
Credentials c = ch.socket().getCredentials();
52+
try {
53+
// SO_PEERCRED is readonly
54+
ch.setOption(UnixSocketOptions.SO_PEERCRED, c);
55+
fail("Should have thrown AssertionError");
56+
} catch (AssertionError ae) {
57+
assertEquals("exception message", ae.getMessage(), "Option not found or not writable");
58+
}
59+
}
60+
61+
@Test
62+
public void readonlySocketChannelOptionTest() throws Exception {
63+
UnixSocketChannel[] sp = UnixSocketChannel.pair();
64+
UnixSocketChannel ch = sp[0];
65+
Credentials c = ch.socket().getCredentials();
66+
try {
67+
// SO_PEERCRED is readonly
68+
ch.setOption(UnixSocketOptions.SO_PEERCRED, c);
69+
fail("Should have thrown AssertionError");
70+
} catch (AssertionError ae) {
71+
assertEquals("exception message", ae.getMessage(), "Option not found or not writable");
72+
}
73+
}
74+
75+
@Test
76+
public void unsupportedChannelOptionTest() throws Exception {
77+
UnixDatagramChannel ch = UnixDatagramChannel.open();
78+
try {
79+
// SO_KEEPALIVE is suitable only for SOCK_STREAM sockets
80+
ch.getOption(UnixSocketOptions.SO_KEEPALIVE);
81+
fail("Should have thrown UnsupportedOperationException");
82+
} catch (UnsupportedOperationException uoe) {
83+
assertEquals("exception message", uoe.getMessage(), "'SO_KEEPALIVE' not supported");
84+
}
85+
}
86+
87+
@Test
88+
public void keepaliveOptionTest() throws Exception {
89+
UnixSocketChannel ch = UnixSocketChannel.open();
90+
boolean origValue = ch.getOption(UnixSocketOptions.SO_KEEPALIVE).booleanValue();
91+
assertEquals("Initial value of SO_KEEPALIVE", origValue, false);
92+
ch.setOption(UnixSocketOptions.SO_KEEPALIVE, Boolean.TRUE);
93+
boolean changedValue = ch.getOption(UnixSocketOptions.SO_KEEPALIVE).booleanValue();
94+
assertEquals("Changed value of SO_KEEPALIVE", changedValue, true);
95+
ch.setOption(UnixSocketOptions.SO_KEEPALIVE, Boolean.FALSE);
96+
changedValue = ch.getOption(UnixSocketOptions.SO_KEEPALIVE).booleanValue();
97+
assertEquals("Changed value of SO_KEEPALIVE", changedValue, origValue);
98+
}
99+
100+
@Test
101+
public void invalidOptionValueTest() throws Exception {
102+
UnixSocketChannel ch = UnixSocketChannel.open();
103+
try {
104+
ch.setOption(UnixSocketOptions.SO_RCVTIMEO, Integer.valueOf(-1));
105+
fail("Should have thrown IllegalArgumentException");
106+
} catch (IllegalArgumentException iae) {
107+
assertEquals("exception message", iae.getMessage(), "Invalid send/receive timeout");
108+
}
109+
try {
110+
ch.setOption(UnixSocketOptions.SO_SNDTIMEO, Integer.valueOf(-1));
111+
fail("Should have thrown IllegalArgumentException");
112+
} catch (IllegalArgumentException iae) {
113+
assertEquals("exception message", iae.getMessage(), "Invalid send/receive timeout");
114+
}
115+
try {
116+
ch.setOption(UnixSocketOptions.SO_RCVBUF, Integer.valueOf(-1));
117+
fail("Should have thrown IllegalArgumentException");
118+
} catch (IllegalArgumentException iae) {
119+
assertEquals("exception message", iae.getMessage(), "Invalid send/receive buffer size");
120+
}
121+
try {
122+
ch.setOption(UnixSocketOptions.SO_SNDBUF, Integer.valueOf(-1));
123+
fail("Should have thrown IllegalArgumentException");
124+
} catch (IllegalArgumentException iae) {
125+
assertEquals("exception message", iae.getMessage(), "Invalid send/receive buffer size");
126+
}
127+
}
128+
129+
@Test
130+
@Ignore
131+
// Linux doubles the values when setting. Check what other platforms do.
132+
public void socketBufferTest() throws Exception {
133+
UnixDatagramChannel ch = UnixDatagramChannel.open();
134+
int rxs = ch.getOption(UnixSocketOptions.SO_RCVBUF);
135+
int txs = ch.getOption(UnixSocketOptions.SO_SNDBUF);
136+
System.out.println(String.format("rxbuf=%d, txbuf=%d", rxs, txs));
137+
ch.setOption(UnixSocketOptions.SO_RCVBUF, rxs - 100);
138+
ch.setOption(UnixSocketOptions.SO_SNDBUF, txs - 100);
139+
rxs = ch.getOption(UnixSocketOptions.SO_RCVBUF);
140+
txs = ch.getOption(UnixSocketOptions.SO_SNDBUF);
141+
System.out.println(String.format("rxbuf=%d, txbuf=%d", rxs, txs));
142+
}
143+
}

0 commit comments

Comments
 (0)