Repository: relayrides/pushy
Pull request #608 (2018-04-29 15:48:07)

Add tests for channel class utility methods
This adds tests for the "get channel class for an event loop" utility methods. The tests themselves are straightforward, but the logistics of managing platform-specific dependencies are complicated.


Patch:
diff --git a/.travis.yml b/.travis.yml
index a3cc5872..902c49a6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,12 +1,24 @@
 language: java
-jdk:
-    - oraclejdk8
-env:
-    - PUSHY_SSL_PROVIDER=jdk
-    - PUSHY_SSL_PROVIDER=netty-tcnative
+
 matrix:
     include:
-        - jdk: openjdk7
-          env: PUSHY_SSL_PROVIDER=
+        - os: linux
+          jdk: oraclejdk8
+          env: PUSHY_SSL_PROVIDER=jdk
+
+        - os: linux
+          jdk: oraclejdk8
+          env: PUSHY_SSL_PROVIDER=netty-tcnative
+
+        - os: linux
+          jdk: openjdk7
           install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V -pl '!micrometer-metrics-listener'
           script: mvn test -B -pl '!micrometer-metrics-listener'
+
+        - os: osx
+          osx_image: xcode8.3
+          env: PUSHY_SSL_PROVIDER=jdk
+
+        - os: osx
+          osx_image: xcode8.3
+          env: PUSHY_SSL_PROVIDER=netty-tcnative
diff --git a/pom.xml b/pom.xml
index a5702dd2..8a5ee5a0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -97,6 +97,28 @@
                 <artifactId>slf4j-simple</artifactId>
                 <version>${slf4j.version}</version>
             </dependency>
+            <dependency>
+                <groupId>io.netty</groupId>
+                <artifactId>netty-transport-native-kqueue</artifactId>
+                <version>${netty.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.netty</groupId>
+                <artifactId>netty-transport-native-kqueue</artifactId>
+                <version>${netty.version}</version>
+                <classifier>osx-x86_64</classifier>
+            </dependency>
+            <dependency>
+                <groupId>io.netty</groupId>
+                <artifactId>netty-transport-native-epoll</artifactId>
+                <version>${netty.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.netty</groupId>
+                <artifactId>netty-transport-native-epoll</artifactId>
+                <version>${netty.version}</version>
+                <classifier>linux-x86_64</classifier>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
@@ -136,6 +158,7 @@
                     <target>1.7</target>
                 </configuration>
             </plugin>
+
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-source-plugin</artifactId>
diff --git a/pushy/pom.xml b/pushy/pom.xml
index 5385339a..4675d733 100644
--- a/pushy/pom.xml
+++ b/pushy/pom.xml
@@ -75,6 +75,16 @@
             <artifactId>slf4j-simple</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-transport-native-kqueue</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-transport-native-epoll</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
@@ -124,6 +134,7 @@
                 </dependency>
             </dependencies>
         </profile>
+
         <profile>
             <id>test-with-netty-tcnative</id>
             <activation>
@@ -140,5 +151,41 @@
                 </dependency>
             </dependencies>
         </profile>
+
+        <profile>
+            <id>test-with-native-kqueue</id>
+            <activation>
+                <property>
+                    <name>env.TRAVIS_OS_NAME</name>
+                    <value>osx</value>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>io.netty</groupId>
+                    <artifactId>netty-transport-native-kqueue</artifactId>
+                    <classifier>osx-x86_64</classifier>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+        </profile>
+
+        <profile>
+            <id>test-with-native-epoll</id>
+            <activation>
+                <property>
+                    <name>env.TRAVIS_OS_NAME</name>
+                    <value>linux</value>
+                </property>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>io.netty</groupId>
+                    <artifactId>netty-transport-native-epoll</artifactId>
+                    <classifier>linux-x86_64</classifier>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+        </profile>
     </profiles>
 </project>
diff --git a/pushy/src/main/java/com/turo/pushy/apns/server/BaseHttp2Server.java b/pushy/src/main/java/com/turo/pushy/apns/server/BaseHttp2Server.java
index 38b2277c..b807640b 100644
--- a/pushy/src/main/java/com/turo/pushy/apns/server/BaseHttp2Server.java
+++ b/pushy/src/main/java/com/turo/pushy/apns/server/BaseHttp2Server.java
@@ -78,7 +78,7 @@ abstract class BaseHttp2Server {
             this.shouldShutDownEventLoopGroup = true;
         }
 
-        this.bootstrap.channel(ServerSocketChannelClassUtil.getServerSocketChannelClass(this.bootstrap.config().group()));
+        this.bootstrap.channel(ServerChannelClassUtil.getServerSocketChannelClass(this.bootstrap.config().group()));
         this.bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
 
             @Override
diff --git a/pushy/src/main/java/com/turo/pushy/apns/server/ServerSocketChannelClassUtil.java b/pushy/src/main/java/com/turo/pushy/apns/server/ServerChannelClassUtil.java
similarity index 98%
rename from pushy/src/main/java/com/turo/pushy/apns/server/ServerSocketChannelClassUtil.java
rename to pushy/src/main/java/com/turo/pushy/apns/server/ServerChannelClassUtil.java
index 9e6935d4..df407f56 100644
--- a/pushy/src/main/java/com/turo/pushy/apns/server/ServerSocketChannelClassUtil.java
+++ b/pushy/src/main/java/com/turo/pushy/apns/server/ServerChannelClassUtil.java
@@ -29,7 +29,7 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 
-class ServerSocketChannelClassUtil {
+class ServerChannelClassUtil {
 
     private static final Map<String, String> SERVER_SOCKET_CHANNEL_CLASSES = new HashMap<>();
 


Test patch:
diff --git a/pushy/src/test/java/com/turo/pushy/apns/ClientChannelClassUtilTest.java b/pushy/src/test/java/com/turo/pushy/apns/ClientChannelClassUtilTest.java
new file mode 100644
index 00000000..04003b58
--- /dev/null
+++ b/pushy/src/test/java/com/turo/pushy/apns/ClientChannelClassUtilTest.java
@@ -0,0 +1,115 @@
+package com.turo.pushy.apns;
+
+import io.netty.channel.epoll.Epoll;
+import io.netty.channel.epoll.EpollDatagramChannel;
+import io.netty.channel.epoll.EpollEventLoopGroup;
+import io.netty.channel.epoll.EpollSocketChannel;
+import io.netty.channel.kqueue.KQueue;
+import io.netty.channel.kqueue.KQueueDatagramChannel;
+import io.netty.channel.kqueue.KQueueEventLoopGroup;
+import io.netty.channel.kqueue.KQueueSocketChannel;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.oio.OioEventLoopGroup;
+import io.netty.channel.socket.nio.NioDatagramChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.channel.socket.oio.OioDatagramChannel;
+import io.netty.channel.socket.oio.OioSocketChannel;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeTrue;
+
+public class ClientChannelClassUtilTest {
+
+    @Test
+    public void testGetCoreSocketChannelClass() {
+        final NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(1);
+        final OioEventLoopGroup oioEventLoopGroup = new OioEventLoopGroup(1);
+
+        try {
+            assertEquals(NioSocketChannel.class, ClientChannelClassUtil.getSocketChannelClass(nioEventLoopGroup));
+            assertEquals(OioSocketChannel.class, ClientChannelClassUtil.getSocketChannelClass(oioEventLoopGroup));
+        } finally {
+            nioEventLoopGroup.shutdownGracefully();
+            oioEventLoopGroup.shutdownGracefully();
+        }
+    }
+
+    @Test
+    public void testGetKqueueSocketChannelClass() {
+        final String unavailabilityMessage =
+                KQueue.unavailabilityCause() != null ? KQueue.unavailabilityCause().getMessage() : null;
+
+        assumeTrue("KQueue not available: " + unavailabilityMessage, KQueue.isAvailable());
+
+        final KQueueEventLoopGroup kQueueEventLoopGroup = new KQueueEventLoopGroup(1);
+
+        try {
+            assertEquals(KQueueSocketChannel.class, ClientChannelClassUtil.getSocketChannelClass(kQueueEventLoopGroup));
+        } finally {
+            kQueueEventLoopGroup.shutdownGracefully();
+        }
+    }
+
+    @Test
+    public void testGetEpollSocketChannelClass() {
+        final String unavailabilityMessage =
+                Epoll.unavailabilityCause() != null ? Epoll.unavailabilityCause().getMessage() : null;
+
+        assumeTrue("Epoll not available: " + unavailabilityMessage, Epoll.isAvailable());
+
+        final EpollEventLoopGroup epollEventLoopGroup = new EpollEventLoopGroup(1);
+
+        try {
+            assertEquals(EpollSocketChannel.class, ClientChannelClassUtil.getSocketChannelClass(epollEventLoopGroup));
+        } finally {
+            epollEventLoopGroup.shutdownGracefully();
+        }
+    }
+
+    @Test
+    public void testGetCoreDatagramChannelClass() {
+        final NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(1);
+        final OioEventLoopGroup oioEventLoopGroup = new OioEventLoopGroup(1);
+
+        try {
+            assertEquals(NioDatagramChannel.class, ClientChannelClassUtil.getDatagramChannelClass(nioEventLoopGroup));
+            assertEquals(OioDatagramChannel.class, ClientChannelClassUtil.getDatagramChannelClass(oioEventLoopGroup));
+        } finally {
+            nioEventLoopGroup.shutdownGracefully();
+            oioEventLoopGroup.shutdownGracefully();
+        }
+    }
+
+    @Test
+    public void testGetKqueueDatagramChannelClass() {
+        final String unavailabilityMessage =
+                KQueue.unavailabilityCause() != null ? KQueue.unavailabilityCause().getMessage() : null;
+
+        assumeTrue("KQueue not available: " + unavailabilityMessage, KQueue.isAvailable());
+
+        final KQueueEventLoopGroup kQueueEventLoopGroup = new KQueueEventLoopGroup(1);
+
+        try {
+            assertEquals(KQueueDatagramChannel.class, ClientChannelClassUtil.getDatagramChannelClass(kQueueEventLoopGroup));
+        } finally {
+            kQueueEventLoopGroup.shutdownGracefully();
+        }
+    }
+
+    @Test
+    public void testGetEpollDatagramChannelClass() {
+        final String unavailabilityMessage =
+                Epoll.unavailabilityCause() != null ? Epoll.unavailabilityCause().getMessage() : null;
+
+        assumeTrue("Epoll not available: " + unavailabilityMessage, Epoll.isAvailable());
+
+        final EpollEventLoopGroup epollEventLoopGroup = new EpollEventLoopGroup(1);
+
+        try {
+            assertEquals(EpollDatagramChannel.class, ClientChannelClassUtil.getDatagramChannelClass(epollEventLoopGroup));
+        } finally {
+            epollEventLoopGroup.shutdownGracefully();
+        }
+    }
+}
diff --git a/pushy/src/test/java/com/turo/pushy/apns/server/ServerChannelClassUtilTest.java b/pushy/src/test/java/com/turo/pushy/apns/server/ServerChannelClassUtilTest.java
new file mode 100644
index 00000000..e175e219
--- /dev/null
+++ b/pushy/src/test/java/com/turo/pushy/apns/server/ServerChannelClassUtilTest.java
@@ -0,0 +1,65 @@
+package com.turo.pushy.apns.server;
+
+import io.netty.channel.epoll.Epoll;
+import io.netty.channel.epoll.EpollEventLoopGroup;
+import io.netty.channel.epoll.EpollServerSocketChannel;
+import io.netty.channel.kqueue.KQueue;
+import io.netty.channel.kqueue.KQueueEventLoopGroup;
+import io.netty.channel.kqueue.KQueueServerSocketChannel;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.oio.OioEventLoopGroup;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.channel.socket.oio.OioServerSocketChannel;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeTrue;
+
+public class ServerChannelClassUtilTest {
+
+    @Test
+    public void testGetCoreSocketChannelClass() {
+        final NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(1);
+        final OioEventLoopGroup oioEventLoopGroup = new OioEventLoopGroup(1);
+
+        try {
+            assertEquals(NioServerSocketChannel.class, ServerChannelClassUtil.getServerSocketChannelClass(nioEventLoopGroup));
+            assertEquals(OioServerSocketChannel.class, ServerChannelClassUtil.getServerSocketChannelClass(oioEventLoopGroup));
+        } finally {
+            nioEventLoopGroup.shutdownGracefully();
+            oioEventLoopGroup.shutdownGracefully();
+        }
+    }
+
+    @Test
+    public void testGetKqueueSocketChannelClass() {
+        final String unavailabilityMessage =
+                KQueue.unavailabilityCause() != null ? KQueue.unavailabilityCause().getMessage() : null;
+
+        assumeTrue("KQueue not available: " + unavailabilityMessage, KQueue.isAvailable());
+
+        final KQueueEventLoopGroup kQueueEventLoopGroup = new KQueueEventLoopGroup(1);
+
+        try {
+            assertEquals(KQueueServerSocketChannel.class, ServerChannelClassUtil.getServerSocketChannelClass(kQueueEventLoopGroup));
+        } finally {
+            kQueueEventLoopGroup.shutdownGracefully();
+        }
+    }
+
+    @Test
+    public void testGetEpollSocketChannelClass() {
+        final String unavailabilityMessage =
+                Epoll.unavailabilityCause() != null ? Epoll.unavailabilityCause().getMessage() : null;
+
+        assumeTrue("Epoll not available: " + unavailabilityMessage, Epoll.isAvailable());
+
+        final EpollEventLoopGroup epollEventLoopGroup = new EpollEventLoopGroup(1);
+
+        try {
+            assertEquals(EpollServerSocketChannel.class, ServerChannelClassUtil.getServerSocketChannelClass(epollEventLoopGroup));
+        } finally {
+            epollEventLoopGroup.shutdownGracefully();
+        }
+    }
+}