se.sics.caracaldb.paxos.PaxosTest.java Source code

Java tutorial

Introduction

Here is the source code for se.sics.caracaldb.paxos.PaxosTest.java

Source

/* 
 * This file is part of the CaracalDB distributed storage system.
 *
 * Copyright (C) 2009 Swedish Institute of Computer Science (SICS) 
 * Copyright (C) 2009 Royal Institute of Technology (KTH)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package se.sics.caracaldb.paxos;

import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import static org.junit.Assert.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.sics.caracaldb.paxos.Commands.ChurnEvent;
import se.sics.caracaldb.paxos.Commands.Fail;
import se.sics.caracaldb.paxos.Commands.Join;
import se.sics.kompics.Kompics;
import se.sics.kompics.Scheduler;
import se.sics.kompics.p2p.experiment.dsl.SimulationScenario;
import se.sics.kompics.p2p.experiment.dsl.adaptor.Operation;
import se.sics.kompics.simulation.SimulatorScheduler;

/**
 *
 * @author Lars Kroll <lkroll@sics.se>
 */
@RunWith(JUnit4.class)
public class PaxosTest {

    private static final Logger LOG = LoggerFactory.getLogger(PaxosTest.class);
    public static final int SEED = 0;
    private static final int BOOT_NUM = 3;
    private static final int OP_NUM = 500;
    private static final int CHURN_NUM = 4;

    private static SimulationScenario scenario;
    private static Scheduler scheduler;
    private static DecisionStore store;

    public static SimulationScenario getScenario() {
        return scenario;
    }

    public static Scheduler getScheduler() {
        return scheduler;
    }

    public static void setStore(DecisionStore store) {
        PaxosTest.store = store;
    }

    @Before
    public void setUp() {
        scenario = null;
        scheduler = null;
        store = null;
    }

    @Test
    public void basic() {
        scenario = new SimulationScenario() {
            {
                StochasticProcess bootProc = new StochasticProcess() {
                    {
                        eventInterArrivalTime(constant(0));
                        raise(1, opStart(BOOT_NUM));
                    }
                };

                StochasticProcess slowOpProc = new StochasticProcess() {
                    {
                        eventInterArrivalTime(uniform(200, 500));
                        raise(OP_NUM, opOp());
                    }
                };

                StochasticProcess verifyProc = new StochasticProcess() {
                    {
                        eventInterArrivalTime(constant(500));
                        raise(Integer.MAX_VALUE, opVerify());
                    }
                };

                bootProc.start();
                //termProc.start();
                slowOpProc.startAfterTerminationOf(1000, bootProc);
                verifyProc.startAfterStartOf(OP_NUM * 500, slowOpProc);
                terminateAfterTerminationOf(OP_NUM * 1000, slowOpProc);
            }
        };

        doTest("basic");
    }

    @Test
    public void fastOps() {
        scenario = new SimulationScenario() {
            {
                SimulationScenario.StochasticProcess bootProc = new SimulationScenario.StochasticProcess() {
                    {
                        eventInterArrivalTime(constant(0));
                        raise(1, opStart(BOOT_NUM));
                    }
                };

                SimulationScenario.StochasticProcess fastOpProc = new SimulationScenario.StochasticProcess() {
                    {
                        eventInterArrivalTime(uniform(50, 100));
                        raise(OP_NUM, opOp());
                    }
                };

                SimulationScenario.StochasticProcess verifyProc = new SimulationScenario.StochasticProcess() {
                    {
                        eventInterArrivalTime(constant(500));
                        raise(Integer.MAX_VALUE, opVerify());
                    }
                };

                bootProc.start();
                //termProc.start();
                fastOpProc.startAfterTerminationOf(1000, bootProc);
                verifyProc.startAfterStartOf(OP_NUM * 500, fastOpProc);
                terminateAfterTerminationOf(OP_NUM * 1000, fastOpProc);
            }
        };

        doTest("fastOps");
    }

    @Test
    public void singleFail() {
        scenario = new SimulationScenario() {
            {
                SimulationScenario.StochasticProcess bootProc = new SimulationScenario.StochasticProcess() {
                    {
                        eventInterArrivalTime(constant(0));
                        raise(1, opStart(BOOT_NUM));
                    }
                };

                StochasticProcess slowOpProc = new StochasticProcess() {
                    {
                        eventInterArrivalTime(uniform(200, 500));
                        raise(OP_NUM, opOp());
                    }
                };

                StochasticProcess nodeFailProc = new StochasticProcess() {
                    {
                        eventInterArrivalTime(constant(0));
                        raise(1, opFail());
                    }
                };

                SimulationScenario.StochasticProcess verifyProc = new SimulationScenario.StochasticProcess() {
                    {
                        eventInterArrivalTime(constant(500));
                        raise(Integer.MAX_VALUE, opVerify());
                    }
                };

                bootProc.start();
                //termProc.start();
                slowOpProc.startAfterTerminationOf(1000, bootProc);
                nodeFailProc.startAfterStartOf(OP_NUM * 200, slowOpProc);
                verifyProc.startAfterStartOf(OP_NUM * 500, slowOpProc);
                terminateAfterTerminationOf(OP_NUM * 1000, slowOpProc);
            }
        };

        doTest("singleFail");
    }

    @Test
    public void churn() {
        scenario = new SimulationScenario() {
            {
                SimulationScenario.StochasticProcess bootProc = new SimulationScenario.StochasticProcess() {
                    {
                        eventInterArrivalTime(constant(0));
                        raise(1, opStart(BOOT_NUM));
                    }
                };

                SimulationScenario.StochasticProcess slowOpProc = new SimulationScenario.StochasticProcess() {
                    {
                        eventInterArrivalTime(uniform(200, 500));
                        raise(OP_NUM, opOp());
                    }
                };

                SimulationScenario.StochasticProcess churnProc = new SimulationScenario.StochasticProcess() {
                    {
                        eventInterArrivalTime(uniform(20000, 30000));
                        raise(CHURN_NUM, opChurn());
                    }
                };

                SimulationScenario.StochasticProcess verifyProc = new SimulationScenario.StochasticProcess() {
                    {
                        eventInterArrivalTime(constant(500));
                        raise(Integer.MAX_VALUE, opVerify());
                    }
                };

                bootProc.start();
                slowOpProc.startAfterTerminationOf(1000, bootProc);
                churnProc.startAfterStartOf(OP_NUM * 50, slowOpProc);
                verifyProc.startAfterStartOf(OP_NUM * 500, slowOpProc);
                terminateAfterTerminationOf(OP_NUM * 1000, slowOpProc);
            }
        };

        doTest("churn");
    }

    private void doTest(String prefix) {
        scenario.setSeed(SEED);

        System.out.println("\n %%%%%%%%%%%%%%%%\n Executing Test: " + prefix + "\n%%%%%%%%%%%%%%%%\n");

        simulate();
        assertNotNull(store);
        assertEquals(OP_NUM, store.numOps());
        //printStore(prefix);
        store.validate();
    }

    private void printStore(String prefix) {
        String folderName = "/tmp/caracaldb/tests";
        File folder = new File(folderName);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        String fileName = folderName + "/" + prefix + System.currentTimeMillis() + ".html";
        File f = new File(fileName);
        try {
            f.createNewFile();
            StringBuilder sb = new StringBuilder();
            store.html(sb);
            FileUtils.writeStringToFile(f, sb.toString());
            Desktop.getDesktop().browse(f.toURI());
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(PaxosTest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void simulate() {
        scheduler = new SimulatorScheduler();
        Kompics.setScheduler(scheduler);
        Kompics.createAndStart(SimulatorMain.class, 1);
    }

    public static Operation<Commands.Start> opStart(final int n) {
        return new Operation<Commands.Start>() {
            @Override
            public Commands.Start generate() {
                return new Commands.Start(n);
            }
        };
    }

    public static Operation<Commands.Verify> opVerify() {
        return new Operation<Commands.Verify>() {
            @Override
            public Commands.Verify generate() {
                return new Commands.Verify();
            }
        };
    }

    public static Operation<Commands.Operation> opOp() {
        return new Operation<Commands.Operation>() {

            @Override
            public Commands.Operation generate() {
                return new Commands.Operation();
            }
        };
    }

    public static Operation<Commands.Join> opJoin() {
        return new Operation<Commands.Join>() {

            @Override
            public Join generate() {
                return new Commands.Join();
            }
        };
    }

    public static Operation<Commands.Fail> opFail() {
        return new Operation<Commands.Fail>() {

            @Override
            public Fail generate() {
                return new Commands.Fail();
            }
        };
    }

    public static Operation<Commands.ChurnEvent> opChurn() {
        return new Operation<Commands.ChurnEvent>() {

            private int i = -1;

            @Override
            public ChurnEvent generate() {
                i++;
                if (i % 2 == 0) {
                    return new Fail();
                } else {
                    return new Join();
                }
            }
        };
    }

}