/* * Quasar: lightweight threads and actors for the JVM. * Copyright (c) 2013-2015, Parallel Universe Software Co. All rights reserved. * * This program and the accompanying materials are dual-licensed under * either the terms of the Eclipse Public License v1.0 as published by * the Eclipse Foundation * * or (per the licensee's choosing) * * under the terms of the GNU Lesser General Public License version 3.0 * as published by the Free Software Foundation. */ package co.paralleluniverse.fibers.io; import co.paralleluniverse.common.test.TestUtil; import co.paralleluniverse.fibers.Fiber; import co.paralleluniverse.fibers.FiberForkJoinScheduler; import co.paralleluniverse.fibers.FiberScheduler; import co.paralleluniverse.fibers.SuspendExecution; import co.paralleluniverse.strands.SuspendableRunnable; import co.paralleluniverse.strands.channels.Channels; import co.paralleluniverse.strands.channels.IntChannel; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.nio.file.Paths; import static java.nio.file.StandardOpenOption.*; import static org.hamcrest.CoreMatchers.*; import org.junit.After; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; import org.junit.rules.TestRule; /** * * @author pron */ public class FiberAsyncIOTest { @Rule public TestName name = new TestName(); @Rule public TestRule watchman = TestUtil.WATCHMAN; private static final int PORT = 1234; private static final Charset charset = Charset.forName("UTF-8"); private static final CharsetEncoder encoder = charset.newEncoder(); private static final CharsetDecoder decoder = charset.newDecoder(); private final FiberScheduler scheduler; public FiberAsyncIOTest() { scheduler = new FiberForkJoinScheduler("test", 4, null, false); } @Before public void setUp() { } @After public void tearDown() { } @Test public void testFiberAsyncSocket() throws Exception { final IntChannel sync = Channels.newIntChannel(0); final Fiber server = new Fiber(scheduler, new SuspendableRunnable() { @Override public void run() throws SuspendExecution, InterruptedException { try (FiberServerSocketChannel socket = FiberServerSocketChannel.open().bind(new InetSocketAddress(PORT))) { sync.send(0); // Start client try (FiberSocketChannel ch = socket.accept()) { ByteBuffer buf = ByteBuffer.allocateDirect(1024); // long-typed reqeust/response int n = ch.read(buf); assertThat(n, is(8)); // we assume the message is sent in a single packet buf.flip(); long req = buf.getLong(); assertThat(req, is(12345678L)); buf.clear(); long res = 87654321L; buf.putLong(res); buf.flip(); n = ch.write(buf); assertThat(n, is(8)); // String reqeust/response buf.clear(); ch.read(buf); // we assume the message is sent in a single packet buf.flip(); String req2 = decoder.decode(buf).toString(); assertThat(req2, is("my request")); String res2 = "my response"; ch.write(encoder.encode(CharBuffer.wrap(res2))); } } catch (IOException e) { throw new RuntimeException(e); } } }).start(); final Fiber client = new Fiber(scheduler, new SuspendableRunnable() { @Override public void run() throws SuspendExecution { try { sync.receive(); // Wait that the server is ready } catch (InterruptedException ex) { // This should never happen throw new AssertionError(ex); } try (FiberSocketChannel ch = FiberSocketChannel.open(new InetSocketAddress(PORT))) { ByteBuffer buf = ByteBuffer.allocateDirect(1024); // long-typed reqeust/response long req = 12345678L; buf.putLong(req); buf.flip(); int n = ch.write(buf); assertThat(n, is(8)); buf.clear(); n = ch.read(buf); assertThat(n, is(8)); // we assume the message is sent in a single packet buf.flip(); long res = buf.getLong(); assertThat(res, is(87654321L)); // String reqeust/response String req2 = "my request"; ch.write(encoder.encode(CharBuffer.wrap(req2))); buf.clear(); ch.read(buf); // we assume the message is sent in a single packet buf.flip(); String res2 = decoder.decode(buf).toString(); assertThat(res2, is("my response")); // verify that the server has closed the socket buf.clear(); n = ch.read(buf); assertThat(n, is(-1)); } catch (IOException e) { throw new RuntimeException(e); } } }).start(); client.join(); server.join(); } @Test public void testFiberAsyncFile() throws Exception { new Fiber(scheduler, new SuspendableRunnable() { @Override public void run() throws SuspendExecution { try (FiberFileChannel ch = FiberFileChannel.open(Paths.get(System.getProperty("user.home"), "fibertest.bin"), READ, WRITE, CREATE, TRUNCATE_EXISTING)) { ByteBuffer buf = ByteBuffer.allocateDirect(1024); String text = "this is my text blahblah"; ch.write(encoder.encode(CharBuffer.wrap(text))); ch.position(0); ch.read(buf); buf.flip(); String read = decoder.decode(buf).toString(); assertThat(read, equalTo(text)); buf.clear(); ch.position(5); ch.read(buf); buf.flip(); read = decoder.decode(buf).toString(); assertThat(read, equalTo(text.substring(5))); } catch (IOException e) { throw new RuntimeException(e); } } }).start().join(); } }