com.alibaba.wasp.client.TestAdmin.java Source code

Java tutorial

Introduction

Here is the source code for com.alibaba.wasp.client.TestAdmin.java

Source

/**
 * Copyright 2011 The Apache Software Foundation
 *
 * 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.
 */
package com.alibaba.wasp.client;

import com.alibaba.wasp.DataType;
import com.alibaba.wasp.EntityGroupInfo;
import com.alibaba.wasp.FConstants;
import com.alibaba.wasp.FieldKeyWord;
import com.alibaba.wasp.NotAllChildTableDisableException;
import com.alibaba.wasp.NotServingEntityGroupException;
import com.alibaba.wasp.ServerName;
import com.alibaba.wasp.TableExistsException;
import com.alibaba.wasp.TableNotDisabledException;
import com.alibaba.wasp.TableNotEnabledException;
import com.alibaba.wasp.TableNotFoundException;
import com.alibaba.wasp.UnknownEntityGroupException;
import com.alibaba.wasp.WaspTestingUtility;
import com.alibaba.wasp.executor.EventHandler;
import com.alibaba.wasp.executor.EventHandler.EventType;
import com.alibaba.wasp.executor.ExecutorService;
import com.alibaba.wasp.fserver.EntityGroup;
import com.alibaba.wasp.fserver.FServer;
import com.alibaba.wasp.master.FMasterServices;
import com.alibaba.wasp.meta.FMetaTestUtil;
import com.alibaba.wasp.meta.FTable;
import com.alibaba.wasp.meta.Field;
import com.alibaba.wasp.zookeeper.ZKTable;
import com.alibaba.wasp.zookeeper.ZooKeeperWatcher;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

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

/**
 * Class to test WaspAdmin. Spins up the minicluster once at test start and then
 * takes it down afterward. Add any testing of WaspAdmin functionality here.
 */
public class TestAdmin {
    final Log LOG = LogFactory.getLog(getClass());
    private final static WaspTestingUtility TEST_UTIL = new WaspTestingUtility();
    private static WaspAdmin admin;
    public static final String TABLE_NAME = "TEST_TABLE";

    public static final byte[] TABLE = Bytes.toBytes(TABLE_NAME);

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        TEST_UTIL.getConfiguration().setBoolean("wasp.online.schema.update.enable", true);
        TEST_UTIL.getConfiguration().set(FConstants.REDO_IMPL, "com.alibaba.wasp.fserver.redo.MemRedoLog");
        TEST_UTIL.getConfiguration().setInt("wasp.fserver.msginterval", 100);
        TEST_UTIL.getConfiguration().setInt("wasp.client.pause", 250);
        TEST_UTIL.getConfiguration().setInt("wasp.client.retries.number", 6);
        TEST_UTIL.getConfiguration().setBoolean("wasp.master.enabletable.roundrobin", true);
        TEST_UTIL.getConfiguration().setBoolean("wasp.ipc.server.blacklist.enable", true);
        TEST_UTIL.startMiniCluster(3);
        admin = TEST_UTIL.getWaspAdmin();
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        TEST_UTIL.shutdownMiniCluster();
    }

    @Test
    public void testSplitUnknownTable() throws InterruptedException {
        final String unknowntable = "fubar";
        Exception exception = null;
        try {
            admin.split(unknowntable, "1234");
        } catch (IOException e) {
            exception = e;
        }
        assertTrue(exception instanceof TableNotFoundException);
    }

    @Test
    public void testDisableAndEnableTable() throws IOException {
        final byte[] table = Bytes.toBytes("testDisableAndEnableTable");
        TEST_UTIL.createTable(table);
        admin.disableTable(table);
        assertTrue("Table must be disabled.", TEST_UTIL.getWaspCluster().getMaster().getAssignmentManager()
                .getZKTable().isDisabledTable(Bytes.toString(table)));

        admin.enableTable(table);
        assertTrue("Table must be enabled.", TEST_UTIL.getWaspCluster().getMaster().getAssignmentManager()
                .getZKTable().isEnabledTable(Bytes.toString(table)));
    }

    @Test
    public void testDisableEnableTableHasChilds() throws IOException, InterruptedException {
        final byte[] rootTable = Bytes.toBytes("testDisableTableHasChildsRoot");
        final byte[] childTable = Bytes.toBytes("testDisableTableHasChildsChild");
        TEST_UTIL.createTable(rootTable);
        TEST_UTIL.waitTableAvailable(rootTable);
        TEST_UTIL.createChildTable(rootTable, childTable);
        TEST_UTIL.waitTableEnabled(childTable, 5000);
        try {
            admin.disableTable(rootTable);
        } catch (Exception e) {
            assertTrue(e instanceof NotAllChildTableDisableException);
        }
        assertTrue("Table must be enabled.", TEST_UTIL.getWaspCluster().getMaster().getAssignmentManager()
                .getZKTable().isEnabledTable(Bytes.toString(rootTable)));
    }

    @Test
    public void testDisableAndEnableTables() throws IOException {
        final byte[] table1 = Bytes.toBytes("testDisableAndEnableTable1");
        final byte[] table2 = Bytes.toBytes("testDisableAndEnableTable2");
        TEST_UTIL.createTable(table1);
        TEST_UTIL.createTable(table2);
        admin.disableTables("testDisableAndEnableTable.*");

        assertTrue("Table must be disabled.", TEST_UTIL.getWaspCluster().getMaster().getAssignmentManager()
                .getZKTable().isDisabledTable(Bytes.toString(table1)));
        assertTrue("Table must be disabled.", TEST_UTIL.getWaspCluster().getMaster().getAssignmentManager()
                .getZKTable().isDisabledTable(Bytes.toString(table2)));

        admin.enableTables("testDisableAndEnableTable.*");

        assertTrue("Table must be enabled.", TEST_UTIL.getWaspCluster().getMaster().getAssignmentManager()
                .getZKTable().isEnabledTable(Bytes.toString(table1)));

        assertTrue("Table must be enabled.", TEST_UTIL.getWaspCluster().getMaster().getAssignmentManager()
                .getZKTable().isEnabledTable(Bytes.toString(table2)));
    }

    @Test
    public void testCreateTable() throws IOException {
        FTable[] tables = admin.listTables();
        int numTables = tables.length;
        TEST_UTIL.createTable(Bytes.toBytes("testCreateTable"));
        tables = admin.listTables();
        assertEquals(numTables + 1, tables.length);
        assertTrue("Table must be enabled.", TEST_UTIL.getWaspCluster().getMaster().getAssignmentManager()
                .getZKTable().isEnabledTable("testCreateTable"));
    }

    /**
     * Verify schema modification takes.
     * 
     * @throws java.io.IOException
     * @throws InterruptedException
     */
    @Test
    public void testOnlineChangeTableSchema() throws IOException, InterruptedException {

    }

    // not pass
    @Test
    public void testShouldFailOnlineSchemaUpdateIfOnlineSchemaIsNotEnabled() throws Exception {
        final byte[] tableName = Bytes.toBytes("changeTableSchemaOnlineFailure");
        TEST_UTIL.getMiniWaspCluster().getMaster().getConfiguration().setBoolean("wasp.online.schema.update.enable",
                false);
        FTable[] tables = admin.listTables();
        int numTables = tables.length;
        TEST_UTIL.createTable(tableName);
        tables = admin.listTables();
        assertEquals(numTables + 1, tables.length);

        // FIRST, do FTable changes.
        FTable fTable = admin.getTableDescriptor(tableName);
        // Make a copy and assert copy is good.
        FTable copy = FMetaTestUtil.makeTable(fTable.getTableName());
        assertTrue(fTable.equals(copy));

        boolean expectedException = false;
        try {
            modifyTable(tableName, copy);
        } catch (TableNotDisabledException re) {
            expectedException = true;
        }
        assertTrue("Online schema update should not happen.", expectedException);
    }

    /**
     * Modify table is async so wait on completion of the table operation in
     * master.
     * 
     * @param tableName
     * @param htd
     * @throws java.io.IOException
     */
    private void modifyTable(final byte[] tableName, final FTable htd) throws IOException {
        FMasterServices services = TEST_UTIL.getMiniWaspCluster().getMaster();
        ExecutorService executor = services.getExecutorService();
        AtomicBoolean done = new AtomicBoolean(false);
        executor.registerListener(EventType.C_M_MODIFY_TABLE, new DoneListener(done));
        admin.modifyTable(tableName, htd);
        while (!done.get()) {
            synchronized (done) {
                try {
                    done.wait(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        executor.unregisterListener(EventType.C_M_MODIFY_TABLE);
    }

    /**
     * Listens for when an event is done in Master.
     */
    static class DoneListener implements EventHandler.EventHandlerListener {
        private final AtomicBoolean done;

        DoneListener(final AtomicBoolean done) {
            super();
            this.done = done;
        }

        @Override
        public void afterProcess(EventHandler event) {
            this.done.set(true);
            synchronized (this.done) {
                // Wake anyone waiting on this value to change.
                this.done.notifyAll();
            }
        }

        @Override
        public void beforeProcess(EventHandler event) {
            // continue
        }
    }

    @Test
    public void testCreateTableWithEntityGroups() throws IOException, InterruptedException {

        byte[] tableName = Bytes.toBytes("testCreateTableWithEntityGroups");

        byte[][] splitKeys = { new byte[] { 1, 1, 1 }, new byte[] { 2, 2, 2 }, new byte[] { 3, 3, 3 },
                new byte[] { 4, 4, 4 }, new byte[] { 5, 5, 5 }, new byte[] { 6, 6, 6 }, new byte[] { 7, 7, 7 },
                new byte[] { 8, 8, 8 }, new byte[] { 9, 9, 9 }, };
        int expectedEntityGroups = splitKeys.length + 1;

        FTable desc = FMetaTestUtil.makeTable(Bytes.toString(tableName));
        admin.createTable(desc, splitKeys);

        Map<EntityGroupInfo, ServerName> entityGroups = admin.getEntityGroupLocations(tableName);
        assertEquals("Tried to create " + expectedEntityGroups + " entityGroups " + "but only found "
                + entityGroups.size(), expectedEntityGroups, entityGroups.size());
        System.err.println("Found " + entityGroups.size() + " entityGroups");

        Iterator<EntityGroupInfo> egis = entityGroups.keySet().iterator();
        EntityGroupInfo egi = egis.next();
        assertTrue(egi.getStartKey() == null || egi.getStartKey().length == 0);
        assertTrue(Bytes.equals(egi.getEndKey(), splitKeys[0]));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), splitKeys[0]));
        assertTrue(Bytes.equals(egi.getEndKey(), splitKeys[1]));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), splitKeys[1]));
        assertTrue(Bytes.equals(egi.getEndKey(), splitKeys[2]));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), splitKeys[2]));
        assertTrue(Bytes.equals(egi.getEndKey(), splitKeys[3]));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), splitKeys[3]));
        assertTrue(Bytes.equals(egi.getEndKey(), splitKeys[4]));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), splitKeys[4]));
        assertTrue(Bytes.equals(egi.getEndKey(), splitKeys[5]));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), splitKeys[5]));
        assertTrue(Bytes.equals(egi.getEndKey(), splitKeys[6]));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), splitKeys[6]));
        assertTrue(Bytes.equals(egi.getEndKey(), splitKeys[7]));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), splitKeys[7]));
        assertTrue(Bytes.equals(egi.getEndKey(), splitKeys[8]));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), splitKeys[8]));
        assertTrue(egi.getEndKey() == null || egi.getEndKey().length == 0);

        // Now test using start/end with a number of entityGroups

        // Use 80 bit numbers to make sure we aren't limited
        byte[] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
        byte[] endKey = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };

        // Splitting into 10 entityGroups, we expect (null,1) ... (9, null)
        // with (1,2) (2,3) (3,4) (4,5) (5,6) (6,7) (7,8) (8,9) in the middle

        expectedEntityGroups = 10;

        byte[] TABLE_2 = Bytes.add(tableName, Bytes.toBytes("_2"));

        desc = FMetaTestUtil.makeTable(Bytes.toString(TABLE_2));
        admin = new WaspAdmin(TEST_UTIL.getConfiguration());
        admin.createTable(desc, startKey, endKey, expectedEntityGroups);

        entityGroups = admin.getEntityGroupLocations(TABLE_2);
        assertEquals("Tried to create " + expectedEntityGroups + " entityGroups " + "but only found "
                + entityGroups.size(), expectedEntityGroups, entityGroups.size());
        System.err.println("Found " + entityGroups.size() + " entityGroups");

        egis = entityGroups.keySet().iterator();
        egi = egis.next();
        assertTrue(egi.getStartKey() == null || egi.getStartKey().length == 0);
        assertTrue(Bytes.equals(egi.getEndKey(), new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }));
        assertTrue(Bytes.equals(egi.getEndKey(), new byte[] { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), new byte[] { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }));
        assertTrue(Bytes.equals(egi.getEndKey(), new byte[] { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), new byte[] { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }));
        assertTrue(Bytes.equals(egi.getEndKey(), new byte[] { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), new byte[] { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }));
        assertTrue(Bytes.equals(egi.getEndKey(), new byte[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), new byte[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }));
        assertTrue(Bytes.equals(egi.getEndKey(), new byte[] { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), new byte[] { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }));
        assertTrue(Bytes.equals(egi.getEndKey(), new byte[] { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 }));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), new byte[] { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 }));
        assertTrue(Bytes.equals(egi.getEndKey(), new byte[] { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), new byte[] { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }));
        assertTrue(Bytes.equals(egi.getEndKey(), new byte[] { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }));
        egi = egis.next();
        assertTrue(Bytes.equals(egi.getStartKey(), new byte[] { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }));
        assertTrue(egi.getEndKey() == null || egi.getEndKey().length == 0);

        // Try once more with something that divides into something infinite

        startKey = new byte[] { 0, 0, 0, 0, 0, 0 };
        endKey = new byte[] { 1, 0, 0, 0, 0, 0 };

        expectedEntityGroups = 5;

        byte[] TABLE_3 = Bytes.add(tableName, Bytes.toBytes("_3"));

        desc = FMetaTestUtil.makeTable(Bytes.toString(TABLE_3));
        admin = new WaspAdmin(TEST_UTIL.getConfiguration());
        admin.createTable(desc, startKey, endKey, expectedEntityGroups);

        entityGroups = admin.getEntityGroupLocations(TABLE_3);
        assertEquals("Tried to create " + expectedEntityGroups + " entityGroups " + "but only found "
                + entityGroups.size(), expectedEntityGroups, entityGroups.size());
        System.err.println("Found " + entityGroups.size() + " entityGroups");

        // Try an invalid case where there are duplicate split keys
        splitKeys = new byte[][] { new byte[] { 1, 1, 1 }, new byte[] { 2, 2, 2 }, new byte[] { 3, 3, 3 },
                new byte[] { 2, 2, 2 } };

        byte[] TABLE_4 = Bytes.add(tableName, Bytes.toBytes("_4"));
        desc = FMetaTestUtil.makeTable(Bytes.toString(TABLE_4));
        WaspAdmin ladmin = new WaspAdmin(TEST_UTIL.getConfiguration());
        try {
            ladmin.createTable(desc, splitKeys);
            assertTrue("Should not be able to create this table because of " + "duplicate split keys", false);
        } catch (IllegalArgumentException iae) {
            // Expected
        }
        ladmin.close();
    }

    @Test
    public void testCreateTableWithOnlyEmptyStartRow() throws IOException {
        byte[][] splitKeys = new byte[1][];
        splitKeys[0] = FConstants.EMPTY_BYTE_ARRAY;
        FTable desc = FMetaTestUtil.makeTable("testCreateTableWithOnlyEmptyStartRow");
        try {
            admin.createTable(desc, splitKeys);
            fail("Test case should fail as empty split key is passed.");
        } catch (IllegalArgumentException e) {
        }
    }

    @Test
    public void testCreateTableWithEmptyRowInTheSplitKeys() throws IOException {
        byte[][] splitKeys = new byte[3][];
        splitKeys[0] = "entityGroup1".getBytes();
        splitKeys[1] = FConstants.EMPTY_BYTE_ARRAY;
        splitKeys[2] = "entityGroup2".getBytes();
        FTable desc = FMetaTestUtil.makeTable("testCreateTableWithEmptyRowInTheSplitKeys");
        try {
            admin.createTable(desc, splitKeys);
            fail("Test case should fail as empty split key is passed.");
        } catch (IllegalArgumentException e) {
        }
    }

    @Test
    public void testTableExist() throws IOException {
        final byte[] table = Bytes.toBytes("testTableExist");
        boolean exist = false;
        exist = admin.tableExists(table);
        assertEquals(false, exist);
        TEST_UTIL.createTable(table);
        exist = admin.tableExists(table);
        assertEquals(true, exist);
    }

    /**
     * 
     * @throws java.io.IOException
     */
    @Test(expected = IllegalArgumentException.class)
    public void testEmptyFTable() throws IOException {
        admin.createTable(new FTable());
    }

    /**
     * 
     * @throws Exception
     */
    @Test
    public void testTableNameClash() throws Exception {
        String name = "testTableNameClash";
        admin.createTable(FMetaTestUtil.makeTable(name + "SOMEUPPERCASE"));
        admin.createTable(FMetaTestUtil.makeTable(name));
        // Before fix, below would fail throwing a NoServerForEntityGroupException.
    }

    /**
     * 
     * @throws java.io.IOException
     */
    @Test(expected = TableExistsException.class)
    public void testTableExistsExceptionWithATable() throws IOException {
        final byte[] name = Bytes.toBytes("testTableExistsExceptionWithATable");
        TEST_UTIL.createTable(name);
        TEST_UTIL.createTable(name);
    }

    /**
     * Can't disable a table if the table isn't in enabled state
     * 
     * @throws java.io.IOException
     */
    @Test(expected = TableNotEnabledException.class)
    public void testTableNotEnabledExceptionWithATable() throws IOException {
        final byte[] name = Bytes.toBytes("testTableNotEnabledExceptionWithATable");
        TEST_UTIL.createTable(name);
        admin.disableTable(name);
        admin.disableTable(name);
    }

    /**
     * Can't enable a table if the table isn't in disabled state
     * 
     * @throws java.io.IOException
     */
    // @Test(expected = TableNotDisabledException.class)
    @Test
    public void testTableNotDisabledExceptionWithATable() throws IOException {
        try {
            final byte[] name = Bytes.toBytes("testTableNotDisabledExceptionWithATable");
            TEST_UTIL.createTable(name);
            admin.enableTable(name);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // not pass
    @Test
    public void testShouldCloseTheEntityGroupBasedOnTheEncodedEntityGroupName() throws Exception {
        byte[] TABLENAME = Bytes.toBytes("TestWASPCloseEntityGroup");
        createTableWithDefaultConf(TABLENAME);
        EntityGroup eg = null;
        FServer fs = TEST_UTIL.getFSForFirstEntityGroupInTable(TABLENAME);
        for (EntityGroup entityGroup : fs.getOnlineEntityGroups()) {
            eg = entityGroup;
            admin.closeEntityGroupWithEncodedEntityGroupName(entityGroup.getEntityGroupInfo().getEncodedName(),
                    fs.getServerName().getServerName());
        }
        Thread.sleep(1000);
        assertFalse("The entityGroup should not be present in online entityGroups list.",
                fs.getOnlineEntityGroups().contains(eg));
    }

    //
    @Test
    public void testCloseEntityGroupIfInvalidEntityGroupNameIsPassed() throws Exception {
        byte[] TABLENAME = Bytes.toBytes("TestWASPCloseEntityGroup1");
        createTableWithDefaultConf(TABLENAME);
        EntityGroup eg = null;
        FServer fs = TEST_UTIL.getFSForFirstEntityGroupInTable(TABLENAME);
        for (EntityGroup entityGroup : fs.getOnlineEntityGroups()) {
            if (entityGroup.getEntityGroupNameAsString().contains("TestWASPCloseEntityGroup1")) {
                eg = entityGroup;
                try {
                    admin.closeEntityGroup("sample", fs.getServerName().getServerName());
                } catch (UnknownEntityGroupException nsege) {
                    // expected, ignore it
                }
            }
        }
        assertTrue("The entityGroup should be present in online entityGroups list.",
                fs.getOnlineEntityGroups().contains(eg));
    }

    @Test(timeout = 36000)
    public void testEnableDisableAddColumnDeleteColumn() throws Exception {
        ZooKeeperWatcher zkw = WaspTestingUtility.getZooKeeperWatcher(TEST_UTIL);
        byte[] tableName = Bytes.toBytes("testMasterAdmin");
        TEST_UTIL.createTable(tableName);
        ZKTable zkTable = new ZKTable(zkw);
        while (!zkTable.isEnabledTable("testMasterAdmin")) {
            Thread.sleep(10);
        }
        admin.disableTable(tableName);
        admin.addColumn(tableName, new Field(FieldKeyWord.REQUIRED, "cf", "col2", DataType.STRING, null));
        admin.enableTable(tableName);
        try {
            admin.deleteColumn(tableName, Bytes.toBytes("col2"));
        } catch (TableNotDisabledException e) {
            LOG.info(e);
        }
        admin.disableTable(tableName);
        admin.deleteTable(tableName);
    }

    @Test
    public void testCloseEntityGroupThatFetchesTheEGIFromMeta() throws Exception {
        byte[] TABLENAME = Bytes.toBytes("TestWASPCloseEntityGroup2");
        createTableWithDefaultConf(TABLENAME);
        EntityGroup eg = null;
        FServer fs = TEST_UTIL.getFSForFirstEntityGroupInTable(TABLENAME);
        for (EntityGroup entityGroup : fs.getOnlineEntityGroups()) {
            if (entityGroup.getEntityGroupNameAsString().contains("TestWASPCloseEntityGroup2")) {
                eg = entityGroup;
                admin.closeEntityGroup(entityGroup.getEntityGroupNameAsString(),
                        fs.getServerName().getServerName());
            }
        }
        boolean isInList = fs.getOnlineEntityGroups().contains(eg);
        long timeout = System.currentTimeMillis() + 2000;
        while ((System.currentTimeMillis() < timeout) && (isInList)) {
            Thread.sleep(100);
            isInList = fs.getOnlineEntityGroups().contains(eg);
        }
        assertFalse("The EntityGroup should not be present in online EntityGroups list.", isInList);
    }

    @Test
    public void testCloseEntityGroupWhenServerNameIsEmpty() throws Exception {
        byte[] TABLENAME = Bytes.toBytes("TestWASPCloseEntityGroupWhenServerNameIsEmpty");
        createTableWithDefaultConf(TABLENAME);
        FServer fs = TEST_UTIL.getFSForFirstEntityGroupInTable(TABLENAME);
        try {
            for (EntityGroup entityGroup : fs.getOnlineEntityGroups()) {
                if (entityGroup.getEntityGroupNameAsString()
                        .contains("TestWASPCloseEntityGroupWhenServerNameIsEmpty")) {
                    admin.closeEntityGroup(entityGroup.getEntityGroupInfo().getEncodedName(), " ");
                }
            }
            fail("The test should throw exception if the servername passed is empty.");
        } catch (IllegalArgumentException e) {
        }
    }

    @Test
    public void testCloseEntityGroupWhenEncodedEntityGroupNameIsNotGiven() throws Exception {
        byte[] TABLENAME = Bytes.toBytes("TestWASPCloseEntityGroup4");
        createTableWithDefaultConf(TABLENAME);
        EntityGroup eg = null;
        FServer fs = TEST_UTIL.getFSForFirstEntityGroupInTable(TABLENAME);

        for (EntityGroup entityGroup : fs.getOnlineEntityGroups()) {
            if (entityGroup.getEntityGroupNameAsString().contains("TestWASPCloseEntityGroup4")) {
                eg = entityGroup;
                try {
                    admin.closeEntityGroupWithEncodedEntityGroupName(entityGroup.getEntityGroupNameAsString(),
                            fs.getServerName().getServerName());
                } catch (NotServingEntityGroupException nseg) {
                    // expected, ignore it.
                }
            }
        }
        assertTrue("The entityGroup should be present in online entityGroups list.",
                fs.getOnlineEntityGroups().contains(eg));
    }

    private void createTableWithDefaultConf(byte[] TABLENAME) throws IOException {
        TEST_UTIL.createTable(TABLENAME);
    }

    /**
     * 
     * @throws java.io.IOException
     */
    @Test
    public void testGetTableEntityGroups() throws IOException {
        byte[] tableName = Bytes.toBytes("testGetTableEntityGroups");
        int expectedEntityGroups = 10;
        // Use 80 bit numbers to make sure we aren't limited
        byte[] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
        byte[] endKey = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
        FTable desc = FMetaTestUtil.makeTable("testGetTableEntityGroups");
        admin.createTable(desc, startKey, endKey, expectedEntityGroups);
        List<EntityGroupInfo> egis = admin.getTableEntityGroups(tableName);
        assertEquals("Tried to create " + expectedEntityGroups + " EntityGroups " + "but only found " + egis.size(),
                expectedEntityGroups, egis.size());
    }

    /**
     * checkWaspAvailable() doesn't close zk connections
     */
    @Test
    public void testCheckWaspAvailableClosesConnection() throws Exception {
        Configuration conf = TEST_UTIL.getConfiguration();
        int initialCount = TestFConnectionUtility.getConnectionCount();
        WaspAdmin.checkWaspAvailable(conf);
        int finalCount = TestFConnectionUtility.getConnectionCount();
        Assert.assertEquals(initialCount, finalCount);
    }

    /**
     * Check if table locked
     * 
     * @throws java.io.IOException
     */
    @Test
    public void testTableLocked() throws IOException {
        try {
            final byte[] name = Bytes.toBytes("testTableLocked");
            TEST_UTIL.createTable(name);
            admin.isTableLocked(name);
        } catch (Exception e) {
            e.printStackTrace();
            assertTrue(false);
        }
    }
}