Package net.sf.katta.integrationTest

Source Code of net.sf.katta.integrationTest.MultiClusterTest

/**
* Copyright 2009 the original author or authors.
*
* Licensed 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.
*/
package net.sf.katta.integrationTest;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import net.sf.katta.AbstractTest;
import net.sf.katta.client.DeployClient;
import net.sf.katta.client.IIndexDeployFuture;
import net.sf.katta.integrationTest.support.KattaMiniCluster;
import net.sf.katta.protocol.InteractionProtocol;
import net.sf.katta.testutil.TestResources;
import net.sf.katta.testutil.TestUtil;
import net.sf.katta.util.ISleepClient;
import net.sf.katta.util.KattaException;
import net.sf.katta.util.SleepClient;
import net.sf.katta.util.SleepServer;
import net.sf.katta.util.ZkConfiguration;
import net.sf.katta.util.ZkKattaUtil;

import org.I0Itec.zkclient.ZkServer;
import org.apache.log4j.Logger;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

/**
* This class tests the situation where you using 2 instances of Katta to talk
* to 2 pools of nodes at the same time.
*/
public class MultiClusterTest extends AbstractTest {

  protected static final Logger LOG = Logger.getLogger(MultiClusterTest.class);

  public static final String INDEX1 = "pool1";
  public static final String INDEX2 = "pool2";

  protected static ISleepClient _client1;
  protected static ISleepClient _client2;

  private static final int POOL_SIZE_1 = 9;
  private static final int POOL_SIZE_2 = 7;

  private static final int NUM_SHARDS_1 = 140;
  private static final int NUM_SHARDS_2 = 70;

  private static ZkServer _zkServer;
  private static KattaMiniCluster _cluster1;
  private static KattaMiniCluster _cluster2;

  @BeforeClass
  public static void onBeforeClass() throws Exception {
    ZkConfiguration conf1 = new ZkConfiguration();
    ZkConfiguration conf2 = new ZkConfiguration();
    conf1.setZKRootPath("MultiClusterTest/pool1");
    conf2.setZKRootPath("MultiClusterTest/pool2");

    _zkServer = ZkKattaUtil.startZkServer(new ZkConfiguration());
    _cluster1 = new KattaMiniCluster(SleepServer.class, conf1, POOL_SIZE_1, 30000);
    _cluster2 = new KattaMiniCluster(SleepServer.class, conf2, POOL_SIZE_2, 40000);
    _cluster1.setZkServer(_zkServer);
    _cluster2.setZkServer(_zkServer);
    _cluster1.start();
    _cluster2.start();

    TestUtil.waitUntilLeaveSafeMode(_cluster1.getMaster());
    TestUtil.waitUntilLeaveSafeMode(_cluster2.getMaster());
    TestUtil.waitUntilNumberOfLiveNode(_cluster1.getProtocol(), POOL_SIZE_1);
    TestUtil.waitUntilNumberOfLiveNode(_cluster2.getProtocol(), POOL_SIZE_2);

    // Create lots of empty shards. SleepServer does not use the directory, but
    // Node does.
    LOG.info("Creating indicies");
    setupIndex(TestResources.EMPTY1_INDEX, NUM_SHARDS_1);
    setupIndex(TestResources.EMPTY2_INDEX, NUM_SHARDS_2);

    // Deploy shards to pool1.
    LOG.info("Deploying index 1");
    deployIndex(_cluster1.getProtocol(), INDEX1, TestResources.EMPTY1_INDEX);

    // Deploy shards to pool2.
    LOG.info("Deploying index 2");
    deployIndex(_cluster2.getProtocol(), INDEX2, TestResources.EMPTY2_INDEX);

    // Verify setup.
    // LOG.info("\n\nPOOL 1 STRUCTURE:\n");
    // _cluster1.getProtocol().showStructure(false);
    // LOG.info("\n\nPOOL 2 STRUCTURE:\n");
    // _cluster2.getProtocol().showStructure(false);

    // Back end ready to run. Create clients.
    LOG.info("Creating clients");
    _client1 = new SleepClient(conf1);
    _client2 = new SleepClient(conf2);
  }

  @AfterClass
  public static void onAfterClass() throws Exception {
    _client1.close();
    _client2.close();
    _cluster1.stop(false);
    _cluster2.stop(false);
    _zkServer.shutdown();
    for (File f : TestResources.EMPTY1_INDEX.listFiles()) {
      deleteFiles(f);
    }
    for (File f : TestResources.EMPTY2_INDEX.listFiles()) {
      deleteFiles(f);
    }
  }

  private static void deployIndex(InteractionProtocol protocol, String indexName, File index)
          throws InterruptedException {
    DeployClient deployClient1 = new DeployClient(protocol);
    IIndexDeployFuture deployment = deployClient1.addIndex(indexName, index.getAbsolutePath(), 1);
    LOG.info("Joining deployment on " + deployment.getClass().getName());
    deployment.joinDeployment();
  }

  private static void setupIndex(File index, int size) {
    if (index.exists() && index.isDirectory()) {
      for (File f : index.listFiles()) {
        deleteFiles(f);
      }
    }
    for (int i = 0; i < size; i++) {
      File f = new File(index, "shard" + i);
      if (!f.mkdirs()) {
        throw new RuntimeException("unable to create folder: " + f.getAbsolutePath());
      }
    }
  }

  private static void deleteFiles(File f) {
    if (f.getName().startsWith(".")) {
      return;
    }
    for (File child : f.listFiles()) {
      deleteFiles(child);
    }
    f.delete();
  }

  @Test
  public void testSerial() throws KattaException {
    assertEquals(NUM_SHARDS_1, _client1.sleep(0L));
    assertEquals(NUM_SHARDS_2, _client2.sleep(0L));
    //
    Random rand = new Random("Multi katta".hashCode());
    for (int i = 0; i < 200; i++) {
      if (rand.nextBoolean()) {
        assertEquals(NUM_SHARDS_1, _client1.sleep(rand.nextInt(5), rand.nextInt(5)));
      }
      if (rand.nextBoolean()) {
        assertEquals(NUM_SHARDS_2, _client2.sleep(rand.nextInt(5), rand.nextInt(5)));
      }
    }
  }

  @Test
  public void testParallel() throws InterruptedException {
    LOG.info("Testing multithreaded access to multiple Katta instances...");
    Long start = System.currentTimeMillis();
    Random rand = new Random("Multi katta2".hashCode());
    List<Thread> threads = new ArrayList<Thread>();
    final List<Throwable> throwables = Collections.synchronizedList(new ArrayList<Throwable>());
    for (int i = 0; i < 15; i++) {
      final Random rand2 = new Random(rand.nextInt());
      Thread thread = new Thread(new Runnable() {
        public void run() {
          try {
            for (int j = 0; j < 400; j++) {
              if (rand2.nextBoolean()) {
                assertEquals(NUM_SHARDS_1, _client1.sleep(rand2.nextInt(2), rand2.nextInt(2)));
              }
              if (rand2.nextBoolean()) {
                assertEquals(NUM_SHARDS_2, _client2.sleep(rand2.nextInt(2), rand2.nextInt(2)));
              }
            }
          } catch (Throwable t) {
            LOG.error("Error! ", t);
            throwables.add(t);
          }
        }
      });
      threads.add(thread);
      thread.start();
    }
    for (Thread t : threads) {
      t.join();
    }
    LOG.info("Took " + (System.currentTimeMillis() - start) + " msec");
    for (Throwable t : throwables) {
      System.err.println(t);
      t.printStackTrace();
    }
    assertTrue(throwables.isEmpty());
  }

}
TOP

Related Classes of net.sf.katta.integrationTest.MultiClusterTest

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.