You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@gossip.apache.org by ec...@apache.org on 2016/06/25 11:46:25 UTC

[3/4] incubator-gossip git commit: [GISSIP-7] add log4j.properties and main/resources; rename test package to org.apache.gossip

[GISSIP-7] add log4j.properties and main/resources; rename test package to org.apache.gossip


Project: http://git-wip-us.apache.org/repos/asf/incubator-gossip/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-gossip/commit/56336566
Tree: http://git-wip-us.apache.org/repos/asf/incubator-gossip/tree/56336566
Diff: http://git-wip-us.apache.org/repos/asf/incubator-gossip/diff/56336566

Branch: refs/heads/master
Commit: 563365664f1092a8c736b70dbc934392fbc7a083
Parents: 2b00d6a
Author: Sree Vaddi <sv...@walmartlabs.com>
Authored: Sun Jun 19 18:09:27 2016 -0700
Committer: Sree Vaddi <sv...@walmartlabs.com>
Committed: Sun Jun 19 18:09:27 2016 -0700

----------------------------------------------------------------------
 src/main/resources/log4j.properties             |  20 +++
 .../io/teknek/gossip/ShutdownDeadtimeTest.java  | 139 -------------------
 .../io/teknek/gossip/StartupSettingsTest.java   |  95 -------------
 .../io/teknek/gossip/TenNodeThreeSeedTest.java  |  96 -------------
 .../org/apache/gossip/ShutdownDeadtimeTest.java | 139 +++++++++++++++++++
 .../org/apache/gossip/StartupSettingsTest.java  |  95 +++++++++++++
 .../org/apache/gossip/TenNodeThreeSeedTest.java |  96 +++++++++++++
 7 files changed, 350 insertions(+), 330 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/56336566/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties
new file mode 100644
index 0000000..e2a60e1
--- /dev/null
+++ b/src/main/resources/log4j.properties
@@ -0,0 +1,20 @@
+#  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.
+
+log4j.rootLogger=INFO,stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%5p %d{HH:mm:ss,SSS} %m%n
+
+log4j.logger.io.teknek=DEBUG
+log4j.logger.com.google.code.gossip=INFO

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/56336566/src/test/java/io/teknek/gossip/ShutdownDeadtimeTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/io/teknek/gossip/ShutdownDeadtimeTest.java b/src/test/java/io/teknek/gossip/ShutdownDeadtimeTest.java
deleted file mode 100644
index 340886a..0000000
--- a/src/test/java/io/teknek/gossip/ShutdownDeadtimeTest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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 io.teknek.gossip;
-
-import io.teknek.tunit.TUnit;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-import java.util.UUID;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-
-
-import org.apache.log4j.Logger;
-import org.junit.Test;
-
-import org.apache.gossip.GossipMember;
-import org.apache.gossip.GossipService;
-import org.apache.gossip.GossipSettings;
-import org.apache.gossip.RemoteGossipMember;
-import org.apache.gossip.event.GossipListener;
-import org.apache.gossip.event.GossipState;
-
-public class ShutdownDeadtimeTest {
-
-  private static final Logger log = Logger.getLogger(ShutdownDeadtimeTest.class );
-  @Test
-  //@Ignore
-  public void DeadNodesDoNotComeAliveAgain() throws InterruptedException, UnknownHostException, URISyntaxException {
-      GossipSettings settings = new GossipSettings(1000, 10000);
-      String cluster = UUID.randomUUID().toString();
-      
-      log.info( "Adding seed nodes" );
-      int seedNodes = 3;
-      List<GossipMember> startupMembers = new ArrayList<>();
-      for (int i = 1; i < seedNodes + 1; ++i) {
-        URI uri = new URI("udp://" + "127.0.0.1" + ":" + (50000 + i));
-        startupMembers.add(new RemoteGossipMember(cluster, uri, i + ""));
-      }
-
-      log.info( "Adding clients" );
-      final List<GossipService> clients = new ArrayList<>();
-      final int clusterMembers = 5;
-      for (int i = 1; i < clusterMembers+1; ++i) {
-          final int j = i;
-          URI uri = new URI("udp://" + "127.0.0.1" + ":" + (50000 + i));
-          GossipService gossipService = new GossipService(cluster, uri, i + "",
-                  startupMembers, settings,
-                  new GossipListener(){
-                      @Override
-                      public void gossipEvent(GossipMember member, GossipState state) {
-                          System.out.println(System.currentTimeMillis() + " Member "+j + " reports "+ member+" "+ state);
-                      }
-                  });
-          clients.add(gossipService);
-          gossipService.start();
-      }
-      TUnit.assertThat(new Callable<Integer> (){
-          public Integer call() throws Exception {
-              int total = 0;
-              for (int i = 0; i < clusterMembers; ++i) {
-                  total += clients.get(i).get_gossipManager().getMemberList().size();
-              }
-              return total;
-          }}).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(20);
-
-      // shutdown one client and verify that one client is lost.
-      Random r = new Random();
-      int randomClientId = r.nextInt(clusterMembers);
-      log.info( "shutting down " + randomClientId );
-      final int shutdownPort = clients.get(randomClientId).get_gossipManager().getMyself().getUri().getPort();
-      final String shutdownId = clients.get(randomClientId).get_gossipManager().getMyself().getId();
-      clients.get(randomClientId).shutdown();
-      TUnit.assertThat(new Callable<Integer> (){
-          public Integer call() throws Exception {
-              int total = 0;
-              for (int i = 0; i < clusterMembers; ++i) {
-                  total += clients.get(i).get_gossipManager().getMemberList().size();
-              }
-              return total;
-          }}).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(16);
-      clients.remove(randomClientId);
-      
-      TUnit.assertThat(new Callable<Integer> (){
-        public Integer call() throws Exception {
-            int total = 0;
-            for (int i = 0; i < clusterMembers - 1; ++i) {
-                total += clients.get(i).get_gossipManager().getDeadList().size();
-            }
-            return total;
-        }}).afterWaitingAtMost(10, TimeUnit.SECONDS).isEqualTo(4);
-      
-      URI uri = new URI("udp://" + "127.0.0.1" + ":" + shutdownPort);
-      // start client again
-      GossipService gossipService = new GossipService(cluster, uri, shutdownId + "",
-              startupMembers, settings,
-              new GossipListener(){
-                  @Override
-                  public void gossipEvent(GossipMember member, GossipState state) {
-                      //System.out.println("revived " + member+" "+ state);
-                  }
-              });
-      clients.add(gossipService);
-      gossipService.start();
-
-      // verify that the client is alive again for every node
-      TUnit.assertThat(new Callable<Integer> (){
-          public Integer call() throws Exception {
-              int total = 0;
-              for (int i = 0; i < clusterMembers; ++i) {
-                  total += clients.get(i).get_gossipManager().getMemberList().size();
-              }
-              return total;
-          }}).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(20);
-      
-      for (int i = 0; i < clusterMembers; ++i) {
-        clients.get(i).shutdown();
-      }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/56336566/src/test/java/io/teknek/gossip/StartupSettingsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/io/teknek/gossip/StartupSettingsTest.java b/src/test/java/io/teknek/gossip/StartupSettingsTest.java
deleted file mode 100644
index a4a9011..0000000
--- a/src/test/java/io/teknek/gossip/StartupSettingsTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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 io.teknek.gossip;
-
-import org.apache.gossip.GossipMember;
-import org.apache.gossip.GossipService;
-import org.apache.gossip.GossipSettings;
-import org.apache.gossip.StartupSettings;
-import org.apache.log4j.Logger;
-import org.json.JSONException;
-import org.junit.Test;
-
-import io.teknek.tunit.TUnit;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.UUID;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Tests support of using {@code StartupSettings} and thereby reading
- * setup config from file.
- */
-public class StartupSettingsTest {
-  private static final Logger log = Logger.getLogger( StartupSettingsTest.class );
-  private static final String CLUSTER = UUID.randomUUID().toString();
-
-  @Test
-  public void testUsingSettingsFile() throws IOException, InterruptedException, JSONException, URISyntaxException {
-    File settingsFile = File.createTempFile("gossipTest",".json");
-    log.debug( "Using settings file: " + settingsFile.getAbsolutePath() );
-    settingsFile.deleteOnExit();
-    writeSettingsFile(settingsFile);
-    URI uri = new URI("udp://" + "127.0.0.1" + ":" + 50000);
-    final GossipService firstService = new GossipService(
-            CLUSTER, uri, UUID.randomUUID().toString(),
-      new ArrayList<GossipMember>(), new GossipSettings(), null);
-    
-    firstService.start();
-    
-    TUnit.assertThat(new Callable<Integer> (){
-      public Integer call() throws Exception {
-          return firstService.get_gossipManager().getMemberList().size();
-      }}).afterWaitingAtMost(30, TimeUnit.SECONDS).isEqualTo(0);
-    final GossipService serviceUnderTest = new GossipService(
-            StartupSettings.fromJSONFile( settingsFile )
-          );
-    serviceUnderTest.start();
-    TUnit.assertThat(new Callable<Integer> (){
-      public Integer call() throws Exception {
-          return serviceUnderTest.get_gossipManager().getMemberList().size();
-      }}).afterWaitingAtMost(10, TimeUnit.SECONDS).isEqualTo(1);
-    firstService.shutdown();
-    serviceUnderTest.shutdown();
-  }
-
-  private void writeSettingsFile( File target ) throws IOException {
-    String settings =
-            "[{\n" + // It is odd that this is meant to be in an array, but oh well.
-            "  \"cluster\":\"" + CLUSTER + "\",\n" +
-            "  \"id\":\"" + UUID.randomUUID() + "\",\n" +
-            "  \"uri\":\"udp://127.0.0.1:50001\",\n" +
-            "  \"gossip_interval\":1000,\n" +
-            "  \"cleanup_interval\":10000,\n" +
-            "  \"members\":[\n" +
-            "    {\"cluster\": \"" + CLUSTER + "\",\"uri\":\"udp://127.0.0.1:5000\"}\n" +
-            "  ]\n" +
-            "}]";
-
-    log.info( "Using settings file with contents of:\n---\n" + settings + "\n---" );
-    FileOutputStream output = new FileOutputStream(target);
-    output.write( settings.getBytes() );
-    output.close();
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/56336566/src/test/java/io/teknek/gossip/TenNodeThreeSeedTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/io/teknek/gossip/TenNodeThreeSeedTest.java b/src/test/java/io/teknek/gossip/TenNodeThreeSeedTest.java
deleted file mode 100644
index 2b5f7fe..0000000
--- a/src/test/java/io/teknek/gossip/TenNodeThreeSeedTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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 io.teknek.gossip;
-
-import io.teknek.tunit.TUnit;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-
-
-import org.apache.log4j.Logger;
-import org.junit.Test;
-
-import org.apache.gossip.GossipMember;
-import org.apache.gossip.GossipService;
-import org.apache.gossip.GossipSettings;
-import org.apache.gossip.RemoteGossipMember;
-import org.apache.gossip.event.GossipListener;
-import org.apache.gossip.event.GossipState;
-
-public class TenNodeThreeSeedTest {
-  private static final Logger log = Logger.getLogger( TenNodeThreeSeedTest.class );
-
-  @Test
-  public void test() throws UnknownHostException, InterruptedException, URISyntaxException{
-    abc();
-  }
-
-  @Test
-  public void testAgain() throws UnknownHostException, InterruptedException, URISyntaxException{
-    abc();
-  }
-
-  public void abc() throws InterruptedException, UnknownHostException, URISyntaxException{
-    GossipSettings settings = new GossipSettings();
-    String cluster = UUID.randomUUID().toString();
-
-    log.info( "Adding seed nodes" );
-    int seedNodes = 3;
-    List<GossipMember> startupMembers = new ArrayList<>();
-    for (int i = 1; i < seedNodes+1; ++i) {
-      URI uri = new URI("udp://" + "127.0.0.1" + ":" + (50000 + i));
-      startupMembers.add(new RemoteGossipMember(cluster, uri, i + ""));
-    }
-
-    log.info( "Adding clients" );
-    final List<GossipService> clients = new ArrayList<>();
-    final int clusterMembers = 5;
-    for (int i = 1; i < clusterMembers+1; ++i) {
-      URI uri = new URI("udp://" + "127.0.0.1" + ":" + (50000 + i));
-      GossipService gossipService = new GossipService(cluster, uri, i + "",
-              startupMembers, settings,
-              new GossipListener(){
-        @Override
-        public void gossipEvent(GossipMember member, GossipState state) {
-          log.info(member+" "+ state);
-        }
-      });
-      clients.add(gossipService);
-      gossipService.start();
-    }
-    TUnit.assertThat(new Callable<Integer> (){
-      public Integer call() throws Exception {
-        int total = 0;
-        for (int i = 0; i < clusterMembers; ++i) {
-          total += clients.get(i).get_gossipManager().getMemberList().size();
-        }
-        return total;
-      }}).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(20);
-    
-    for (int i = 0; i < clusterMembers; ++i) {
-      clients.get(i).shutdown();
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/56336566/src/test/java/org/apache/gossip/ShutdownDeadtimeTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/gossip/ShutdownDeadtimeTest.java b/src/test/java/org/apache/gossip/ShutdownDeadtimeTest.java
new file mode 100644
index 0000000..0420444
--- /dev/null
+++ b/src/test/java/org/apache/gossip/ShutdownDeadtimeTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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 org.apache.gossip;
+
+import io.teknek.tunit.TUnit;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+
+import org.apache.log4j.Logger;
+import org.junit.Test;
+
+import org.apache.gossip.GossipMember;
+import org.apache.gossip.GossipService;
+import org.apache.gossip.GossipSettings;
+import org.apache.gossip.RemoteGossipMember;
+import org.apache.gossip.event.GossipListener;
+import org.apache.gossip.event.GossipState;
+
+public class ShutdownDeadtimeTest {
+
+  private static final Logger log = Logger.getLogger(ShutdownDeadtimeTest.class );
+  @Test
+  //@Ignore
+  public void DeadNodesDoNotComeAliveAgain() throws InterruptedException, UnknownHostException, URISyntaxException {
+      GossipSettings settings = new GossipSettings(1000, 10000);
+      String cluster = UUID.randomUUID().toString();
+      
+      log.info( "Adding seed nodes" );
+      int seedNodes = 3;
+      List<GossipMember> startupMembers = new ArrayList<>();
+      for (int i = 1; i < seedNodes + 1; ++i) {
+        URI uri = new URI("udp://" + "127.0.0.1" + ":" + (50000 + i));
+        startupMembers.add(new RemoteGossipMember(cluster, uri, i + ""));
+      }
+
+      log.info( "Adding clients" );
+      final List<GossipService> clients = new ArrayList<>();
+      final int clusterMembers = 5;
+      for (int i = 1; i < clusterMembers+1; ++i) {
+          final int j = i;
+          URI uri = new URI("udp://" + "127.0.0.1" + ":" + (50000 + i));
+          GossipService gossipService = new GossipService(cluster, uri, i + "",
+                  startupMembers, settings,
+                  new GossipListener(){
+                      @Override
+                      public void gossipEvent(GossipMember member, GossipState state) {
+                          System.out.println(System.currentTimeMillis() + " Member "+j + " reports "+ member+" "+ state);
+                      }
+                  });
+          clients.add(gossipService);
+          gossipService.start();
+      }
+      TUnit.assertThat(new Callable<Integer> (){
+          public Integer call() throws Exception {
+              int total = 0;
+              for (int i = 0; i < clusterMembers; ++i) {
+                  total += clients.get(i).get_gossipManager().getMemberList().size();
+              }
+              return total;
+          }}).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(20);
+
+      // shutdown one client and verify that one client is lost.
+      Random r = new Random();
+      int randomClientId = r.nextInt(clusterMembers);
+      log.info( "shutting down " + randomClientId );
+      final int shutdownPort = clients.get(randomClientId).get_gossipManager().getMyself().getUri().getPort();
+      final String shutdownId = clients.get(randomClientId).get_gossipManager().getMyself().getId();
+      clients.get(randomClientId).shutdown();
+      TUnit.assertThat(new Callable<Integer> (){
+          public Integer call() throws Exception {
+              int total = 0;
+              for (int i = 0; i < clusterMembers; ++i) {
+                  total += clients.get(i).get_gossipManager().getMemberList().size();
+              }
+              return total;
+          }}).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(16);
+      clients.remove(randomClientId);
+      
+      TUnit.assertThat(new Callable<Integer> (){
+        public Integer call() throws Exception {
+            int total = 0;
+            for (int i = 0; i < clusterMembers - 1; ++i) {
+                total += clients.get(i).get_gossipManager().getDeadList().size();
+            }
+            return total;
+        }}).afterWaitingAtMost(10, TimeUnit.SECONDS).isEqualTo(4);
+      
+      URI uri = new URI("udp://" + "127.0.0.1" + ":" + shutdownPort);
+      // start client again
+      GossipService gossipService = new GossipService(cluster, uri, shutdownId + "",
+              startupMembers, settings,
+              new GossipListener(){
+                  @Override
+                  public void gossipEvent(GossipMember member, GossipState state) {
+                      //System.out.println("revived " + member+" "+ state);
+                  }
+              });
+      clients.add(gossipService);
+      gossipService.start();
+
+      // verify that the client is alive again for every node
+      TUnit.assertThat(new Callable<Integer> (){
+          public Integer call() throws Exception {
+              int total = 0;
+              for (int i = 0; i < clusterMembers; ++i) {
+                  total += clients.get(i).get_gossipManager().getMemberList().size();
+              }
+              return total;
+          }}).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(20);
+      
+      for (int i = 0; i < clusterMembers; ++i) {
+        clients.get(i).shutdown();
+      }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/56336566/src/test/java/org/apache/gossip/StartupSettingsTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/gossip/StartupSettingsTest.java b/src/test/java/org/apache/gossip/StartupSettingsTest.java
new file mode 100644
index 0000000..363b4e2
--- /dev/null
+++ b/src/test/java/org/apache/gossip/StartupSettingsTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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 org.apache.gossip;
+
+import org.apache.gossip.GossipMember;
+import org.apache.gossip.GossipService;
+import org.apache.gossip.GossipSettings;
+import org.apache.gossip.StartupSettings;
+import org.apache.log4j.Logger;
+import org.json.JSONException;
+import org.junit.Test;
+
+import io.teknek.tunit.TUnit;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests support of using {@code StartupSettings} and thereby reading
+ * setup config from file.
+ */
+public class StartupSettingsTest {
+  private static final Logger log = Logger.getLogger( StartupSettingsTest.class );
+  private static final String CLUSTER = UUID.randomUUID().toString();
+
+  @Test
+  public void testUsingSettingsFile() throws IOException, InterruptedException, JSONException, URISyntaxException {
+    File settingsFile = File.createTempFile("gossipTest",".json");
+    log.debug( "Using settings file: " + settingsFile.getAbsolutePath() );
+    settingsFile.deleteOnExit();
+    writeSettingsFile(settingsFile);
+    URI uri = new URI("udp://" + "127.0.0.1" + ":" + 50000);
+    final GossipService firstService = new GossipService(
+            CLUSTER, uri, UUID.randomUUID().toString(),
+      new ArrayList<GossipMember>(), new GossipSettings(), null);
+    
+    firstService.start();
+    
+    TUnit.assertThat(new Callable<Integer> (){
+      public Integer call() throws Exception {
+          return firstService.get_gossipManager().getMemberList().size();
+      }}).afterWaitingAtMost(30, TimeUnit.SECONDS).isEqualTo(0);
+    final GossipService serviceUnderTest = new GossipService(
+            StartupSettings.fromJSONFile( settingsFile )
+          );
+    serviceUnderTest.start();
+    TUnit.assertThat(new Callable<Integer> (){
+      public Integer call() throws Exception {
+          return serviceUnderTest.get_gossipManager().getMemberList().size();
+      }}).afterWaitingAtMost(10, TimeUnit.SECONDS).isEqualTo(1);
+    firstService.shutdown();
+    serviceUnderTest.shutdown();
+  }
+
+  private void writeSettingsFile( File target ) throws IOException {
+    String settings =
+            "[{\n" + // It is odd that this is meant to be in an array, but oh well.
+            "  \"cluster\":\"" + CLUSTER + "\",\n" +
+            "  \"id\":\"" + UUID.randomUUID() + "\",\n" +
+            "  \"uri\":\"udp://127.0.0.1:50001\",\n" +
+            "  \"gossip_interval\":1000,\n" +
+            "  \"cleanup_interval\":10000,\n" +
+            "  \"members\":[\n" +
+            "    {\"cluster\": \"" + CLUSTER + "\",\"uri\":\"udp://127.0.0.1:5000\"}\n" +
+            "  ]\n" +
+            "}]";
+
+    log.info( "Using settings file with contents of:\n---\n" + settings + "\n---" );
+    FileOutputStream output = new FileOutputStream(target);
+    output.write( settings.getBytes() );
+    output.close();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-gossip/blob/56336566/src/test/java/org/apache/gossip/TenNodeThreeSeedTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/gossip/TenNodeThreeSeedTest.java b/src/test/java/org/apache/gossip/TenNodeThreeSeedTest.java
new file mode 100644
index 0000000..d194efe
--- /dev/null
+++ b/src/test/java/org/apache/gossip/TenNodeThreeSeedTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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 org.apache.gossip;
+
+import io.teknek.tunit.TUnit;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+
+import org.apache.log4j.Logger;
+import org.junit.Test;
+
+import org.apache.gossip.GossipMember;
+import org.apache.gossip.GossipService;
+import org.apache.gossip.GossipSettings;
+import org.apache.gossip.RemoteGossipMember;
+import org.apache.gossip.event.GossipListener;
+import org.apache.gossip.event.GossipState;
+
+public class TenNodeThreeSeedTest {
+  private static final Logger log = Logger.getLogger( TenNodeThreeSeedTest.class );
+
+  @Test
+  public void test() throws UnknownHostException, InterruptedException, URISyntaxException{
+    abc();
+  }
+
+  @Test
+  public void testAgain() throws UnknownHostException, InterruptedException, URISyntaxException{
+    abc();
+  }
+
+  public void abc() throws InterruptedException, UnknownHostException, URISyntaxException{
+    GossipSettings settings = new GossipSettings();
+    String cluster = UUID.randomUUID().toString();
+
+    log.info( "Adding seed nodes" );
+    int seedNodes = 3;
+    List<GossipMember> startupMembers = new ArrayList<>();
+    for (int i = 1; i < seedNodes+1; ++i) {
+      URI uri = new URI("udp://" + "127.0.0.1" + ":" + (50000 + i));
+      startupMembers.add(new RemoteGossipMember(cluster, uri, i + ""));
+    }
+
+    log.info( "Adding clients" );
+    final List<GossipService> clients = new ArrayList<>();
+    final int clusterMembers = 5;
+    for (int i = 1; i < clusterMembers+1; ++i) {
+      URI uri = new URI("udp://" + "127.0.0.1" + ":" + (50000 + i));
+      GossipService gossipService = new GossipService(cluster, uri, i + "",
+              startupMembers, settings,
+              new GossipListener(){
+        @Override
+        public void gossipEvent(GossipMember member, GossipState state) {
+          log.info(member+" "+ state);
+        }
+      });
+      clients.add(gossipService);
+      gossipService.start();
+    }
+    TUnit.assertThat(new Callable<Integer> (){
+      public Integer call() throws Exception {
+        int total = 0;
+        for (int i = 0; i < clusterMembers; ++i) {
+          total += clients.get(i).get_gossipManager().getMemberList().size();
+        }
+        return total;
+      }}).afterWaitingAtMost(20, TimeUnit.SECONDS).isEqualTo(20);
+    
+    for (int i = 0; i < clusterMembers; ++i) {
+      clients.get(i).shutdown();
+    }
+  }
+}