edu.illinois.imunit.examples.hadoop.TestRPC.java Source code

Java tutorial

Introduction

Here is the source code for edu.illinois.imunit.examples.hadoop.TestRPC.java

Source

package edu.illinois.imunit.examples.hadoop;

import org.junit.runner.RunWith;
import edu.illinois.imunit.IMUnitRunner;
import static edu.illinois.imunit.IMUnit.fireEvent;

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.io.IOException;
import java.net.InetSocketAddress;

//import org.apache.commons.logging.Log;
//import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.ipc.RPC;
import org.apache.hadoop.ipc.VersionedProtocol;
import org.apache.hadoop.ipc.RPC.Server;
import org.apache.hadoop.net.NetUtils;
import org.junit.Test;
import static org.junit.Assert.*;
import edu.illinois.imunit.Schedule;
import edu.illinois.imunit.Schedules;

/** Unit tests for RPC. */
@RunWith(IMUnitRunner.class)
public class TestRPC {
    private static final String ADDRESS = "0.0.0.0";

    //  public static final Log LOG =
    //    LogFactory.getLog(TestRPC.class);

    private static Configuration conf = new Configuration();

    int datasize = 1024 * 100;
    int numThreads = 50;

    public interface TestProtocol extends VersionedProtocol {
        public static final long versionID = 1L;

        void ping() throws IOException;

        void slowPing(boolean shouldSlow) throws IOException;

        String echo(String value) throws IOException;

        String[] echo(String[] value) throws IOException;

        Writable echo(Writable value) throws IOException;

        int add(int v1, int v2) throws IOException;

        int add(int[] values) throws IOException;

        int error() throws IOException;

        void testServerGet() throws IOException;

        int[] exchange(int[] values) throws IOException;
    }

    public static class TestImpl implements TestProtocol {
        int fastPingCounter = 0;

        public long getProtocolVersion(String protocol, long clientVersion) {
            return TestProtocol.versionID;
        }

        public void ping() {
        }

        public synchronized void slowPing(boolean shouldSlow) {
            if (shouldSlow) {
                while (fastPingCounter < 2) {
                    try {
                        wait(); // slow response until two fast pings happened
                    } catch (InterruptedException ignored) {
                    }
                }
                fastPingCounter -= 2;
            } else {
                fastPingCounter++;
                notify();
            }
        }

        public String echo(String value) throws IOException {
            return value;
        }

        public String[] echo(String[] values) throws IOException {
            return values;
        }

        public Writable echo(Writable writable) {
            return writable;
        }

        public int add(int v1, int v2) {
            return v1 + v2;
        }

        public int add(int[] values) {
            int sum = 0;
            for (int i = 0; i < values.length; i++) {
                sum += values[i];
            }
            return sum;
        }

        public int error() throws IOException {
            throw new IOException("bobo");
        }

        public void testServerGet() throws IOException {
            if (!(Server.get() instanceof RPC.Server)) {
                throw new IOException("Server.get() failed");
            }
        }

        public int[] exchange(int[] values) {
            for (int i = 0; i < values.length; i++) {
                values[i] = i;
            }
            return values;
        }
    }

    //
    // an object that does a bunch of transactions
    //
    static class Transactions implements Runnable {
        int datasize;
        TestProtocol proxy;

        Transactions(TestProtocol proxy, int datasize) {
            this.proxy = proxy;
            this.datasize = datasize;
        }

        // do two RPC that transfers data.
        public void run() {
            int[] indata = new int[datasize];
            int[] outdata = null;
            int val = 0;
            try {
                outdata = proxy.exchange(indata);
                val = proxy.add(1, 2);
            } catch (IOException e) {
                assertTrue("Exception from RPC exchange() " + e, false);
            }
            assertEquals(indata.length, outdata.length);
            assertEquals(val, 3);
            for (int i = 0; i < outdata.length; i++) {
                assertEquals(outdata[i], i);
            }
        }
    }

    //
    // A class that does an RPC but does not read its response.
    //
    static class SlowRPC implements Runnable {
        private TestProtocol proxy;
        private volatile boolean done;

        SlowRPC(TestProtocol proxy) {
            this.proxy = proxy;
            done = false;
        }

        boolean isDone() {
            return done;
        }

        public void run() {
            try {
                proxy.slowPing(true); // this would hang until two fast pings happened
                fireEvent("slowrpcDone");
                done = true;
            } catch (IOException e) {
                assertTrue("SlowRPC ping exception " + e, false);
            }
        }
    }

    @Test
    @Schedule(name = "slowDone", value = "slowrpcDone@SlowRPC->beforeStop@main")
    public void testSlowRpc() throws Exception {
        System.out.println("Testing Slow RPC");
        // create a server with two handlers
        Server server = RPC.getServer(TestProtocol.class, new TestImpl(), ADDRESS, 0, 2, false, conf, null);
        TestProtocol proxy = null;

        try {
            server.start();

            InetSocketAddress addr = NetUtils.getConnectAddress(server);

            // create a client
            proxy = (TestProtocol) RPC.getProxy(TestProtocol.class, TestProtocol.versionID, addr, conf);

            SlowRPC slowrpc = new SlowRPC(proxy);
            Thread thread = new Thread(slowrpc, "SlowRPC");
            thread.start(); // send a slow RPC, which won't return until two fast pings
            assertTrue("slowDone", !slowrpc.isDone());

            proxy.slowPing(false); // first fast ping

            // verify that the first RPC is still stuck
            assertTrue("slowDone", !slowrpc.isDone());

            proxy.slowPing(false); // second fast ping

            // Now the slow ping should be able to be executed

            //Original code :
            //OPWAIT while (!slowrpc.isDone()) {
            //OPWAIT  System.out.println("Waiting for slow RPC to get done.");
            //OPWAIT  try {
            //    Thread.sleep(1000);
            //OPWAIT  } catch (Exception e) {}
            //OPWAIT }

        } finally {
            fireEvent("beforeStop");
            server.stop();
            if (proxy != null) {
                RPC.stopProxy(proxy);
            }
            System.out.println("Down slow rpc testing");
        }
        //Interrupt thread manually
        Thread[] t = new Thread[2];
        Thread.enumerate(t);
        t[1].interrupt();
    }

    private static final String ACL_CONFIG = "test.protocol.acl";

}