Package org.voltdb.network

Source Code of org.voltdb.network.NIOWriteStreamTest$MockPort

/* This file is part of VoltDB.
* Copyright (C) 2008-2010 VoltDB L.L.C.
*
* This file contains original code and/or modifications of original code.
* Any modifications made by VoltDB L.L.C. are licensed under the following
* terms and conditions:
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/* Copyright (C) 2008
* Evan Jones
* Massachusetts Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

package org.voltdb.network;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.GatheringByteChannel;
import junit.framework.*;
import java.nio.channels.SelectionKey;
import org.voltdb.utils.DBBPool;
import org.voltdb.utils.EstTime;
import org.voltdb.utils.EstTimeUpdater;

public class NIOWriteStreamTest extends TestCase {

    private static class MockPort extends VoltPort {

        @Override
        public String toString() {
            return null;
        }

        public MockPort() {
            super(null, null, 2048, "");
        }

        @Override
        public void setInterests(int opsToAdd, int opsToRemove) {
            this.opsToAdd = opsToAdd;
        }

        public boolean checkWriteSet() {
            if (opsToAdd == SelectionKey.OP_WRITE) {
                opsToAdd = 0;
                return true;
            }
            return false;
        }

        int opsToAdd;
    }

    DBBPool pool;

    @Override
    public void setUp() {
        pool = new DBBPool();
    }

    @Override
    public void tearDown() {
        pool.clear();
    }

    /**
     * Mock channel that will either consume all, some or no
     * bytes from the buffer.
     */
    private static class MockChannel implements GatheringByteChannel {
        MockChannel(int behavior) {
            m_behavior = behavior;
        }

        private boolean wroteSizeZero = false;
        private boolean didOversizeWrite = false;
        private boolean wrotePartial = false;

        @Override
        public int write(ByteBuffer src) throws IOException {
            if (!m_open) throw new IOException();

            if (!src.hasRemaining()) {
                wroteSizeZero = true;
            }

            if (!src.isDirect()) {
                if (src.remaining() > NIOWriteStream.MAX_GATHERING_WRITE) {
                    didOversizeWrite = true;
                }
            }
            if (m_behavior == SINK) {
                int remaining = src.remaining();
                src.position(src.limit());
                return remaining;
            }
            else if (m_behavior == FULL) {
                return 0;
            }
            else if (m_behavior == PARTIAL) {
                if (wrotePartial) {
                    return 0;
                } else {
                    wrotePartial = true;
                }
                ByteBuffer copy = ByteBuffer.allocate(src.remaining());
                src.get(copy.array(), 0, src.remaining()/2);
                return src.remaining();
            }
            assert(false);
            return -1;
        }

        public long write(ByteBuffer src[]) throws IOException {
            if (!m_open) throw new IOException();

            if (m_behavior == SINK) {
                int remaining = src[0].remaining();
                src[0].position(src[0].limit());
                return remaining;
            }
            else if (m_behavior == FULL) {
                return 0;
            }
            else if (m_behavior == PARTIAL) {
                if (wrotePartial) {
                    return 0;
                } else {
                    wrotePartial = true;
                }
                ByteBuffer copy = ByteBuffer.allocate(src[0].remaining());
                src[0].get(copy.array(), 0, src[0].remaining()/2);
                return src[0].remaining();
            }
            assert(false);
            return -1;
        }

        @Override
        public void close() throws IOException {
            // TODO Auto-generated method stub
        }

        @Override
        public boolean isOpen() {
            return m_open;
        }

        public boolean m_open = true;

        public int m_behavior;
        public static int SINK = 0;     // accept all data
        public static int FULL = 1;     // accept no data
        public static int PARTIAL = 2// accept some data
        @Override
        public long write(ByteBuffer[] srcs, int offset, int length)
                throws IOException {
            // TODO Auto-generated method stub
            return 0;
        }
    }


    public void testSink() throws IOException {
        MockChannel channel = new MockChannel(MockChannel.SINK);
        MockPort port = new MockPort();
        NIOWriteStream wstream = new NIOWriteStream(port);
        assertTrue(wstream.isEmpty());

        ByteBuffer tmp = ByteBuffer.allocate(5);
        tmp.put((byte) 1);
        tmp.put((byte) 2);
        tmp.flip();
        assertTrue(wstream.enqueue(tmp));
        assertTrue(port.checkWriteSet());
        assertEquals(2, wstream.drainTo(channel, wstream.swapAndSerializeQueuedWrites(pool)));
        assertTrue(wstream.isEmpty());
        wstream.shutdown();
        port.toString();
    }

    public void testFull() throws IOException {
        MockChannel channel = new MockChannel(MockChannel.FULL);
        MockPort port = new MockPort();
        NIOWriteStream wstream = new NIOWriteStream(port);
        assertTrue(wstream.isEmpty());

        ByteBuffer tmp = ByteBuffer.allocate(5);
        tmp.put((byte)1);
        tmp.put((byte)2);
        tmp.put((byte)3);
        tmp.put((byte)4);
        tmp.flip();
        assertTrue(wstream.enqueue(tmp));
        assertTrue(port.checkWriteSet());
        assertEquals(0, wstream.drainTo(channel, wstream.swapAndSerializeQueuedWrites(pool)));
        assertFalse(wstream.isEmpty());

        channel.m_behavior = MockChannel.SINK;
        int wrote = wstream.drainTo(channel, wstream.swapAndSerializeQueuedWrites(pool));
        assertEquals(4, wrote);
        assertTrue(wstream.isEmpty());
        wstream.shutdown();
    }

    public void testPartial() throws IOException {
        MockChannel channel = new MockChannel(MockChannel.PARTIAL);
        MockPort port = new MockPort();
        NIOWriteStream wstream = new NIOWriteStream(port);
        assertTrue(wstream.isEmpty());

        ByteBuffer tmp = ByteBuffer.allocate(5);
        tmp.put((byte)1);
        tmp.put((byte)2);
        tmp.put((byte)3);
        tmp.put((byte)4);
        tmp.flip();
        assertTrue(wstream.enqueue(tmp));
        assertTrue(port.checkWriteSet());
        int wrote = wstream.drainTo(channel, wstream.swapAndSerializeQueuedWrites(pool));
        assertFalse(wstream.isEmpty());
        assertEquals(2, wrote);

        channel.wrotePartial = false;

        ByteBuffer tmp2 = ByteBuffer.allocate(4);
        tmp2.put((byte)5);
        tmp2.put((byte)6);
        tmp2.put((byte)7);
        tmp2.put((byte)8);
        tmp2.flip();
        wstream.enqueue(tmp2);
        org.voltdb.utils.DBBPool.BBContainer containers[] = wstream.swapAndSerializeQueuedWrites(pool);
        wrote += wstream.drainTo( channel, containers);
        assertFalse(wstream.isEmpty());
        // wrote half of half of the first buffer (note +=)
        assertEquals(3, wrote);

        channel.m_behavior = MockChannel.SINK;
        wrote += wstream.drainTo( channel, wstream.swapAndSerializeQueuedWrites(pool));
        assertEquals(8, wrote);
        assertTrue(wstream.isEmpty());
        wstream.shutdown();
    }

    public void testClosed() throws IOException {
        MockChannel channel = new MockChannel(MockChannel.FULL);
        MockPort port = new MockPort();
        NIOWriteStream wstream = new NIOWriteStream(port);

        ByteBuffer tmp = ByteBuffer.allocate(5);
        tmp.put((byte)1);
        tmp.put((byte)2);
        tmp.put((byte)3);
        tmp.put((byte)4);
        tmp.flip();
        assertTrue(wstream.enqueue(tmp));
        assertTrue(port.checkWriteSet());
        int closed = wstream.drainTo(channel, wstream.swapAndSerializeQueuedWrites(pool));
        assertEquals(closed, 0);

        channel.m_open = false;

        boolean threwException = false;
        try {
            assertEquals( -1, wstream.drainTo( channel, wstream.swapAndSerializeQueuedWrites(pool)));
        } catch (IOException e) {
            threwException = true;
        }
        assertTrue(threwException);
        wstream.shutdown();

    }

    public void testLargeNonDirectWrite() throws IOException {
        MockChannel channel = new MockChannel(MockChannel.SINK);
        MockPort port = new MockPort();
        NIOWriteStream wstream = new NIOWriteStream(port);

        ByteBuffer tmp = ByteBuffer.allocate(NIOWriteStream.MAX_GATHERING_WRITE * 2);

        assertTrue(wstream.enqueue(tmp));
        assertTrue(port.checkWriteSet());
        int written = wstream.drainTo( channel, wstream.swapAndSerializeQueuedWrites(pool));
        assertEquals( NIOWriteStream.MAX_GATHERING_WRITE * 2, written);
        assertFalse(channel.didOversizeWrite);
        assertTrue(channel.wroteSizeZero);
        wstream.shutdown();
    }

    public void testLastWriteDelta() throws Exception {
        final MockChannel channel = new MockChannel(MockChannel.SINK);
        MockPort port = new MockPort();
        NIOWriteStream wstream = new NIOWriteStream(port);

        assertEquals( 0, wstream.calculatePendingWriteDelta(999));

        EstTimeUpdater.update(System.currentTimeMillis());

        /**
         * Test the basic write and drain
         */
        final ByteBuffer b = ByteBuffer.allocate(5);
        wstream.enqueue(b.duplicate());
        assertEquals( 5, wstream.calculatePendingWriteDelta(EstTime.currentTimeMillis() + 5));
        wstream.drainTo( channel, wstream.swapAndSerializeQueuedWrites(pool));
        assertEquals( 0, wstream.calculatePendingWriteDelta(EstTime.currentTimeMillis() + 5));

        Thread.sleep(20);
        EstTimeUpdater.update(System.currentTimeMillis());

        wstream.enqueue(b.duplicate());
        assertEquals( 5, wstream.calculatePendingWriteDelta(EstTime.currentTimeMillis() + 5));
        wstream.enqueue(b.duplicate());
        assertEquals( 5, wstream.calculatePendingWriteDelta(EstTime.currentTimeMillis() + 5));
        channel.m_behavior = MockChannel.PARTIAL;
        wstream.drainTo( channel, wstream.swapAndSerializeQueuedWrites(pool));
        assertEquals( 5, wstream.calculatePendingWriteDelta(EstTime.currentTimeMillis() + 5));

        wstream.shutdown();
    }

}
TOP

Related Classes of org.voltdb.network.NIOWriteStreamTest$MockPort

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.