content: package com.alibaba.druid.pool.ha.node;
  
  import com.alibaba.druid.pool.DruidDataSource;
  import com.alibaba.druid.pool.ha.HighAvailableDataSource;
  import com.alibaba.druid.pool.ha.MockDataSource;
  import org.junit.After;
  import org.junit.Before;
  import org.junit.Test;
  
  import javax.sql.DataSource;
  
  import java.util.HashMap;
  import java.util.Map;
  
  import static org.junit.Assert.assertEquals;
  import static org.junit.Assert.assertFalse;
  import static org.junit.Assert.assertTrue;
  
  public class PoolUpdaterTest {
      private HighAvailableDataSource haDataSource;
      private PoolUpdater updater;
  
      @Before
      public void setUp() throws Exception {
          haDataSource = new HighAvailableDataSource();
          Map<String, DataSource> map = new HashMap<String, DataSource>();
          haDataSource.setDataSourceMap(map);
  
          updater = new PoolUpdater(haDataSource);
          updater.init();
      }
  
      @After
      public void tearDown() throws Exception {
          haDataSource.destroy();
          haDataSource = null;
          updater = null;
      }
  
      @Test
      public void testUpdate() {
          updater.init();
          assertTrue(updater.isInited());
          haDataSource.getDataSourceMap().put("foo", new MockDataSource("foo"));
          haDataSource.getDataSourceMap().put("bar", new MockDataSource("bar"));
  
          NodeEvent event = new NodeEvent();
          event.setNodeName("foo");
          event.setType(NodeEventTypeEnum.DELETE);
  
          updater.update(new FileNodeListener(), new NodeEvent[]{event});
          validateDeleteNode();
  
          event = new NodeEvent();
          event.setNodeName("foo");
          event.setType(NodeEventTypeEnum.ADD);
          updater.update(new FileNodeListener(), new NodeEvent[]{event});
          assertFalse(updater.getNodesToDel().contains("foo"));
          assertFalse(haDataSource.isInBlackList("foo"));
      }
  
      @Test
      public void testRemoveDataSources() {
          String url = "jdbc:derby:memory:foo;create=true";
          String name = "foo";
          addNode(url, name);
          DruidDataSource ds = (DruidDataSource) haDataSource.getDataSourceMap().get(name);
  
          updater.getNodesToDel().add(name);
          haDataSource.addBlackList(name);
  
          updater.removeDataSources();
          assertTrue(haDataSource.getDataSourceMap().isEmpty());
          assertFalse(haDataSource.isInBlackList(name));
          assertTrue(ds.isClosed());
      }
  
      @Test
      public void testRemoveDataSources_nodeNotExisted() {
          DataSource ds = new MockDataSource("foo");
          haDataSource.getDataSourceMap().put("foo", ds);
          updater.getNodesToDel().add("bar");
          updater.removeDataSources();
          assertFalse(updater.getNodesToDel().contains("bar"));
          assertEquals(1, haDataSource.getDataSourceMap().size());
      }
  
      @Test
      public void testRemoveDataSources_notDruid() {
          DataSource ds = new MockDataSource("foo");
          haDataSource.getDataSourceMap().put("foo", ds);
          updater.getNodesToDel().add("foo");
          updater.removeDataSources();
          assertFalse(updater.getNodesToDel().contains("foo"));
          assertTrue(haDataSource.getDataSourceMap().isEmpty());
      }
  
      @Test
      public void testUpdate_onlyOneLeftToRemove() {
          haDataSource.getDataSourceMap().put("foo", new MockDataSource("foo"));
  
          NodeEvent event = new NodeEvent();
          event.setNodeName("foo");
          event.setType(NodeEventTypeEnum.DELETE);
  
          updater.update(new FileNodeListener(), new NodeEvent[]{event});
          assertTrue(haDataSource.getDataSourceMap().containsKey("foo"));
      }
  
      @Test
      public void testAddNode() {
          String url = "jdbc:derby:memory:foo;create=true";
          String name = "foo";
          addNode(url, name);
          String targetUrl = ((DruidDataSource) haDataSource.getDataSourceMap().get(name)).getUrl();
          assertEquals(1, haDataSource.getDataSourceMap().size());
          assertEquals(url, targetUrl);
      }
  
      @Test
      public void testAddNode_alreadyExisted() {
          DataSource ds = new MockDataSource("foo");
          haDataSource.getDataSourceMap().put("foo", ds);
          updater.getNodesToDel().add("foo");
  
          addNode("foo_url", "foo");
  
          assertFalse(updater.getNodesToDel().contains("foo"));
          assertFalse(haDataSource.isInBlackList("foo"));
          assertEquals(ds, haDataSource.getDataSourceMap().get("foo"));
      }
  
      @Test
      public void testDeleteNode_notExisted() {
          NodeEvent event = new NodeEvent();
          event.setNodeName("foo");
          event.setType(NodeEventTypeEnum.DELETE);
          updater.deleteNode(event);
          assertTrue(updater.getNodesToDel().isEmpty());
          assertFalse(haDataSource.isInBlackList("foo"));
      }
  
      @Test
      public void testDeleteNode() {
          haDataSource.getDataSourceMap().put("foo", new MockDataSource("foo"));
          haDataSource.getDataSourceMap().put("bar", new MockDataSource("bar"));
  
          NodeEvent event = new NodeEvent();
          event.setNodeName("foo");
          event.setType(NodeEventTypeEnum.DELETE);
          updater.deleteNode(event);
          validateDeleteNode();
      }
  
      private void validateDeleteNode() {
          assertEquals(1, updater.getNodesToDel().size());
          assertTrue(updater.getNodesToDel().contains("foo"));
          assertTrue(haDataSource.isInBlackList("foo"));
      }
  
      private void addNode(String url, String name) {
          NodeEvent event = new NodeEvent();
          event.setNodeName(name);
          event.setUrl(url);
          event.setType(NodeEventTypeEnum.ADD);
          updater.addNode(event);
      }
  }
  