1 /*
2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 /* @test
27  * @bug 6350055
28  * @run testng AtomicUpdates
29  * @summary Unit test for SelectionKey interestOpsOr and interestOpsAnd
30  */
31 
32 import java.io.Closeable;
33 import java.io.IOException;
34 import java.net.InetAddress;
35 import java.net.InetSocketAddress;
36 import java.nio.channels.CancelledKeyException;
37 import java.nio.channels.SelectableChannel;
38 import java.nio.channels.SelectionKey;
39 import java.nio.channels.Selector;
40 import java.nio.channels.ServerSocketChannel;
41 import java.nio.channels.SocketChannel;
42 import org.testng.annotations.Test;
43 
44 import static java.nio.channels.SelectionKey.OP_READ;
45 import static java.nio.channels.SelectionKey.OP_WRITE;
46 import static java.nio.channels.SelectionKey.OP_CONNECT;
47 import static java.nio.channels.SelectionKey.OP_ACCEPT;
48 import static org.testng.Assert.*;
49 
50 @Test
51 public class AtomicUpdates {
52 
keyFor(SocketChannel sc)53     private SelectionKey keyFor(SocketChannel sc) {
54         return new SelectionKey() {
55             private int ops;
56             private boolean invalid;
57             private void ensureValid() {
58                 if (!isValid())
59                     throw new CancelledKeyException();
60             }
61             @Override
62             public SelectableChannel channel() {
63                 return sc;
64             }
65             @Override
66             public Selector selector() {
67                 throw new RuntimeException();
68             }
69             @Override
70             public boolean isValid() {
71                 return !invalid;
72             }
73             @Override
74             public void cancel() {
75                 invalid = true;
76             }
77             @Override
78             public int interestOps() {
79                 ensureValid();
80                 return ops;
81             }
82             @Override
83             public SelectionKey interestOps(int ops) {
84                 ensureValid();
85                 if ((ops & ~channel().validOps()) != 0)
86                     throw new IllegalArgumentException();
87                 this.ops = ops;
88                 return this;
89             }
90             @Override
91             public int readyOps() {
92                 ensureValid();
93                 return 0;
94             }
95         };
96     }
97 
test(SelectionKey key)98     private void test(SelectionKey key) {
99         assertTrue(key.channel() instanceof SocketChannel);
100         key.interestOps(0);
101 
102         // 0 -> 0
103         int previous = key.interestOpsOr(0);
104         assertTrue(previous == 0);
105         assertTrue(key.interestOps() == 0);
106 
107         // 0 -> OP_CONNECT
108         previous = key.interestOpsOr(OP_CONNECT);
109         assertTrue(previous == 0);
110         assertTrue(key.interestOps() == OP_CONNECT);
111 
112         // OP_CONNECT -> OP_CONNECT
113         previous = key.interestOpsOr(0);
114         assertTrue(previous == OP_CONNECT);
115         assertTrue(key.interestOps() == OP_CONNECT);
116 
117         // OP_CONNECT -> OP_CONNECT | OP_READ | OP_WRITE
118         previous = key.interestOpsOr(OP_READ | OP_WRITE);
119         assertTrue(previous == OP_CONNECT);
120         assertTrue(key.interestOps() == (OP_CONNECT | OP_READ | OP_WRITE));
121 
122         // OP_CONNECT | OP_READ | OP_WRITE -> OP_CONNECT
123         previous = key.interestOpsAnd(~(OP_READ | OP_WRITE));
124         assertTrue(previous == (OP_CONNECT | OP_READ | OP_WRITE));
125         assertTrue(key.interestOps() == OP_CONNECT);
126 
127         // OP_CONNECT -> 0
128         previous = key.interestOpsAnd(~OP_CONNECT);
129         assertTrue(previous == OP_CONNECT);
130         assertTrue(key.interestOps() == 0);
131 
132         // OP_READ | OP_WRITE -> OP_READ | OP_WRITE
133         key.interestOps(OP_READ | OP_WRITE);
134         previous = key.interestOpsAnd(~OP_ACCEPT);
135         assertTrue(previous == (OP_READ | OP_WRITE));
136         assertTrue(key.interestOps() == (OP_READ | OP_WRITE));
137 
138         // OP_READ | OP_WRITE -> 0
139         previous = key.interestOpsAnd(0);
140         assertTrue(previous == (OP_READ | OP_WRITE));
141         assertTrue(key.interestOps() == 0);
142 
143         // 0 -> 0
144         previous = key.interestOpsAnd(0);
145         assertTrue(previous == 0);
146         assertTrue(key.interestOps() == 0);
147 
148         try {
149             key.interestOpsOr(OP_ACCEPT);
150             fail("IllegalArgumentException expected");
151         } catch (IllegalArgumentException expected) { }
152 
153         key.cancel();
154         try {
155             key.interestOpsOr(OP_READ);
156             fail("CancelledKeyException expected");
157         } catch (CancelledKeyException expected) { }
158         try {
159             key.interestOpsAnd(~OP_READ);
160             fail("CancelledKeyException expected");
161         } catch (CancelledKeyException expected) { }
162     }
163 
164     /**
165      * Test default implementation of interestOpsOr/interestOpsAnd
166      */
testDefaultImplementation()167     public void testDefaultImplementation() throws Exception {
168         try (SocketChannel sc = SocketChannel.open()) {
169             SelectionKey key = keyFor(sc);
170             test(key);
171         }
172     }
173 
174     /**
175      * Test the default provider implementation of SelectionKey.
176      */
testNioImplementation()177     public void testNioImplementation() throws Exception {
178         try (SocketChannel sc = SocketChannel.open();
179              Selector sel = Selector.open()) {
180             sc.configureBlocking(false);
181             SelectionKey key = sc.register(sel, 0);
182             test(key);
183         }
184     }
185 }
186 
187