Uploaded image for project: 'Geode'
  1. Geode
  2. GEODE-3413

Overhaul launcher tests and process tests

    Details

    • Type: Improvement
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.3.0
    • Component/s: gfsh

      Description

      The launcher and process tests are closely related and in need of overhauling to improve debugging and remove flakiness.

      In addition, the org.apache.geode.internal.process package is need of improving the test code coverage.

      Launcher tests:

      • geode-assembly/src/test/java/org/apache/geode/distributed/LocatorLauncherAssemblyIntegrationTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherIntegrationTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherServiceStatusTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/LauncherMemberMXBeanIntegrationTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/LocatorLauncherIntegrationTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/LocatorLauncherLocalFileIntegrationTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/LocatorLauncherLocalIntegrationTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/LocatorLauncherRemoteFileIntegrationTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/LocatorLauncherRemoteIntegrationTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/LocatorLauncherRemoteWithCustomLoggingIntegrationTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/LocatorLauncherTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/LocatorStateTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherIntegrationTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherLocalFileIntegrationTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherLocalIntegrationTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteFileIntegrationTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteWithCustomLoggingIntegrationTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteWithCustomLoggingIntegrationTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherTest.java
      • geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherWithProviderIntegrationTest.java

      Process tests:

      • geode-core/src/test/java/org/apache/geode/internal/process/BlockingProcessStreamReaderJUnitTest.java
      • geode-core/src/test/java/org/apache/geode/internal/process/FileProcessControllerIntegrationJUnitTest.java
      • geode-core/src/test/java/org/apache/geode/internal/process/LocalProcessControllerJUnitTest.java
      • geode-core/src/test/java/org/apache/geode/internal/process/LocalProcessLauncherDUnitTest.java
      • geode-core/src/test/java/org/apache/geode/internal/process/LocalProcessLauncherJUnitTest.java
      • geode-core/src/test/java/org/apache/geode/internal/process/NonBlockingProcessStreamReaderJUnitTest.java
      • geode-core/src/test/java/org/apache/geode/internal/process/PidFileJUnitTest.java
      • geode-core/src/test/java/org/apache/geode/internal/process/ProcessControllerFactoryJUnitTest.java

        Issue Links

          Activity

          Hide
          githubbot ASF GitHub Bot added a comment -

          GitHub user kirklund opened a pull request:

          https://github.com/apache/geode/pull/699

          GEODE-3413: overhaul launcher and process classes and tests

          This is primarily an overall of all ServerLauncher and LocatorLauncher
          tests and org.apache.geode.internal.process tests. The main classes in
          org.apachage.geode.internal.process package are also cleaned up.

          In addition, several bugs involving these classes and tests are fixed.

          Here is the complete list of tickets that are resolved in this overhaul:

          • GEODE-1229: LocatorLauncherRemoteJUnitTest.testStartOverwritesStalePidFile
          • GEODE-2791: LocatorLauncherAssemblyIntegrationTest.testLocatorStopsWhenJmxPortIsNonZero fails intermittently with AssertionError
          • GEODE-1308: CI failure: LocatorLauncherTest.testSetBindAddressToNonLocalHost
          • GEODE-1309: CI failure: ServerLauncherTest.testSetServerBindAddressToNonLocalHost
          • GEODE-3193: locator pid file is removed even if there was a problem while shutting down
          • GEODE-3413: Overhaul launcher tests and process tests
          • GEODE-3414: Cleanup org.apache.geode.internal.process package

          Note I moved all useful tests from LocatorLauncherAssemblyIntegrationTest
          into the other launcher tests in geode-core.

          You can merge this pull request into a Git repository by running:

          $ git pull https://github.com/kirklund/geode GEODE-3183-3413-3414

          Alternatively you can review and apply these changes as the patch at:

          https://github.com/apache/geode/pull/699.patch

          To close this pull request, make a commit to your master/trunk branch
          with (at least) the following in the commit message:

          This closes #699


          commit 69cdd5cbc7423577b0a5fcde5f8da486437fa387
          Author: Kirk Lund <klund@apache.org>
          Date: 2017-07-10T19:30:09Z

          GEODE-3413: overhaul launcher and process classes and tests

          This is primarily an overall of all ServerLauncher and LocatorLauncher
          tests and org.apache.geode.internal.process tests. The main classes in
          org.apachage.geode.internal.process package are also cleaned up.

          In addition, several bugs involving these classes and tests are fixed.

          Here is the complete list of tickets that are resolved in this overhaul:

          • GEODE-1229: LocatorLauncherRemoteJUnitTest.testStartOverwritesStalePidFile
          • GEODE-2791: LocatorLauncherAssemblyIntegrationTest.testLocatorStopsWhenJmxPortIsNonZero fails intermittently with AssertionError
          • GEODE-1308: CI failure: LocatorLauncherTest.testSetBindAddressToNonLocalHost
          • GEODE-1309: CI failure: ServerLauncherTest.testSetServerBindAddressToNonLocalHost
          • GEODE-3193: locator pid file is removed even if there was a problem while shutting down
          • GEODE-3413: Overhaul launcher tests and process tests
          • GEODE-3414: Cleanup org.apache.geode.internal.process package

          Note I moved all useful tests from LocatorLauncherAssemblyIntegrationTest
          into the other launcher tests in geode-core.


          Show
          githubbot ASF GitHub Bot added a comment - GitHub user kirklund opened a pull request: https://github.com/apache/geode/pull/699 GEODE-3413 : overhaul launcher and process classes and tests This is primarily an overall of all ServerLauncher and LocatorLauncher tests and org.apache.geode.internal.process tests. The main classes in org.apachage.geode.internal.process package are also cleaned up. In addition, several bugs involving these classes and tests are fixed. Here is the complete list of tickets that are resolved in this overhaul: GEODE-1229 : LocatorLauncherRemoteJUnitTest.testStartOverwritesStalePidFile GEODE-2791 : LocatorLauncherAssemblyIntegrationTest.testLocatorStopsWhenJmxPortIsNonZero fails intermittently with AssertionError GEODE-1308 : CI failure: LocatorLauncherTest.testSetBindAddressToNonLocalHost GEODE-1309 : CI failure: ServerLauncherTest.testSetServerBindAddressToNonLocalHost GEODE-3193 : locator pid file is removed even if there was a problem while shutting down GEODE-3413 : Overhaul launcher tests and process tests GEODE-3414 : Cleanup org.apache.geode.internal.process package Note I moved all useful tests from LocatorLauncherAssemblyIntegrationTest into the other launcher tests in geode-core. You can merge this pull request into a Git repository by running: $ git pull https://github.com/kirklund/geode GEODE-3183 -3413-3414 Alternatively you can review and apply these changes as the patch at: https://github.com/apache/geode/pull/699.patch To close this pull request, make a commit to your master/trunk branch with (at least) the following in the commit message: This closes #699 commit 69cdd5cbc7423577b0a5fcde5f8da486437fa387 Author: Kirk Lund <klund@apache.org> Date: 2017-07-10T19:30:09Z GEODE-3413 : overhaul launcher and process classes and tests This is primarily an overall of all ServerLauncher and LocatorLauncher tests and org.apache.geode.internal.process tests. The main classes in org.apachage.geode.internal.process package are also cleaned up. In addition, several bugs involving these classes and tests are fixed. Here is the complete list of tickets that are resolved in this overhaul: GEODE-1229 : LocatorLauncherRemoteJUnitTest.testStartOverwritesStalePidFile GEODE-2791 : LocatorLauncherAssemblyIntegrationTest.testLocatorStopsWhenJmxPortIsNonZero fails intermittently with AssertionError GEODE-1308 : CI failure: LocatorLauncherTest.testSetBindAddressToNonLocalHost GEODE-1309 : CI failure: ServerLauncherTest.testSetServerBindAddressToNonLocalHost GEODE-3193 : locator pid file is removed even if there was a problem while shutting down GEODE-3413 : Overhaul launcher tests and process tests GEODE-3414 : Cleanup org.apache.geode.internal.process package Note I moved all useful tests from LocatorLauncherAssemblyIntegrationTest into the other launcher tests in geode-core.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132281558

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherIntegrationTest.java —
          @@ -47,26 +50,21 @@

          @Before
          public void setUp() throws Exception

          { - this.gemfirePropertiesFile = - this.temporaryFolder.newFile(DistributionConfig.GEMFIRE_PREFIX + "properties"); + propertiesFile = temporaryFolder.newFile(GEMFIRE_PREFIX + "properties"); - this.expectedGemfireProperties = new Properties(); - this.expectedGemfireProperties.setProperty(NAME, "memberOne"); - this.expectedGemfireProperties.setProperty(GROUPS, "groupOne, groupTwo"); - this.expectedGemfireProperties.store(new FileWriter(this.gemfirePropertiesFile, false), - this.testName.getMethodName()); + expectedProperties = new Properties(); + expectedProperties.setProperty(NAME, "memberOne"); + expectedProperties.setProperty(GROUPS, "groupOne, groupTwo"); + expectedProperties.store(new FileWriter(propertiesFile, false), testName.getMethodName()); - assertThat(this.gemfirePropertiesFile).isNotNull(); - assertThat(this.gemfirePropertiesFile.exists()).isTrue(); - assertThat(this.gemfirePropertiesFile.isFile()).isTrue(); + assertThat(propertiesFile).exists().isFile(); }

          @Test

          • public void testLoadGemFirePropertiesFromFile() throws Exception {
          • final Properties actualGemFireProperties =
          • AbstractLauncher.loadGemFireProperties(this.gemfirePropertiesFile.toURI().toURL());
            + public void loadGemFirePropertiesFromFile() throws Exception { + Properties loadedProperties = loadGemFireProperties(propertiesFile.toURI().toURL()); - assertThat(actualGemFireProperties).isNotNull(); - assertThat(actualGemFireProperties).isEqualTo(this.expectedGemfireProperties); + assertThat(loadedProperties).isEqualTo(expectedProperties); }

            +

              • End diff –

          nit-pick: unnecessary blank line

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132281558 — Diff: geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherIntegrationTest.java — @@ -47,26 +50,21 @@ @Before public void setUp() throws Exception { - this.gemfirePropertiesFile = - this.temporaryFolder.newFile(DistributionConfig.GEMFIRE_PREFIX + "properties"); + propertiesFile = temporaryFolder.newFile(GEMFIRE_PREFIX + "properties"); - this.expectedGemfireProperties = new Properties(); - this.expectedGemfireProperties.setProperty(NAME, "memberOne"); - this.expectedGemfireProperties.setProperty(GROUPS, "groupOne, groupTwo"); - this.expectedGemfireProperties.store(new FileWriter(this.gemfirePropertiesFile, false), - this.testName.getMethodName()); + expectedProperties = new Properties(); + expectedProperties.setProperty(NAME, "memberOne"); + expectedProperties.setProperty(GROUPS, "groupOne, groupTwo"); + expectedProperties.store(new FileWriter(propertiesFile, false), testName.getMethodName()); - assertThat(this.gemfirePropertiesFile).isNotNull(); - assertThat(this.gemfirePropertiesFile.exists()).isTrue(); - assertThat(this.gemfirePropertiesFile.isFile()).isTrue(); + assertThat(propertiesFile).exists().isFile(); } @Test public void testLoadGemFirePropertiesFromFile() throws Exception { final Properties actualGemFireProperties = AbstractLauncher.loadGemFireProperties(this.gemfirePropertiesFile.toURI().toURL()); + public void loadGemFirePropertiesFromFile() throws Exception { + Properties loadedProperties = loadGemFireProperties(propertiesFile.toURI().toURL()); - assertThat(actualGemFireProperties).isNotNull(); - assertThat(actualGemFireProperties).isEqualTo(this.expectedGemfireProperties); + assertThat(loadedProperties).isEqualTo(expectedProperties); } + End diff – nit-pick: unnecessary blank line
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132285291

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherTest.java —
          @@ -14,253 +14,370 @@
          */
          package org.apache.geode.distributed;

          +import static java.util.concurrent.TimeUnit.DAYS;
          +import static java.util.concurrent.TimeUnit.HOURS;
          +import static java.util.concurrent.TimeUnit.MILLISECONDS;
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static java.util.concurrent.TimeUnit.SECONDS;
          +import static org.apache.geode.distributed.AbstractLauncher.ServiceState.toDaysHoursMinutesSeconds;
          import static org.apache.geode.distributed.ConfigurationProperties.NAME;
          -import static org.junit.Assert.assertEquals;
          -import static org.junit.Assert.assertFalse;
          -import static org.junit.Assert.assertNotNull;
          -import static org.junit.Assert.assertNull;
          -import static org.junit.Assert.assertTrue;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.assertj.core.api.Assertions.entry;
          import static org.mockito.Mockito.mock;
          import static org.mockito.Mockito.times;
          import static org.mockito.Mockito.verify;

          +import java.net.URL;
          +import java.util.Properties;
          +
          import org.apache.commons.lang.StringUtils;
          -import org.apache.geode.test.junit.categories.UnitTest;
          import org.junit.Test;
          import org.junit.experimental.categories.Category;

          -import java.net.MalformedURLException;
          -import java.net.URL;
          -import java.util.Properties;
          -import java.util.concurrent.TimeUnit;
          +import org.apache.geode.test.junit.categories.UnitTest;

          /**

          • * The AbstractLauncherTest class is a test suite of unit tests testing the contract and
          • * functionality of the AbstractLauncher class.
          • * <p/>
          • *
          • * @see org.apache.geode.distributed.AbstractLauncher
          • * @see org.junit.Assert
          • * @see org.junit.Test
            + * Unit tests for {@link AbstractLauncher}

            .
            + *

          • @since GemFire 7.0
            */
            @Category(UnitTest.class)
            public class AbstractLauncherTest {
          • private AbstractLauncher<?> createAbstractLauncher(final String memberName,
          • final String memberId) { - return new FakeServiceLauncher(memberName, memberId); - }

            -
            @Test

          • public void shouldBeMockable() throws Exception {
            + public void canBeMocked() throws Exception { AbstractLauncher mockAbstractLauncher = mock(AbstractLauncher.class); mockAbstractLauncher.setDebug(true); verify(mockAbstractLauncher, times(1)).setDebug(true); }

          @Test

          • public void testIsSet() {
          • final Properties properties = new Properties();
            + public void isSetReturnsFalseIfPropertyDoesNotExist() throws Exception { + assertThat(AbstractLauncher.isSet(new Properties(), NAME)).isFalse(); + }
          • assertFalse(properties.containsKey(NAME));
          • assertFalse(AbstractLauncher.isSet(properties, NAME));
            + @Test
            + public void isSetReturnsFalseIfPropertyHasEmptyValue() throws Exception { + Properties properties = new Properties(); properties.setProperty(NAME, ""); - assertTrue(properties.containsKey(NAME)); - assertFalse(AbstractLauncher.isSet(properties, NAME)); + assertThat(AbstractLauncher.isSet(properties, NAME)).isFalse(); + }

            +
            + @Test
            + public void isSetReturnsFalseIfPropertyHasBlankValue() throws Exception

            { + Properties properties = new Properties(); properties.setProperty(NAME, " "); - assertTrue(properties.containsKey(NAME)); - assertFalse(AbstractLauncher.isSet(properties, NAME)); + assertThat(AbstractLauncher.isSet(properties, NAME)).isFalse(); + }

            +
            + @Test
            + public void isSetReturnsFalseIfPropertyHasRealValue() throws Exception {

              • End diff –

          Shouldn't this test name be 'isSetReturnsTrueIfPropertyHasRealValue'

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132285291 — Diff: geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherTest.java — @@ -14,253 +14,370 @@ */ package org.apache.geode.distributed; +import static java.util.concurrent.TimeUnit.DAYS; +import static java.util.concurrent.TimeUnit.HOURS; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.apache.geode.distributed.AbstractLauncher.ServiceState.toDaysHoursMinutesSeconds; import static org.apache.geode.distributed.ConfigurationProperties.NAME; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import java.net.URL; +import java.util.Properties; + import org.apache.commons.lang.StringUtils; -import org.apache.geode.test.junit.categories.UnitTest; import org.junit.Test; import org.junit.experimental.categories.Category; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Properties; -import java.util.concurrent.TimeUnit; +import org.apache.geode.test.junit.categories.UnitTest; /** * The AbstractLauncherTest class is a test suite of unit tests testing the contract and * functionality of the AbstractLauncher class. * <p/> * * @see org.apache.geode.distributed.AbstractLauncher * @see org.junit.Assert * @see org.junit.Test + * Unit tests for {@link AbstractLauncher} . + * @since GemFire 7.0 */ @Category(UnitTest.class) public class AbstractLauncherTest { private AbstractLauncher<?> createAbstractLauncher(final String memberName, final String memberId) { - return new FakeServiceLauncher(memberName, memberId); - } - @Test public void shouldBeMockable() throws Exception { + public void canBeMocked() throws Exception { AbstractLauncher mockAbstractLauncher = mock(AbstractLauncher.class); mockAbstractLauncher.setDebug(true); verify(mockAbstractLauncher, times(1)).setDebug(true); } @Test public void testIsSet() { final Properties properties = new Properties(); + public void isSetReturnsFalseIfPropertyDoesNotExist() throws Exception { + assertThat(AbstractLauncher.isSet(new Properties(), NAME)).isFalse(); + } assertFalse(properties.containsKey(NAME)); assertFalse(AbstractLauncher.isSet(properties, NAME)); + @Test + public void isSetReturnsFalseIfPropertyHasEmptyValue() throws Exception { + Properties properties = new Properties(); properties.setProperty(NAME, ""); - assertTrue(properties.containsKey(NAME)); - assertFalse(AbstractLauncher.isSet(properties, NAME)); + assertThat(AbstractLauncher.isSet(properties, NAME)).isFalse(); + } + + @Test + public void isSetReturnsFalseIfPropertyHasBlankValue() throws Exception { + Properties properties = new Properties(); properties.setProperty(NAME, " "); - assertTrue(properties.containsKey(NAME)); - assertFalse(AbstractLauncher.isSet(properties, NAME)); + assertThat(AbstractLauncher.isSet(properties, NAME)).isFalse(); + } + + @Test + public void isSetReturnsFalseIfPropertyHasRealValue() throws Exception { End diff – Shouldn't this test name be 'isSetReturnsTrueIfPropertyHasRealValue'
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132287600

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherTest.java —
          @@ -14,253 +14,370 @@
          */
          package org.apache.geode.distributed;

          +import static java.util.concurrent.TimeUnit.DAYS;
          +import static java.util.concurrent.TimeUnit.HOURS;
          +import static java.util.concurrent.TimeUnit.MILLISECONDS;
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static java.util.concurrent.TimeUnit.SECONDS;
          +import static org.apache.geode.distributed.AbstractLauncher.ServiceState.toDaysHoursMinutesSeconds;
          import static org.apache.geode.distributed.ConfigurationProperties.NAME;
          -import static org.junit.Assert.assertEquals;
          -import static org.junit.Assert.assertFalse;
          -import static org.junit.Assert.assertNotNull;
          -import static org.junit.Assert.assertNull;
          -import static org.junit.Assert.assertTrue;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.assertj.core.api.Assertions.entry;
          import static org.mockito.Mockito.mock;
          import static org.mockito.Mockito.times;
          import static org.mockito.Mockito.verify;

          +import java.net.URL;
          +import java.util.Properties;
          +
          import org.apache.commons.lang.StringUtils;
          -import org.apache.geode.test.junit.categories.UnitTest;
          import org.junit.Test;
          import org.junit.experimental.categories.Category;

          -import java.net.MalformedURLException;
          -import java.net.URL;
          -import java.util.Properties;
          -import java.util.concurrent.TimeUnit;
          +import org.apache.geode.test.junit.categories.UnitTest;

          /**

          • * The AbstractLauncherTest class is a test suite of unit tests testing the contract and
          • * functionality of the AbstractLauncher class.
          • * <p/>
          • *
          • * @see org.apache.geode.distributed.AbstractLauncher
          • * @see org.junit.Assert
          • * @see org.junit.Test
            + * Unit tests for {@link AbstractLauncher}

            .
            + *

          • @since GemFire 7.0
            */
            @Category(UnitTest.class)
            public class AbstractLauncherTest {
          • private AbstractLauncher<?> createAbstractLauncher(final String memberName,
          • final String memberId) { - return new FakeServiceLauncher(memberName, memberId); - }

            -
            @Test

          • public void shouldBeMockable() throws Exception {
            + public void canBeMocked() throws Exception { AbstractLauncher mockAbstractLauncher = mock(AbstractLauncher.class); mockAbstractLauncher.setDebug(true); verify(mockAbstractLauncher, times(1)).setDebug(true); }

          @Test

          • public void testIsSet() {
          • final Properties properties = new Properties();
            + public void isSetReturnsFalseIfPropertyDoesNotExist() throws Exception { + assertThat(AbstractLauncher.isSet(new Properties(), NAME)).isFalse(); + }
          • assertFalse(properties.containsKey(NAME));
          • assertFalse(AbstractLauncher.isSet(properties, NAME));
            + @Test
            + public void isSetReturnsFalseIfPropertyHasEmptyValue() throws Exception {
            + Properties properties = new Properties();

          properties.setProperty(NAME, "");
          — End diff –

          For consistency with following tests use 'StringUtils.EMPTY' instead of '""'.

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132287600 — Diff: geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherTest.java — @@ -14,253 +14,370 @@ */ package org.apache.geode.distributed; +import static java.util.concurrent.TimeUnit.DAYS; +import static java.util.concurrent.TimeUnit.HOURS; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.apache.geode.distributed.AbstractLauncher.ServiceState.toDaysHoursMinutesSeconds; import static org.apache.geode.distributed.ConfigurationProperties.NAME; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import java.net.URL; +import java.util.Properties; + import org.apache.commons.lang.StringUtils; -import org.apache.geode.test.junit.categories.UnitTest; import org.junit.Test; import org.junit.experimental.categories.Category; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Properties; -import java.util.concurrent.TimeUnit; +import org.apache.geode.test.junit.categories.UnitTest; /** * The AbstractLauncherTest class is a test suite of unit tests testing the contract and * functionality of the AbstractLauncher class. * <p/> * * @see org.apache.geode.distributed.AbstractLauncher * @see org.junit.Assert * @see org.junit.Test + * Unit tests for {@link AbstractLauncher} . + * @since GemFire 7.0 */ @Category(UnitTest.class) public class AbstractLauncherTest { private AbstractLauncher<?> createAbstractLauncher(final String memberName, final String memberId) { - return new FakeServiceLauncher(memberName, memberId); - } - @Test public void shouldBeMockable() throws Exception { + public void canBeMocked() throws Exception { AbstractLauncher mockAbstractLauncher = mock(AbstractLauncher.class); mockAbstractLauncher.setDebug(true); verify(mockAbstractLauncher, times(1)).setDebug(true); } @Test public void testIsSet() { final Properties properties = new Properties(); + public void isSetReturnsFalseIfPropertyDoesNotExist() throws Exception { + assertThat(AbstractLauncher.isSet(new Properties(), NAME)).isFalse(); + } assertFalse(properties.containsKey(NAME)); assertFalse(AbstractLauncher.isSet(properties, NAME)); + @Test + public void isSetReturnsFalseIfPropertyHasEmptyValue() throws Exception { + Properties properties = new Properties(); properties.setProperty(NAME, ""); — End diff – For consistency with following tests use 'StringUtils.EMPTY' instead of '""'.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132291477

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherTest.java —
          @@ -14,253 +14,370 @@
          */
          package org.apache.geode.distributed;

          +import static java.util.concurrent.TimeUnit.DAYS;
          +import static java.util.concurrent.TimeUnit.HOURS;
          +import static java.util.concurrent.TimeUnit.MILLISECONDS;
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static java.util.concurrent.TimeUnit.SECONDS;
          +import static org.apache.geode.distributed.AbstractLauncher.ServiceState.toDaysHoursMinutesSeconds;
          import static org.apache.geode.distributed.ConfigurationProperties.NAME;
          -import static org.junit.Assert.assertEquals;
          -import static org.junit.Assert.assertFalse;
          -import static org.junit.Assert.assertNotNull;
          -import static org.junit.Assert.assertNull;
          -import static org.junit.Assert.assertTrue;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.assertj.core.api.Assertions.entry;
          import static org.mockito.Mockito.mock;
          import static org.mockito.Mockito.times;
          import static org.mockito.Mockito.verify;

          +import java.net.URL;
          +import java.util.Properties;
          +
          import org.apache.commons.lang.StringUtils;
          -import org.apache.geode.test.junit.categories.UnitTest;
          import org.junit.Test;
          import org.junit.experimental.categories.Category;

          -import java.net.MalformedURLException;
          -import java.net.URL;
          -import java.util.Properties;
          -import java.util.concurrent.TimeUnit;
          +import org.apache.geode.test.junit.categories.UnitTest;

          /**

          • * The AbstractLauncherTest class is a test suite of unit tests testing the contract and
          • * functionality of the AbstractLauncher class.
          • * <p/>
          • *
          • * @see org.apache.geode.distributed.AbstractLauncher
          • * @see org.junit.Assert
          • * @see org.junit.Test
            + * Unit tests for {@link AbstractLauncher}

            .
            + *

          • @since GemFire 7.0
            */
            @Category(UnitTest.class)
            public class AbstractLauncherTest {
          • private AbstractLauncher<?> createAbstractLauncher(final String memberName,
          • final String memberId) { - return new FakeServiceLauncher(memberName, memberId); - }

            -
            @Test

          • public void shouldBeMockable() throws Exception {
            + public void canBeMocked() throws Exception { AbstractLauncher mockAbstractLauncher = mock(AbstractLauncher.class); mockAbstractLauncher.setDebug(true); verify(mockAbstractLauncher, times(1)).setDebug(true); }

          @Test

          • public void testIsSet() {
          • final Properties properties = new Properties();
            + public void isSetReturnsFalseIfPropertyDoesNotExist() throws Exception { + assertThat(AbstractLauncher.isSet(new Properties(), NAME)).isFalse(); + }
          • assertFalse(properties.containsKey(NAME));
          • assertFalse(AbstractLauncher.isSet(properties, NAME));
            + @Test
            + public void isSetReturnsFalseIfPropertyHasEmptyValue() throws Exception { + Properties properties = new Properties(); properties.setProperty(NAME, ""); - assertTrue(properties.containsKey(NAME)); - assertFalse(AbstractLauncher.isSet(properties, NAME)); + assertThat(AbstractLauncher.isSet(properties, NAME)).isFalse(); + }

            +
            + @Test
            + public void isSetReturnsFalseIfPropertyHasBlankValue() throws Exception

            { + Properties properties = new Properties(); properties.setProperty(NAME, " "); - assertTrue(properties.containsKey(NAME)); - assertFalse(AbstractLauncher.isSet(properties, NAME)); + assertThat(AbstractLauncher.isSet(properties, NAME)).isFalse(); + }

            +
            + @Test
            + public void isSetReturnsFalseIfPropertyHasRealValue() throws Exception

            { + Properties properties = new Properties(); properties.setProperty(NAME, "memberOne"); - assertTrue(AbstractLauncher.isSet(properties, NAME)); - assertFalse(AbstractLauncher.isSet(properties, "NaMe")); + assertThat(AbstractLauncher.isSet(properties, NAME)).isTrue(); }

          @Test

          • public void testLoadGemFirePropertiesWithNullURL() {
          • final Properties properties = AbstractLauncher.loadGemFireProperties(null);
          • assertNotNull(properties);
          • assertTrue(properties.isEmpty());
            + public void isSetKeyIsCaseSensitive() throws Exception { + Properties properties = new Properties(); + + properties.setProperty(NAME, "memberOne"); + + assertThat(AbstractLauncher.isSet(properties, "NaMe")).isFalse(); }

          @Test

          • public void testLoadGemFirePropertiesWithNonExistingURL() throws MalformedURLException {
          • final Properties properties = AbstractLauncher
          • .loadGemFireProperties(new URL("file:///path/to/non_existing/gemfire.properties"));
          • assertNotNull(properties);
          • assertTrue(properties.isEmpty());
            + public void loadGemFirePropertiesWithNullURLReturnsEmptyProperties() throws Exception { + URL nullUrl = null; + + Properties properties = AbstractLauncher.loadGemFireProperties(nullUrl); + + assertThat(properties).isNotNull().isEmpty(); }

          @Test

          • public void testGetDistributedSystemProperties() {
          • AbstractLauncher<?> launcher = createAbstractLauncher("memberOne", "1");
            + public void loadGemFirePropertiesWithNonExistingURLReturnsEmptyProperties() throws Exception { + URL nonExistingUrl = new URL("file:///path/to/non_existing/gemfire.properties"); + + Properties properties = AbstractLauncher.loadGemFireProperties(nonExistingUrl); - assertNotNull(launcher); - assertEquals("1", launcher.getMemberId()); - assertEquals("memberOne", launcher.getMemberName()); + assertThat(properties).isNotNull().isEmpty(); + }
          • Properties distributedSystemProperties = launcher.getDistributedSystemProperties();
            + @Test
            + public void abstractLauncherHasMemberIdAndMemberName() throws Exception {
              • End diff –

          I don't see the need for all the tests that exercise methods that are overridden in the embedded test class for AbstractLauncher. Any test that calls, for instance, 'launcher.getMemberId()' is only testing the test class, not the default implementation in the abstract class.

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132291477 — Diff: geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherTest.java — @@ -14,253 +14,370 @@ */ package org.apache.geode.distributed; +import static java.util.concurrent.TimeUnit.DAYS; +import static java.util.concurrent.TimeUnit.HOURS; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.apache.geode.distributed.AbstractLauncher.ServiceState.toDaysHoursMinutesSeconds; import static org.apache.geode.distributed.ConfigurationProperties.NAME; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import java.net.URL; +import java.util.Properties; + import org.apache.commons.lang.StringUtils; -import org.apache.geode.test.junit.categories.UnitTest; import org.junit.Test; import org.junit.experimental.categories.Category; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Properties; -import java.util.concurrent.TimeUnit; +import org.apache.geode.test.junit.categories.UnitTest; /** * The AbstractLauncherTest class is a test suite of unit tests testing the contract and * functionality of the AbstractLauncher class. * <p/> * * @see org.apache.geode.distributed.AbstractLauncher * @see org.junit.Assert * @see org.junit.Test + * Unit tests for {@link AbstractLauncher} . + * @since GemFire 7.0 */ @Category(UnitTest.class) public class AbstractLauncherTest { private AbstractLauncher<?> createAbstractLauncher(final String memberName, final String memberId) { - return new FakeServiceLauncher(memberName, memberId); - } - @Test public void shouldBeMockable() throws Exception { + public void canBeMocked() throws Exception { AbstractLauncher mockAbstractLauncher = mock(AbstractLauncher.class); mockAbstractLauncher.setDebug(true); verify(mockAbstractLauncher, times(1)).setDebug(true); } @Test public void testIsSet() { final Properties properties = new Properties(); + public void isSetReturnsFalseIfPropertyDoesNotExist() throws Exception { + assertThat(AbstractLauncher.isSet(new Properties(), NAME)).isFalse(); + } assertFalse(properties.containsKey(NAME)); assertFalse(AbstractLauncher.isSet(properties, NAME)); + @Test + public void isSetReturnsFalseIfPropertyHasEmptyValue() throws Exception { + Properties properties = new Properties(); properties.setProperty(NAME, ""); - assertTrue(properties.containsKey(NAME)); - assertFalse(AbstractLauncher.isSet(properties, NAME)); + assertThat(AbstractLauncher.isSet(properties, NAME)).isFalse(); + } + + @Test + public void isSetReturnsFalseIfPropertyHasBlankValue() throws Exception { + Properties properties = new Properties(); properties.setProperty(NAME, " "); - assertTrue(properties.containsKey(NAME)); - assertFalse(AbstractLauncher.isSet(properties, NAME)); + assertThat(AbstractLauncher.isSet(properties, NAME)).isFalse(); + } + + @Test + public void isSetReturnsFalseIfPropertyHasRealValue() throws Exception { + Properties properties = new Properties(); properties.setProperty(NAME, "memberOne"); - assertTrue(AbstractLauncher.isSet(properties, NAME)); - assertFalse(AbstractLauncher.isSet(properties, "NaMe")); + assertThat(AbstractLauncher.isSet(properties, NAME)).isTrue(); } @Test public void testLoadGemFirePropertiesWithNullURL() { final Properties properties = AbstractLauncher.loadGemFireProperties(null); assertNotNull(properties); assertTrue(properties.isEmpty()); + public void isSetKeyIsCaseSensitive() throws Exception { + Properties properties = new Properties(); + + properties.setProperty(NAME, "memberOne"); + + assertThat(AbstractLauncher.isSet(properties, "NaMe")).isFalse(); } @Test public void testLoadGemFirePropertiesWithNonExistingURL() throws MalformedURLException { final Properties properties = AbstractLauncher .loadGemFireProperties(new URL("file:///path/to/non_existing/gemfire.properties")); assertNotNull(properties); assertTrue(properties.isEmpty()); + public void loadGemFirePropertiesWithNullURLReturnsEmptyProperties() throws Exception { + URL nullUrl = null; + + Properties properties = AbstractLauncher.loadGemFireProperties(nullUrl); + + assertThat(properties).isNotNull().isEmpty(); } @Test public void testGetDistributedSystemProperties() { AbstractLauncher<?> launcher = createAbstractLauncher("memberOne", "1"); + public void loadGemFirePropertiesWithNonExistingURLReturnsEmptyProperties() throws Exception { + URL nonExistingUrl = new URL("file:///path/to/non_existing/gemfire.properties"); + + Properties properties = AbstractLauncher.loadGemFireProperties(nonExistingUrl); - assertNotNull(launcher); - assertEquals("1", launcher.getMemberId()); - assertEquals("memberOne", launcher.getMemberName()); + assertThat(properties).isNotNull().isEmpty(); + } Properties distributedSystemProperties = launcher.getDistributedSystemProperties(); + @Test + public void abstractLauncherHasMemberIdAndMemberName() throws Exception { End diff – I don't see the need for all the tests that exercise methods that are overridden in the embedded test class for AbstractLauncher. Any test that calls, for instance, 'launcher.getMemberId()' is only testing the test class, not the default implementation in the abstract class.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132301005

          — Diff: geode-core/src/test/java/org/apache/geode/internal/process/lang/AvailablePidTest.java —
          @@ -0,0 +1,74 @@
          +/*
          + * 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.geode.internal.process.lang;
          — End diff –

          Ideally there would be a test for 'findAvailablePid(existing processPid)' returns a random pid.

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132301005 — Diff: geode-core/src/test/java/org/apache/geode/internal/process/lang/AvailablePidTest.java — @@ -0,0 +1,74 @@ +/* + * 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.geode.internal.process.lang; — End diff – Ideally there would be a test for 'findAvailablePid(existing processPid)' returns a random pid.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132299177

          — Diff: geode-core/src/main/java/org/apache/geode/config/internal/ClusterConfigurationNotAvailableException.java —
          @@ -0,0 +1,29 @@
          +/*
          + * 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.geode.config.internal;
          — End diff –

          Do we want to use org.apache.geode.internal.config instead?

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132299177 — Diff: geode-core/src/main/java/org/apache/geode/config/internal/ClusterConfigurationNotAvailableException.java — @@ -0,0 +1,29 @@ +/* + * 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.geode.config.internal; — End diff – Do we want to use org.apache.geode.internal.config instead?
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132305098

          — Diff: geode-core/src/test/java/org/apache/geode/internal/process/AbstractProcessStreamReaderIntegrationTest.java —
          @@ -0,0 +1,234 @@
          +/*
          + * 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.geode.internal.process;
          +
          +import static java.util.concurrent.TimeUnit.MILLISECONDS;
          +import static org.apache.commons.lang.SystemUtils.LINE_SEPARATOR;
          +
          +import java.io.File;
          +import java.util.ArrayList;
          +import java.util.Arrays;
          +import java.util.List;
          +
          +import org.awaitility.Awaitility;
          +import org.awaitility.core.ConditionFactory;
          +import org.junit.After;
          +
          +import org.apache.geode.internal.util.StopWatch;
          +
          +/**
          + * Abstract base class for functional integration testing of

          {@link ProcessStreamReader}.
          + */
          +public abstract class AbstractProcessStreamReaderIntegrationTest {
          +
          + /** Timeout to join to a running ProcessStreamReader thread */
          + protected static final int READER_JOIN_TIMEOUT_MILLIS = 20 * 1000;
          +
          + /** Sleep timeout for {@link ProcessSleeps} instead of sleeping Long.MAX_VALUE */
          + private static final int PROCESS_FAILSAFE_TIMEOUT_MILLIS = 10 * 60 * 1000;
          +
          + /** Additional time for launched processes to live before terminating */
          + private static final int PROCESS_TIME_TO_LIVE_MILLIS = 3 * 500;
          +
          + /** Timeout to wait for a new {@link ProcessStreamReader}

          to be running */
          + private static final int WAIT_FOR_READER_IS_RUNNING_TIMEOUT_MILLIS = 20 * 1000;
          +
          + protected Process process;
          + protected ProcessStreamReader stderr;
          + protected ProcessStreamReader stdout;
          +
          + @After
          + public void afterProcessStreamReaderTestCase() throws Exception {
          + if (stderr != null)

          { + stderr.stop(); + }

          + if (stdout != null)

          { + stdout.stop(); + }

          + if (process != null) {
          + try

          { + process.getErrorStream().close(); + process.getInputStream().close(); + process.getOutputStream().close(); + }

          finally

          { + // this is async and can require more than 10 seconds on slower machines + process.destroy(); + }

          + }
          + }
          +
          + protected ConditionFactory await()

          { + return Awaitility.await().atMost(WAIT_FOR_READER_IS_RUNNING_TIMEOUT_MILLIS, MILLISECONDS); + }

          +
          + protected static boolean isAlive(final Process process) {
          — End diff –

          All callers to this method should now be changed to use the new API instead of this old hack:
          ```java
          process.isAlive()
          ```

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132305098 — Diff: geode-core/src/test/java/org/apache/geode/internal/process/AbstractProcessStreamReaderIntegrationTest.java — @@ -0,0 +1,234 @@ +/* + * 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.geode.internal.process; + +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.apache.commons.lang.SystemUtils.LINE_SEPARATOR; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.awaitility.Awaitility; +import org.awaitility.core.ConditionFactory; +import org.junit.After; + +import org.apache.geode.internal.util.StopWatch; + +/** + * Abstract base class for functional integration testing of {@link ProcessStreamReader}. + */ +public abstract class AbstractProcessStreamReaderIntegrationTest { + + /** Timeout to join to a running ProcessStreamReader thread */ + protected static final int READER_JOIN_TIMEOUT_MILLIS = 20 * 1000; + + /** Sleep timeout for {@link ProcessSleeps} instead of sleeping Long.MAX_VALUE */ + private static final int PROCESS_FAILSAFE_TIMEOUT_MILLIS = 10 * 60 * 1000; + + /** Additional time for launched processes to live before terminating */ + private static final int PROCESS_TIME_TO_LIVE_MILLIS = 3 * 500; + + /** Timeout to wait for a new {@link ProcessStreamReader} to be running */ + private static final int WAIT_FOR_READER_IS_RUNNING_TIMEOUT_MILLIS = 20 * 1000; + + protected Process process; + protected ProcessStreamReader stderr; + protected ProcessStreamReader stdout; + + @After + public void afterProcessStreamReaderTestCase() throws Exception { + if (stderr != null) { + stderr.stop(); + } + if (stdout != null) { + stdout.stop(); + } + if (process != null) { + try { + process.getErrorStream().close(); + process.getInputStream().close(); + process.getOutputStream().close(); + } finally { + // this is async and can require more than 10 seconds on slower machines + process.destroy(); + } + } + } + + protected ConditionFactory await() { + return Awaitility.await().atMost(WAIT_FOR_READER_IS_RUNNING_TIMEOUT_MILLIS, MILLISECONDS); + } + + protected static boolean isAlive(final Process process) { — End diff – All callers to this method should now be changed to use the new API instead of this old hack: ```java process.isAlive() ```
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132307026

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherTest.java —
          @@ -14,253 +14,370 @@
          */
          package org.apache.geode.distributed;

          +import static java.util.concurrent.TimeUnit.DAYS;
          +import static java.util.concurrent.TimeUnit.HOURS;
          +import static java.util.concurrent.TimeUnit.MILLISECONDS;
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static java.util.concurrent.TimeUnit.SECONDS;
          +import static org.apache.geode.distributed.AbstractLauncher.ServiceState.toDaysHoursMinutesSeconds;
          import static org.apache.geode.distributed.ConfigurationProperties.NAME;
          -import static org.junit.Assert.assertEquals;
          -import static org.junit.Assert.assertFalse;
          -import static org.junit.Assert.assertNotNull;
          -import static org.junit.Assert.assertNull;
          -import static org.junit.Assert.assertTrue;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.assertj.core.api.Assertions.entry;
          import static org.mockito.Mockito.mock;
          import static org.mockito.Mockito.times;
          import static org.mockito.Mockito.verify;

          +import java.net.URL;
          +import java.util.Properties;
          +
          import org.apache.commons.lang.StringUtils;
          -import org.apache.geode.test.junit.categories.UnitTest;
          import org.junit.Test;
          import org.junit.experimental.categories.Category;

          -import java.net.MalformedURLException;
          -import java.net.URL;
          -import java.util.Properties;
          -import java.util.concurrent.TimeUnit;
          +import org.apache.geode.test.junit.categories.UnitTest;

          /**

          • * The AbstractLauncherTest class is a test suite of unit tests testing the contract and
          • * functionality of the AbstractLauncher class.
          • * <p/>
          • *
          • * @see org.apache.geode.distributed.AbstractLauncher
          • * @see org.junit.Assert
          • * @see org.junit.Test
            + * Unit tests for {@link AbstractLauncher}

            .
            + *

          • @since GemFire 7.0
            */
            @Category(UnitTest.class)
            public class AbstractLauncherTest {
          • private AbstractLauncher<?> createAbstractLauncher(final String memberName,
          • final String memberId) { - return new FakeServiceLauncher(memberName, memberId); - }

            -
            @Test

          • public void shouldBeMockable() throws Exception {
            + public void canBeMocked() throws Exception { AbstractLauncher mockAbstractLauncher = mock(AbstractLauncher.class); mockAbstractLauncher.setDebug(true); verify(mockAbstractLauncher, times(1)).setDebug(true); }

          @Test

          • public void testIsSet() {
          • final Properties properties = new Properties();
            + public void isSetReturnsFalseIfPropertyDoesNotExist() throws Exception { + assertThat(AbstractLauncher.isSet(new Properties(), NAME)).isFalse(); + }
          • assertFalse(properties.containsKey(NAME));
          • assertFalse(AbstractLauncher.isSet(properties, NAME));
            + @Test
            + public void isSetReturnsFalseIfPropertyHasEmptyValue() throws Exception { + Properties properties = new Properties(); properties.setProperty(NAME, ""); - assertTrue(properties.containsKey(NAME)); - assertFalse(AbstractLauncher.isSet(properties, NAME)); + assertThat(AbstractLauncher.isSet(properties, NAME)).isFalse(); + }

            +
            + @Test
            + public void isSetReturnsFalseIfPropertyHasBlankValue() throws Exception

            { + Properties properties = new Properties(); properties.setProperty(NAME, " "); - assertTrue(properties.containsKey(NAME)); - assertFalse(AbstractLauncher.isSet(properties, NAME)); + assertThat(AbstractLauncher.isSet(properties, NAME)).isFalse(); + }

            +
            + @Test
            + public void isSetReturnsFalseIfPropertyHasRealValue() throws Exception {

              • End diff –

          Nice catch!

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132307026 — Diff: geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherTest.java — @@ -14,253 +14,370 @@ */ package org.apache.geode.distributed; +import static java.util.concurrent.TimeUnit.DAYS; +import static java.util.concurrent.TimeUnit.HOURS; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.apache.geode.distributed.AbstractLauncher.ServiceState.toDaysHoursMinutesSeconds; import static org.apache.geode.distributed.ConfigurationProperties.NAME; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import java.net.URL; +import java.util.Properties; + import org.apache.commons.lang.StringUtils; -import org.apache.geode.test.junit.categories.UnitTest; import org.junit.Test; import org.junit.experimental.categories.Category; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Properties; -import java.util.concurrent.TimeUnit; +import org.apache.geode.test.junit.categories.UnitTest; /** * The AbstractLauncherTest class is a test suite of unit tests testing the contract and * functionality of the AbstractLauncher class. * <p/> * * @see org.apache.geode.distributed.AbstractLauncher * @see org.junit.Assert * @see org.junit.Test + * Unit tests for {@link AbstractLauncher} . + * @since GemFire 7.0 */ @Category(UnitTest.class) public class AbstractLauncherTest { private AbstractLauncher<?> createAbstractLauncher(final String memberName, final String memberId) { - return new FakeServiceLauncher(memberName, memberId); - } - @Test public void shouldBeMockable() throws Exception { + public void canBeMocked() throws Exception { AbstractLauncher mockAbstractLauncher = mock(AbstractLauncher.class); mockAbstractLauncher.setDebug(true); verify(mockAbstractLauncher, times(1)).setDebug(true); } @Test public void testIsSet() { final Properties properties = new Properties(); + public void isSetReturnsFalseIfPropertyDoesNotExist() throws Exception { + assertThat(AbstractLauncher.isSet(new Properties(), NAME)).isFalse(); + } assertFalse(properties.containsKey(NAME)); assertFalse(AbstractLauncher.isSet(properties, NAME)); + @Test + public void isSetReturnsFalseIfPropertyHasEmptyValue() throws Exception { + Properties properties = new Properties(); properties.setProperty(NAME, ""); - assertTrue(properties.containsKey(NAME)); - assertFalse(AbstractLauncher.isSet(properties, NAME)); + assertThat(AbstractLauncher.isSet(properties, NAME)).isFalse(); + } + + @Test + public void isSetReturnsFalseIfPropertyHasBlankValue() throws Exception { + Properties properties = new Properties(); properties.setProperty(NAME, " "); - assertTrue(properties.containsKey(NAME)); - assertFalse(AbstractLauncher.isSet(properties, NAME)); + assertThat(AbstractLauncher.isSet(properties, NAME)).isFalse(); + } + + @Test + public void isSetReturnsFalseIfPropertyHasRealValue() throws Exception { End diff – Nice catch!
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132308040

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherTest.java —
          @@ -14,253 +14,370 @@
          */
          package org.apache.geode.distributed;

          +import static java.util.concurrent.TimeUnit.DAYS;
          +import static java.util.concurrent.TimeUnit.HOURS;
          +import static java.util.concurrent.TimeUnit.MILLISECONDS;
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static java.util.concurrent.TimeUnit.SECONDS;
          +import static org.apache.geode.distributed.AbstractLauncher.ServiceState.toDaysHoursMinutesSeconds;
          import static org.apache.geode.distributed.ConfigurationProperties.NAME;
          -import static org.junit.Assert.assertEquals;
          -import static org.junit.Assert.assertFalse;
          -import static org.junit.Assert.assertNotNull;
          -import static org.junit.Assert.assertNull;
          -import static org.junit.Assert.assertTrue;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.assertj.core.api.Assertions.entry;
          import static org.mockito.Mockito.mock;
          import static org.mockito.Mockito.times;
          import static org.mockito.Mockito.verify;

          +import java.net.URL;
          +import java.util.Properties;
          +
          import org.apache.commons.lang.StringUtils;
          -import org.apache.geode.test.junit.categories.UnitTest;
          import org.junit.Test;
          import org.junit.experimental.categories.Category;

          -import java.net.MalformedURLException;
          -import java.net.URL;
          -import java.util.Properties;
          -import java.util.concurrent.TimeUnit;
          +import org.apache.geode.test.junit.categories.UnitTest;

          /**

          • * The AbstractLauncherTest class is a test suite of unit tests testing the contract and
          • * functionality of the AbstractLauncher class.
          • * <p/>
          • *
          • * @see org.apache.geode.distributed.AbstractLauncher
          • * @see org.junit.Assert
          • * @see org.junit.Test
            + * Unit tests for {@link AbstractLauncher}

            .
            + *

          • @since GemFire 7.0
            */
            @Category(UnitTest.class)
            public class AbstractLauncherTest {
          • private AbstractLauncher<?> createAbstractLauncher(final String memberName,
          • final String memberId) { - return new FakeServiceLauncher(memberName, memberId); - }

            -
            @Test

          • public void shouldBeMockable() throws Exception {
            + public void canBeMocked() throws Exception { AbstractLauncher mockAbstractLauncher = mock(AbstractLauncher.class); mockAbstractLauncher.setDebug(true); verify(mockAbstractLauncher, times(1)).setDebug(true); }

          @Test

          • public void testIsSet() {
          • final Properties properties = new Properties();
            + public void isSetReturnsFalseIfPropertyDoesNotExist() throws Exception { + assertThat(AbstractLauncher.isSet(new Properties(), NAME)).isFalse(); + }
          • assertFalse(properties.containsKey(NAME));
          • assertFalse(AbstractLauncher.isSet(properties, NAME));
            + @Test
            + public void isSetReturnsFalseIfPropertyHasEmptyValue() throws Exception {
            + Properties properties = new Properties();

          properties.setProperty(NAME, "");
          — End diff –

          Done! I made this change in all launcher and process main classes and test classes.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132308040 — Diff: geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherTest.java — @@ -14,253 +14,370 @@ */ package org.apache.geode.distributed; +import static java.util.concurrent.TimeUnit.DAYS; +import static java.util.concurrent.TimeUnit.HOURS; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.apache.geode.distributed.AbstractLauncher.ServiceState.toDaysHoursMinutesSeconds; import static org.apache.geode.distributed.ConfigurationProperties.NAME; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import java.net.URL; +import java.util.Properties; + import org.apache.commons.lang.StringUtils; -import org.apache.geode.test.junit.categories.UnitTest; import org.junit.Test; import org.junit.experimental.categories.Category; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Properties; -import java.util.concurrent.TimeUnit; +import org.apache.geode.test.junit.categories.UnitTest; /** * The AbstractLauncherTest class is a test suite of unit tests testing the contract and * functionality of the AbstractLauncher class. * <p/> * * @see org.apache.geode.distributed.AbstractLauncher * @see org.junit.Assert * @see org.junit.Test + * Unit tests for {@link AbstractLauncher} . + * @since GemFire 7.0 */ @Category(UnitTest.class) public class AbstractLauncherTest { private AbstractLauncher<?> createAbstractLauncher(final String memberName, final String memberId) { - return new FakeServiceLauncher(memberName, memberId); - } - @Test public void shouldBeMockable() throws Exception { + public void canBeMocked() throws Exception { AbstractLauncher mockAbstractLauncher = mock(AbstractLauncher.class); mockAbstractLauncher.setDebug(true); verify(mockAbstractLauncher, times(1)).setDebug(true); } @Test public void testIsSet() { final Properties properties = new Properties(); + public void isSetReturnsFalseIfPropertyDoesNotExist() throws Exception { + assertThat(AbstractLauncher.isSet(new Properties(), NAME)).isFalse(); + } assertFalse(properties.containsKey(NAME)); assertFalse(AbstractLauncher.isSet(properties, NAME)); + @Test + public void isSetReturnsFalseIfPropertyHasEmptyValue() throws Exception { + Properties properties = new Properties(); properties.setProperty(NAME, ""); — End diff – Done! I made this change in all launcher and process main classes and test classes.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132308711

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherIntegrationTest.java —
          @@ -47,26 +50,21 @@

          @Before
          public void setUp() throws Exception

          { - this.gemfirePropertiesFile = - this.temporaryFolder.newFile(DistributionConfig.GEMFIRE_PREFIX + "properties"); + propertiesFile = temporaryFolder.newFile(GEMFIRE_PREFIX + "properties"); - this.expectedGemfireProperties = new Properties(); - this.expectedGemfireProperties.setProperty(NAME, "memberOne"); - this.expectedGemfireProperties.setProperty(GROUPS, "groupOne, groupTwo"); - this.expectedGemfireProperties.store(new FileWriter(this.gemfirePropertiesFile, false), - this.testName.getMethodName()); + expectedProperties = new Properties(); + expectedProperties.setProperty(NAME, "memberOne"); + expectedProperties.setProperty(GROUPS, "groupOne, groupTwo"); + expectedProperties.store(new FileWriter(propertiesFile, false), testName.getMethodName()); - assertThat(this.gemfirePropertiesFile).isNotNull(); - assertThat(this.gemfirePropertiesFile.exists()).isTrue(); - assertThat(this.gemfirePropertiesFile.isFile()).isTrue(); + assertThat(propertiesFile).exists().isFile(); }

          @Test

          • public void testLoadGemFirePropertiesFromFile() throws Exception {
          • final Properties actualGemFireProperties =
          • AbstractLauncher.loadGemFireProperties(this.gemfirePropertiesFile.toURI().toURL());
            + public void loadGemFirePropertiesFromFile() throws Exception { + Properties loadedProperties = loadGemFireProperties(propertiesFile.toURI().toURL()); - assertThat(actualGemFireProperties).isNotNull(); - assertThat(actualGemFireProperties).isEqualTo(this.expectedGemfireProperties); + assertThat(loadedProperties).isEqualTo(expectedProperties); }

            +

              • End diff –

          Removed from all classes in change-set.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132308711 — Diff: geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherIntegrationTest.java — @@ -47,26 +50,21 @@ @Before public void setUp() throws Exception { - this.gemfirePropertiesFile = - this.temporaryFolder.newFile(DistributionConfig.GEMFIRE_PREFIX + "properties"); + propertiesFile = temporaryFolder.newFile(GEMFIRE_PREFIX + "properties"); - this.expectedGemfireProperties = new Properties(); - this.expectedGemfireProperties.setProperty(NAME, "memberOne"); - this.expectedGemfireProperties.setProperty(GROUPS, "groupOne, groupTwo"); - this.expectedGemfireProperties.store(new FileWriter(this.gemfirePropertiesFile, false), - this.testName.getMethodName()); + expectedProperties = new Properties(); + expectedProperties.setProperty(NAME, "memberOne"); + expectedProperties.setProperty(GROUPS, "groupOne, groupTwo"); + expectedProperties.store(new FileWriter(propertiesFile, false), testName.getMethodName()); - assertThat(this.gemfirePropertiesFile).isNotNull(); - assertThat(this.gemfirePropertiesFile.exists()).isTrue(); - assertThat(this.gemfirePropertiesFile.isFile()).isTrue(); + assertThat(propertiesFile).exists().isFile(); } @Test public void testLoadGemFirePropertiesFromFile() throws Exception { final Properties actualGemFireProperties = AbstractLauncher.loadGemFireProperties(this.gemfirePropertiesFile.toURI().toURL()); + public void loadGemFirePropertiesFromFile() throws Exception { + Properties loadedProperties = loadGemFireProperties(propertiesFile.toURI().toURL()); - assertThat(actualGemFireProperties).isNotNull(); - assertThat(actualGemFireProperties).isEqualTo(this.expectedGemfireProperties); + assertThat(loadedProperties).isEqualTo(expectedProperties); } + End diff – Removed from all classes in change-set.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132312206

          — Diff: geode-core/src/test/java/org/apache/geode/internal/process/FileProcessControllerIntegrationTest.java —
          @@ -0,0 +1,243 @@
          +/*
          + * 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.geode.internal.process;
          +
          +import static com.googlecode.catchexception.CatchException.caughtException;
          +import static com.googlecode.catchexception.CatchException.verifyException;
          +import static java.util.concurrent.TimeUnit.MILLISECONDS;
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.assertj.core.api.Assertions.assertThatThrownBy;
          +import static org.mockito.Mockito.mock;
          +import static org.mockito.Mockito.when;
          +
          +import java.io.File;
          +import java.util.concurrent.ExecutorService;
          +import java.util.concurrent.Executors;
          +import java.util.concurrent.TimeoutException;
          +import java.util.concurrent.atomic.AtomicReference;
          +
          +import org.awaitility.Awaitility;
          +import org.awaitility.core.ConditionFactory;
          +import org.junit.After;
          +import org.junit.Before;
          +import org.junit.Ignore;
          +import org.junit.Rule;
          +import org.junit.Test;
          +import org.junit.experimental.categories.Category;
          +import org.junit.rules.ErrorCollector;
          +import org.junit.rules.TemporaryFolder;
          +import org.junit.rules.TestName;
          +
          +import org.apache.geode.distributed.AbstractLauncher.Status;
          +import org.apache.geode.distributed.LocatorLauncher;
          +import org.apache.geode.distributed.LocatorLauncher.Builder;
          +import org.apache.geode.distributed.LocatorLauncher.LocatorState;
          +import org.apache.geode.internal.process.io.EmptyFileWriter;
          +import org.apache.geode.internal.process.io.IntegerFileWriter;
          +import org.apache.geode.internal.process.io.StringFileWriter;
          +import org.apache.geode.test.junit.categories.IntegrationTest;
          +
          +/**
          + * Integration tests for

          {@link FileProcessController}

          .
          + */
          +@Category(IntegrationTest.class)
          +public class FileProcessControllerIntegrationTest {
          +
          + private static final String STATUS_JSON = generateStatusJson();
          +
          + private final AtomicReference<String> statusRef = new AtomicReference<>();
          +
          + private File pidFile;
          + private File statusFile;
          + private File statusRequestFile;
          + private File stopRequestFile;
          + private int pid;
          + private FileControllerParameters params;
          + private ExecutorService executor;
          +
          + @Rule
          + public ErrorCollector errorCollector = new ErrorCollector();
          +
          + @Rule
          + public TemporaryFolder temporaryFolder = new TemporaryFolder();
          +
          + @Rule
          + public TestName testName = new TestName();
          +
          + @Before
          + public void setUp() throws Exception

          { + ProcessType processType = ProcessType.LOCATOR; + File directory = temporaryFolder.getRoot(); + pidFile = new File(directory, processType.getPidFileName()); + statusFile = new File(directory, processType.getStatusFileName()); + statusRequestFile = new File(directory, processType.getStatusRequestFileName()); + stopRequestFile = new File(directory, processType.getStopRequestFileName()); + pid = ProcessUtils.identifyPid(); + + params = mock(FileControllerParameters.class); + when(params.getPidFile()).thenReturn(pidFile); + when(params.getProcessId()).thenReturn(pid); + when(params.getProcessType()).thenReturn(processType); + when(params.getDirectory()).thenReturn(temporaryFolder.getRoot()); + + executor = Executors.newSingleThreadExecutor(); + }

          +
          + @After
          + public void tearDown() throws Exception

          { + assertThat(executor.shutdownNow()).isEmpty(); + }

          +
          + @Test
          + public void statusShouldAwaitTimeoutWhileFileIsEmpty() throws Exception

          { + // given: FileProcessController with empty pidFile + FileProcessController controller = new FileProcessController(params, pid, 10, MILLISECONDS); + + // when: + verifyException(controller).status(); + + // then: we expect TimeoutException to be thrown + assertThat((Exception) caughtException()).isInstanceOf(TimeoutException.class) + .hasMessageContaining("Timed out waiting for process to create").hasNoCause(); + }

          +
          + @Test
          + public void statusShouldReturnJsonFromStatusFile() throws Exception {
          + // given: FileProcessController with pidFile containing real pid
          + new IntegerFileWriter(pidFile).writeToFile(pid);
          + FileProcessController controller = new FileProcessController(params, pid, 2, MINUTES);
          +
          + // when: status is called in one thread
          + executor.execute(() -> {
          + try

          { + statusRef.set(controller.status()); + }

          catch (Exception e)

          { + errorCollector.addError(e); + }

          + });
          +
          + // and: json is written to the status file
          + new StringFileWriter(statusFile).writeToFile(STATUS_JSON);
          +
          + // then: returned status should be the json in the file
          + await().until(() -> assertThat(statusRef.get()).isEqualTo(STATUS_JSON));
          + }
          +
          + @Ignore // GEODE-3278
          — End diff –

          This test has a few interesting things including the @Ignore for GEODE-3278 that warrant more documentation.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132312206 — Diff: geode-core/src/test/java/org/apache/geode/internal/process/FileProcessControllerIntegrationTest.java — @@ -0,0 +1,243 @@ +/* + * 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.geode.internal.process; + +import static com.googlecode.catchexception.CatchException.caughtException; +import static com.googlecode.catchexception.CatchException.verifyException; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicReference; + +import org.awaitility.Awaitility; +import org.awaitility.core.ConditionFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.ErrorCollector; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestName; + +import org.apache.geode.distributed.AbstractLauncher.Status; +import org.apache.geode.distributed.LocatorLauncher; +import org.apache.geode.distributed.LocatorLauncher.Builder; +import org.apache.geode.distributed.LocatorLauncher.LocatorState; +import org.apache.geode.internal.process.io.EmptyFileWriter; +import org.apache.geode.internal.process.io.IntegerFileWriter; +import org.apache.geode.internal.process.io.StringFileWriter; +import org.apache.geode.test.junit.categories.IntegrationTest; + +/** + * Integration tests for {@link FileProcessController} . + */ +@Category(IntegrationTest.class) +public class FileProcessControllerIntegrationTest { + + private static final String STATUS_JSON = generateStatusJson(); + + private final AtomicReference<String> statusRef = new AtomicReference<>(); + + private File pidFile; + private File statusFile; + private File statusRequestFile; + private File stopRequestFile; + private int pid; + private FileControllerParameters params; + private ExecutorService executor; + + @Rule + public ErrorCollector errorCollector = new ErrorCollector(); + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Rule + public TestName testName = new TestName(); + + @Before + public void setUp() throws Exception { + ProcessType processType = ProcessType.LOCATOR; + File directory = temporaryFolder.getRoot(); + pidFile = new File(directory, processType.getPidFileName()); + statusFile = new File(directory, processType.getStatusFileName()); + statusRequestFile = new File(directory, processType.getStatusRequestFileName()); + stopRequestFile = new File(directory, processType.getStopRequestFileName()); + pid = ProcessUtils.identifyPid(); + + params = mock(FileControllerParameters.class); + when(params.getPidFile()).thenReturn(pidFile); + when(params.getProcessId()).thenReturn(pid); + when(params.getProcessType()).thenReturn(processType); + when(params.getDirectory()).thenReturn(temporaryFolder.getRoot()); + + executor = Executors.newSingleThreadExecutor(); + } + + @After + public void tearDown() throws Exception { + assertThat(executor.shutdownNow()).isEmpty(); + } + + @Test + public void statusShouldAwaitTimeoutWhileFileIsEmpty() throws Exception { + // given: FileProcessController with empty pidFile + FileProcessController controller = new FileProcessController(params, pid, 10, MILLISECONDS); + + // when: + verifyException(controller).status(); + + // then: we expect TimeoutException to be thrown + assertThat((Exception) caughtException()).isInstanceOf(TimeoutException.class) + .hasMessageContaining("Timed out waiting for process to create").hasNoCause(); + } + + @Test + public void statusShouldReturnJsonFromStatusFile() throws Exception { + // given: FileProcessController with pidFile containing real pid + new IntegerFileWriter(pidFile).writeToFile(pid); + FileProcessController controller = new FileProcessController(params, pid, 2, MINUTES); + + // when: status is called in one thread + executor.execute(() -> { + try { + statusRef.set(controller.status()); + } catch (Exception e) { + errorCollector.addError(e); + } + }); + + // and: json is written to the status file + new StringFileWriter(statusFile).writeToFile(STATUS_JSON); + + // then: returned status should be the json in the file + await().until(() -> assertThat(statusRef.get()).isEqualTo(STATUS_JSON)); + } + + @Ignore // GEODE-3278 — End diff – This test has a few interesting things including the @Ignore for GEODE-3278 that warrant more documentation.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user PurelyApplied commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132312668

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java —
          @@ -1848,8 +1884,7 @@ public LocatorLauncher build() {
          private final String name;

          Command(final String name, final String... options) {

          • assert !StringUtils
          • .isBlank(name) : "The name of the locator launcher command must be specified!";
            + assert Unable to render embedded object: File ( "The name of the locator launcher command must be specified) not found.";
              • End diff –

          As long as we're touching this, we could consider using `isNotBlank` for better readability.

          Show
          githubbot ASF GitHub Bot added a comment - Github user PurelyApplied commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132312668 — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java — @@ -1848,8 +1884,7 @@ public LocatorLauncher build() { private final String name; Command(final String name, final String... options) { assert !StringUtils .isBlank(name) : "The name of the locator launcher command must be specified!"; + assert Unable to render embedded object: File ( "The name of the locator launcher command must be specified) not found. "; End diff – As long as we're touching this, we could consider using `isNotBlank` for better readability.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user PurelyApplied commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132306579

          — Diff: geode-core/src/main/java/org/apache/geode/internal/cache/ClusterConfigurationLoader.java —
          @@ -31,7 +31,7 @@
          import org.apache.geode.internal.admin.remote.DistributionLocatorId;
          import org.apache.geode.internal.i18n.LocalizedStrings;
          import org.apache.geode.internal.logging.LogService;
          -import org.apache.geode.internal.process.ClusterConfigurationNotAvailableException;
          +import org.apache.geode.config.internal.ClusterConfigurationNotAvailableException;
          — End diff –

          Classic Pat nitpick: don't forget to reorder / optimize your imports to go `statics`, `java`, `javax`, (other), `org.apache.geode`.

          This applies to the following files:
          ```
          geode-core/src/main/java/org/apache/geode/distributed/ServerLauncher.java
          geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java
          geode-core/src/main/java/org/apache/geode/internal/cache/ClusterConfigurationLoader.java
          geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java
          geode-core/src/main/java/org/apache/geode/internal/process/LocalProcessLauncher.java
          geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/StartServerCommand.java
          ```

          Show
          githubbot ASF GitHub Bot added a comment - Github user PurelyApplied commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132306579 — Diff: geode-core/src/main/java/org/apache/geode/internal/cache/ClusterConfigurationLoader.java — @@ -31,7 +31,7 @@ import org.apache.geode.internal.admin.remote.DistributionLocatorId; import org.apache.geode.internal.i18n.LocalizedStrings; import org.apache.geode.internal.logging.LogService; -import org.apache.geode.internal.process.ClusterConfigurationNotAvailableException; +import org.apache.geode.config.internal.ClusterConfigurationNotAvailableException; — End diff – Classic Pat nitpick: don't forget to reorder / optimize your imports to go `statics`, `java`, `javax`, (other), `org.apache.geode`. This applies to the following files: ``` geode-core/src/main/java/org/apache/geode/distributed/ServerLauncher.java geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java geode-core/src/main/java/org/apache/geode/internal/cache/ClusterConfigurationLoader.java geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java geode-core/src/main/java/org/apache/geode/internal/process/LocalProcessLauncher.java geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/StartServerCommand.java ```
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user PurelyApplied commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132307061

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/AbstractLauncher.java —
          @@ -157,7 +162,7 @@ protected static Properties loadGemFireProperties(final URL url) {
          if (url != null) {
          try

          { properties.load(new FileReader(new File(url.toURI()))); - }

          catch (Exception e)

          { + }

          catch (Exception ignored) {
          — End diff –

          Are we really ignoring the exception if we're doing something in response to it?
          Ditto lines 272, 438.

          Show
          githubbot ASF GitHub Bot added a comment - Github user PurelyApplied commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132307061 — Diff: geode-core/src/main/java/org/apache/geode/distributed/AbstractLauncher.java — @@ -157,7 +162,7 @@ protected static Properties loadGemFireProperties(final URL url) { if (url != null) { try { properties.load(new FileReader(new File(url.toURI()))); - } catch (Exception e) { + } catch (Exception ignored) { — End diff – Are we really ignoring the exception if we're doing something in response to it? Ditto lines 272, 438.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user PurelyApplied commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132311304

          — Diff: geode-core/src/main/java/org/apache/geode/internal/process/MBeanProcessController.java —
          @@ -228,9 +230,9 @@ private void disconnect() {

          • @throws PidUnavailableException if parsing the pid from the RuntimeMXBean name fails
            */
            boolean checkPidMatches() throws IllegalStateException, IOException, PidUnavailableException {
              • End diff –

          This appears to be unused? The JavaDoc has it as "NOT USED EXCEPT IN TEST." This is perhaps no longer true?

          Show
          githubbot ASF GitHub Bot added a comment - Github user PurelyApplied commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132311304 — Diff: geode-core/src/main/java/org/apache/geode/internal/process/MBeanProcessController.java — @@ -228,9 +230,9 @@ private void disconnect() { @throws PidUnavailableException if parsing the pid from the RuntimeMXBean name fails */ boolean checkPidMatches() throws IllegalStateException, IOException, PidUnavailableException { End diff – This appears to be unused? The JavaDoc has it as "NOT USED EXCEPT IN TEST." This is perhaps no longer true?
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user PurelyApplied commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132312583

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/AbstractLauncher.java —
          @@ -502,7 +507,7 @@ protected static Integer identifyPid() {
          }
          }

          • // TODO refactor the logic in this method into a DateTimeFormatUtils class
            + // consider refactoring the logic in this method into a DateTimeFormatUtils class
              • End diff –

          I'd remove this and the line 510 comments altogether. If the suggestion has value, we should open a ticket for it.

          Likewise `LocatorLauncher:382`, `ServerLauncher:523`

          Show
          githubbot ASF GitHub Bot added a comment - Github user PurelyApplied commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132312583 — Diff: geode-core/src/main/java/org/apache/geode/distributed/AbstractLauncher.java — @@ -502,7 +507,7 @@ protected static Integer identifyPid() { } } // TODO refactor the logic in this method into a DateTimeFormatUtils class + // consider refactoring the logic in this method into a DateTimeFormatUtils class End diff – I'd remove this and the line 510 comments altogether. If the suggestion has value, we should open a ticket for it. Likewise `LocatorLauncher:382`, `ServerLauncher:523`
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132304059

          — Diff: geode-core/src/test/java/org/apache/geode/internal/process/BlockingProcessStreamReaderIntegrationTest.java —
          @@ -0,0 +1,179 @@
          +/*
          + * 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.geode.internal.process;
          +
          +import static org.apache.geode.internal.lang.SystemUtils.isWindows;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.junit.Assume.assumeFalse;
          +
          +import org.junit.Before;
          +import org.junit.Test;
          +import org.junit.experimental.categories.Category;
          +
          +import org.apache.geode.internal.process.ProcessStreamReader.Builder;
          +import org.apache.geode.internal.process.ProcessStreamReader.ReadingMode;
          +import org.apache.geode.test.junit.categories.IntegrationTest;
          +
          +/**
          + * Functional integration tests for BlockingProcessStreamReader. All tests are skipped on Windows
          + * due to TRAC bug #51967 which is caused by a JDK bug. See
          — End diff –

          See my other comment regarding specific bug reference.

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132304059 — Diff: geode-core/src/test/java/org/apache/geode/internal/process/BlockingProcessStreamReaderIntegrationTest.java — @@ -0,0 +1,179 @@ +/* + * 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.geode.internal.process; + +import static org.apache.geode.internal.lang.SystemUtils.isWindows; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assume.assumeFalse; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import org.apache.geode.internal.process.ProcessStreamReader.Builder; +import org.apache.geode.internal.process.ProcessStreamReader.ReadingMode; +import org.apache.geode.test.junit.categories.IntegrationTest; + +/** + * Functional integration tests for BlockingProcessStreamReader. All tests are skipped on Windows + * due to TRAC bug #51967 which is caused by a JDK bug. See — End diff – See my other comment regarding specific bug reference.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132314371

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java —
          @@ -0,0 +1,505 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.internal.AvailablePort.SOCKET;
          +import static org.apache.geode.internal.AvailablePort.isPortAvailable;
          +import static org.apache.geode.internal.process.ProcessUtils.identifyPid;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.junit.Assert.assertTrue;
          +
          +import java.io.BufferedReader;
          +import java.io.File;
          +import java.io.FileReader;
          +import java.io.FileWriter;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.lang.management.ManagementFactory;
          +import java.net.ServerSocket;
          +import java.nio.file.Files;
          +import java.util.List;
          +import java.util.Properties;
          +import java.util.concurrent.Callable;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.apache.commons.lang.StringUtils;
          +import org.apache.logging.log4j.Logger;
          +import org.awaitility.Awaitility;
          +import org.awaitility.core.ConditionFactory;
          +import org.junit.After;
          +import org.junit.Before;
          +import org.junit.Rule;
          +import org.junit.contrib.java.lang.system.RestoreSystemProperties;
          +import org.junit.rules.TemporaryFolder;
          +import org.junit.rules.TestName;
          +
          +import org.apache.geode.distributed.internal.DistributionConfig;
          +import org.apache.geode.distributed.internal.InternalDistributedSystem;
          +import org.apache.geode.internal.logging.LogService;
          +import org.apache.geode.internal.net.SocketCreatorFactory;
          +import org.apache.geode.internal.process.PidUnavailableException;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +import org.apache.geode.internal.process.ProcessType;
          +import org.apache.geode.internal.process.ProcessUtils;
          +import org.apache.geode.internal.process.lang.AvailablePid;
          +import org.apache.geode.internal.util.StopWatch;
          +import org.apache.geode.test.dunit.IgnoredException;
          +
          +/**
          + * Abstract base class for integration tests of both

          {@link LocatorLauncher}

          and
          + *

          {@link ServerLauncher}

          .
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class LauncherIntegrationTestCase {
          + protected static final Logger logger = LogService.getLogger();
          +
          + protected static final int WAIT_FOR_PROCESS_TO_DIE_TIMEOUT = 5 * 60 * 1000; // 5 minutes
          + protected static final int TIMEOUT_MILLISECONDS = WAIT_FOR_PROCESS_TO_DIE_TIMEOUT;
          + protected static final int WAIT_FOR_FILE_CREATION_TIMEOUT = 10 * 1000; // 10s
          + protected static final int WAIT_FOR_FILE_DELETION_TIMEOUT = 10 * 1000; // 10s
          + protected static final int WAIT_FOR_MBEAN_TIMEOUT = 10 * 1000; // 10s
          — End diff –

          Unused field?

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132314371 — Diff: geode-core/src/test/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java — @@ -0,0 +1,505 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.internal.AvailablePort.SOCKET; +import static org.apache.geode.internal.AvailablePort.isPortAvailable; +import static org.apache.geode.internal.process.ProcessUtils.identifyPid; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.management.ManagementFactory; +import java.net.ServerSocket; +import java.nio.file.Files; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; +import org.awaitility.Awaitility; +import org.awaitility.core.ConditionFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.contrib.java.lang.system.RestoreSystemProperties; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestName; + +import org.apache.geode.distributed.internal.DistributionConfig; +import org.apache.geode.distributed.internal.InternalDistributedSystem; +import org.apache.geode.internal.logging.LogService; +import org.apache.geode.internal.net.SocketCreatorFactory; +import org.apache.geode.internal.process.PidUnavailableException; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; +import org.apache.geode.internal.process.ProcessType; +import org.apache.geode.internal.process.ProcessUtils; +import org.apache.geode.internal.process.lang.AvailablePid; +import org.apache.geode.internal.util.StopWatch; +import org.apache.geode.test.dunit.IgnoredException; + +/** + * Abstract base class for integration tests of both {@link LocatorLauncher} and + * {@link ServerLauncher} . + * + * @since GemFire 8.0 + */ +public abstract class LauncherIntegrationTestCase { + protected static final Logger logger = LogService.getLogger(); + + protected static final int WAIT_FOR_PROCESS_TO_DIE_TIMEOUT = 5 * 60 * 1000; // 5 minutes + protected static final int TIMEOUT_MILLISECONDS = WAIT_FOR_PROCESS_TO_DIE_TIMEOUT; + protected static final int WAIT_FOR_FILE_CREATION_TIMEOUT = 10 * 1000; // 10s + protected static final int WAIT_FOR_FILE_DELETION_TIMEOUT = 10 * 1000; // 10s + protected static final int WAIT_FOR_MBEAN_TIMEOUT = 10 * 1000; // 10s — End diff – Unused field?
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132314473

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java —
          @@ -0,0 +1,505 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.internal.AvailablePort.SOCKET;
          +import static org.apache.geode.internal.AvailablePort.isPortAvailable;
          +import static org.apache.geode.internal.process.ProcessUtils.identifyPid;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.junit.Assert.assertTrue;
          +
          +import java.io.BufferedReader;
          +import java.io.File;
          +import java.io.FileReader;
          +import java.io.FileWriter;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.lang.management.ManagementFactory;
          +import java.net.ServerSocket;
          +import java.nio.file.Files;
          +import java.util.List;
          +import java.util.Properties;
          +import java.util.concurrent.Callable;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.apache.commons.lang.StringUtils;
          +import org.apache.logging.log4j.Logger;
          +import org.awaitility.Awaitility;
          +import org.awaitility.core.ConditionFactory;
          +import org.junit.After;
          +import org.junit.Before;
          +import org.junit.Rule;
          +import org.junit.contrib.java.lang.system.RestoreSystemProperties;
          +import org.junit.rules.TemporaryFolder;
          +import org.junit.rules.TestName;
          +
          +import org.apache.geode.distributed.internal.DistributionConfig;
          +import org.apache.geode.distributed.internal.InternalDistributedSystem;
          +import org.apache.geode.internal.logging.LogService;
          +import org.apache.geode.internal.net.SocketCreatorFactory;
          +import org.apache.geode.internal.process.PidUnavailableException;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +import org.apache.geode.internal.process.ProcessType;
          +import org.apache.geode.internal.process.ProcessUtils;
          +import org.apache.geode.internal.process.lang.AvailablePid;
          +import org.apache.geode.internal.util.StopWatch;
          +import org.apache.geode.test.dunit.IgnoredException;
          +
          +/**
          + * Abstract base class for integration tests of both

          {@link LocatorLauncher}

          and
          + *

          {@link ServerLauncher}

          .
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class LauncherIntegrationTestCase {
          + protected static final Logger logger = LogService.getLogger();
          +
          + protected static final int WAIT_FOR_PROCESS_TO_DIE_TIMEOUT = 5 * 60 * 1000; // 5 minutes
          + protected static final int TIMEOUT_MILLISECONDS = WAIT_FOR_PROCESS_TO_DIE_TIMEOUT;
          + protected static final int WAIT_FOR_FILE_CREATION_TIMEOUT = 10 * 1000; // 10s
          + protected static final int WAIT_FOR_FILE_DELETION_TIMEOUT = 10 * 1000; // 10s
          + protected static final int WAIT_FOR_MBEAN_TIMEOUT = 10 * 1000; // 10s
          + protected static final int INTERVAL_MILLISECONDS = 100;
          +
          + protected static final int PREFERRED_FAKE_PID = 42;
          +
          + private static final String EXPECTED_EXCEPTION_ADD =
          + "<ExpectedException action=add>{}</ExpectedException>";
          + private static final String EXPECTED_EXCEPTION_REMOVE =
          — End diff –

          Unused fields?

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132314473 — Diff: geode-core/src/test/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java — @@ -0,0 +1,505 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.internal.AvailablePort.SOCKET; +import static org.apache.geode.internal.AvailablePort.isPortAvailable; +import static org.apache.geode.internal.process.ProcessUtils.identifyPid; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.management.ManagementFactory; +import java.net.ServerSocket; +import java.nio.file.Files; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; +import org.awaitility.Awaitility; +import org.awaitility.core.ConditionFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.contrib.java.lang.system.RestoreSystemProperties; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestName; + +import org.apache.geode.distributed.internal.DistributionConfig; +import org.apache.geode.distributed.internal.InternalDistributedSystem; +import org.apache.geode.internal.logging.LogService; +import org.apache.geode.internal.net.SocketCreatorFactory; +import org.apache.geode.internal.process.PidUnavailableException; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; +import org.apache.geode.internal.process.ProcessType; +import org.apache.geode.internal.process.ProcessUtils; +import org.apache.geode.internal.process.lang.AvailablePid; +import org.apache.geode.internal.util.StopWatch; +import org.apache.geode.test.dunit.IgnoredException; + +/** + * Abstract base class for integration tests of both {@link LocatorLauncher} and + * {@link ServerLauncher} . + * + * @since GemFire 8.0 + */ +public abstract class LauncherIntegrationTestCase { + protected static final Logger logger = LogService.getLogger(); + + protected static final int WAIT_FOR_PROCESS_TO_DIE_TIMEOUT = 5 * 60 * 1000; // 5 minutes + protected static final int TIMEOUT_MILLISECONDS = WAIT_FOR_PROCESS_TO_DIE_TIMEOUT; + protected static final int WAIT_FOR_FILE_CREATION_TIMEOUT = 10 * 1000; // 10s + protected static final int WAIT_FOR_FILE_DELETION_TIMEOUT = 10 * 1000; // 10s + protected static final int WAIT_FOR_MBEAN_TIMEOUT = 10 * 1000; // 10s + protected static final int INTERVAL_MILLISECONDS = 100; + + protected static final int PREFERRED_FAKE_PID = 42; + + private static final String EXPECTED_EXCEPTION_ADD = + "<ExpectedException action=add>{}</ExpectedException>"; + private static final String EXPECTED_EXCEPTION_REMOVE = — End diff – Unused fields?
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132315473

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java —
          @@ -0,0 +1,505 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.internal.AvailablePort.SOCKET;
          +import static org.apache.geode.internal.AvailablePort.isPortAvailable;
          +import static org.apache.geode.internal.process.ProcessUtils.identifyPid;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.junit.Assert.assertTrue;
          +
          +import java.io.BufferedReader;
          +import java.io.File;
          +import java.io.FileReader;
          +import java.io.FileWriter;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.lang.management.ManagementFactory;
          +import java.net.ServerSocket;
          +import java.nio.file.Files;
          +import java.util.List;
          +import java.util.Properties;
          +import java.util.concurrent.Callable;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.apache.commons.lang.StringUtils;
          +import org.apache.logging.log4j.Logger;
          +import org.awaitility.Awaitility;
          +import org.awaitility.core.ConditionFactory;
          +import org.junit.After;
          +import org.junit.Before;
          +import org.junit.Rule;
          +import org.junit.contrib.java.lang.system.RestoreSystemProperties;
          +import org.junit.rules.TemporaryFolder;
          +import org.junit.rules.TestName;
          +
          +import org.apache.geode.distributed.internal.DistributionConfig;
          +import org.apache.geode.distributed.internal.InternalDistributedSystem;
          +import org.apache.geode.internal.logging.LogService;
          +import org.apache.geode.internal.net.SocketCreatorFactory;
          +import org.apache.geode.internal.process.PidUnavailableException;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +import org.apache.geode.internal.process.ProcessType;
          +import org.apache.geode.internal.process.ProcessUtils;
          +import org.apache.geode.internal.process.lang.AvailablePid;
          +import org.apache.geode.internal.util.StopWatch;
          +import org.apache.geode.test.dunit.IgnoredException;
          +
          +/**
          + * Abstract base class for integration tests of both

          {@link LocatorLauncher}

          and
          + *

          {@link ServerLauncher}

          .
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class LauncherIntegrationTestCase {
          + protected static final Logger logger = LogService.getLogger();
          +
          + protected static final int WAIT_FOR_PROCESS_TO_DIE_TIMEOUT = 5 * 60 * 1000; // 5 minutes
          + protected static final int TIMEOUT_MILLISECONDS = WAIT_FOR_PROCESS_TO_DIE_TIMEOUT;
          + protected static final int WAIT_FOR_FILE_CREATION_TIMEOUT = 10 * 1000; // 10s
          + protected static final int WAIT_FOR_FILE_DELETION_TIMEOUT = 10 * 1000; // 10s
          + protected static final int WAIT_FOR_MBEAN_TIMEOUT = 10 * 1000; // 10s
          + protected static final int INTERVAL_MILLISECONDS = 100;
          +
          + protected static final int PREFERRED_FAKE_PID = 42;
          +
          + private static final String EXPECTED_EXCEPTION_ADD =
          + "<ExpectedException action=add>{}</ExpectedException>";
          + private static final String EXPECTED_EXCEPTION_REMOVE =
          + "<ExpectedException action=remove>{}</ExpectedException>";
          + private static final String EXPECTED_EXCEPTION_MBEAN_NOT_REGISTERED =
          + "MBean Not Registered In GemFire Domain";
          +
          + private IgnoredException ignoredException;
          +
          + protected int localPid;
          + protected int fakePid;
          +
          + protected volatile ServerSocket socket;
          +
          + protected volatile File pidFile;
          + protected volatile File stopRequestFile;
          + protected volatile File statusRequestFile;
          + protected volatile File statusFile;
          +
          + @Rule
          + public TestName testName = new TestName();
          +
          + @Rule
          + public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
          +
          + @Rule
          + public TemporaryFolder temporaryFolder = new TemporaryFolder();
          +
          + @Before
          + public void setUpAbstractLauncherIntegrationTestCase() throws Exception

          { + System.setProperty(DistributionConfig.GEMFIRE_PREFIX + MCAST_PORT, Integer.toString(0)); + ignoredException = + IgnoredException.addIgnoredException(EXPECTED_EXCEPTION_MBEAN_NOT_REGISTERED); + localPid = identifyPid(); + fakePid = new AvailablePid().findAvailablePid(PREFERRED_FAKE_PID); + }

          +
          + @After
          + public void tearDownAbstractLauncherIntegrationTestCase() throws Exception {
          + ignoredException.remove();
          + if (this.socket != null)

          { + this.socket.close(); + this.socket = null; + }

          + delete(this.pidFile);
          + delete(this.stopRequestFile);
          + delete(this.statusRequestFile);
          + delete(this.statusFile);
          + }
          +
          + protected abstract ProcessType getProcessType();
          +
          + protected String getStopRequestFileName()

          { + return getProcessType().getStopRequestFileName(); + }

          +
          + protected String getStatusRequestFileName()

          { + return getProcessType().getStatusRequestFileName(); + }

          +
          + protected String getStatusFileName()

          { + return getProcessType().getStatusFileName(); + }

          +
          + protected void givenEmptyWorkingDirectory()

          { + assertThat(getWorkingDirectory().listFiles()).hasSize(0); + }

          +
          + protected List<String> getJvmArguments()

          { + return ManagementFactory.getRuntimeMXBean().getInputArguments(); + }

          +
          + protected ConditionFactory await()

          { + return Awaitility.await().atMost(2, MINUTES); + }

          +
          + public String getClassPath()

          { + // alternative: ManagementFactory.getRuntimeMXBean().getClassPath() + return System.getProperty("java.class.path"); + }

          +
          + public String getJavaPath() {
          + try

          { + return new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath(); + }

          catch (IOException e)

          { + throw new UncheckedIOException(e); + }
          + }
          +
          + protected File getPidFile() { + return new File(getWorkingDirectory(), getProcessType().getPidFileName()); + }
          +
          + protected File getLogFile() { + return new File(getWorkingDirectory(), getUniqueName() + ".log"); + }
          +
          + protected String getLogFilePath() {
          + try { + return getLogFile().getCanonicalPath(); + } catch (IOException e) { + throw new UncheckedIOException(e); + }

          + }
          +
          + protected File getWorkingDirectory()

          { + return this.temporaryFolder.getRoot(); + }

          +
          + protected String getWorkingDirectoryPath() {
          + try

          { + return getWorkingDirectory().getCanonicalPath(); + }

          catch (IOException e)

          { + throw new UncheckedIOException(e); + }

          + }
          +
          + protected void createPidFile(final Object content) {
          — End diff –

          IDE flags several unused methods

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132315473 — Diff: geode-core/src/test/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java — @@ -0,0 +1,505 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.internal.AvailablePort.SOCKET; +import static org.apache.geode.internal.AvailablePort.isPortAvailable; +import static org.apache.geode.internal.process.ProcessUtils.identifyPid; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.management.ManagementFactory; +import java.net.ServerSocket; +import java.nio.file.Files; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; +import org.awaitility.Awaitility; +import org.awaitility.core.ConditionFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.contrib.java.lang.system.RestoreSystemProperties; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestName; + +import org.apache.geode.distributed.internal.DistributionConfig; +import org.apache.geode.distributed.internal.InternalDistributedSystem; +import org.apache.geode.internal.logging.LogService; +import org.apache.geode.internal.net.SocketCreatorFactory; +import org.apache.geode.internal.process.PidUnavailableException; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; +import org.apache.geode.internal.process.ProcessType; +import org.apache.geode.internal.process.ProcessUtils; +import org.apache.geode.internal.process.lang.AvailablePid; +import org.apache.geode.internal.util.StopWatch; +import org.apache.geode.test.dunit.IgnoredException; + +/** + * Abstract base class for integration tests of both {@link LocatorLauncher} and + * {@link ServerLauncher} . + * + * @since GemFire 8.0 + */ +public abstract class LauncherIntegrationTestCase { + protected static final Logger logger = LogService.getLogger(); + + protected static final int WAIT_FOR_PROCESS_TO_DIE_TIMEOUT = 5 * 60 * 1000; // 5 minutes + protected static final int TIMEOUT_MILLISECONDS = WAIT_FOR_PROCESS_TO_DIE_TIMEOUT; + protected static final int WAIT_FOR_FILE_CREATION_TIMEOUT = 10 * 1000; // 10s + protected static final int WAIT_FOR_FILE_DELETION_TIMEOUT = 10 * 1000; // 10s + protected static final int WAIT_FOR_MBEAN_TIMEOUT = 10 * 1000; // 10s + protected static final int INTERVAL_MILLISECONDS = 100; + + protected static final int PREFERRED_FAKE_PID = 42; + + private static final String EXPECTED_EXCEPTION_ADD = + "<ExpectedException action=add>{}</ExpectedException>"; + private static final String EXPECTED_EXCEPTION_REMOVE = + "<ExpectedException action=remove>{}</ExpectedException>"; + private static final String EXPECTED_EXCEPTION_MBEAN_NOT_REGISTERED = + "MBean Not Registered In GemFire Domain"; + + private IgnoredException ignoredException; + + protected int localPid; + protected int fakePid; + + protected volatile ServerSocket socket; + + protected volatile File pidFile; + protected volatile File stopRequestFile; + protected volatile File statusRequestFile; + protected volatile File statusFile; + + @Rule + public TestName testName = new TestName(); + + @Rule + public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties(); + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Before + public void setUpAbstractLauncherIntegrationTestCase() throws Exception { + System.setProperty(DistributionConfig.GEMFIRE_PREFIX + MCAST_PORT, Integer.toString(0)); + ignoredException = + IgnoredException.addIgnoredException(EXPECTED_EXCEPTION_MBEAN_NOT_REGISTERED); + localPid = identifyPid(); + fakePid = new AvailablePid().findAvailablePid(PREFERRED_FAKE_PID); + } + + @After + public void tearDownAbstractLauncherIntegrationTestCase() throws Exception { + ignoredException.remove(); + if (this.socket != null) { + this.socket.close(); + this.socket = null; + } + delete(this.pidFile); + delete(this.stopRequestFile); + delete(this.statusRequestFile); + delete(this.statusFile); + } + + protected abstract ProcessType getProcessType(); + + protected String getStopRequestFileName() { + return getProcessType().getStopRequestFileName(); + } + + protected String getStatusRequestFileName() { + return getProcessType().getStatusRequestFileName(); + } + + protected String getStatusFileName() { + return getProcessType().getStatusFileName(); + } + + protected void givenEmptyWorkingDirectory() { + assertThat(getWorkingDirectory().listFiles()).hasSize(0); + } + + protected List<String> getJvmArguments() { + return ManagementFactory.getRuntimeMXBean().getInputArguments(); + } + + protected ConditionFactory await() { + return Awaitility.await().atMost(2, MINUTES); + } + + public String getClassPath() { + // alternative: ManagementFactory.getRuntimeMXBean().getClassPath() + return System.getProperty("java.class.path"); + } + + public String getJavaPath() { + try { + return new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + protected File getPidFile() { + return new File(getWorkingDirectory(), getProcessType().getPidFileName()); + } + + protected File getLogFile() { + return new File(getWorkingDirectory(), getUniqueName() + ".log"); + } + + protected String getLogFilePath() { + try { + return getLogFile().getCanonicalPath(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + protected File getWorkingDirectory() { + return this.temporaryFolder.getRoot(); + } + + protected String getWorkingDirectoryPath() { + try { + return getWorkingDirectory().getCanonicalPath(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + protected void createPidFile(final Object content) { — End diff – IDE flags several unused methods
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132303567

          — Diff: geode-core/src/test/java/org/apache/geode/internal/process/BlockingProcessStreamReaderWindowsTest.java —
          @@ -0,0 +1,97 @@
          +/*
          + * 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.geode.internal.process;
          +
          +import static org.apache.geode.internal.lang.SystemUtils.isWindows;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.assertj.core.api.Assertions.assertThatThrownBy;
          +import static org.junit.Assume.assumeTrue;
          +
          +import java.util.concurrent.ExecutorService;
          +import java.util.concurrent.Executors;
          +import java.util.concurrent.Future;
          +import java.util.concurrent.TimeUnit;
          +import java.util.concurrent.TimeoutException;
          +
          +import org.junit.After;
          +import org.junit.Before;
          +import org.junit.Test;
          +import org.junit.experimental.categories.Category;
          +
          +import org.apache.geode.test.junit.categories.IntegrationTest;
          +
          +/**
          + * Functional integration test

          {@link #hangsOnWindows}

          for BlockingProcessStreamReader which
          + * verifies TRAC #51967 on Windows. The hang is caused by a JDK bug in which a thread invoking
          — End diff –

          The bug number reference is not meaningful in the context of the geode community. I suggest rewording this to remove the specific reference while still describing the the nature of the bug that this test verifies the fix for.

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132303567 — Diff: geode-core/src/test/java/org/apache/geode/internal/process/BlockingProcessStreamReaderWindowsTest.java — @@ -0,0 +1,97 @@ +/* + * 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.geode.internal.process; + +import static org.apache.geode.internal.lang.SystemUtils.isWindows; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assume.assumeTrue; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import org.apache.geode.test.junit.categories.IntegrationTest; + +/** + * Functional integration test {@link #hangsOnWindows} for BlockingProcessStreamReader which + * verifies TRAC #51967 on Windows. The hang is caused by a JDK bug in which a thread invoking — End diff – The bug number reference is not meaningful in the context of the geode community. I suggest rewording this to remove the specific reference while still describing the the nature of the bug that this test verifies the fix for.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132314337

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java —
          @@ -0,0 +1,505 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.internal.AvailablePort.SOCKET;
          +import static org.apache.geode.internal.AvailablePort.isPortAvailable;
          +import static org.apache.geode.internal.process.ProcessUtils.identifyPid;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.junit.Assert.assertTrue;
          +
          +import java.io.BufferedReader;
          +import java.io.File;
          +import java.io.FileReader;
          +import java.io.FileWriter;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.lang.management.ManagementFactory;
          +import java.net.ServerSocket;
          +import java.nio.file.Files;
          +import java.util.List;
          +import java.util.Properties;
          +import java.util.concurrent.Callable;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.apache.commons.lang.StringUtils;
          +import org.apache.logging.log4j.Logger;
          +import org.awaitility.Awaitility;
          +import org.awaitility.core.ConditionFactory;
          +import org.junit.After;
          +import org.junit.Before;
          +import org.junit.Rule;
          +import org.junit.contrib.java.lang.system.RestoreSystemProperties;
          +import org.junit.rules.TemporaryFolder;
          +import org.junit.rules.TestName;
          +
          +import org.apache.geode.distributed.internal.DistributionConfig;
          +import org.apache.geode.distributed.internal.InternalDistributedSystem;
          +import org.apache.geode.internal.logging.LogService;
          +import org.apache.geode.internal.net.SocketCreatorFactory;
          +import org.apache.geode.internal.process.PidUnavailableException;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +import org.apache.geode.internal.process.ProcessType;
          +import org.apache.geode.internal.process.ProcessUtils;
          +import org.apache.geode.internal.process.lang.AvailablePid;
          +import org.apache.geode.internal.util.StopWatch;
          +import org.apache.geode.test.dunit.IgnoredException;
          +
          +/**
          + * Abstract base class for integration tests of both

          {@link LocatorLauncher}

          and
          + *

          {@link ServerLauncher}

          .
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class LauncherIntegrationTestCase {
          + protected static final Logger logger = LogService.getLogger();
          +
          + protected static final int WAIT_FOR_PROCESS_TO_DIE_TIMEOUT = 5 * 60 * 1000; // 5 minutes
          + protected static final int TIMEOUT_MILLISECONDS = WAIT_FOR_PROCESS_TO_DIE_TIMEOUT;
          — End diff –

          Unused field?

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132314337 — Diff: geode-core/src/test/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java — @@ -0,0 +1,505 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.internal.AvailablePort.SOCKET; +import static org.apache.geode.internal.AvailablePort.isPortAvailable; +import static org.apache.geode.internal.process.ProcessUtils.identifyPid; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.management.ManagementFactory; +import java.net.ServerSocket; +import java.nio.file.Files; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; +import org.awaitility.Awaitility; +import org.awaitility.core.ConditionFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.contrib.java.lang.system.RestoreSystemProperties; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestName; + +import org.apache.geode.distributed.internal.DistributionConfig; +import org.apache.geode.distributed.internal.InternalDistributedSystem; +import org.apache.geode.internal.logging.LogService; +import org.apache.geode.internal.net.SocketCreatorFactory; +import org.apache.geode.internal.process.PidUnavailableException; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; +import org.apache.geode.internal.process.ProcessType; +import org.apache.geode.internal.process.ProcessUtils; +import org.apache.geode.internal.process.lang.AvailablePid; +import org.apache.geode.internal.util.StopWatch; +import org.apache.geode.test.dunit.IgnoredException; + +/** + * Abstract base class for integration tests of both {@link LocatorLauncher} and + * {@link ServerLauncher} . + * + * @since GemFire 8.0 + */ +public abstract class LauncherIntegrationTestCase { + protected static final Logger logger = LogService.getLogger(); + + protected static final int WAIT_FOR_PROCESS_TO_DIE_TIMEOUT = 5 * 60 * 1000; // 5 minutes + protected static final int TIMEOUT_MILLISECONDS = WAIT_FOR_PROCESS_TO_DIE_TIMEOUT; — End diff – Unused field?
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132321751

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java —
          @@ -0,0 +1,270 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX;
          +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +
          +import java.io.File;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.net.BindException;
          +import java.util.ArrayList;
          +import java.util.List;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.junit.After;
          +import org.junit.Before;
          +
          +import org.apache.geode.distributed.AbstractLauncher.Status;
          +import org.apache.geode.internal.process.ProcessStreamReader;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +
          +/**
          + * Abstract base class for integration tests of

          {@link ServerLauncher}

          as an application main in a
          + * forked JVM.
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class ServerLauncherRemoteIntegrationTestCase
          + extends ServerLauncherIntegrationTestCase implements UsesServerCommand {
          +
          + private final AtomicBoolean threwBindException = new AtomicBoolean();
          +
          + protected volatile Process process;
          + protected volatile ProcessStreamReader processOutReader;
          + protected volatile ProcessStreamReader processErrReader;
          +
          + private ServerCommand serverCommand;
          +
          + @Before
          + public void setUp() throws Exception

          { + serverCommand = new ServerCommand(this); + }

          +
          + @After
          + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception {
          + if (this.process != null)

          { + this.process.destroy(); + this.process = null; + }

          + if (this.processOutReader != null && this.processOutReader.isRunning())

          { + this.processOutReader.stop(); + }

          + if (this.processErrReader != null && this.processErrReader.isRunning())

          { + this.processErrReader.stop(); + }

          + }
          +
          + @Override
          + public List<String> getJvmArguments()

          { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + }

          +
          + @Override
          + public String getName()

          { + return getUniqueName(); + }

          +
          + @Override
          + public boolean getDisableDefaultServer()

          { + return false; + }

          +
          + protected void assertThatServerThrewBindException()

          { + assertThat(threwBindException.get()).isTrue(); + }
          +
          + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + }

          +
          + protected ServerLauncher startServer(final ServerCommand command)

          { + return awaitStart(command); + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command,
          + final ProcessStreamReader.InputListener outListener,
          + final ProcessStreamReader.InputListener errListener) throws Exception

          { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command) {
          + try

          { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          catch (IOException e)

          { + throw new UncheckedIOException(e); + }
          + }
          +
          + protected ServerLauncher awaitStart(final File workingDirectory) {
          + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + }

          + }
          +
          + @Override
          + protected ServerLauncher awaitStart(final ServerLauncher launcher)

          { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart()

          { + return awaitStart(this.launcher); + }

          +
          + protected void awaitStop() {
          — End diff –

          Delete unused method.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132321751 — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java — @@ -0,0 +1,270 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX; +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.net.BindException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.After; +import org.junit.Before; + +import org.apache.geode.distributed.AbstractLauncher.Status; +import org.apache.geode.internal.process.ProcessStreamReader; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; + +/** + * Abstract base class for integration tests of {@link ServerLauncher} as an application main in a + * forked JVM. + * + * @since GemFire 8.0 + */ +public abstract class ServerLauncherRemoteIntegrationTestCase + extends ServerLauncherIntegrationTestCase implements UsesServerCommand { + + private final AtomicBoolean threwBindException = new AtomicBoolean(); + + protected volatile Process process; + protected volatile ProcessStreamReader processOutReader; + protected volatile ProcessStreamReader processErrReader; + + private ServerCommand serverCommand; + + @Before + public void setUp() throws Exception { + serverCommand = new ServerCommand(this); + } + + @After + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception { + if (this.process != null) { + this.process.destroy(); + this.process = null; + } + if (this.processOutReader != null && this.processOutReader.isRunning()) { + this.processOutReader.stop(); + } + if (this.processErrReader != null && this.processErrReader.isRunning()) { + this.processErrReader.stop(); + } + } + + @Override + public List<String> getJvmArguments() { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + } + + @Override + public String getName() { + return getUniqueName(); + } + + @Override + public boolean getDisableDefaultServer() { + return false; + } + + protected void assertThatServerThrewBindException() { + assertThat(threwBindException.get()).isTrue(); + } + + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + } + + protected ServerLauncher startServer(final ServerCommand command) { + return awaitStart(command); + } + + protected ServerLauncher awaitStart(final ServerCommand command, + final ProcessStreamReader.InputListener outListener, + final ProcessStreamReader.InputListener errListener) throws Exception { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart(final ServerCommand command) { + try { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + protected ServerLauncher awaitStart(final File workingDirectory) { + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Override + protected ServerLauncher awaitStart(final ServerLauncher launcher) { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart() { + return awaitStart(this.launcher); + } + + protected void awaitStop() { — End diff – Delete unused method.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132321779

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java —
          @@ -0,0 +1,270 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX;
          +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +
          +import java.io.File;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.net.BindException;
          +import java.util.ArrayList;
          +import java.util.List;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.junit.After;
          +import org.junit.Before;
          +
          +import org.apache.geode.distributed.AbstractLauncher.Status;
          +import org.apache.geode.internal.process.ProcessStreamReader;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +
          +/**
          + * Abstract base class for integration tests of

          {@link ServerLauncher}

          as an application main in a
          + * forked JVM.
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class ServerLauncherRemoteIntegrationTestCase
          + extends ServerLauncherIntegrationTestCase implements UsesServerCommand {
          +
          + private final AtomicBoolean threwBindException = new AtomicBoolean();
          +
          + protected volatile Process process;
          + protected volatile ProcessStreamReader processOutReader;
          + protected volatile ProcessStreamReader processErrReader;
          +
          + private ServerCommand serverCommand;
          +
          + @Before
          + public void setUp() throws Exception

          { + serverCommand = new ServerCommand(this); + }

          +
          + @After
          + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception {
          + if (this.process != null)

          { + this.process.destroy(); + this.process = null; + }

          + if (this.processOutReader != null && this.processOutReader.isRunning())

          { + this.processOutReader.stop(); + }

          + if (this.processErrReader != null && this.processErrReader.isRunning())

          { + this.processErrReader.stop(); + }

          + }
          +
          + @Override
          + public List<String> getJvmArguments()

          { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + }

          +
          + @Override
          + public String getName()

          { + return getUniqueName(); + }

          +
          + @Override
          + public boolean getDisableDefaultServer()

          { + return false; + }

          +
          + protected void assertThatServerThrewBindException()

          { + assertThat(threwBindException.get()).isTrue(); + }
          +
          + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + }

          +
          + protected ServerLauncher startServer(final ServerCommand command)

          { + return awaitStart(command); + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command,
          + final ProcessStreamReader.InputListener outListener,
          + final ProcessStreamReader.InputListener errListener) throws Exception

          { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command) {
          + try

          { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          catch (IOException e)

          { + throw new UncheckedIOException(e); + }
          + }
          +
          + protected ServerLauncher awaitStart(final File workingDirectory) {
          + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + }

          + }
          +
          + @Override
          + protected ServerLauncher awaitStart(final ServerLauncher launcher)

          { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart()

          { + return awaitStart(this.launcher); + }

          +
          + protected void awaitStop()

          { + await().until(() -> assertThat(this.process.isAlive()).isFalse()); + }

          +
          + protected void assertStopOf(final Process process)

          { + await().until(() -> assertThat(process.isAlive()).isFalse()); + }

          +
          + protected Process getServerProcess()

          { + return this.process; + }

          +
          + protected void startServerShouldFail(final ServerCommand command, final InputListener outListener,
          + final InputListener errListener) throws IOException, InterruptedException

          { + executeCommandWithReaders(command.create(), outListener, errListener); + process.waitFor(2, MINUTES); + assertThat(process.isAlive()).isFalse(); + assertThat(process.exitValue()).isEqualTo(1); + }

          +
          + protected void startServerShouldFail(final ServerCommand command)
          + throws IOException, InterruptedException

          { + startServerShouldFail(command, createBindExceptionListener("sysout", threwBindException), + createBindExceptionListener("syserr", threwBindException)); + }

          +
          + protected void startServerShouldFail() throws IOException, InterruptedException

          { + startServerShouldFail(serverCommand); + }

          +
          + private InputListener createBindExceptionListener(final String name,
          + final AtomicBoolean threwBindException)

          { + return createExpectedListener(name, getUniqueName() + "#" + name, BindException.class.getName(), + threwBindException); + }

          +
          + @Override
          + protected ServerLauncher startServer()

          { + return startServer(serverCommand); + }

          +
          + protected void assertThatProcessIsNotAlive() {
          — End diff –

          Delete unused method.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132321779 — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java — @@ -0,0 +1,270 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX; +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.net.BindException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.After; +import org.junit.Before; + +import org.apache.geode.distributed.AbstractLauncher.Status; +import org.apache.geode.internal.process.ProcessStreamReader; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; + +/** + * Abstract base class for integration tests of {@link ServerLauncher} as an application main in a + * forked JVM. + * + * @since GemFire 8.0 + */ +public abstract class ServerLauncherRemoteIntegrationTestCase + extends ServerLauncherIntegrationTestCase implements UsesServerCommand { + + private final AtomicBoolean threwBindException = new AtomicBoolean(); + + protected volatile Process process; + protected volatile ProcessStreamReader processOutReader; + protected volatile ProcessStreamReader processErrReader; + + private ServerCommand serverCommand; + + @Before + public void setUp() throws Exception { + serverCommand = new ServerCommand(this); + } + + @After + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception { + if (this.process != null) { + this.process.destroy(); + this.process = null; + } + if (this.processOutReader != null && this.processOutReader.isRunning()) { + this.processOutReader.stop(); + } + if (this.processErrReader != null && this.processErrReader.isRunning()) { + this.processErrReader.stop(); + } + } + + @Override + public List<String> getJvmArguments() { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + } + + @Override + public String getName() { + return getUniqueName(); + } + + @Override + public boolean getDisableDefaultServer() { + return false; + } + + protected void assertThatServerThrewBindException() { + assertThat(threwBindException.get()).isTrue(); + } + + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + } + + protected ServerLauncher startServer(final ServerCommand command) { + return awaitStart(command); + } + + protected ServerLauncher awaitStart(final ServerCommand command, + final ProcessStreamReader.InputListener outListener, + final ProcessStreamReader.InputListener errListener) throws Exception { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart(final ServerCommand command) { + try { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + protected ServerLauncher awaitStart(final File workingDirectory) { + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Override + protected ServerLauncher awaitStart(final ServerLauncher launcher) { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart() { + return awaitStart(this.launcher); + } + + protected void awaitStop() { + await().until(() -> assertThat(this.process.isAlive()).isFalse()); + } + + protected void assertStopOf(final Process process) { + await().until(() -> assertThat(process.isAlive()).isFalse()); + } + + protected Process getServerProcess() { + return this.process; + } + + protected void startServerShouldFail(final ServerCommand command, final InputListener outListener, + final InputListener errListener) throws IOException, InterruptedException { + executeCommandWithReaders(command.create(), outListener, errListener); + process.waitFor(2, MINUTES); + assertThat(process.isAlive()).isFalse(); + assertThat(process.exitValue()).isEqualTo(1); + } + + protected void startServerShouldFail(final ServerCommand command) + throws IOException, InterruptedException { + startServerShouldFail(command, createBindExceptionListener("sysout", threwBindException), + createBindExceptionListener("syserr", threwBindException)); + } + + protected void startServerShouldFail() throws IOException, InterruptedException { + startServerShouldFail(serverCommand); + } + + private InputListener createBindExceptionListener(final String name, + final AtomicBoolean threwBindException) { + return createExpectedListener(name, getUniqueName() + "#" + name, BindException.class.getName(), + threwBindException); + } + + @Override + protected ServerLauncher startServer() { + return startServer(serverCommand); + } + + protected void assertThatProcessIsNotAlive() { — End diff – Delete unused method.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132321846

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java —
          @@ -0,0 +1,270 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX;
          +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +
          +import java.io.File;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.net.BindException;
          +import java.util.ArrayList;
          +import java.util.List;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.junit.After;
          +import org.junit.Before;
          +
          +import org.apache.geode.distributed.AbstractLauncher.Status;
          +import org.apache.geode.internal.process.ProcessStreamReader;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +
          +/**
          + * Abstract base class for integration tests of

          {@link ServerLauncher}

          as an application main in a
          + * forked JVM.
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class ServerLauncherRemoteIntegrationTestCase
          + extends ServerLauncherIntegrationTestCase implements UsesServerCommand {
          +
          + private final AtomicBoolean threwBindException = new AtomicBoolean();
          +
          + protected volatile Process process;
          + protected volatile ProcessStreamReader processOutReader;
          + protected volatile ProcessStreamReader processErrReader;
          +
          + private ServerCommand serverCommand;
          +
          + @Before
          + public void setUp() throws Exception

          { + serverCommand = new ServerCommand(this); + }

          +
          + @After
          + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception {
          + if (this.process != null)

          { + this.process.destroy(); + this.process = null; + }

          + if (this.processOutReader != null && this.processOutReader.isRunning())

          { + this.processOutReader.stop(); + }

          + if (this.processErrReader != null && this.processErrReader.isRunning())

          { + this.processErrReader.stop(); + }

          + }
          +
          + @Override
          + public List<String> getJvmArguments()

          { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + }

          +
          + @Override
          + public String getName()

          { + return getUniqueName(); + }

          +
          + @Override
          + public boolean getDisableDefaultServer()

          { + return false; + }

          +
          + protected void assertThatServerThrewBindException()

          { + assertThat(threwBindException.get()).isTrue(); + }
          +
          + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + }

          +
          + protected ServerLauncher startServer(final ServerCommand command)

          { + return awaitStart(command); + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command,
          + final ProcessStreamReader.InputListener outListener,
          + final ProcessStreamReader.InputListener errListener) throws Exception

          { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command) {
          + try

          { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          catch (IOException e)

          { + throw new UncheckedIOException(e); + }
          + }
          +
          + protected ServerLauncher awaitStart(final File workingDirectory) {
          + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + }

          + }
          +
          + @Override
          + protected ServerLauncher awaitStart(final ServerLauncher launcher)

          { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart()

          { + return awaitStart(this.launcher); + }

          +
          + protected void awaitStop()

          { + await().until(() -> assertThat(this.process.isAlive()).isFalse()); + }

          +
          + protected void assertStopOf(final Process process)

          { + await().until(() -> assertThat(process.isAlive()).isFalse()); + }

          +
          + protected Process getServerProcess()

          { + return this.process; + }

          +
          + protected void startServerShouldFail(final ServerCommand command, final InputListener outListener,
          + final InputListener errListener) throws IOException, InterruptedException

          { + executeCommandWithReaders(command.create(), outListener, errListener); + process.waitFor(2, MINUTES); + assertThat(process.isAlive()).isFalse(); + assertThat(process.exitValue()).isEqualTo(1); + }

          +
          + protected void startServerShouldFail(final ServerCommand command)
          + throws IOException, InterruptedException

          { + startServerShouldFail(command, createBindExceptionListener("sysout", threwBindException), + createBindExceptionListener("syserr", threwBindException)); + }

          +
          + protected void startServerShouldFail() throws IOException, InterruptedException

          { + startServerShouldFail(serverCommand); + }

          +
          + private InputListener createBindExceptionListener(final String name,
          + final AtomicBoolean threwBindException)

          { + return createExpectedListener(name, getUniqueName() + "#" + name, BindException.class.getName(), + threwBindException); + }

          +
          + @Override
          + protected ServerLauncher startServer()

          { + return startServer(serverCommand); + }

          +
          + protected void assertThatProcessIsNotAlive()

          { + assertThatProcessIsNotAlive(process); + }

          +
          + protected void assertThatProcessIsNotAlive(final Process process)

          { + assertThat(process.isAlive()).isFalse(); + }
          +
          + protected void assertProcessIsNotAlive() { + assertThat(process.isAlive()).isFalse(); + }

          +
          + protected void assertProcessIsAlive() {
          — End diff –

          Delete unused method. Etc. I'm not gonna mark the rest of these... just delete them if they're unused.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132321846 — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java — @@ -0,0 +1,270 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX; +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.net.BindException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.After; +import org.junit.Before; + +import org.apache.geode.distributed.AbstractLauncher.Status; +import org.apache.geode.internal.process.ProcessStreamReader; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; + +/** + * Abstract base class for integration tests of {@link ServerLauncher} as an application main in a + * forked JVM. + * + * @since GemFire 8.0 + */ +public abstract class ServerLauncherRemoteIntegrationTestCase + extends ServerLauncherIntegrationTestCase implements UsesServerCommand { + + private final AtomicBoolean threwBindException = new AtomicBoolean(); + + protected volatile Process process; + protected volatile ProcessStreamReader processOutReader; + protected volatile ProcessStreamReader processErrReader; + + private ServerCommand serverCommand; + + @Before + public void setUp() throws Exception { + serverCommand = new ServerCommand(this); + } + + @After + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception { + if (this.process != null) { + this.process.destroy(); + this.process = null; + } + if (this.processOutReader != null && this.processOutReader.isRunning()) { + this.processOutReader.stop(); + } + if (this.processErrReader != null && this.processErrReader.isRunning()) { + this.processErrReader.stop(); + } + } + + @Override + public List<String> getJvmArguments() { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + } + + @Override + public String getName() { + return getUniqueName(); + } + + @Override + public boolean getDisableDefaultServer() { + return false; + } + + protected void assertThatServerThrewBindException() { + assertThat(threwBindException.get()).isTrue(); + } + + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + } + + protected ServerLauncher startServer(final ServerCommand command) { + return awaitStart(command); + } + + protected ServerLauncher awaitStart(final ServerCommand command, + final ProcessStreamReader.InputListener outListener, + final ProcessStreamReader.InputListener errListener) throws Exception { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart(final ServerCommand command) { + try { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + protected ServerLauncher awaitStart(final File workingDirectory) { + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Override + protected ServerLauncher awaitStart(final ServerLauncher launcher) { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart() { + return awaitStart(this.launcher); + } + + protected void awaitStop() { + await().until(() -> assertThat(this.process.isAlive()).isFalse()); + } + + protected void assertStopOf(final Process process) { + await().until(() -> assertThat(process.isAlive()).isFalse()); + } + + protected Process getServerProcess() { + return this.process; + } + + protected void startServerShouldFail(final ServerCommand command, final InputListener outListener, + final InputListener errListener) throws IOException, InterruptedException { + executeCommandWithReaders(command.create(), outListener, errListener); + process.waitFor(2, MINUTES); + assertThat(process.isAlive()).isFalse(); + assertThat(process.exitValue()).isEqualTo(1); + } + + protected void startServerShouldFail(final ServerCommand command) + throws IOException, InterruptedException { + startServerShouldFail(command, createBindExceptionListener("sysout", threwBindException), + createBindExceptionListener("syserr", threwBindException)); + } + + protected void startServerShouldFail() throws IOException, InterruptedException { + startServerShouldFail(serverCommand); + } + + private InputListener createBindExceptionListener(final String name, + final AtomicBoolean threwBindException) { + return createExpectedListener(name, getUniqueName() + "#" + name, BindException.class.getName(), + threwBindException); + } + + @Override + protected ServerLauncher startServer() { + return startServer(serverCommand); + } + + protected void assertThatProcessIsNotAlive() { + assertThatProcessIsNotAlive(process); + } + + protected void assertThatProcessIsNotAlive(final Process process) { + assertThat(process.isAlive()).isFalse(); + } + + protected void assertProcessIsNotAlive() { + assertThat(process.isAlive()).isFalse(); + } + + protected void assertProcessIsAlive() { — End diff – Delete unused method. Etc. I'm not gonna mark the rest of these... just delete them if they're unused.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132321738

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java —
          @@ -0,0 +1,270 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX;
          +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +
          +import java.io.File;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.net.BindException;
          +import java.util.ArrayList;
          +import java.util.List;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.junit.After;
          +import org.junit.Before;
          +
          +import org.apache.geode.distributed.AbstractLauncher.Status;
          +import org.apache.geode.internal.process.ProcessStreamReader;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +
          +/**
          + * Abstract base class for integration tests of

          {@link ServerLauncher}

          as an application main in a
          + * forked JVM.
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class ServerLauncherRemoteIntegrationTestCase
          + extends ServerLauncherIntegrationTestCase implements UsesServerCommand {
          +
          + private final AtomicBoolean threwBindException = new AtomicBoolean();
          +
          + protected volatile Process process;
          + protected volatile ProcessStreamReader processOutReader;
          + protected volatile ProcessStreamReader processErrReader;
          +
          + private ServerCommand serverCommand;
          +
          + @Before
          + public void setUp() throws Exception

          { + serverCommand = new ServerCommand(this); + }

          +
          + @After
          + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception {
          + if (this.process != null)

          { + this.process.destroy(); + this.process = null; + }

          + if (this.processOutReader != null && this.processOutReader.isRunning())

          { + this.processOutReader.stop(); + }

          + if (this.processErrReader != null && this.processErrReader.isRunning())

          { + this.processErrReader.stop(); + }

          + }
          +
          + @Override
          + public List<String> getJvmArguments()

          { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + }

          +
          + @Override
          + public String getName()

          { + return getUniqueName(); + }

          +
          + @Override
          + public boolean getDisableDefaultServer()

          { + return false; + }

          +
          + protected void assertThatServerThrewBindException()

          { + assertThat(threwBindException.get()).isTrue(); + }
          +
          + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + }

          +
          + protected ServerLauncher startServer(final ServerCommand command)

          { + return awaitStart(command); + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command,
          + final ProcessStreamReader.InputListener outListener,
          + final ProcessStreamReader.InputListener errListener) throws Exception

          { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command) {
          + try

          { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          catch (IOException e)

          { + throw new UncheckedIOException(e); + }
          + }
          +
          + protected ServerLauncher awaitStart(final File workingDirectory) {
          + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + }

          + }
          +
          + @Override
          + protected ServerLauncher awaitStart(final ServerLauncher launcher)

          { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart() {
          — End diff –

          Delete unused method.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132321738 — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java — @@ -0,0 +1,270 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX; +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.net.BindException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.After; +import org.junit.Before; + +import org.apache.geode.distributed.AbstractLauncher.Status; +import org.apache.geode.internal.process.ProcessStreamReader; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; + +/** + * Abstract base class for integration tests of {@link ServerLauncher} as an application main in a + * forked JVM. + * + * @since GemFire 8.0 + */ +public abstract class ServerLauncherRemoteIntegrationTestCase + extends ServerLauncherIntegrationTestCase implements UsesServerCommand { + + private final AtomicBoolean threwBindException = new AtomicBoolean(); + + protected volatile Process process; + protected volatile ProcessStreamReader processOutReader; + protected volatile ProcessStreamReader processErrReader; + + private ServerCommand serverCommand; + + @Before + public void setUp() throws Exception { + serverCommand = new ServerCommand(this); + } + + @After + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception { + if (this.process != null) { + this.process.destroy(); + this.process = null; + } + if (this.processOutReader != null && this.processOutReader.isRunning()) { + this.processOutReader.stop(); + } + if (this.processErrReader != null && this.processErrReader.isRunning()) { + this.processErrReader.stop(); + } + } + + @Override + public List<String> getJvmArguments() { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + } + + @Override + public String getName() { + return getUniqueName(); + } + + @Override + public boolean getDisableDefaultServer() { + return false; + } + + protected void assertThatServerThrewBindException() { + assertThat(threwBindException.get()).isTrue(); + } + + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + } + + protected ServerLauncher startServer(final ServerCommand command) { + return awaitStart(command); + } + + protected ServerLauncher awaitStart(final ServerCommand command, + final ProcessStreamReader.InputListener outListener, + final ProcessStreamReader.InputListener errListener) throws Exception { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart(final ServerCommand command) { + try { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + protected ServerLauncher awaitStart(final File workingDirectory) { + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Override + protected ServerLauncher awaitStart(final ServerLauncher launcher) { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart() { — End diff – Delete unused method.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132321803

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java —
          @@ -0,0 +1,270 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX;
          +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +
          +import java.io.File;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.net.BindException;
          +import java.util.ArrayList;
          +import java.util.List;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.junit.After;
          +import org.junit.Before;
          +
          +import org.apache.geode.distributed.AbstractLauncher.Status;
          +import org.apache.geode.internal.process.ProcessStreamReader;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +
          +/**
          + * Abstract base class for integration tests of

          {@link ServerLauncher}

          as an application main in a
          + * forked JVM.
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class ServerLauncherRemoteIntegrationTestCase
          + extends ServerLauncherIntegrationTestCase implements UsesServerCommand {
          +
          + private final AtomicBoolean threwBindException = new AtomicBoolean();
          +
          + protected volatile Process process;
          + protected volatile ProcessStreamReader processOutReader;
          + protected volatile ProcessStreamReader processErrReader;
          +
          + private ServerCommand serverCommand;
          +
          + @Before
          + public void setUp() throws Exception

          { + serverCommand = new ServerCommand(this); + }

          +
          + @After
          + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception {
          + if (this.process != null)

          { + this.process.destroy(); + this.process = null; + }

          + if (this.processOutReader != null && this.processOutReader.isRunning())

          { + this.processOutReader.stop(); + }

          + if (this.processErrReader != null && this.processErrReader.isRunning())

          { + this.processErrReader.stop(); + }

          + }
          +
          + @Override
          + public List<String> getJvmArguments()

          { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + }

          +
          + @Override
          + public String getName()

          { + return getUniqueName(); + }

          +
          + @Override
          + public boolean getDisableDefaultServer()

          { + return false; + }

          +
          + protected void assertThatServerThrewBindException()

          { + assertThat(threwBindException.get()).isTrue(); + }
          +
          + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + }

          +
          + protected ServerLauncher startServer(final ServerCommand command)

          { + return awaitStart(command); + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command,
          + final ProcessStreamReader.InputListener outListener,
          + final ProcessStreamReader.InputListener errListener) throws Exception

          { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command) {
          + try

          { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          catch (IOException e)

          { + throw new UncheckedIOException(e); + }
          + }
          +
          + protected ServerLauncher awaitStart(final File workingDirectory) {
          + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + }

          + }
          +
          + @Override
          + protected ServerLauncher awaitStart(final ServerLauncher launcher)

          { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart()

          { + return awaitStart(this.launcher); + }

          +
          + protected void awaitStop()

          { + await().until(() -> assertThat(this.process.isAlive()).isFalse()); + }

          +
          + protected void assertStopOf(final Process process)

          { + await().until(() -> assertThat(process.isAlive()).isFalse()); + }

          +
          + protected Process getServerProcess()

          { + return this.process; + }

          +
          + protected void startServerShouldFail(final ServerCommand command, final InputListener outListener,
          + final InputListener errListener) throws IOException, InterruptedException

          { + executeCommandWithReaders(command.create(), outListener, errListener); + process.waitFor(2, MINUTES); + assertThat(process.isAlive()).isFalse(); + assertThat(process.exitValue()).isEqualTo(1); + }

          +
          + protected void startServerShouldFail(final ServerCommand command)
          + throws IOException, InterruptedException

          { + startServerShouldFail(command, createBindExceptionListener("sysout", threwBindException), + createBindExceptionListener("syserr", threwBindException)); + }

          +
          + protected void startServerShouldFail() throws IOException, InterruptedException

          { + startServerShouldFail(serverCommand); + }

          +
          + private InputListener createBindExceptionListener(final String name,
          + final AtomicBoolean threwBindException)

          { + return createExpectedListener(name, getUniqueName() + "#" + name, BindException.class.getName(), + threwBindException); + }

          +
          + @Override
          + protected ServerLauncher startServer()

          { + return startServer(serverCommand); + }

          +
          + protected void assertThatProcessIsNotAlive()

          { + assertThatProcessIsNotAlive(process); + }

          +
          + protected void assertThatProcessIsNotAlive(final Process process)

          { + assertThat(process.isAlive()).isFalse(); + }

          +
          + protected void assertProcessIsNotAlive() {
          — End diff –

          Delete unused method.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132321803 — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java — @@ -0,0 +1,270 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX; +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.net.BindException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.After; +import org.junit.Before; + +import org.apache.geode.distributed.AbstractLauncher.Status; +import org.apache.geode.internal.process.ProcessStreamReader; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; + +/** + * Abstract base class for integration tests of {@link ServerLauncher} as an application main in a + * forked JVM. + * + * @since GemFire 8.0 + */ +public abstract class ServerLauncherRemoteIntegrationTestCase + extends ServerLauncherIntegrationTestCase implements UsesServerCommand { + + private final AtomicBoolean threwBindException = new AtomicBoolean(); + + protected volatile Process process; + protected volatile ProcessStreamReader processOutReader; + protected volatile ProcessStreamReader processErrReader; + + private ServerCommand serverCommand; + + @Before + public void setUp() throws Exception { + serverCommand = new ServerCommand(this); + } + + @After + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception { + if (this.process != null) { + this.process.destroy(); + this.process = null; + } + if (this.processOutReader != null && this.processOutReader.isRunning()) { + this.processOutReader.stop(); + } + if (this.processErrReader != null && this.processErrReader.isRunning()) { + this.processErrReader.stop(); + } + } + + @Override + public List<String> getJvmArguments() { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + } + + @Override + public String getName() { + return getUniqueName(); + } + + @Override + public boolean getDisableDefaultServer() { + return false; + } + + protected void assertThatServerThrewBindException() { + assertThat(threwBindException.get()).isTrue(); + } + + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + } + + protected ServerLauncher startServer(final ServerCommand command) { + return awaitStart(command); + } + + protected ServerLauncher awaitStart(final ServerCommand command, + final ProcessStreamReader.InputListener outListener, + final ProcessStreamReader.InputListener errListener) throws Exception { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart(final ServerCommand command) { + try { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + protected ServerLauncher awaitStart(final File workingDirectory) { + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Override + protected ServerLauncher awaitStart(final ServerLauncher launcher) { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart() { + return awaitStart(this.launcher); + } + + protected void awaitStop() { + await().until(() -> assertThat(this.process.isAlive()).isFalse()); + } + + protected void assertStopOf(final Process process) { + await().until(() -> assertThat(process.isAlive()).isFalse()); + } + + protected Process getServerProcess() { + return this.process; + } + + protected void startServerShouldFail(final ServerCommand command, final InputListener outListener, + final InputListener errListener) throws IOException, InterruptedException { + executeCommandWithReaders(command.create(), outListener, errListener); + process.waitFor(2, MINUTES); + assertThat(process.isAlive()).isFalse(); + assertThat(process.exitValue()).isEqualTo(1); + } + + protected void startServerShouldFail(final ServerCommand command) + throws IOException, InterruptedException { + startServerShouldFail(command, createBindExceptionListener("sysout", threwBindException), + createBindExceptionListener("syserr", threwBindException)); + } + + protected void startServerShouldFail() throws IOException, InterruptedException { + startServerShouldFail(serverCommand); + } + + private InputListener createBindExceptionListener(final String name, + final AtomicBoolean threwBindException) { + return createExpectedListener(name, getUniqueName() + "#" + name, BindException.class.getName(), + threwBindException); + } + + @Override + protected ServerLauncher startServer() { + return startServer(serverCommand); + } + + protected void assertThatProcessIsNotAlive() { + assertThatProcessIsNotAlive(process); + } + + protected void assertThatProcessIsNotAlive(final Process process) { + assertThat(process.isAlive()).isFalse(); + } + + protected void assertProcessIsNotAlive() { — End diff – Delete unused method.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132322055

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherTest.java —
          @@ -14,253 +14,370 @@
          */
          package org.apache.geode.distributed;

          +import static java.util.concurrent.TimeUnit.DAYS;
          +import static java.util.concurrent.TimeUnit.HOURS;
          +import static java.util.concurrent.TimeUnit.MILLISECONDS;
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static java.util.concurrent.TimeUnit.SECONDS;
          +import static org.apache.geode.distributed.AbstractLauncher.ServiceState.toDaysHoursMinutesSeconds;
          import static org.apache.geode.distributed.ConfigurationProperties.NAME;
          -import static org.junit.Assert.assertEquals;
          -import static org.junit.Assert.assertFalse;
          -import static org.junit.Assert.assertNotNull;
          -import static org.junit.Assert.assertNull;
          -import static org.junit.Assert.assertTrue;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.assertj.core.api.Assertions.entry;
          import static org.mockito.Mockito.mock;
          import static org.mockito.Mockito.times;
          import static org.mockito.Mockito.verify;

          +import java.net.URL;
          +import java.util.Properties;
          +
          import org.apache.commons.lang.StringUtils;
          -import org.apache.geode.test.junit.categories.UnitTest;
          import org.junit.Test;
          import org.junit.experimental.categories.Category;

          -import java.net.MalformedURLException;
          -import java.net.URL;
          -import java.util.Properties;
          -import java.util.concurrent.TimeUnit;
          +import org.apache.geode.test.junit.categories.UnitTest;

          /**

          • * The AbstractLauncherTest class is a test suite of unit tests testing the contract and
          • * functionality of the AbstractLauncher class.
          • * <p/>
          • *
          • * @see org.apache.geode.distributed.AbstractLauncher
          • * @see org.junit.Assert
          • * @see org.junit.Test
            + * Unit tests for {@link AbstractLauncher}

            .
            + *

          • @since GemFire 7.0
            */
            @Category(UnitTest.class)
            public class AbstractLauncherTest {
          • private AbstractLauncher<?> createAbstractLauncher(final String memberName,
          • final String memberId) { - return new FakeServiceLauncher(memberName, memberId); - }

            -
            @Test

          • public void shouldBeMockable() throws Exception {
            + public void canBeMocked() throws Exception { AbstractLauncher mockAbstractLauncher = mock(AbstractLauncher.class); mockAbstractLauncher.setDebug(true); verify(mockAbstractLauncher, times(1)).setDebug(true); }

          @Test

          • public void testIsSet() {
          • final Properties properties = new Properties();
            + public void isSetReturnsFalseIfPropertyDoesNotExist() throws Exception { + assertThat(AbstractLauncher.isSet(new Properties(), NAME)).isFalse(); + }
          • assertFalse(properties.containsKey(NAME));
          • assertFalse(AbstractLauncher.isSet(properties, NAME));
            + @Test
            + public void isSetReturnsFalseIfPropertyHasEmptyValue() throws Exception { + Properties properties = new Properties(); properties.setProperty(NAME, ""); - assertTrue(properties.containsKey(NAME)); - assertFalse(AbstractLauncher.isSet(properties, NAME)); + assertThat(AbstractLauncher.isSet(properties, NAME)).isFalse(); + }

            +
            + @Test
            + public void isSetReturnsFalseIfPropertyHasBlankValue() throws Exception

            { + Properties properties = new Properties(); properties.setProperty(NAME, " "); - assertTrue(properties.containsKey(NAME)); - assertFalse(AbstractLauncher.isSet(properties, NAME)); + assertThat(AbstractLauncher.isSet(properties, NAME)).isFalse(); + }

            +
            + @Test
            + public void isSetReturnsFalseIfPropertyHasRealValue() throws Exception

            { + Properties properties = new Properties(); properties.setProperty(NAME, "memberOne"); - assertTrue(AbstractLauncher.isSet(properties, NAME)); - assertFalse(AbstractLauncher.isSet(properties, "NaMe")); + assertThat(AbstractLauncher.isSet(properties, NAME)).isTrue(); }

          @Test

          • public void testLoadGemFirePropertiesWithNullURL() {
          • final Properties properties = AbstractLauncher.loadGemFireProperties(null);
          • assertNotNull(properties);
          • assertTrue(properties.isEmpty());
            + public void isSetKeyIsCaseSensitive() throws Exception { + Properties properties = new Properties(); + + properties.setProperty(NAME, "memberOne"); + + assertThat(AbstractLauncher.isSet(properties, "NaMe")).isFalse(); }

          @Test

          • public void testLoadGemFirePropertiesWithNonExistingURL() throws MalformedURLException {
          • final Properties properties = AbstractLauncher
          • .loadGemFireProperties(new URL("file:///path/to/non_existing/gemfire.properties"));
          • assertNotNull(properties);
          • assertTrue(properties.isEmpty());
            + public void loadGemFirePropertiesWithNullURLReturnsEmptyProperties() throws Exception { + URL nullUrl = null; + + Properties properties = AbstractLauncher.loadGemFireProperties(nullUrl); + + assertThat(properties).isNotNull().isEmpty(); }

          @Test

          • public void testGetDistributedSystemProperties() {
          • AbstractLauncher<?> launcher = createAbstractLauncher("memberOne", "1");
            + public void loadGemFirePropertiesWithNonExistingURLReturnsEmptyProperties() throws Exception { + URL nonExistingUrl = new URL("file:///path/to/non_existing/gemfire.properties"); + + Properties properties = AbstractLauncher.loadGemFireProperties(nonExistingUrl); - assertNotNull(launcher); - assertEquals("1", launcher.getMemberId()); - assertEquals("memberOne", launcher.getMemberName()); + assertThat(properties).isNotNull().isEmpty(); + }
          • Properties distributedSystemProperties = launcher.getDistributedSystemProperties();
            + @Test
            + public void abstractLauncherHasMemberIdAndMemberName() throws Exception {
              • End diff –

          Deleted.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132322055 — Diff: geode-core/src/test/java/org/apache/geode/distributed/AbstractLauncherTest.java — @@ -14,253 +14,370 @@ */ package org.apache.geode.distributed; +import static java.util.concurrent.TimeUnit.DAYS; +import static java.util.concurrent.TimeUnit.HOURS; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.apache.geode.distributed.AbstractLauncher.ServiceState.toDaysHoursMinutesSeconds; import static org.apache.geode.distributed.ConfigurationProperties.NAME; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import java.net.URL; +import java.util.Properties; + import org.apache.commons.lang.StringUtils; -import org.apache.geode.test.junit.categories.UnitTest; import org.junit.Test; import org.junit.experimental.categories.Category; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Properties; -import java.util.concurrent.TimeUnit; +import org.apache.geode.test.junit.categories.UnitTest; /** * The AbstractLauncherTest class is a test suite of unit tests testing the contract and * functionality of the AbstractLauncher class. * <p/> * * @see org.apache.geode.distributed.AbstractLauncher * @see org.junit.Assert * @see org.junit.Test + * Unit tests for {@link AbstractLauncher} . + * @since GemFire 7.0 */ @Category(UnitTest.class) public class AbstractLauncherTest { private AbstractLauncher<?> createAbstractLauncher(final String memberName, final String memberId) { - return new FakeServiceLauncher(memberName, memberId); - } - @Test public void shouldBeMockable() throws Exception { + public void canBeMocked() throws Exception { AbstractLauncher mockAbstractLauncher = mock(AbstractLauncher.class); mockAbstractLauncher.setDebug(true); verify(mockAbstractLauncher, times(1)).setDebug(true); } @Test public void testIsSet() { final Properties properties = new Properties(); + public void isSetReturnsFalseIfPropertyDoesNotExist() throws Exception { + assertThat(AbstractLauncher.isSet(new Properties(), NAME)).isFalse(); + } assertFalse(properties.containsKey(NAME)); assertFalse(AbstractLauncher.isSet(properties, NAME)); + @Test + public void isSetReturnsFalseIfPropertyHasEmptyValue() throws Exception { + Properties properties = new Properties(); properties.setProperty(NAME, ""); - assertTrue(properties.containsKey(NAME)); - assertFalse(AbstractLauncher.isSet(properties, NAME)); + assertThat(AbstractLauncher.isSet(properties, NAME)).isFalse(); + } + + @Test + public void isSetReturnsFalseIfPropertyHasBlankValue() throws Exception { + Properties properties = new Properties(); properties.setProperty(NAME, " "); - assertTrue(properties.containsKey(NAME)); - assertFalse(AbstractLauncher.isSet(properties, NAME)); + assertThat(AbstractLauncher.isSet(properties, NAME)).isFalse(); + } + + @Test + public void isSetReturnsFalseIfPropertyHasRealValue() throws Exception { + Properties properties = new Properties(); properties.setProperty(NAME, "memberOne"); - assertTrue(AbstractLauncher.isSet(properties, NAME)); - assertFalse(AbstractLauncher.isSet(properties, "NaMe")); + assertThat(AbstractLauncher.isSet(properties, NAME)).isTrue(); } @Test public void testLoadGemFirePropertiesWithNullURL() { final Properties properties = AbstractLauncher.loadGemFireProperties(null); assertNotNull(properties); assertTrue(properties.isEmpty()); + public void isSetKeyIsCaseSensitive() throws Exception { + Properties properties = new Properties(); + + properties.setProperty(NAME, "memberOne"); + + assertThat(AbstractLauncher.isSet(properties, "NaMe")).isFalse(); } @Test public void testLoadGemFirePropertiesWithNonExistingURL() throws MalformedURLException { final Properties properties = AbstractLauncher .loadGemFireProperties(new URL("file:///path/to/non_existing/gemfire.properties")); assertNotNull(properties); assertTrue(properties.isEmpty()); + public void loadGemFirePropertiesWithNullURLReturnsEmptyProperties() throws Exception { + URL nullUrl = null; + + Properties properties = AbstractLauncher.loadGemFireProperties(nullUrl); + + assertThat(properties).isNotNull().isEmpty(); } @Test public void testGetDistributedSystemProperties() { AbstractLauncher<?> launcher = createAbstractLauncher("memberOne", "1"); + public void loadGemFirePropertiesWithNonExistingURLReturnsEmptyProperties() throws Exception { + URL nonExistingUrl = new URL("file:///path/to/non_existing/gemfire.properties"); + + Properties properties = AbstractLauncher.loadGemFireProperties(nonExistingUrl); - assertNotNull(launcher); - assertEquals("1", launcher.getMemberId()); - assertEquals("memberOne", launcher.getMemberName()); + assertThat(properties).isNotNull().isEmpty(); + } Properties distributedSystemProperties = launcher.getDistributedSystemProperties(); + @Test + public void abstractLauncherHasMemberIdAndMemberName() throws Exception { End diff – Deleted.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132323674

          — Diff: geode-core/src/test/java/org/apache/geode/internal/process/lang/AvailablePidTest.java —
          @@ -0,0 +1,74 @@
          +/*
          + * 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.geode.internal.process.lang;
          — End diff –

          I'm not sure how to test this. For example, my first idea is to invoke it twice and make sure they're not the same but I don't think that's a safe assertion. It's also probably not safe to assert that they're not sequential. Hmm...

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132323674 — Diff: geode-core/src/test/java/org/apache/geode/internal/process/lang/AvailablePidTest.java — @@ -0,0 +1,74 @@ +/* + * 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.geode.internal.process.lang; — End diff – I'm not sure how to test this. For example, my first idea is to invoke it twice and make sure they're not the same but I don't think that's a safe assertion. It's also probably not safe to assert that they're not sequential. Hmm...
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132324550

          — Diff: geode-core/src/test/java/org/apache/geode/internal/process/lang/AvailablePidTest.java —
          @@ -0,0 +1,74 @@
          +/*
          + * 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.geode.internal.process.lang;
          — End diff –

          Actually, just realized AvailablePid returns unused pids. Nothing in the javadoc or API says anything about it being "random" – that's just how it's implemented. So the only really important details is that the pid is unused.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132324550 — Diff: geode-core/src/test/java/org/apache/geode/internal/process/lang/AvailablePidTest.java — @@ -0,0 +1,74 @@ +/* + * 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.geode.internal.process.lang; — End diff – Actually, just realized AvailablePid returns unused pids. Nothing in the javadoc or API says anything about it being "random" – that's just how it's implemented. So the only really important details is that the pid is unused.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132324608

          — Diff: geode-core/src/test/java/org/apache/geode/internal/process/lang/AvailablePidTest.java —
          @@ -0,0 +1,74 @@
          +/*
          + * 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.geode.internal.process.lang;
          — End diff –

          Oops there it is in the javadocs of the methods.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132324608 — Diff: geode-core/src/test/java/org/apache/geode/internal/process/lang/AvailablePidTest.java — @@ -0,0 +1,74 @@ +/* + * 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.geode.internal.process.lang; — End diff – Oops there it is in the javadocs of the methods.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132326281

          — Diff: geode-core/src/test/java/org/apache/geode/internal/process/lang/AvailablePidTest.java —
          @@ -0,0 +1,74 @@
          +/*
          + * 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.geode.internal.process.lang;
          — End diff –

          ```java
          @Test(timeout = DEFAULT_TIMEOUT_MILLIS)
          public void findAvailablePidShouldReturnRandomPid() throws Exception

          { Random random = spy(new Random()); availablePid = new AvailablePid(random, DEFAULT_TIMEOUT_MILLIS); availablePid.findAvailablePid(); verify(random, atLeastOnce()).nextInt(anyInt()); }

          ```

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132326281 — Diff: geode-core/src/test/java/org/apache/geode/internal/process/lang/AvailablePidTest.java — @@ -0,0 +1,74 @@ +/* + * 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.geode.internal.process.lang; — End diff – ```java @Test(timeout = DEFAULT_TIMEOUT_MILLIS) public void findAvailablePidShouldReturnRandomPid() throws Exception { Random random = spy(new Random()); availablePid = new AvailablePid(random, DEFAULT_TIMEOUT_MILLIS); availablePid.findAvailablePid(); verify(random, atLeastOnce()).nextInt(anyInt()); } ```
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132325049

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java —
          @@ -1075,8 +1082,7 @@ private LocatorState stopWithWorkingDirectory() {
          try {
          final ProcessController controller =
          new ProcessControllerFactory().createProcessController(this.controllerParameters,

          • new File(getWorkingDirectory()), ProcessType.LOCATOR.getPidFileName(),
          • READ_PID_FILE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
            + new File(getWorkingDirectory()), ProcessType.LOCATOR.getPidFileName());
            parsedPid = controller.getProcessId();

          // NOTE in-process request will go infinite loop unless we do the following
          — End diff –

          There are several opportunities for collapsing multiple catch blocks in this class, such as the try/catch that starts at line 1082

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132325049 — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java — @@ -1075,8 +1082,7 @@ private LocatorState stopWithWorkingDirectory() { try { final ProcessController controller = new ProcessControllerFactory().createProcessController(this.controllerParameters, new File(getWorkingDirectory()), ProcessType.LOCATOR.getPidFileName(), READ_PID_FILE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); + new File(getWorkingDirectory()), ProcessType.LOCATOR.getPidFileName()); parsedPid = controller.getProcessId(); // NOTE in-process request will go infinite loop unless we do the following — End diff – There are several opportunities for collapsing multiple catch blocks in this class, such as the try/catch that starts at line 1082
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132520010

          — Diff: geode-core/src/main/java/org/apache/geode/internal/process/StartupStatus.java —
          @@ -14,29 +14,37 @@
          */
          package org.apache.geode.internal.process;

          +import static org.apache.commons.lang.Validate.notNull;
          +
          import org.apache.logging.log4j.Logger;

          -import org.apache.geode.internal.logging.LogService;
          import org.apache.geode.i18n.StringId;
          +import org.apache.geode.internal.logging.LogService;

          /**

          • Extracted from LogWriterImpl and changed to static.
          • *
            */
              • End diff –

          Is this javadoc necessary?

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132520010 — Diff: geode-core/src/main/java/org/apache/geode/internal/process/StartupStatus.java — @@ -14,29 +14,37 @@ */ package org.apache.geode.internal.process; +import static org.apache.commons.lang.Validate.notNull; + import org.apache.logging.log4j.Logger; -import org.apache.geode.internal.logging.LogService; import org.apache.geode.i18n.StringId; +import org.apache.geode.internal.logging.LogService; /** Extracted from LogWriterImpl and changed to static. * */ End diff – Is this javadoc necessary?
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132497014

          — Diff: geode-core/src/test/java/org/apache/geode/internal/process/NonBlockingProcessStreamReaderIntegrationTest.java —
          @@ -0,0 +1,182 @@
          +/*
          + * 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.geode.internal.process;
          +
          +import static org.apache.geode.internal.process.ProcessStreamReader.ReadingMode.NON_BLOCKING;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +
          +import org.junit.Before;
          +import org.junit.Test;
          +import org.junit.experimental.categories.Category;
          +
          +import org.apache.geode.internal.process.ProcessStreamReader.Builder;
          +import org.apache.geode.test.junit.categories.IntegrationTest;
          +
          +/**
          + * Functional integration tests for NonBlockingProcessStreamReader which was introduced to fix TRAC
          + * #51967.
          + *
          + * @see BlockingProcessStreamReaderIntegrationTest
          + * @see BlockingProcessStreamReaderWindowsTest
          + *
          + * @since GemFire 8.2
          + */
          +@Category(IntegrationTest.class)
          +public class NonBlockingProcessStreamReaderIntegrationTest
          + extends BaseProcessStreamReaderIntegrationTest {
          +
          + private StringBuffer stdoutBuffer;
          + private StringBuffer stderrBuffer;
          +
          + @Before
          + public void before()

          { + stdoutBuffer = new StringBuffer(); + stderrBuffer = new StringBuffer(); + }

          +
          + /**
          + * This test hangs on Windows if the implementation is blocking instead of non-blocking.
          + */
          + @Test
          + public void canCloseStreamsWhileProcessIsAlive() throws Exception {
          + // arrange
          + process = new ProcessBuilder(createCommandLine(ProcessSleeps.class)).start();
          + stdout = new Builder(process).inputStream(process.getInputStream()).readingMode(NON_BLOCKING)
          + .build().start();
          + stderr = new Builder(process).inputStream(process.getErrorStream()).readingMode(NON_BLOCKING)
          — End diff –

          It looks like there may be an opportunity to extract a method from the common code from the beginning of each test. Yes, there are some variations on setting stdout and stderr, so maybe a couple methods to avoid duplicated code?

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132497014 — Diff: geode-core/src/test/java/org/apache/geode/internal/process/NonBlockingProcessStreamReaderIntegrationTest.java — @@ -0,0 +1,182 @@ +/* + * 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.geode.internal.process; + +import static org.apache.geode.internal.process.ProcessStreamReader.ReadingMode.NON_BLOCKING; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import org.apache.geode.internal.process.ProcessStreamReader.Builder; +import org.apache.geode.test.junit.categories.IntegrationTest; + +/** + * Functional integration tests for NonBlockingProcessStreamReader which was introduced to fix TRAC + * #51967. + * + * @see BlockingProcessStreamReaderIntegrationTest + * @see BlockingProcessStreamReaderWindowsTest + * + * @since GemFire 8.2 + */ +@Category(IntegrationTest.class) +public class NonBlockingProcessStreamReaderIntegrationTest + extends BaseProcessStreamReaderIntegrationTest { + + private StringBuffer stdoutBuffer; + private StringBuffer stderrBuffer; + + @Before + public void before() { + stdoutBuffer = new StringBuffer(); + stderrBuffer = new StringBuffer(); + } + + /** + * This test hangs on Windows if the implementation is blocking instead of non-blocking. + */ + @Test + public void canCloseStreamsWhileProcessIsAlive() throws Exception { + // arrange + process = new ProcessBuilder(createCommandLine(ProcessSleeps.class)).start(); + stdout = new Builder(process).inputStream(process.getInputStream()).readingMode(NON_BLOCKING) + .build().start(); + stderr = new Builder(process).inputStream(process.getErrorStream()).readingMode(NON_BLOCKING) — End diff – It looks like there may be an opportunity to extract a method from the common code from the beginning of each test. Yes, there are some variations on setting stdout and stderr, so maybe a couple methods to avoid duplicated code?
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132501696

          — Diff: geode-core/src/test/java/org/apache/geode/internal/process/mbean/Process.java —
          @@ -16,7 +16,6 @@

          /**

          • Extracted from LocalProcessControllerDUnitTest.
          • *
            */
              • End diff –

          This javadoc doesn't seem meaningful.

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132501696 — Diff: geode-core/src/test/java/org/apache/geode/internal/process/mbean/Process.java — @@ -16,7 +16,6 @@ /** Extracted from LocalProcessControllerDUnitTest. * */ End diff – This javadoc doesn't seem meaningful.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132515331

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/ServerLauncher.java —
          @@ -810,9 +819,6 @@ public void setStatus(final String statusMessage)

          { LocalizedStrings.Launcher_Command_START_PID_UNAVAILABLE_ERROR_MESSAGE.toLocalizedString( getServiceName(), getId(), getWorkingDirectory(), e.getMessage()), e); - }

          catch (ClusterConfigurationNotAvailableException e)

          { - failOnStart(e); - throw e; }

          catch (RuntimeException e) {
          failOnStart(e);
          — End diff –

          Opportunity to combine catch blocks?

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132515331 — Diff: geode-core/src/main/java/org/apache/geode/distributed/ServerLauncher.java — @@ -810,9 +819,6 @@ public void setStatus(final String statusMessage) { LocalizedStrings.Launcher_Command_START_PID_UNAVAILABLE_ERROR_MESSAGE.toLocalizedString( getServiceName(), getId(), getWorkingDirectory(), e.getMessage()), e); - } catch (ClusterConfigurationNotAvailableException e) { - failOnStart(e); - throw e; } catch (RuntimeException e) { failOnStart(e); — End diff – Opportunity to combine catch blocks?
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user pdxrunner commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132483129

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/LocatorLauncherLocalIntegrationTest.java —
          @@ -14,745 +14,270 @@
          */
          package org.apache.geode.distributed;

          -import org.apache.geode.distributed.AbstractLauncher.Status;
          +import static org.apache.geode.distributed.AbstractLauncher.Status.NOT_RESPONDING;
          +import static org.apache.geode.distributed.AbstractLauncher.Status.ONLINE;
          +import static org.apache.geode.distributed.AbstractLauncher.Status.STOPPED;
          +import static org.apache.geode.distributed.ConfigurationProperties.DISABLE_AUTO_RECONNECT;
          +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.distributed.ConfigurationProperties.NAME;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.assertj.core.api.Assertions.assertThatThrownBy;
          +
          +import java.io.File;
          +import java.net.BindException;
          +import java.net.InetAddress;
          +import java.util.Collections;
          +
          +import org.junit.After;
          +import org.junit.Before;
          +import org.junit.Test;
          +import org.junit.experimental.categories.Category;
          +
          import org.apache.geode.distributed.LocatorLauncher.Builder;
          import org.apache.geode.distributed.LocatorLauncher.LocatorState;
          import org.apache.geode.distributed.internal.InternalLocator;
          -import org.apache.geode.internal.*;
          -import org.apache.geode.internal.net.SocketCreatorFactory;
          +import org.apache.geode.internal.GemFireVersion;
          import org.apache.geode.internal.process.ProcessControllerFactory;
          import org.apache.geode.internal.process.ProcessType;
          -import org.apache.geode.internal.process.ProcessUtils;
          -import org.apache.geode.internal.security.SecurableCommunicationChannel;
          import org.apache.geode.test.junit.categories.IntegrationTest;
          -import org.apache.geode.test.junit.runners.CategoryWithParameterizedRunnerFactory;
          -import org.junit.After;
          -import org.junit.Before;
          -import org.junit.Ignore;
          -import org.junit.Test;
          -import org.junit.experimental.categories.Category;
          -import org.junit.runner.RunWith;
          -import org.junit.runners.Parameterized;
          -
          -import java.io.File;
          -import java.lang.management.ManagementFactory;
          -import java.net.BindException;
          -import java.net.InetAddress;
          -
          -import static org.apache.geode.distributed.ConfigurationProperties.*;
          -import static org.junit.Assert.*;

          /**

          • * Tests usage of LocatorLauncher as a local API in existing JVM.
            + * Integration tests for using {@link LocatorLauncher}

            as an in-process API within an existing JVM.
            *

          • @since GemFire 8.0
            */
            @Category(IntegrationTest.class)
            -@RunWith(Parameterized.class)
            -@Parameterized.UseParametersRunnerFactory(CategoryWithParameterizedRunnerFactory.class)
            -public class LocatorLauncherLocalIntegrationTest
          • extends AbstractLocatorLauncherIntegrationTestCase {
            +public class LocatorLauncherLocalIntegrationTest extends LocatorLauncherIntegrationTestCase {

          @Before

          • public final void setUpLocatorLauncherLocalIntegrationTest() throws Exception {
            + public void setUpLocatorLauncherLocalIntegrationTest() throws Exception { disconnectFromDS(); - System.setProperty(ProcessType.TEST_PREFIX_PROPERTY, getUniqueName() + "-"); + System.setProperty(ProcessType.PROPERTY_TEST_PREFIX, getUniqueName() + "-"); + assertThat(new ProcessControllerFactory().isAttachAPIFound()).isTrue(); }

          @After

          • public final void tearDownLocatorLauncherLocalIntegrationTest() throws Exception {
            + public void tearDownLocatorLauncherLocalIntegrationTest() throws Exception { disconnectFromDS(); }

          @Test

          • public void testBuilderSetProperties() throws Throwable {
          • this.launcher = new Builder().setForce(true).setMemberName(getUniqueName())
          • .setPort(this.locatorPort).setWorkingDirectory(this.workingDirectory)
          • .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory)
          • .set(DISABLE_AUTO_RECONNECT, "true").set(LOG_LEVEL, "config").set(MCAST_PORT, "0").build();
            -
          • try { - assertEquals(Status.ONLINE, this.launcher.start().getStatus()); - waitForLocatorToStart(this.launcher, true); - - final InternalLocator locator = this.launcher.getLocator(); - assertNotNull(locator); - - final DistributedSystem distributedSystem = locator.getDistributedSystem(); - - assertNotNull(distributedSystem); - assertEquals("true", distributedSystem.getProperties().getProperty(DISABLE_AUTO_RECONNECT)); - assertEquals("0", distributedSystem.getProperties().getProperty(MCAST_PORT)); - assertEquals("config", distributedSystem.getProperties().getProperty(LOG_LEVEL)); - assertEquals(getUniqueName(), distributedSystem.getProperties().getProperty(NAME)); - }

            catch (Throwable e)

            { - this.errorCollector.addError(e); - }
            -
            - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - assertNull(this.launcher.getLocator()); - } catch (Throwable e) { - this.errorCollector.addError(e); - }

            + public void usesLocatorPortAsDefaultPort() throws Exception

            { + launcher = givenLocatorLauncher(); + + assertThat(launcher.getPort()).isEqualTo(defaultLocatorPort); }

          @Test

          • public void testIsAttachAPIFound() throws Exception {
          • final ProcessControllerFactory factory = new ProcessControllerFactory();
          • assertTrue(factory.isAttachAPIFound());
            + public void startReturnsOnline() throws Exception { + launcher = givenLocatorLauncher(); + + assertThat(launcher.start().getStatus()).isEqualTo(ONLINE); }

          @Test

          • public void testStartCreatesPidFile() throws Throwable {
          • this.launcher = new Builder().setMemberName(getUniqueName()).setPort(this.locatorPort)
          • .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory)
          • .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config")
          • .build();
            -
          • try { - this.launcher.start(); - waitForLocatorToStart(this.launcher); - assertEquals(Status.ONLINE, this.launcher.status().getStatus()); - - // validate the pid file and its contents - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertTrue(this.pidFile.exists()); - final int pid = readPid(this.pidFile); - assertTrue(pid > 0); - assertTrue(ProcessUtils.isProcessAlive(pid)); - assertEquals(getPid(), pid); - - assertEquals(Status.ONLINE, this.launcher.status().getStatus()); - - }

            catch (Throwable e)

            { - this.errorCollector.addError(e); - }
            -
            - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - waitForFileToDelete(this.pidFile); - } catch (Throwable e) { - this.errorCollector.addError(e); - }

            + public void startWithPortUsesPort() throws Exception

            { + LocatorLauncher launcher = startLocator(newBuilder().setPort(defaultLocatorPort)); + + assertThat(launcher.getLocator().getPort()).isEqualTo(defaultLocatorPort); }

          @Test

          • public void testStartDeletesStaleControlFiles() throws Throwable {
          • // create existing control files
          • this.stopRequestFile =
          • new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getStopRequestFileName());
          • this.stopRequestFile.createNewFile();
          • assertTrue(this.stopRequestFile.exists());
            -
          • this.statusRequestFile =
          • new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getStatusRequestFileName());
          • this.statusRequestFile.createNewFile();
          • assertTrue(this.statusRequestFile.exists());
            -
          • this.statusFile =
          • new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getStatusFileName());
          • this.statusFile.createNewFile();
          • assertTrue(this.statusFile.exists());
            -
          • // build and start the locator
          • final Builder builder = new Builder().setMemberName(getUniqueName()).setPort(this.locatorPort)
          • .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory)
          • .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config");
            -
          • assertFalse(builder.getForce());
          • this.launcher = builder.build();
          • assertFalse(this.launcher.isForcing());
          • this.launcher.start();
            -
          • try { - waitForLocatorToStart(this.launcher); - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            -
            - try { - // validate the pid file and its contents - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertTrue(this.pidFile.exists()); - final int pid = readPid(this.pidFile); - assertTrue(pid > 0); - assertTrue(ProcessUtils.isProcessAlive(pid)); - assertEquals(getPid(), pid); - - // validate stale control files were deleted - assertFalse(stopRequestFile.exists()); - assertFalse(statusRequestFile.exists()); - assertFalse(statusFile.exists()); - - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            -
            - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - waitForFileToDelete(this.pidFile); - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            + public void startWithPortZeroUsesAnEphemeralPort() throws Exception { + LocatorLauncher launcher = startLocator(newBuilder().setPort(0)); + + assertThat(launcher.getLocator().getPort()).isGreaterThan(0); + assertThat(launcher.getLocator().isPeerLocator()).isTrue(); }

            @Test
            - public void testStartOverwritesStalePidFile() throws Throwable {
            - // create existing pid file
            - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName());
            - assertFalse("Integer.MAX_VALUE shouldn't be the same as local pid " + Integer.MAX_VALUE,
            - Integer.MAX_VALUE == ProcessUtils.identifyPid());
            - writePid(this.pidFile, Integer.MAX_VALUE);
            -
            - // build and start the locator
            - final Builder builder = new Builder().setMemberName(getUniqueName()).setPort(this.locatorPort)
            - .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory)
            - .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config");
            -
            - assertFalse(builder.getForce());
            - this.launcher = builder.build();
            - assertFalse(this.launcher.isForcing());
            - this.launcher.start();
            -
            - try { - waitForLocatorToStart(this.launcher); - }

            catch (Throwable e)

            { - this.errorCollector.addError(e); - }
            -
            - try { - // validate the pid file and its contents - assertTrue(this.pidFile.exists()); - final int pid = readPid(this.pidFile); - assertTrue(pid > 0); - assertTrue(ProcessUtils.isProcessAlive(pid)); - assertEquals(getPid(), pid); - } catch (Throwable e) { - this.errorCollector.addError(e); - }

            -

          • try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - waitForFileToDelete(this.pidFile); - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            + public void startUsesBuilderValues() throws Exception { + LocatorLauncher launcher = startLocator(newBuilder().setPort(nonDefaultLocatorPort)); + + InternalLocator locator = launcher.getLocator(); + assertThat(locator.getPort()).isEqualTo(nonDefaultLocatorPort); + + DistributedSystem system = locator.getDistributedSystem(); + assertThat(system.getProperties().getProperty(DISABLE_AUTO_RECONNECT)).isEqualTo("true"); + assertThat(system.getProperties().getProperty(LOG_LEVEL)).isEqualTo("config"); + assertThat(system.getProperties().getProperty(MCAST_PORT)).isEqualTo("0"); + assertThat(system.getProperties().getProperty(NAME)).isEqualTo(getUniqueName()); }

            @Test
            - @Ignore("Need to rewrite this without using dunit.Host")
            - public void testStartUsingForceOverwritesExistingPidFile() throws Throwable {}
            - /*
            - * assertTrue(getUniqueName() + " is broken if PID == Integer.MAX_VALUE",
            - * ProcessUtils.identifyPid() != Integer.MAX_VALUE);
            - *
            - * // create existing pid file this.pidFile = new File(ProcessType.LOCATOR.getPidFileName());
            - * final int realPid = Host.getHost(0).getVM(3).invoke(() -> ProcessUtils.identifyPid());
            - * assertFalse(realPid == ProcessUtils.identifyPid()); writePid(this.pidFile, realPid);
            - *
            - * // build and start the locator final Builder builder = new Builder() .setForce(true)
            - * .setMemberName(getUniqueName()) .setPort(this.locatorPort) .setRedirectOutput(true)
            - *
            - * assertTrue(builder.getForce()); this.launcher = builder.build();
            - * assertTrue(this.launcher.isForcing()); this.launcher.start();
            - *
            - * // collect and throw the FIRST failure Throwable failure = null;
            - *
            - * try { waitForLocatorToStart(this.launcher); - * - * // validate the pid file and its contents assertTrue(this.pidFile.exists()); final int pid = - * readPid(this.pidFile); assertTrue(pid > 0); assertTrue(ProcessUtils.isProcessAlive(pid)); - * assertIndexDetailsEquals(getPid(), pid); - * - * // validate log file was created final String logFileName = getUniqueName()+".log"; - * assertTrue("Log file should exist: " + logFileName, new File(logFileName).exists()); - * - * } catch (Throwable e) { logger.error(e); if (failure == null) { failure = e; } }
            - *
            - * try { assertIndexDetailsEquals(Status.STOPPED, this.launcher.stop().getStatus()); - * waitForFileToDelete(this.pidFile); } catch (Throwable e) { logger.error(e); if (failure ==
            - * null) { failure = e; } }
            - *
            - * if (failure != null) { throw failure; } } // testStartUsingForceOverwritesExistingPidFile
            - */
            + public void startCreatesPidFile() throws Exception { + startLocator(); + + assertThat(getPidFile()).exists(); + }
            +
            + @Test
            + public void pidFileContainsServerPid() throws Exception { + startLocator(); + + assertThat(getLocatorPid()).isEqualTo(localPid); + }
            +
            + @Test
            + public void startDeletesStaleControlFiles() throws Exception { + File stopRequestFile = givenControlFile(getProcessType().getStopRequestFileName()); + File statusRequestFile = givenControlFile(getProcessType().getStatusRequestFileName()); + File statusFile = givenControlFile(getProcessType().getStatusFileName()); + + startLocator(); + + assertDeletionOf(stopRequestFile); + assertDeletionOf(statusRequestFile); + assertDeletionOf(statusFile); + }

            @Test
            - public void testStartWithDefaultPortInUseFails() throws Throwable {
            - // Test makes no sense in this case
            - if (this.locatorPort == 0) { - return; - }
            -
            - this.socket =
            - SocketCreatorFactory.getSocketCreatorForComponent(SecurableCommunicationChannel.CLUSTER)
            - .createServerSocket(this.locatorPort, 50, null, -1);
            - assertTrue(this.socket.isBound());
            - assertFalse(this.socket.isClosed());
            - assertFalse(AvailablePort.isPortAvailable(this.locatorPort, AvailablePort.SOCKET));
            -
            - assertNotNull(System.getProperty(DistributionLocator.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY));
            - assertEquals(this.locatorPort,
            - Integer.valueOf(System.getProperty(DistributionLocator.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY))
            - .intValue());
            - assertFalse(AvailablePort.isPortAvailable(this.locatorPort, AvailablePort.SOCKET));
            -
            - this.launcher = new Builder().setMemberName(getUniqueName()).setRedirectOutput(true)
            - .setWorkingDirectory(this.workingDirectory)
            - .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config")
            - .build();
            -
            - assertEquals(this.locatorPort, this.launcher.getPort().intValue());
            -
            - RuntimeException expected = null;
            - try { - this.launcher.start(); - - // why did it not fail like it's supposed to? - final String property = - System.getProperty(DistributionLocator.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY); - assertNotNull(property); - assertEquals(this.locatorPort, Integer.valueOf(property).intValue()); - assertFalse(AvailablePort.isPortAvailable(this.locatorPort, AvailablePort.SOCKET)); - assertEquals(this.locatorPort, this.launcher.getPort().intValue()); - assertEquals(this.locatorPort, this.socket.getLocalPort()); - assertTrue(this.socket.isBound()); - assertFalse(this.socket.isClosed()); - - fail("LocatorLauncher start should have thrown RuntimeException caused by BindException"); - } catch (RuntimeException e) { - expected = e; - assertNotNull(expected.getMessage()); - // BindException text varies by platform - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            -
            - try { - assertNotNull(expected); - final Throwable cause = expected.getCause(); - assertNotNull(cause); - assertTrue(cause instanceof BindException); - // BindException string varies by platform - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            -
            - try { - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertFalse("Pid file should not exist: " + this.pidFile, this.pidFile.exists()); - - // creation of log file seems to be random -- look into why sometime - final String logFileName = getUniqueName() + ".log"; - assertFalse("Log file should not exist: " + logFileName, - new File(this.temporaryFolder.getRoot(), logFileName).exists()); - - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            -
            - // just in case the launcher started...
            - LocatorState status = null;
            - try { - status = this.launcher.stop(); - } catch (Throwable t) { - // ignore - }
            -
            - try { - waitForFileToDelete(this.pidFile); - assertEquals(getExpectedStopStatusForNotRunning(), status.getStatus()); - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            + public void startOverwritesStalePidFile() throws Exception { + givenPidFile(fakePid); + + startLocator(); + + assertThat(getLocatorPid()).isNotEqualTo(fakePid); }

            @Test
            - @Ignore("Need to rewrite this without using dunit.Host")
            - public void testStartWithExistingPidFileFails()
            - throws Throwable {}/*
            - * // create existing pid file final int realPid =
            - * Host.getHost(0).getVM(3).invoke(() -> ProcessUtils.identifyPid());
            - * assertFalse("Remote pid shouldn't be the same as local pid " + realPid,
            - * realPid == ProcessUtils.identifyPid());
            - *
            - * this.pidFile = new File(ProcessType.LOCATOR.getPidFileName());
            - * writePid(this.pidFile, realPid);
            - *
            - * // build and start the locator final Builder builder = new Builder()
            - * .setMemberName(getUniqueName()) .setPort(this.locatorPort)
            - * .setRedirectOutput(true) .set(logLevel, "config");
            - *
            - * assertFalse(builder.getForce()); this.launcher = builder.build();
            - * assertFalse(this.launcher.isForcing());
            - *
            - * // collect and throw the FIRST failure Throwable failure = null;
            - * RuntimeException expected = null;
            - *
            - * try { this.launcher.start(); - * fail("LocatorLauncher start should have thrown RuntimeException caused by FileAlreadyExistsException" - * ); } catch (RuntimeException e) { expected = e; - * assertNotNull(expected.getMessage()); assertTrue(expected.getMessage(), - * expected.getMessage(). - * contains("A PID file already exists and a Locator may be running in")); - * assertIndexDetailsEquals(RuntimeException.class, expected.getClass()); }
            - * catch (Throwable e) { logger.error(e); if (failure == null) { failure = - * e; } }
            - *
            - * // just in case the launcher started... LocatorState status = null; try
            - * { status = this.launcher.stop(); } catch (Throwable t) { // ignore }
            - *
            - * try { assertNotNull(expected); final Throwable cause = - * expected.getCause(); assertNotNull(cause); assertTrue(cause instanceof - * FileAlreadyExistsException); - * assertTrue(cause.getMessage().contains("Pid file already exists: ")); - * assertTrue(cause.getMessage().contains("vf.gf.locator.pid for process " - * + realPid)); } catch (Throwable e) { logger.error(e); if (failure ==
            - * null) { failure = e; } }
            - *
            - * try { delete(this.pidFile); final Status theStatus = status.getStatus(); - * assertFalse(theStatus == Status.STARTING); assertFalse(theStatus == - * Status.ONLINE); } catch (Throwable e) { logger.error(e); if (failure ==
            - * null) { failure = e; } }
            - *
            - * if (failure != null) { throw failure; } } //
            - * testStartWithExistingPidFileFails
            - */
            + public void startWithDefaultPortInUseFailsWithBindException() throws Exception { + givenLocatorPortInUse(defaultLocatorPort); + + launcher = new Builder().build(); + + assertThatThrownBy(() -> launcher.start()).isInstanceOf(RuntimeException.class) + .hasCauseInstanceOf(BindException.class); + }

            @Test
            - public void testStartUsingPort() throws Throwable {
            - // generate one free port and then use it instead of default
            - final int freeTCPPort = AvailablePortHelper.getRandomAvailableTCPPort();
            - assertTrue(AvailablePort.isPortAvailable(freeTCPPort, AvailablePort.SOCKET));
            -
            - this.launcher = new Builder().setMemberName(getUniqueName()).setPort(freeTCPPort)
            - .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory)
            - .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config")
            - .build();
            -
            - int pid = 0;
            - try { - // if start succeeds without throwing exception then #47778 is fixed - this.launcher.start(); - waitForLocatorToStart(this.launcher); - - // validate the pid file and its contents - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertTrue(pidFile.exists()); - pid = readPid(pidFile); - assertTrue(pid > 0); - assertTrue(ProcessUtils.isProcessAlive(pid)); - assertEquals(getPid(), pid); - - // verify locator did not use default port - assertTrue(AvailablePort.isPortAvailable(this.locatorPort, AvailablePort.SOCKET)); - - final LocatorState status = this.launcher.status(); - final String portString = status.getPort(); - assertEquals("Port should be \"" + freeTCPPort + "\" instead of " + portString, - String.valueOf(freeTCPPort), portString); - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            -
            - // stop the locator
            - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - waitForFileToDelete(this.pidFile); - }

            catch (Throwable e)

            { - this.errorCollector.addError(e); - }
            + public void startWithLocatorPortInUseFailsWithBindException() throws Exception { + givenServerPortInUse(nonDefaultLocatorPort); + + launcher = new Builder().setPort(nonDefaultLocatorPort).build(); + + assertThatThrownBy(() -> this.launcher.start()).isInstanceOf(RuntimeException.class) + .hasCauseInstanceOf(BindException.class); }

            @Test
            - public void testStartUsingPortInUseFails() throws Throwable {
            - // Test makes no sense in this case
            - if (this.locatorPort == 0) { - return; - }
            -
            - // generate one free port and then use it instead of default
            - this.socket =
            - SocketCreatorFactory.getSocketCreatorForComponent(SecurableCommunicationChannel.CLUSTER)
            - .createServerSocket(this.locatorPort, 50, null, -1);
            -
            - this.launcher = new Builder().setMemberName(getUniqueName()).setPort(this.locatorPort)
            - .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory)
            - .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config")
            - .build();
            -
            - RuntimeException expected = null;
            - try { - this.launcher.start(); - fail("LocatorLauncher start should have thrown RuntimeException caused by BindException"); - } catch (RuntimeException e) { - expected = e; - assertNotNull(expected.getMessage()); - // BindException string varies by platform - } catch (Throwable e) { - this.errorCollector.addError(e); - }

            -

          • try { - assertNotNull(expected); - final Throwable cause = expected.getCause(); - assertNotNull(cause); - assertTrue(cause instanceof BindException); - // BindException string varies by platform - }

            catch (Throwable e)

            { - this.errorCollector.addError(e); - }
            -
            - try { - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertFalse("Pid file should not exist: " + this.pidFile, this.pidFile.exists()); - - // creation of log file seems to be random -- look into why sometime - final String logFileName = getUniqueName() + ".log"; - assertFalse("Log file should not exist: " + logFileName, - new File(this.temporaryFolder.getRoot(), logFileName).exists()); - - } catch (Throwable e) { - this.errorCollector.addError(e); - }

            -

          • // just in case the launcher started...
          • LocatorState status = null;
          • try { - status = this.launcher.stop(); - }

            catch (Throwable t)

            { - // ignore - }

            -

          • try { - waitForFileToDelete(this.pidFile); - assertEquals(getExpectedStopStatusForNotRunning(), status.getStatus()); - }

            catch (Throwable e)

            { - this.errorCollector.addError(e); - }

            + public void statusWithPidReturnsOnlineWithDetails() throws Exception {
            + givenRunningLocator();
            +
            + LocatorState locatorState = new Builder().setPid(localPid).build().status();
            +
            + assertThat(locatorState.getStatus()).isEqualTo(ONLINE);
            + assertThat(locatorState.getClasspath()).isEqualTo(getClassPath());
            + assertThat(locatorState.getGemFireVersion()).isEqualTo(GemFireVersion.getGemFireVersion());
            + assertThat(locatorState.getHost()).isEqualTo(InetAddress.getLocalHost().getCanonicalHostName());

              • End diff –

          This assertion may fail in IDE's test environment. It would be great to have something that works reliably for host name/IP in all build & test environments: IDEs, Concourse, & Jenkins.

          OK, maybe it's just my local machine configuration. If I have an alias for `localhost` in my `/etc/hosts` file, then this comparison fails. With no alias, then it works as expected. (MacOS)

          Show
          githubbot ASF GitHub Bot added a comment - Github user pdxrunner commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132483129 — Diff: geode-core/src/test/java/org/apache/geode/distributed/LocatorLauncherLocalIntegrationTest.java — @@ -14,745 +14,270 @@ */ package org.apache.geode.distributed; -import org.apache.geode.distributed.AbstractLauncher.Status; +import static org.apache.geode.distributed.AbstractLauncher.Status.NOT_RESPONDING; +import static org.apache.geode.distributed.AbstractLauncher.Status.ONLINE; +import static org.apache.geode.distributed.AbstractLauncher.Status.STOPPED; +import static org.apache.geode.distributed.ConfigurationProperties.DISABLE_AUTO_RECONNECT; +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.distributed.ConfigurationProperties.NAME; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.io.File; +import java.net.BindException; +import java.net.InetAddress; +import java.util.Collections; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + import org.apache.geode.distributed.LocatorLauncher.Builder; import org.apache.geode.distributed.LocatorLauncher.LocatorState; import org.apache.geode.distributed.internal.InternalLocator; -import org.apache.geode.internal.*; -import org.apache.geode.internal.net.SocketCreatorFactory; +import org.apache.geode.internal.GemFireVersion; import org.apache.geode.internal.process.ProcessControllerFactory; import org.apache.geode.internal.process.ProcessType; -import org.apache.geode.internal.process.ProcessUtils; -import org.apache.geode.internal.security.SecurableCommunicationChannel; import org.apache.geode.test.junit.categories.IntegrationTest; -import org.apache.geode.test.junit.runners.CategoryWithParameterizedRunnerFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.io.File; -import java.lang.management.ManagementFactory; -import java.net.BindException; -import java.net.InetAddress; - -import static org.apache.geode.distributed.ConfigurationProperties.*; -import static org.junit.Assert.*; /** * Tests usage of LocatorLauncher as a local API in existing JVM. + * Integration tests for using {@link LocatorLauncher} as an in-process API within an existing JVM. * @since GemFire 8.0 */ @Category(IntegrationTest.class) -@RunWith(Parameterized.class) -@Parameterized.UseParametersRunnerFactory(CategoryWithParameterizedRunnerFactory.class) -public class LocatorLauncherLocalIntegrationTest extends AbstractLocatorLauncherIntegrationTestCase { +public class LocatorLauncherLocalIntegrationTest extends LocatorLauncherIntegrationTestCase { @Before public final void setUpLocatorLauncherLocalIntegrationTest() throws Exception { + public void setUpLocatorLauncherLocalIntegrationTest() throws Exception { disconnectFromDS(); - System.setProperty(ProcessType.TEST_PREFIX_PROPERTY, getUniqueName() + "-"); + System.setProperty(ProcessType.PROPERTY_TEST_PREFIX, getUniqueName() + "-"); + assertThat(new ProcessControllerFactory().isAttachAPIFound()).isTrue(); } @After public final void tearDownLocatorLauncherLocalIntegrationTest() throws Exception { + public void tearDownLocatorLauncherLocalIntegrationTest() throws Exception { disconnectFromDS(); } @Test public void testBuilderSetProperties() throws Throwable { this.launcher = new Builder().setForce(true).setMemberName(getUniqueName()) .setPort(this.locatorPort).setWorkingDirectory(this.workingDirectory) .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory) .set(DISABLE_AUTO_RECONNECT, "true").set(LOG_LEVEL, "config").set(MCAST_PORT, "0").build(); - try { - assertEquals(Status.ONLINE, this.launcher.start().getStatus()); - waitForLocatorToStart(this.launcher, true); - - final InternalLocator locator = this.launcher.getLocator(); - assertNotNull(locator); - - final DistributedSystem distributedSystem = locator.getDistributedSystem(); - - assertNotNull(distributedSystem); - assertEquals("true", distributedSystem.getProperties().getProperty(DISABLE_AUTO_RECONNECT)); - assertEquals("0", distributedSystem.getProperties().getProperty(MCAST_PORT)); - assertEquals("config", distributedSystem.getProperties().getProperty(LOG_LEVEL)); - assertEquals(getUniqueName(), distributedSystem.getProperties().getProperty(NAME)); - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - assertNull(this.launcher.getLocator()); - } catch (Throwable e) { - this.errorCollector.addError(e); - } + public void usesLocatorPortAsDefaultPort() throws Exception { + launcher = givenLocatorLauncher(); + + assertThat(launcher.getPort()).isEqualTo(defaultLocatorPort); } @Test public void testIsAttachAPIFound() throws Exception { final ProcessControllerFactory factory = new ProcessControllerFactory(); assertTrue(factory.isAttachAPIFound()); + public void startReturnsOnline() throws Exception { + launcher = givenLocatorLauncher(); + + assertThat(launcher.start().getStatus()).isEqualTo(ONLINE); } @Test public void testStartCreatesPidFile() throws Throwable { this.launcher = new Builder().setMemberName(getUniqueName()).setPort(this.locatorPort) .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory) .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config") .build(); - try { - this.launcher.start(); - waitForLocatorToStart(this.launcher); - assertEquals(Status.ONLINE, this.launcher.status().getStatus()); - - // validate the pid file and its contents - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertTrue(this.pidFile.exists()); - final int pid = readPid(this.pidFile); - assertTrue(pid > 0); - assertTrue(ProcessUtils.isProcessAlive(pid)); - assertEquals(getPid(), pid); - - assertEquals(Status.ONLINE, this.launcher.status().getStatus()); - - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - waitForFileToDelete(this.pidFile); - } catch (Throwable e) { - this.errorCollector.addError(e); - } + public void startWithPortUsesPort() throws Exception { + LocatorLauncher launcher = startLocator(newBuilder().setPort(defaultLocatorPort)); + + assertThat(launcher.getLocator().getPort()).isEqualTo(defaultLocatorPort); } @Test public void testStartDeletesStaleControlFiles() throws Throwable { // create existing control files this.stopRequestFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getStopRequestFileName()); this.stopRequestFile.createNewFile(); assertTrue(this.stopRequestFile.exists()); - this.statusRequestFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getStatusRequestFileName()); this.statusRequestFile.createNewFile(); assertTrue(this.statusRequestFile.exists()); - this.statusFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getStatusFileName()); this.statusFile.createNewFile(); assertTrue(this.statusFile.exists()); - // build and start the locator final Builder builder = new Builder().setMemberName(getUniqueName()).setPort(this.locatorPort) .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory) .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config"); - assertFalse(builder.getForce()); this.launcher = builder.build(); assertFalse(this.launcher.isForcing()); this.launcher.start(); - try { - waitForLocatorToStart(this.launcher); - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - try { - // validate the pid file and its contents - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertTrue(this.pidFile.exists()); - final int pid = readPid(this.pidFile); - assertTrue(pid > 0); - assertTrue(ProcessUtils.isProcessAlive(pid)); - assertEquals(getPid(), pid); - - // validate stale control files were deleted - assertFalse(stopRequestFile.exists()); - assertFalse(statusRequestFile.exists()); - assertFalse(statusFile.exists()); - - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - waitForFileToDelete(this.pidFile); - } catch (Throwable e) { - this.errorCollector.addError(e); - } + public void startWithPortZeroUsesAnEphemeralPort() throws Exception { + LocatorLauncher launcher = startLocator(newBuilder().setPort(0)); + + assertThat(launcher.getLocator().getPort()).isGreaterThan(0); + assertThat(launcher.getLocator().isPeerLocator()).isTrue(); } @Test - public void testStartOverwritesStalePidFile() throws Throwable { - // create existing pid file - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertFalse("Integer.MAX_VALUE shouldn't be the same as local pid " + Integer.MAX_VALUE, - Integer.MAX_VALUE == ProcessUtils.identifyPid()); - writePid(this.pidFile, Integer.MAX_VALUE); - - // build and start the locator - final Builder builder = new Builder().setMemberName(getUniqueName()).setPort(this.locatorPort) - .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory) - .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config"); - - assertFalse(builder.getForce()); - this.launcher = builder.build(); - assertFalse(this.launcher.isForcing()); - this.launcher.start(); - - try { - waitForLocatorToStart(this.launcher); - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - try { - // validate the pid file and its contents - assertTrue(this.pidFile.exists()); - final int pid = readPid(this.pidFile); - assertTrue(pid > 0); - assertTrue(ProcessUtils.isProcessAlive(pid)); - assertEquals(getPid(), pid); - } catch (Throwable e) { - this.errorCollector.addError(e); - } - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - waitForFileToDelete(this.pidFile); - } catch (Throwable e) { - this.errorCollector.addError(e); - } + public void startUsesBuilderValues() throws Exception { + LocatorLauncher launcher = startLocator(newBuilder().setPort(nonDefaultLocatorPort)); + + InternalLocator locator = launcher.getLocator(); + assertThat(locator.getPort()).isEqualTo(nonDefaultLocatorPort); + + DistributedSystem system = locator.getDistributedSystem(); + assertThat(system.getProperties().getProperty(DISABLE_AUTO_RECONNECT)).isEqualTo("true"); + assertThat(system.getProperties().getProperty(LOG_LEVEL)).isEqualTo("config"); + assertThat(system.getProperties().getProperty(MCAST_PORT)).isEqualTo("0"); + assertThat(system.getProperties().getProperty(NAME)).isEqualTo(getUniqueName()); } @Test - @Ignore("Need to rewrite this without using dunit.Host") - public void testStartUsingForceOverwritesExistingPidFile() throws Throwable {} - /* - * assertTrue(getUniqueName() + " is broken if PID == Integer.MAX_VALUE", - * ProcessUtils.identifyPid() != Integer.MAX_VALUE); - * - * // create existing pid file this.pidFile = new File(ProcessType.LOCATOR.getPidFileName()); - * final int realPid = Host.getHost(0).getVM(3).invoke(() -> ProcessUtils.identifyPid()); - * assertFalse(realPid == ProcessUtils.identifyPid()); writePid(this.pidFile, realPid); - * - * // build and start the locator final Builder builder = new Builder() .setForce(true) - * .setMemberName(getUniqueName()) .setPort(this.locatorPort) .setRedirectOutput(true) - * - * assertTrue(builder.getForce()); this.launcher = builder.build(); - * assertTrue(this.launcher.isForcing()); this.launcher.start(); - * - * // collect and throw the FIRST failure Throwable failure = null; - * - * try { waitForLocatorToStart(this.launcher); - * - * // validate the pid file and its contents assertTrue(this.pidFile.exists()); final int pid = - * readPid(this.pidFile); assertTrue(pid > 0); assertTrue(ProcessUtils.isProcessAlive(pid)); - * assertIndexDetailsEquals(getPid(), pid); - * - * // validate log file was created final String logFileName = getUniqueName()+".log"; - * assertTrue("Log file should exist: " + logFileName, new File(logFileName).exists()); - * - * } catch (Throwable e) { logger.error(e); if (failure == null) { failure = e; } } - * - * try { assertIndexDetailsEquals(Status.STOPPED, this.launcher.stop().getStatus()); - * waitForFileToDelete(this.pidFile); } catch (Throwable e) { logger.error(e); if (failure == - * null) { failure = e; } } - * - * if (failure != null) { throw failure; } } // testStartUsingForceOverwritesExistingPidFile - */ + public void startCreatesPidFile() throws Exception { + startLocator(); + + assertThat(getPidFile()).exists(); + } + + @Test + public void pidFileContainsServerPid() throws Exception { + startLocator(); + + assertThat(getLocatorPid()).isEqualTo(localPid); + } + + @Test + public void startDeletesStaleControlFiles() throws Exception { + File stopRequestFile = givenControlFile(getProcessType().getStopRequestFileName()); + File statusRequestFile = givenControlFile(getProcessType().getStatusRequestFileName()); + File statusFile = givenControlFile(getProcessType().getStatusFileName()); + + startLocator(); + + assertDeletionOf(stopRequestFile); + assertDeletionOf(statusRequestFile); + assertDeletionOf(statusFile); + } @Test - public void testStartWithDefaultPortInUseFails() throws Throwable { - // Test makes no sense in this case - if (this.locatorPort == 0) { - return; - } - - this.socket = - SocketCreatorFactory.getSocketCreatorForComponent(SecurableCommunicationChannel.CLUSTER) - .createServerSocket(this.locatorPort, 50, null, -1); - assertTrue(this.socket.isBound()); - assertFalse(this.socket.isClosed()); - assertFalse(AvailablePort.isPortAvailable(this.locatorPort, AvailablePort.SOCKET)); - - assertNotNull(System.getProperty(DistributionLocator.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY)); - assertEquals(this.locatorPort, - Integer.valueOf(System.getProperty(DistributionLocator.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY)) - .intValue()); - assertFalse(AvailablePort.isPortAvailable(this.locatorPort, AvailablePort.SOCKET)); - - this.launcher = new Builder().setMemberName(getUniqueName()).setRedirectOutput(true) - .setWorkingDirectory(this.workingDirectory) - .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config") - .build(); - - assertEquals(this.locatorPort, this.launcher.getPort().intValue()); - - RuntimeException expected = null; - try { - this.launcher.start(); - - // why did it not fail like it's supposed to? - final String property = - System.getProperty(DistributionLocator.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY); - assertNotNull(property); - assertEquals(this.locatorPort, Integer.valueOf(property).intValue()); - assertFalse(AvailablePort.isPortAvailable(this.locatorPort, AvailablePort.SOCKET)); - assertEquals(this.locatorPort, this.launcher.getPort().intValue()); - assertEquals(this.locatorPort, this.socket.getLocalPort()); - assertTrue(this.socket.isBound()); - assertFalse(this.socket.isClosed()); - - fail("LocatorLauncher start should have thrown RuntimeException caused by BindException"); - } catch (RuntimeException e) { - expected = e; - assertNotNull(expected.getMessage()); - // BindException text varies by platform - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - try { - assertNotNull(expected); - final Throwable cause = expected.getCause(); - assertNotNull(cause); - assertTrue(cause instanceof BindException); - // BindException string varies by platform - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - try { - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertFalse("Pid file should not exist: " + this.pidFile, this.pidFile.exists()); - - // creation of log file seems to be random -- look into why sometime - final String logFileName = getUniqueName() + ".log"; - assertFalse("Log file should not exist: " + logFileName, - new File(this.temporaryFolder.getRoot(), logFileName).exists()); - - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - // just in case the launcher started... - LocatorState status = null; - try { - status = this.launcher.stop(); - } catch (Throwable t) { - // ignore - } - - try { - waitForFileToDelete(this.pidFile); - assertEquals(getExpectedStopStatusForNotRunning(), status.getStatus()); - } catch (Throwable e) { - this.errorCollector.addError(e); - } + public void startOverwritesStalePidFile() throws Exception { + givenPidFile(fakePid); + + startLocator(); + + assertThat(getLocatorPid()).isNotEqualTo(fakePid); } @Test - @Ignore("Need to rewrite this without using dunit.Host") - public void testStartWithExistingPidFileFails() - throws Throwable {}/* - * // create existing pid file final int realPid = - * Host.getHost(0).getVM(3).invoke(() -> ProcessUtils.identifyPid()); - * assertFalse("Remote pid shouldn't be the same as local pid " + realPid, - * realPid == ProcessUtils.identifyPid()); - * - * this.pidFile = new File(ProcessType.LOCATOR.getPidFileName()); - * writePid(this.pidFile, realPid); - * - * // build and start the locator final Builder builder = new Builder() - * .setMemberName(getUniqueName()) .setPort(this.locatorPort) - * .setRedirectOutput(true) .set(logLevel, "config"); - * - * assertFalse(builder.getForce()); this.launcher = builder.build(); - * assertFalse(this.launcher.isForcing()); - * - * // collect and throw the FIRST failure Throwable failure = null; - * RuntimeException expected = null; - * - * try { this.launcher.start(); - * fail("LocatorLauncher start should have thrown RuntimeException caused by FileAlreadyExistsException" - * ); } catch (RuntimeException e) { expected = e; - * assertNotNull(expected.getMessage()); assertTrue(expected.getMessage(), - * expected.getMessage(). - * contains("A PID file already exists and a Locator may be running in")); - * assertIndexDetailsEquals(RuntimeException.class, expected.getClass()); } - * catch (Throwable e) { logger.error(e); if (failure == null) { failure = - * e; } } - * - * // just in case the launcher started... LocatorState status = null; try - * { status = this.launcher.stop(); } catch (Throwable t) { // ignore } - * - * try { assertNotNull(expected); final Throwable cause = - * expected.getCause(); assertNotNull(cause); assertTrue(cause instanceof - * FileAlreadyExistsException); - * assertTrue(cause.getMessage().contains("Pid file already exists: ")); - * assertTrue(cause.getMessage().contains("vf.gf.locator.pid for process " - * + realPid)); } catch (Throwable e) { logger.error(e); if (failure == - * null) { failure = e; } } - * - * try { delete(this.pidFile); final Status theStatus = status.getStatus(); - * assertFalse(theStatus == Status.STARTING); assertFalse(theStatus == - * Status.ONLINE); } catch (Throwable e) { logger.error(e); if (failure == - * null) { failure = e; } } - * - * if (failure != null) { throw failure; } } // - * testStartWithExistingPidFileFails - */ + public void startWithDefaultPortInUseFailsWithBindException() throws Exception { + givenLocatorPortInUse(defaultLocatorPort); + + launcher = new Builder().build(); + + assertThatThrownBy(() -> launcher.start()).isInstanceOf(RuntimeException.class) + .hasCauseInstanceOf(BindException.class); + } @Test - public void testStartUsingPort() throws Throwable { - // generate one free port and then use it instead of default - final int freeTCPPort = AvailablePortHelper.getRandomAvailableTCPPort(); - assertTrue(AvailablePort.isPortAvailable(freeTCPPort, AvailablePort.SOCKET)); - - this.launcher = new Builder().setMemberName(getUniqueName()).setPort(freeTCPPort) - .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory) - .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config") - .build(); - - int pid = 0; - try { - // if start succeeds without throwing exception then #47778 is fixed - this.launcher.start(); - waitForLocatorToStart(this.launcher); - - // validate the pid file and its contents - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertTrue(pidFile.exists()); - pid = readPid(pidFile); - assertTrue(pid > 0); - assertTrue(ProcessUtils.isProcessAlive(pid)); - assertEquals(getPid(), pid); - - // verify locator did not use default port - assertTrue(AvailablePort.isPortAvailable(this.locatorPort, AvailablePort.SOCKET)); - - final LocatorState status = this.launcher.status(); - final String portString = status.getPort(); - assertEquals("Port should be \"" + freeTCPPort + "\" instead of " + portString, - String.valueOf(freeTCPPort), portString); - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - // stop the locator - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - waitForFileToDelete(this.pidFile); - } catch (Throwable e) { - this.errorCollector.addError(e); - } + public void startWithLocatorPortInUseFailsWithBindException() throws Exception { + givenServerPortInUse(nonDefaultLocatorPort); + + launcher = new Builder().setPort(nonDefaultLocatorPort).build(); + + assertThatThrownBy(() -> this.launcher.start()).isInstanceOf(RuntimeException.class) + .hasCauseInstanceOf(BindException.class); } @Test - public void testStartUsingPortInUseFails() throws Throwable { - // Test makes no sense in this case - if (this.locatorPort == 0) { - return; - } - - // generate one free port and then use it instead of default - this.socket = - SocketCreatorFactory.getSocketCreatorForComponent(SecurableCommunicationChannel.CLUSTER) - .createServerSocket(this.locatorPort, 50, null, -1); - - this.launcher = new Builder().setMemberName(getUniqueName()).setPort(this.locatorPort) - .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory) - .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config") - .build(); - - RuntimeException expected = null; - try { - this.launcher.start(); - fail("LocatorLauncher start should have thrown RuntimeException caused by BindException"); - } catch (RuntimeException e) { - expected = e; - assertNotNull(expected.getMessage()); - // BindException string varies by platform - } catch (Throwable e) { - this.errorCollector.addError(e); - } - try { - assertNotNull(expected); - final Throwable cause = expected.getCause(); - assertNotNull(cause); - assertTrue(cause instanceof BindException); - // BindException string varies by platform - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - try { - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertFalse("Pid file should not exist: " + this.pidFile, this.pidFile.exists()); - - // creation of log file seems to be random -- look into why sometime - final String logFileName = getUniqueName() + ".log"; - assertFalse("Log file should not exist: " + logFileName, - new File(this.temporaryFolder.getRoot(), logFileName).exists()); - - } catch (Throwable e) { - this.errorCollector.addError(e); - } - // just in case the launcher started... LocatorState status = null; try { - status = this.launcher.stop(); - } catch (Throwable t) { - // ignore - } - try { - waitForFileToDelete(this.pidFile); - assertEquals(getExpectedStopStatusForNotRunning(), status.getStatus()); - } catch (Throwable e) { - this.errorCollector.addError(e); - } + public void statusWithPidReturnsOnlineWithDetails() throws Exception { + givenRunningLocator(); + + LocatorState locatorState = new Builder().setPid(localPid).build().status(); + + assertThat(locatorState.getStatus()).isEqualTo(ONLINE); + assertThat(locatorState.getClasspath()).isEqualTo(getClassPath()); + assertThat(locatorState.getGemFireVersion()).isEqualTo(GemFireVersion.getGemFireVersion()); + assertThat(locatorState.getHost()).isEqualTo(InetAddress.getLocalHost().getCanonicalHostName()); End diff – This assertion may fail in IDE's test environment. It would be great to have something that works reliably for host name/IP in all build & test environments: IDEs, Concourse, & Jenkins. OK, maybe it's just my local machine configuration. If I have an alias for `localhost` in my `/etc/hosts` file, then this comparison fails. With no alias, then it works as expected. (MacOS)
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132532612

          — Diff: geode-core/src/main/java/org/apache/geode/config/internal/ClusterConfigurationNotAvailableException.java —
          @@ -0,0 +1,29 @@
          +/*
          + * 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.geode.config.internal;
          — End diff –

          Changed.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132532612 — Diff: geode-core/src/main/java/org/apache/geode/config/internal/ClusterConfigurationNotAvailableException.java — @@ -0,0 +1,29 @@ +/* + * 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.geode.config.internal; — End diff – Changed.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132532641

          — Diff: geode-core/src/test/java/org/apache/geode/internal/process/FileProcessControllerIntegrationTest.java —
          @@ -0,0 +1,243 @@
          +/*
          + * 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.geode.internal.process;
          +
          +import static com.googlecode.catchexception.CatchException.caughtException;
          +import static com.googlecode.catchexception.CatchException.verifyException;
          +import static java.util.concurrent.TimeUnit.MILLISECONDS;
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.assertj.core.api.Assertions.assertThatThrownBy;
          +import static org.mockito.Mockito.mock;
          +import static org.mockito.Mockito.when;
          +
          +import java.io.File;
          +import java.util.concurrent.ExecutorService;
          +import java.util.concurrent.Executors;
          +import java.util.concurrent.TimeoutException;
          +import java.util.concurrent.atomic.AtomicReference;
          +
          +import org.awaitility.Awaitility;
          +import org.awaitility.core.ConditionFactory;
          +import org.junit.After;
          +import org.junit.Before;
          +import org.junit.Ignore;
          +import org.junit.Rule;
          +import org.junit.Test;
          +import org.junit.experimental.categories.Category;
          +import org.junit.rules.ErrorCollector;
          +import org.junit.rules.TemporaryFolder;
          +import org.junit.rules.TestName;
          +
          +import org.apache.geode.distributed.AbstractLauncher.Status;
          +import org.apache.geode.distributed.LocatorLauncher;
          +import org.apache.geode.distributed.LocatorLauncher.Builder;
          +import org.apache.geode.distributed.LocatorLauncher.LocatorState;
          +import org.apache.geode.internal.process.io.EmptyFileWriter;
          +import org.apache.geode.internal.process.io.IntegerFileWriter;
          +import org.apache.geode.internal.process.io.StringFileWriter;
          +import org.apache.geode.test.junit.categories.IntegrationTest;
          +
          +/**
          + * Integration tests for

          {@link FileProcessController}

          .
          + */
          +@Category(IntegrationTest.class)
          +public class FileProcessControllerIntegrationTest {
          +
          + private static final String STATUS_JSON = generateStatusJson();
          +
          + private final AtomicReference<String> statusRef = new AtomicReference<>();
          +
          + private File pidFile;
          + private File statusFile;
          + private File statusRequestFile;
          + private File stopRequestFile;
          + private int pid;
          + private FileControllerParameters params;
          + private ExecutorService executor;
          +
          + @Rule
          + public ErrorCollector errorCollector = new ErrorCollector();
          +
          + @Rule
          + public TemporaryFolder temporaryFolder = new TemporaryFolder();
          +
          + @Rule
          + public TestName testName = new TestName();
          +
          + @Before
          + public void setUp() throws Exception

          { + ProcessType processType = ProcessType.LOCATOR; + File directory = temporaryFolder.getRoot(); + pidFile = new File(directory, processType.getPidFileName()); + statusFile = new File(directory, processType.getStatusFileName()); + statusRequestFile = new File(directory, processType.getStatusRequestFileName()); + stopRequestFile = new File(directory, processType.getStopRequestFileName()); + pid = ProcessUtils.identifyPid(); + + params = mock(FileControllerParameters.class); + when(params.getPidFile()).thenReturn(pidFile); + when(params.getProcessId()).thenReturn(pid); + when(params.getProcessType()).thenReturn(processType); + when(params.getDirectory()).thenReturn(temporaryFolder.getRoot()); + + executor = Executors.newSingleThreadExecutor(); + }

          +
          + @After
          + public void tearDown() throws Exception

          { + assertThat(executor.shutdownNow()).isEmpty(); + }

          +
          + @Test
          + public void statusShouldAwaitTimeoutWhileFileIsEmpty() throws Exception

          { + // given: FileProcessController with empty pidFile + FileProcessController controller = new FileProcessController(params, pid, 10, MILLISECONDS); + + // when: + verifyException(controller).status(); + + // then: we expect TimeoutException to be thrown + assertThat((Exception) caughtException()).isInstanceOf(TimeoutException.class) + .hasMessageContaining("Timed out waiting for process to create").hasNoCause(); + }

          +
          + @Test
          + public void statusShouldReturnJsonFromStatusFile() throws Exception {
          + // given: FileProcessController with pidFile containing real pid
          + new IntegerFileWriter(pidFile).writeToFile(pid);
          + FileProcessController controller = new FileProcessController(params, pid, 2, MINUTES);
          +
          + // when: status is called in one thread
          + executor.execute(() -> {
          + try

          { + statusRef.set(controller.status()); + }

          catch (Exception e)

          { + errorCollector.addError(e); + }

          + });
          +
          + // and: json is written to the status file
          + new StringFileWriter(statusFile).writeToFile(STATUS_JSON);
          +
          + // then: returned status should be the json in the file
          + await().until(() -> assertThat(statusRef.get()).isEqualTo(STATUS_JSON));
          + }
          +
          + @Ignore // GEODE-3278
          — End diff –

          Done.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132532641 — Diff: geode-core/src/test/java/org/apache/geode/internal/process/FileProcessControllerIntegrationTest.java — @@ -0,0 +1,243 @@ +/* + * 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.geode.internal.process; + +import static com.googlecode.catchexception.CatchException.caughtException; +import static com.googlecode.catchexception.CatchException.verifyException; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicReference; + +import org.awaitility.Awaitility; +import org.awaitility.core.ConditionFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.ErrorCollector; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestName; + +import org.apache.geode.distributed.AbstractLauncher.Status; +import org.apache.geode.distributed.LocatorLauncher; +import org.apache.geode.distributed.LocatorLauncher.Builder; +import org.apache.geode.distributed.LocatorLauncher.LocatorState; +import org.apache.geode.internal.process.io.EmptyFileWriter; +import org.apache.geode.internal.process.io.IntegerFileWriter; +import org.apache.geode.internal.process.io.StringFileWriter; +import org.apache.geode.test.junit.categories.IntegrationTest; + +/** + * Integration tests for {@link FileProcessController} . + */ +@Category(IntegrationTest.class) +public class FileProcessControllerIntegrationTest { + + private static final String STATUS_JSON = generateStatusJson(); + + private final AtomicReference<String> statusRef = new AtomicReference<>(); + + private File pidFile; + private File statusFile; + private File statusRequestFile; + private File stopRequestFile; + private int pid; + private FileControllerParameters params; + private ExecutorService executor; + + @Rule + public ErrorCollector errorCollector = new ErrorCollector(); + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Rule + public TestName testName = new TestName(); + + @Before + public void setUp() throws Exception { + ProcessType processType = ProcessType.LOCATOR; + File directory = temporaryFolder.getRoot(); + pidFile = new File(directory, processType.getPidFileName()); + statusFile = new File(directory, processType.getStatusFileName()); + statusRequestFile = new File(directory, processType.getStatusRequestFileName()); + stopRequestFile = new File(directory, processType.getStopRequestFileName()); + pid = ProcessUtils.identifyPid(); + + params = mock(FileControllerParameters.class); + when(params.getPidFile()).thenReturn(pidFile); + when(params.getProcessId()).thenReturn(pid); + when(params.getProcessType()).thenReturn(processType); + when(params.getDirectory()).thenReturn(temporaryFolder.getRoot()); + + executor = Executors.newSingleThreadExecutor(); + } + + @After + public void tearDown() throws Exception { + assertThat(executor.shutdownNow()).isEmpty(); + } + + @Test + public void statusShouldAwaitTimeoutWhileFileIsEmpty() throws Exception { + // given: FileProcessController with empty pidFile + FileProcessController controller = new FileProcessController(params, pid, 10, MILLISECONDS); + + // when: + verifyException(controller).status(); + + // then: we expect TimeoutException to be thrown + assertThat((Exception) caughtException()).isInstanceOf(TimeoutException.class) + .hasMessageContaining("Timed out waiting for process to create").hasNoCause(); + } + + @Test + public void statusShouldReturnJsonFromStatusFile() throws Exception { + // given: FileProcessController with pidFile containing real pid + new IntegerFileWriter(pidFile).writeToFile(pid); + FileProcessController controller = new FileProcessController(params, pid, 2, MINUTES); + + // when: status is called in one thread + executor.execute(() -> { + try { + statusRef.set(controller.status()); + } catch (Exception e) { + errorCollector.addError(e); + } + }); + + // and: json is written to the status file + new StringFileWriter(statusFile).writeToFile(STATUS_JSON); + + // then: returned status should be the json in the file + await().until(() -> assertThat(statusRef.get()).isEqualTo(STATUS_JSON)); + } + + @Ignore // GEODE-3278 — End diff – Done.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132532669

          — Diff: geode-core/src/test/java/org/apache/geode/internal/process/AbstractProcessStreamReaderIntegrationTest.java —
          @@ -0,0 +1,234 @@
          +/*
          + * 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.geode.internal.process;
          +
          +import static java.util.concurrent.TimeUnit.MILLISECONDS;
          +import static org.apache.commons.lang.SystemUtils.LINE_SEPARATOR;
          +
          +import java.io.File;
          +import java.util.ArrayList;
          +import java.util.Arrays;
          +import java.util.List;
          +
          +import org.awaitility.Awaitility;
          +import org.awaitility.core.ConditionFactory;
          +import org.junit.After;
          +
          +import org.apache.geode.internal.util.StopWatch;
          +
          +/**
          + * Abstract base class for functional integration testing of

          {@link ProcessStreamReader}.
          + */
          +public abstract class AbstractProcessStreamReaderIntegrationTest {
          +
          + /** Timeout to join to a running ProcessStreamReader thread */
          + protected static final int READER_JOIN_TIMEOUT_MILLIS = 20 * 1000;
          +
          + /** Sleep timeout for {@link ProcessSleeps} instead of sleeping Long.MAX_VALUE */
          + private static final int PROCESS_FAILSAFE_TIMEOUT_MILLIS = 10 * 60 * 1000;
          +
          + /** Additional time for launched processes to live before terminating */
          + private static final int PROCESS_TIME_TO_LIVE_MILLIS = 3 * 500;
          +
          + /** Timeout to wait for a new {@link ProcessStreamReader}

          to be running */
          + private static final int WAIT_FOR_READER_IS_RUNNING_TIMEOUT_MILLIS = 20 * 1000;
          +
          + protected Process process;
          + protected ProcessStreamReader stderr;
          + protected ProcessStreamReader stdout;
          +
          + @After
          + public void afterProcessStreamReaderTestCase() throws Exception {
          + if (stderr != null)

          { + stderr.stop(); + }

          + if (stdout != null)

          { + stdout.stop(); + }

          + if (process != null) {
          + try

          { + process.getErrorStream().close(); + process.getInputStream().close(); + process.getOutputStream().close(); + }

          finally

          { + // this is async and can require more than 10 seconds on slower machines + process.destroy(); + }

          + }
          + }
          +
          + protected ConditionFactory await()

          { + return Awaitility.await().atMost(WAIT_FOR_READER_IS_RUNNING_TIMEOUT_MILLIS, MILLISECONDS); + }

          +
          + protected static boolean isAlive(final Process process) {
          — End diff –

          Done.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132532669 — Diff: geode-core/src/test/java/org/apache/geode/internal/process/AbstractProcessStreamReaderIntegrationTest.java — @@ -0,0 +1,234 @@ +/* + * 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.geode.internal.process; + +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.apache.commons.lang.SystemUtils.LINE_SEPARATOR; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.awaitility.Awaitility; +import org.awaitility.core.ConditionFactory; +import org.junit.After; + +import org.apache.geode.internal.util.StopWatch; + +/** + * Abstract base class for functional integration testing of {@link ProcessStreamReader}. + */ +public abstract class AbstractProcessStreamReaderIntegrationTest { + + /** Timeout to join to a running ProcessStreamReader thread */ + protected static final int READER_JOIN_TIMEOUT_MILLIS = 20 * 1000; + + /** Sleep timeout for {@link ProcessSleeps} instead of sleeping Long.MAX_VALUE */ + private static final int PROCESS_FAILSAFE_TIMEOUT_MILLIS = 10 * 60 * 1000; + + /** Additional time for launched processes to live before terminating */ + private static final int PROCESS_TIME_TO_LIVE_MILLIS = 3 * 500; + + /** Timeout to wait for a new {@link ProcessStreamReader} to be running */ + private static final int WAIT_FOR_READER_IS_RUNNING_TIMEOUT_MILLIS = 20 * 1000; + + protected Process process; + protected ProcessStreamReader stderr; + protected ProcessStreamReader stdout; + + @After + public void afterProcessStreamReaderTestCase() throws Exception { + if (stderr != null) { + stderr.stop(); + } + if (stdout != null) { + stdout.stop(); + } + if (process != null) { + try { + process.getErrorStream().close(); + process.getInputStream().close(); + process.getOutputStream().close(); + } finally { + // this is async and can require more than 10 seconds on slower machines + process.destroy(); + } + } + } + + protected ConditionFactory await() { + return Awaitility.await().atMost(WAIT_FOR_READER_IS_RUNNING_TIMEOUT_MILLIS, MILLISECONDS); + } + + protected static boolean isAlive(final Process process) { — End diff – Done.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132533643

          — Diff: geode-core/src/main/java/org/apache/geode/internal/cache/ClusterConfigurationLoader.java —
          @@ -31,7 +31,7 @@
          import org.apache.geode.internal.admin.remote.DistributionLocatorId;
          import org.apache.geode.internal.i18n.LocalizedStrings;
          import org.apache.geode.internal.logging.LogService;
          -import org.apache.geode.internal.process.ClusterConfigurationNotAvailableException;
          +import org.apache.geode.config.internal.ClusterConfigurationNotAvailableException;
          — End diff –

          Done.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132533643 — Diff: geode-core/src/main/java/org/apache/geode/internal/cache/ClusterConfigurationLoader.java — @@ -31,7 +31,7 @@ import org.apache.geode.internal.admin.remote.DistributionLocatorId; import org.apache.geode.internal.i18n.LocalizedStrings; import org.apache.geode.internal.logging.LogService; -import org.apache.geode.internal.process.ClusterConfigurationNotAvailableException; +import org.apache.geode.config.internal.ClusterConfigurationNotAvailableException; — End diff – Done.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132535229

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/AbstractLauncher.java —
          @@ -157,7 +162,7 @@ protected static Properties loadGemFireProperties(final URL url) {
          if (url != null) {
          try

          { properties.load(new FileReader(new File(url.toURI()))); - }

          catch (Exception e)

          { + }

          catch (Exception ignored) {
          — End diff –

          Done.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132535229 — Diff: geode-core/src/main/java/org/apache/geode/distributed/AbstractLauncher.java — @@ -157,7 +162,7 @@ protected static Properties loadGemFireProperties(final URL url) { if (url != null) { try { properties.load(new FileReader(new File(url.toURI()))); - } catch (Exception e) { + } catch (Exception ignored) { — End diff – Done.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132541592

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/AbstractLauncher.java —
          @@ -502,7 +507,7 @@ protected static Integer identifyPid() {
          }
          }

          • // TODO refactor the logic in this method into a DateTimeFormatUtils class
            + // consider refactoring the logic in this method into a DateTimeFormatUtils class
              • End diff –

          Deleted.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132541592 — Diff: geode-core/src/main/java/org/apache/geode/distributed/AbstractLauncher.java — @@ -502,7 +507,7 @@ protected static Integer identifyPid() { } } // TODO refactor the logic in this method into a DateTimeFormatUtils class + // consider refactoring the logic in this method into a DateTimeFormatUtils class End diff – Deleted.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132541795

          — Diff: geode-core/src/main/java/org/apache/geode/internal/process/MBeanProcessController.java —
          @@ -228,9 +230,9 @@ private void disconnect() {

          • @throws PidUnavailableException if parsing the pid from the RuntimeMXBean name fails
            */
            boolean checkPidMatches() throws IllegalStateException, IOException, PidUnavailableException {
              • End diff –

          Deleted.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132541795 — Diff: geode-core/src/main/java/org/apache/geode/internal/process/MBeanProcessController.java — @@ -228,9 +230,9 @@ private void disconnect() { @throws PidUnavailableException if parsing the pid from the RuntimeMXBean name fails */ boolean checkPidMatches() throws IllegalStateException, IOException, PidUnavailableException { End diff – Deleted.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132541957

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java —
          @@ -1848,8 +1884,7 @@ public LocatorLauncher build() {
          private final String name;

          Command(final String name, final String... options) {

          • assert !StringUtils
          • .isBlank(name) : "The name of the locator launcher command must be specified!";
            + assert Unable to render embedded object: File ( "The name of the locator launcher command must be specified) not found.";
              • End diff –

          Changed.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132541957 — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java — @@ -1848,8 +1884,7 @@ public LocatorLauncher build() { private final String name; Command(final String name, final String... options) { assert !StringUtils .isBlank(name) : "The name of the locator launcher command must be specified!"; + assert Unable to render embedded object: File ( "The name of the locator launcher command must be specified) not found. "; End diff – Changed.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132542008

          — Diff: geode-core/src/test/java/org/apache/geode/internal/process/BlockingProcessStreamReaderWindowsTest.java —
          @@ -0,0 +1,97 @@
          +/*
          + * 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.geode.internal.process;
          +
          +import static org.apache.geode.internal.lang.SystemUtils.isWindows;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.assertj.core.api.Assertions.assertThatThrownBy;
          +import static org.junit.Assume.assumeTrue;
          +
          +import java.util.concurrent.ExecutorService;
          +import java.util.concurrent.Executors;
          +import java.util.concurrent.Future;
          +import java.util.concurrent.TimeUnit;
          +import java.util.concurrent.TimeoutException;
          +
          +import org.junit.After;
          +import org.junit.Before;
          +import org.junit.Test;
          +import org.junit.experimental.categories.Category;
          +
          +import org.apache.geode.test.junit.categories.IntegrationTest;
          +
          +/**
          + * Functional integration test

          {@link #hangsOnWindows}

          for BlockingProcessStreamReader which
          + * verifies TRAC #51967 on Windows. The hang is caused by a JDK bug in which a thread invoking
          — End diff –

          I added description.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132542008 — Diff: geode-core/src/test/java/org/apache/geode/internal/process/BlockingProcessStreamReaderWindowsTest.java — @@ -0,0 +1,97 @@ +/* + * 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.geode.internal.process; + +import static org.apache.geode.internal.lang.SystemUtils.isWindows; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assume.assumeTrue; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import org.apache.geode.test.junit.categories.IntegrationTest; + +/** + * Functional integration test {@link #hangsOnWindows} for BlockingProcessStreamReader which + * verifies TRAC #51967 on Windows. The hang is caused by a JDK bug in which a thread invoking — End diff – I added description.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132542016

          — Diff: geode-core/src/test/java/org/apache/geode/internal/process/BlockingProcessStreamReaderIntegrationTest.java —
          @@ -0,0 +1,179 @@
          +/*
          + * 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.geode.internal.process;
          +
          +import static org.apache.geode.internal.lang.SystemUtils.isWindows;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.junit.Assume.assumeFalse;
          +
          +import org.junit.Before;
          +import org.junit.Test;
          +import org.junit.experimental.categories.Category;
          +
          +import org.apache.geode.internal.process.ProcessStreamReader.Builder;
          +import org.apache.geode.internal.process.ProcessStreamReader.ReadingMode;
          +import org.apache.geode.test.junit.categories.IntegrationTest;
          +
          +/**
          + * Functional integration tests for BlockingProcessStreamReader. All tests are skipped on Windows
          + * due to TRAC bug #51967 which is caused by a JDK bug. See
          — End diff –

          I added description.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132542016 — Diff: geode-core/src/test/java/org/apache/geode/internal/process/BlockingProcessStreamReaderIntegrationTest.java — @@ -0,0 +1,179 @@ +/* + * 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.geode.internal.process; + +import static org.apache.geode.internal.lang.SystemUtils.isWindows; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assume.assumeFalse; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import org.apache.geode.internal.process.ProcessStreamReader.Builder; +import org.apache.geode.internal.process.ProcessStreamReader.ReadingMode; +import org.apache.geode.test.junit.categories.IntegrationTest; + +/** + * Functional integration tests for BlockingProcessStreamReader. All tests are skipped on Windows + * due to TRAC bug #51967 which is caused by a JDK bug. See — End diff – I added description.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132542063

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java —
          @@ -0,0 +1,505 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.internal.AvailablePort.SOCKET;
          +import static org.apache.geode.internal.AvailablePort.isPortAvailable;
          +import static org.apache.geode.internal.process.ProcessUtils.identifyPid;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.junit.Assert.assertTrue;
          +
          +import java.io.BufferedReader;
          +import java.io.File;
          +import java.io.FileReader;
          +import java.io.FileWriter;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.lang.management.ManagementFactory;
          +import java.net.ServerSocket;
          +import java.nio.file.Files;
          +import java.util.List;
          +import java.util.Properties;
          +import java.util.concurrent.Callable;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.apache.commons.lang.StringUtils;
          +import org.apache.logging.log4j.Logger;
          +import org.awaitility.Awaitility;
          +import org.awaitility.core.ConditionFactory;
          +import org.junit.After;
          +import org.junit.Before;
          +import org.junit.Rule;
          +import org.junit.contrib.java.lang.system.RestoreSystemProperties;
          +import org.junit.rules.TemporaryFolder;
          +import org.junit.rules.TestName;
          +
          +import org.apache.geode.distributed.internal.DistributionConfig;
          +import org.apache.geode.distributed.internal.InternalDistributedSystem;
          +import org.apache.geode.internal.logging.LogService;
          +import org.apache.geode.internal.net.SocketCreatorFactory;
          +import org.apache.geode.internal.process.PidUnavailableException;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +import org.apache.geode.internal.process.ProcessType;
          +import org.apache.geode.internal.process.ProcessUtils;
          +import org.apache.geode.internal.process.lang.AvailablePid;
          +import org.apache.geode.internal.util.StopWatch;
          +import org.apache.geode.test.dunit.IgnoredException;
          +
          +/**
          + * Abstract base class for integration tests of both

          {@link LocatorLauncher}

          and
          + *

          {@link ServerLauncher}

          .
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class LauncherIntegrationTestCase {
          + protected static final Logger logger = LogService.getLogger();
          +
          + protected static final int WAIT_FOR_PROCESS_TO_DIE_TIMEOUT = 5 * 60 * 1000; // 5 minutes
          + protected static final int TIMEOUT_MILLISECONDS = WAIT_FOR_PROCESS_TO_DIE_TIMEOUT;
          — End diff –

          All unused fields deleted.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132542063 — Diff: geode-core/src/test/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java — @@ -0,0 +1,505 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.internal.AvailablePort.SOCKET; +import static org.apache.geode.internal.AvailablePort.isPortAvailable; +import static org.apache.geode.internal.process.ProcessUtils.identifyPid; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.management.ManagementFactory; +import java.net.ServerSocket; +import java.nio.file.Files; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; +import org.awaitility.Awaitility; +import org.awaitility.core.ConditionFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.contrib.java.lang.system.RestoreSystemProperties; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestName; + +import org.apache.geode.distributed.internal.DistributionConfig; +import org.apache.geode.distributed.internal.InternalDistributedSystem; +import org.apache.geode.internal.logging.LogService; +import org.apache.geode.internal.net.SocketCreatorFactory; +import org.apache.geode.internal.process.PidUnavailableException; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; +import org.apache.geode.internal.process.ProcessType; +import org.apache.geode.internal.process.ProcessUtils; +import org.apache.geode.internal.process.lang.AvailablePid; +import org.apache.geode.internal.util.StopWatch; +import org.apache.geode.test.dunit.IgnoredException; + +/** + * Abstract base class for integration tests of both {@link LocatorLauncher} and + * {@link ServerLauncher} . + * + * @since GemFire 8.0 + */ +public abstract class LauncherIntegrationTestCase { + protected static final Logger logger = LogService.getLogger(); + + protected static final int WAIT_FOR_PROCESS_TO_DIE_TIMEOUT = 5 * 60 * 1000; // 5 minutes + protected static final int TIMEOUT_MILLISECONDS = WAIT_FOR_PROCESS_TO_DIE_TIMEOUT; — End diff – All unused fields deleted.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132542091

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java —
          @@ -0,0 +1,505 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.internal.AvailablePort.SOCKET;
          +import static org.apache.geode.internal.AvailablePort.isPortAvailable;
          +import static org.apache.geode.internal.process.ProcessUtils.identifyPid;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.junit.Assert.assertTrue;
          +
          +import java.io.BufferedReader;
          +import java.io.File;
          +import java.io.FileReader;
          +import java.io.FileWriter;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.lang.management.ManagementFactory;
          +import java.net.ServerSocket;
          +import java.nio.file.Files;
          +import java.util.List;
          +import java.util.Properties;
          +import java.util.concurrent.Callable;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.apache.commons.lang.StringUtils;
          +import org.apache.logging.log4j.Logger;
          +import org.awaitility.Awaitility;
          +import org.awaitility.core.ConditionFactory;
          +import org.junit.After;
          +import org.junit.Before;
          +import org.junit.Rule;
          +import org.junit.contrib.java.lang.system.RestoreSystemProperties;
          +import org.junit.rules.TemporaryFolder;
          +import org.junit.rules.TestName;
          +
          +import org.apache.geode.distributed.internal.DistributionConfig;
          +import org.apache.geode.distributed.internal.InternalDistributedSystem;
          +import org.apache.geode.internal.logging.LogService;
          +import org.apache.geode.internal.net.SocketCreatorFactory;
          +import org.apache.geode.internal.process.PidUnavailableException;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +import org.apache.geode.internal.process.ProcessType;
          +import org.apache.geode.internal.process.ProcessUtils;
          +import org.apache.geode.internal.process.lang.AvailablePid;
          +import org.apache.geode.internal.util.StopWatch;
          +import org.apache.geode.test.dunit.IgnoredException;
          +
          +/**
          + * Abstract base class for integration tests of both

          {@link LocatorLauncher}

          and
          + *

          {@link ServerLauncher}

          .
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class LauncherIntegrationTestCase {
          + protected static final Logger logger = LogService.getLogger();
          +
          + protected static final int WAIT_FOR_PROCESS_TO_DIE_TIMEOUT = 5 * 60 * 1000; // 5 minutes
          + protected static final int TIMEOUT_MILLISECONDS = WAIT_FOR_PROCESS_TO_DIE_TIMEOUT;
          + protected static final int WAIT_FOR_FILE_CREATION_TIMEOUT = 10 * 1000; // 10s
          + protected static final int WAIT_FOR_FILE_DELETION_TIMEOUT = 10 * 1000; // 10s
          + protected static final int WAIT_FOR_MBEAN_TIMEOUT = 10 * 1000; // 10s
          — End diff –

          All unused fields deleted.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132542091 — Diff: geode-core/src/test/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java — @@ -0,0 +1,505 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.internal.AvailablePort.SOCKET; +import static org.apache.geode.internal.AvailablePort.isPortAvailable; +import static org.apache.geode.internal.process.ProcessUtils.identifyPid; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.management.ManagementFactory; +import java.net.ServerSocket; +import java.nio.file.Files; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; +import org.awaitility.Awaitility; +import org.awaitility.core.ConditionFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.contrib.java.lang.system.RestoreSystemProperties; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestName; + +import org.apache.geode.distributed.internal.DistributionConfig; +import org.apache.geode.distributed.internal.InternalDistributedSystem; +import org.apache.geode.internal.logging.LogService; +import org.apache.geode.internal.net.SocketCreatorFactory; +import org.apache.geode.internal.process.PidUnavailableException; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; +import org.apache.geode.internal.process.ProcessType; +import org.apache.geode.internal.process.ProcessUtils; +import org.apache.geode.internal.process.lang.AvailablePid; +import org.apache.geode.internal.util.StopWatch; +import org.apache.geode.test.dunit.IgnoredException; + +/** + * Abstract base class for integration tests of both {@link LocatorLauncher} and + * {@link ServerLauncher} . + * + * @since GemFire 8.0 + */ +public abstract class LauncherIntegrationTestCase { + protected static final Logger logger = LogService.getLogger(); + + protected static final int WAIT_FOR_PROCESS_TO_DIE_TIMEOUT = 5 * 60 * 1000; // 5 minutes + protected static final int TIMEOUT_MILLISECONDS = WAIT_FOR_PROCESS_TO_DIE_TIMEOUT; + protected static final int WAIT_FOR_FILE_CREATION_TIMEOUT = 10 * 1000; // 10s + protected static final int WAIT_FOR_FILE_DELETION_TIMEOUT = 10 * 1000; // 10s + protected static final int WAIT_FOR_MBEAN_TIMEOUT = 10 * 1000; // 10s — End diff – All unused fields deleted.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132542106

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java —
          @@ -0,0 +1,505 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.internal.AvailablePort.SOCKET;
          +import static org.apache.geode.internal.AvailablePort.isPortAvailable;
          +import static org.apache.geode.internal.process.ProcessUtils.identifyPid;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.junit.Assert.assertTrue;
          +
          +import java.io.BufferedReader;
          +import java.io.File;
          +import java.io.FileReader;
          +import java.io.FileWriter;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.lang.management.ManagementFactory;
          +import java.net.ServerSocket;
          +import java.nio.file.Files;
          +import java.util.List;
          +import java.util.Properties;
          +import java.util.concurrent.Callable;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.apache.commons.lang.StringUtils;
          +import org.apache.logging.log4j.Logger;
          +import org.awaitility.Awaitility;
          +import org.awaitility.core.ConditionFactory;
          +import org.junit.After;
          +import org.junit.Before;
          +import org.junit.Rule;
          +import org.junit.contrib.java.lang.system.RestoreSystemProperties;
          +import org.junit.rules.TemporaryFolder;
          +import org.junit.rules.TestName;
          +
          +import org.apache.geode.distributed.internal.DistributionConfig;
          +import org.apache.geode.distributed.internal.InternalDistributedSystem;
          +import org.apache.geode.internal.logging.LogService;
          +import org.apache.geode.internal.net.SocketCreatorFactory;
          +import org.apache.geode.internal.process.PidUnavailableException;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +import org.apache.geode.internal.process.ProcessType;
          +import org.apache.geode.internal.process.ProcessUtils;
          +import org.apache.geode.internal.process.lang.AvailablePid;
          +import org.apache.geode.internal.util.StopWatch;
          +import org.apache.geode.test.dunit.IgnoredException;
          +
          +/**
          + * Abstract base class for integration tests of both

          {@link LocatorLauncher}

          and
          + *

          {@link ServerLauncher}

          .
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class LauncherIntegrationTestCase {
          + protected static final Logger logger = LogService.getLogger();
          +
          + protected static final int WAIT_FOR_PROCESS_TO_DIE_TIMEOUT = 5 * 60 * 1000; // 5 minutes
          + protected static final int TIMEOUT_MILLISECONDS = WAIT_FOR_PROCESS_TO_DIE_TIMEOUT;
          + protected static final int WAIT_FOR_FILE_CREATION_TIMEOUT = 10 * 1000; // 10s
          + protected static final int WAIT_FOR_FILE_DELETION_TIMEOUT = 10 * 1000; // 10s
          + protected static final int WAIT_FOR_MBEAN_TIMEOUT = 10 * 1000; // 10s
          + protected static final int INTERVAL_MILLISECONDS = 100;
          +
          + protected static final int PREFERRED_FAKE_PID = 42;
          +
          + private static final String EXPECTED_EXCEPTION_ADD =
          + "<ExpectedException action=add>{}</ExpectedException>";
          + private static final String EXPECTED_EXCEPTION_REMOVE =
          — End diff –

          All unused fields deleted.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132542106 — Diff: geode-core/src/test/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java — @@ -0,0 +1,505 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.internal.AvailablePort.SOCKET; +import static org.apache.geode.internal.AvailablePort.isPortAvailable; +import static org.apache.geode.internal.process.ProcessUtils.identifyPid; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.management.ManagementFactory; +import java.net.ServerSocket; +import java.nio.file.Files; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; +import org.awaitility.Awaitility; +import org.awaitility.core.ConditionFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.contrib.java.lang.system.RestoreSystemProperties; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestName; + +import org.apache.geode.distributed.internal.DistributionConfig; +import org.apache.geode.distributed.internal.InternalDistributedSystem; +import org.apache.geode.internal.logging.LogService; +import org.apache.geode.internal.net.SocketCreatorFactory; +import org.apache.geode.internal.process.PidUnavailableException; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; +import org.apache.geode.internal.process.ProcessType; +import org.apache.geode.internal.process.ProcessUtils; +import org.apache.geode.internal.process.lang.AvailablePid; +import org.apache.geode.internal.util.StopWatch; +import org.apache.geode.test.dunit.IgnoredException; + +/** + * Abstract base class for integration tests of both {@link LocatorLauncher} and + * {@link ServerLauncher} . + * + * @since GemFire 8.0 + */ +public abstract class LauncherIntegrationTestCase { + protected static final Logger logger = LogService.getLogger(); + + protected static final int WAIT_FOR_PROCESS_TO_DIE_TIMEOUT = 5 * 60 * 1000; // 5 minutes + protected static final int TIMEOUT_MILLISECONDS = WAIT_FOR_PROCESS_TO_DIE_TIMEOUT; + protected static final int WAIT_FOR_FILE_CREATION_TIMEOUT = 10 * 1000; // 10s + protected static final int WAIT_FOR_FILE_DELETION_TIMEOUT = 10 * 1000; // 10s + protected static final int WAIT_FOR_MBEAN_TIMEOUT = 10 * 1000; // 10s + protected static final int INTERVAL_MILLISECONDS = 100; + + protected static final int PREFERRED_FAKE_PID = 42; + + private static final String EXPECTED_EXCEPTION_ADD = + "<ExpectedException action=add>{}</ExpectedException>"; + private static final String EXPECTED_EXCEPTION_REMOVE = — End diff – All unused fields deleted.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132542146

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java —
          @@ -0,0 +1,505 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.internal.AvailablePort.SOCKET;
          +import static org.apache.geode.internal.AvailablePort.isPortAvailable;
          +import static org.apache.geode.internal.process.ProcessUtils.identifyPid;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.junit.Assert.assertTrue;
          +
          +import java.io.BufferedReader;
          +import java.io.File;
          +import java.io.FileReader;
          +import java.io.FileWriter;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.lang.management.ManagementFactory;
          +import java.net.ServerSocket;
          +import java.nio.file.Files;
          +import java.util.List;
          +import java.util.Properties;
          +import java.util.concurrent.Callable;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.apache.commons.lang.StringUtils;
          +import org.apache.logging.log4j.Logger;
          +import org.awaitility.Awaitility;
          +import org.awaitility.core.ConditionFactory;
          +import org.junit.After;
          +import org.junit.Before;
          +import org.junit.Rule;
          +import org.junit.contrib.java.lang.system.RestoreSystemProperties;
          +import org.junit.rules.TemporaryFolder;
          +import org.junit.rules.TestName;
          +
          +import org.apache.geode.distributed.internal.DistributionConfig;
          +import org.apache.geode.distributed.internal.InternalDistributedSystem;
          +import org.apache.geode.internal.logging.LogService;
          +import org.apache.geode.internal.net.SocketCreatorFactory;
          +import org.apache.geode.internal.process.PidUnavailableException;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +import org.apache.geode.internal.process.ProcessType;
          +import org.apache.geode.internal.process.ProcessUtils;
          +import org.apache.geode.internal.process.lang.AvailablePid;
          +import org.apache.geode.internal.util.StopWatch;
          +import org.apache.geode.test.dunit.IgnoredException;
          +
          +/**
          + * Abstract base class for integration tests of both

          {@link LocatorLauncher}

          and
          + *

          {@link ServerLauncher}

          .
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class LauncherIntegrationTestCase {
          + protected static final Logger logger = LogService.getLogger();
          +
          + protected static final int WAIT_FOR_PROCESS_TO_DIE_TIMEOUT = 5 * 60 * 1000; // 5 minutes
          + protected static final int TIMEOUT_MILLISECONDS = WAIT_FOR_PROCESS_TO_DIE_TIMEOUT;
          + protected static final int WAIT_FOR_FILE_CREATION_TIMEOUT = 10 * 1000; // 10s
          + protected static final int WAIT_FOR_FILE_DELETION_TIMEOUT = 10 * 1000; // 10s
          + protected static final int WAIT_FOR_MBEAN_TIMEOUT = 10 * 1000; // 10s
          + protected static final int INTERVAL_MILLISECONDS = 100;
          +
          + protected static final int PREFERRED_FAKE_PID = 42;
          +
          + private static final String EXPECTED_EXCEPTION_ADD =
          + "<ExpectedException action=add>{}</ExpectedException>";
          + private static final String EXPECTED_EXCEPTION_REMOVE =
          + "<ExpectedException action=remove>{}</ExpectedException>";
          + private static final String EXPECTED_EXCEPTION_MBEAN_NOT_REGISTERED =
          + "MBean Not Registered In GemFire Domain";
          +
          + private IgnoredException ignoredException;
          +
          + protected int localPid;
          + protected int fakePid;
          +
          + protected volatile ServerSocket socket;
          +
          + protected volatile File pidFile;
          + protected volatile File stopRequestFile;
          + protected volatile File statusRequestFile;
          + protected volatile File statusFile;
          +
          + @Rule
          + public TestName testName = new TestName();
          +
          + @Rule
          + public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
          +
          + @Rule
          + public TemporaryFolder temporaryFolder = new TemporaryFolder();
          +
          + @Before
          + public void setUpAbstractLauncherIntegrationTestCase() throws Exception

          { + System.setProperty(DistributionConfig.GEMFIRE_PREFIX + MCAST_PORT, Integer.toString(0)); + ignoredException = + IgnoredException.addIgnoredException(EXPECTED_EXCEPTION_MBEAN_NOT_REGISTERED); + localPid = identifyPid(); + fakePid = new AvailablePid().findAvailablePid(PREFERRED_FAKE_PID); + }

          +
          + @After
          + public void tearDownAbstractLauncherIntegrationTestCase() throws Exception {
          + ignoredException.remove();
          + if (this.socket != null)

          { + this.socket.close(); + this.socket = null; + }

          + delete(this.pidFile);
          + delete(this.stopRequestFile);
          + delete(this.statusRequestFile);
          + delete(this.statusFile);
          + }
          +
          + protected abstract ProcessType getProcessType();
          +
          + protected String getStopRequestFileName()

          { + return getProcessType().getStopRequestFileName(); + }

          +
          + protected String getStatusRequestFileName()

          { + return getProcessType().getStatusRequestFileName(); + }

          +
          + protected String getStatusFileName()

          { + return getProcessType().getStatusFileName(); + }

          +
          + protected void givenEmptyWorkingDirectory()

          { + assertThat(getWorkingDirectory().listFiles()).hasSize(0); + }

          +
          + protected List<String> getJvmArguments()

          { + return ManagementFactory.getRuntimeMXBean().getInputArguments(); + }

          +
          + protected ConditionFactory await()

          { + return Awaitility.await().atMost(2, MINUTES); + }

          +
          + public String getClassPath()

          { + // alternative: ManagementFactory.getRuntimeMXBean().getClassPath() + return System.getProperty("java.class.path"); + }

          +
          + public String getJavaPath() {
          + try

          { + return new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath(); + }

          catch (IOException e)

          { + throw new UncheckedIOException(e); + }
          + }
          +
          + protected File getPidFile() { + return new File(getWorkingDirectory(), getProcessType().getPidFileName()); + }
          +
          + protected File getLogFile() { + return new File(getWorkingDirectory(), getUniqueName() + ".log"); + }
          +
          + protected String getLogFilePath() {
          + try { + return getLogFile().getCanonicalPath(); + } catch (IOException e) { + throw new UncheckedIOException(e); + }

          + }
          +
          + protected File getWorkingDirectory()

          { + return this.temporaryFolder.getRoot(); + }

          +
          + protected String getWorkingDirectoryPath() {
          + try

          { + return getWorkingDirectory().getCanonicalPath(); + }

          catch (IOException e)

          { + throw new UncheckedIOException(e); + }

          + }
          +
          + protected void createPidFile(final Object content) {
          — End diff –

          All unused methods deleted.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132542146 — Diff: geode-core/src/test/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java — @@ -0,0 +1,505 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.internal.AvailablePort.SOCKET; +import static org.apache.geode.internal.AvailablePort.isPortAvailable; +import static org.apache.geode.internal.process.ProcessUtils.identifyPid; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.management.ManagementFactory; +import java.net.ServerSocket; +import java.nio.file.Files; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.Logger; +import org.awaitility.Awaitility; +import org.awaitility.core.ConditionFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.contrib.java.lang.system.RestoreSystemProperties; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestName; + +import org.apache.geode.distributed.internal.DistributionConfig; +import org.apache.geode.distributed.internal.InternalDistributedSystem; +import org.apache.geode.internal.logging.LogService; +import org.apache.geode.internal.net.SocketCreatorFactory; +import org.apache.geode.internal.process.PidUnavailableException; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; +import org.apache.geode.internal.process.ProcessType; +import org.apache.geode.internal.process.ProcessUtils; +import org.apache.geode.internal.process.lang.AvailablePid; +import org.apache.geode.internal.util.StopWatch; +import org.apache.geode.test.dunit.IgnoredException; + +/** + * Abstract base class for integration tests of both {@link LocatorLauncher} and + * {@link ServerLauncher} . + * + * @since GemFire 8.0 + */ +public abstract class LauncherIntegrationTestCase { + protected static final Logger logger = LogService.getLogger(); + + protected static final int WAIT_FOR_PROCESS_TO_DIE_TIMEOUT = 5 * 60 * 1000; // 5 minutes + protected static final int TIMEOUT_MILLISECONDS = WAIT_FOR_PROCESS_TO_DIE_TIMEOUT; + protected static final int WAIT_FOR_FILE_CREATION_TIMEOUT = 10 * 1000; // 10s + protected static final int WAIT_FOR_FILE_DELETION_TIMEOUT = 10 * 1000; // 10s + protected static final int WAIT_FOR_MBEAN_TIMEOUT = 10 * 1000; // 10s + protected static final int INTERVAL_MILLISECONDS = 100; + + protected static final int PREFERRED_FAKE_PID = 42; + + private static final String EXPECTED_EXCEPTION_ADD = + "<ExpectedException action=add>{}</ExpectedException>"; + private static final String EXPECTED_EXCEPTION_REMOVE = + "<ExpectedException action=remove>{}</ExpectedException>"; + private static final String EXPECTED_EXCEPTION_MBEAN_NOT_REGISTERED = + "MBean Not Registered In GemFire Domain"; + + private IgnoredException ignoredException; + + protected int localPid; + protected int fakePid; + + protected volatile ServerSocket socket; + + protected volatile File pidFile; + protected volatile File stopRequestFile; + protected volatile File statusRequestFile; + protected volatile File statusFile; + + @Rule + public TestName testName = new TestName(); + + @Rule + public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties(); + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Before + public void setUpAbstractLauncherIntegrationTestCase() throws Exception { + System.setProperty(DistributionConfig.GEMFIRE_PREFIX + MCAST_PORT, Integer.toString(0)); + ignoredException = + IgnoredException.addIgnoredException(EXPECTED_EXCEPTION_MBEAN_NOT_REGISTERED); + localPid = identifyPid(); + fakePid = new AvailablePid().findAvailablePid(PREFERRED_FAKE_PID); + } + + @After + public void tearDownAbstractLauncherIntegrationTestCase() throws Exception { + ignoredException.remove(); + if (this.socket != null) { + this.socket.close(); + this.socket = null; + } + delete(this.pidFile); + delete(this.stopRequestFile); + delete(this.statusRequestFile); + delete(this.statusFile); + } + + protected abstract ProcessType getProcessType(); + + protected String getStopRequestFileName() { + return getProcessType().getStopRequestFileName(); + } + + protected String getStatusRequestFileName() { + return getProcessType().getStatusRequestFileName(); + } + + protected String getStatusFileName() { + return getProcessType().getStatusFileName(); + } + + protected void givenEmptyWorkingDirectory() { + assertThat(getWorkingDirectory().listFiles()).hasSize(0); + } + + protected List<String> getJvmArguments() { + return ManagementFactory.getRuntimeMXBean().getInputArguments(); + } + + protected ConditionFactory await() { + return Awaitility.await().atMost(2, MINUTES); + } + + public String getClassPath() { + // alternative: ManagementFactory.getRuntimeMXBean().getClassPath() + return System.getProperty("java.class.path"); + } + + public String getJavaPath() { + try { + return new File(new File(System.getProperty("java.home"), "bin"), "java").getCanonicalPath(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + protected File getPidFile() { + return new File(getWorkingDirectory(), getProcessType().getPidFileName()); + } + + protected File getLogFile() { + return new File(getWorkingDirectory(), getUniqueName() + ".log"); + } + + protected String getLogFilePath() { + try { + return getLogFile().getCanonicalPath(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + protected File getWorkingDirectory() { + return this.temporaryFolder.getRoot(); + } + + protected String getWorkingDirectoryPath() { + try { + return getWorkingDirectory().getCanonicalPath(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + protected void createPidFile(final Object content) { — End diff – All unused methods deleted.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132542157

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java —
          @@ -0,0 +1,270 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX;
          +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +
          +import java.io.File;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.net.BindException;
          +import java.util.ArrayList;
          +import java.util.List;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.junit.After;
          +import org.junit.Before;
          +
          +import org.apache.geode.distributed.AbstractLauncher.Status;
          +import org.apache.geode.internal.process.ProcessStreamReader;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +
          +/**
          + * Abstract base class for integration tests of

          {@link ServerLauncher}

          as an application main in a
          + * forked JVM.
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class ServerLauncherRemoteIntegrationTestCase
          + extends ServerLauncherIntegrationTestCase implements UsesServerCommand {
          +
          + private final AtomicBoolean threwBindException = new AtomicBoolean();
          +
          + protected volatile Process process;
          + protected volatile ProcessStreamReader processOutReader;
          + protected volatile ProcessStreamReader processErrReader;
          +
          + private ServerCommand serverCommand;
          +
          + @Before
          + public void setUp() throws Exception

          { + serverCommand = new ServerCommand(this); + }

          +
          + @After
          + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception {
          + if (this.process != null)

          { + this.process.destroy(); + this.process = null; + }

          + if (this.processOutReader != null && this.processOutReader.isRunning())

          { + this.processOutReader.stop(); + }

          + if (this.processErrReader != null && this.processErrReader.isRunning())

          { + this.processErrReader.stop(); + }

          + }
          +
          + @Override
          + public List<String> getJvmArguments()

          { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + }

          +
          + @Override
          + public String getName()

          { + return getUniqueName(); + }

          +
          + @Override
          + public boolean getDisableDefaultServer()

          { + return false; + }

          +
          + protected void assertThatServerThrewBindException()

          { + assertThat(threwBindException.get()).isTrue(); + }
          +
          + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + }

          +
          + protected ServerLauncher startServer(final ServerCommand command)

          { + return awaitStart(command); + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command,
          + final ProcessStreamReader.InputListener outListener,
          + final ProcessStreamReader.InputListener errListener) throws Exception

          { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command) {
          + try

          { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          catch (IOException e)

          { + throw new UncheckedIOException(e); + }
          + }
          +
          + protected ServerLauncher awaitStart(final File workingDirectory) {
          + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + }

          + }
          +
          + @Override
          + protected ServerLauncher awaitStart(final ServerLauncher launcher)

          { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart() {
          — End diff –

          All unused methods deleted.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132542157 — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java — @@ -0,0 +1,270 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX; +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.net.BindException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.After; +import org.junit.Before; + +import org.apache.geode.distributed.AbstractLauncher.Status; +import org.apache.geode.internal.process.ProcessStreamReader; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; + +/** + * Abstract base class for integration tests of {@link ServerLauncher} as an application main in a + * forked JVM. + * + * @since GemFire 8.0 + */ +public abstract class ServerLauncherRemoteIntegrationTestCase + extends ServerLauncherIntegrationTestCase implements UsesServerCommand { + + private final AtomicBoolean threwBindException = new AtomicBoolean(); + + protected volatile Process process; + protected volatile ProcessStreamReader processOutReader; + protected volatile ProcessStreamReader processErrReader; + + private ServerCommand serverCommand; + + @Before + public void setUp() throws Exception { + serverCommand = new ServerCommand(this); + } + + @After + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception { + if (this.process != null) { + this.process.destroy(); + this.process = null; + } + if (this.processOutReader != null && this.processOutReader.isRunning()) { + this.processOutReader.stop(); + } + if (this.processErrReader != null && this.processErrReader.isRunning()) { + this.processErrReader.stop(); + } + } + + @Override + public List<String> getJvmArguments() { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + } + + @Override + public String getName() { + return getUniqueName(); + } + + @Override + public boolean getDisableDefaultServer() { + return false; + } + + protected void assertThatServerThrewBindException() { + assertThat(threwBindException.get()).isTrue(); + } + + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + } + + protected ServerLauncher startServer(final ServerCommand command) { + return awaitStart(command); + } + + protected ServerLauncher awaitStart(final ServerCommand command, + final ProcessStreamReader.InputListener outListener, + final ProcessStreamReader.InputListener errListener) throws Exception { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart(final ServerCommand command) { + try { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + protected ServerLauncher awaitStart(final File workingDirectory) { + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Override + protected ServerLauncher awaitStart(final ServerLauncher launcher) { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart() { — End diff – All unused methods deleted.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132542169

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java —
          @@ -0,0 +1,270 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX;
          +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +
          +import java.io.File;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.net.BindException;
          +import java.util.ArrayList;
          +import java.util.List;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.junit.After;
          +import org.junit.Before;
          +
          +import org.apache.geode.distributed.AbstractLauncher.Status;
          +import org.apache.geode.internal.process.ProcessStreamReader;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +
          +/**
          + * Abstract base class for integration tests of

          {@link ServerLauncher}

          as an application main in a
          + * forked JVM.
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class ServerLauncherRemoteIntegrationTestCase
          + extends ServerLauncherIntegrationTestCase implements UsesServerCommand {
          +
          + private final AtomicBoolean threwBindException = new AtomicBoolean();
          +
          + protected volatile Process process;
          + protected volatile ProcessStreamReader processOutReader;
          + protected volatile ProcessStreamReader processErrReader;
          +
          + private ServerCommand serverCommand;
          +
          + @Before
          + public void setUp() throws Exception

          { + serverCommand = new ServerCommand(this); + }

          +
          + @After
          + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception {
          + if (this.process != null)

          { + this.process.destroy(); + this.process = null; + }

          + if (this.processOutReader != null && this.processOutReader.isRunning())

          { + this.processOutReader.stop(); + }

          + if (this.processErrReader != null && this.processErrReader.isRunning())

          { + this.processErrReader.stop(); + }

          + }
          +
          + @Override
          + public List<String> getJvmArguments()

          { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + }

          +
          + @Override
          + public String getName()

          { + return getUniqueName(); + }

          +
          + @Override
          + public boolean getDisableDefaultServer()

          { + return false; + }

          +
          + protected void assertThatServerThrewBindException()

          { + assertThat(threwBindException.get()).isTrue(); + }
          +
          + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + }

          +
          + protected ServerLauncher startServer(final ServerCommand command)

          { + return awaitStart(command); + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command,
          + final ProcessStreamReader.InputListener outListener,
          + final ProcessStreamReader.InputListener errListener) throws Exception

          { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command) {
          + try

          { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          catch (IOException e)

          { + throw new UncheckedIOException(e); + }
          + }
          +
          + protected ServerLauncher awaitStart(final File workingDirectory) {
          + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + }

          + }
          +
          + @Override
          + protected ServerLauncher awaitStart(final ServerLauncher launcher)

          { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart()

          { + return awaitStart(this.launcher); + }

          +
          + protected void awaitStop()

          { + await().until(() -> assertThat(this.process.isAlive()).isFalse()); + }

          +
          + protected void assertStopOf(final Process process)

          { + await().until(() -> assertThat(process.isAlive()).isFalse()); + }

          +
          + protected Process getServerProcess()

          { + return this.process; + }

          +
          + protected void startServerShouldFail(final ServerCommand command, final InputListener outListener,
          + final InputListener errListener) throws IOException, InterruptedException

          { + executeCommandWithReaders(command.create(), outListener, errListener); + process.waitFor(2, MINUTES); + assertThat(process.isAlive()).isFalse(); + assertThat(process.exitValue()).isEqualTo(1); + }

          +
          + protected void startServerShouldFail(final ServerCommand command)
          + throws IOException, InterruptedException

          { + startServerShouldFail(command, createBindExceptionListener("sysout", threwBindException), + createBindExceptionListener("syserr", threwBindException)); + }

          +
          + protected void startServerShouldFail() throws IOException, InterruptedException

          { + startServerShouldFail(serverCommand); + }

          +
          + private InputListener createBindExceptionListener(final String name,
          + final AtomicBoolean threwBindException)

          { + return createExpectedListener(name, getUniqueName() + "#" + name, BindException.class.getName(), + threwBindException); + }

          +
          + @Override
          + protected ServerLauncher startServer()

          { + return startServer(serverCommand); + }

          +
          + protected void assertThatProcessIsNotAlive() {
          — End diff –

          All unused methods deleted.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132542169 — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java — @@ -0,0 +1,270 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX; +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.net.BindException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.After; +import org.junit.Before; + +import org.apache.geode.distributed.AbstractLauncher.Status; +import org.apache.geode.internal.process.ProcessStreamReader; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; + +/** + * Abstract base class for integration tests of {@link ServerLauncher} as an application main in a + * forked JVM. + * + * @since GemFire 8.0 + */ +public abstract class ServerLauncherRemoteIntegrationTestCase + extends ServerLauncherIntegrationTestCase implements UsesServerCommand { + + private final AtomicBoolean threwBindException = new AtomicBoolean(); + + protected volatile Process process; + protected volatile ProcessStreamReader processOutReader; + protected volatile ProcessStreamReader processErrReader; + + private ServerCommand serverCommand; + + @Before + public void setUp() throws Exception { + serverCommand = new ServerCommand(this); + } + + @After + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception { + if (this.process != null) { + this.process.destroy(); + this.process = null; + } + if (this.processOutReader != null && this.processOutReader.isRunning()) { + this.processOutReader.stop(); + } + if (this.processErrReader != null && this.processErrReader.isRunning()) { + this.processErrReader.stop(); + } + } + + @Override + public List<String> getJvmArguments() { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + } + + @Override + public String getName() { + return getUniqueName(); + } + + @Override + public boolean getDisableDefaultServer() { + return false; + } + + protected void assertThatServerThrewBindException() { + assertThat(threwBindException.get()).isTrue(); + } + + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + } + + protected ServerLauncher startServer(final ServerCommand command) { + return awaitStart(command); + } + + protected ServerLauncher awaitStart(final ServerCommand command, + final ProcessStreamReader.InputListener outListener, + final ProcessStreamReader.InputListener errListener) throws Exception { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart(final ServerCommand command) { + try { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + protected ServerLauncher awaitStart(final File workingDirectory) { + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Override + protected ServerLauncher awaitStart(final ServerLauncher launcher) { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart() { + return awaitStart(this.launcher); + } + + protected void awaitStop() { + await().until(() -> assertThat(this.process.isAlive()).isFalse()); + } + + protected void assertStopOf(final Process process) { + await().until(() -> assertThat(process.isAlive()).isFalse()); + } + + protected Process getServerProcess() { + return this.process; + } + + protected void startServerShouldFail(final ServerCommand command, final InputListener outListener, + final InputListener errListener) throws IOException, InterruptedException { + executeCommandWithReaders(command.create(), outListener, errListener); + process.waitFor(2, MINUTES); + assertThat(process.isAlive()).isFalse(); + assertThat(process.exitValue()).isEqualTo(1); + } + + protected void startServerShouldFail(final ServerCommand command) + throws IOException, InterruptedException { + startServerShouldFail(command, createBindExceptionListener("sysout", threwBindException), + createBindExceptionListener("syserr", threwBindException)); + } + + protected void startServerShouldFail() throws IOException, InterruptedException { + startServerShouldFail(serverCommand); + } + + private InputListener createBindExceptionListener(final String name, + final AtomicBoolean threwBindException) { + return createExpectedListener(name, getUniqueName() + "#" + name, BindException.class.getName(), + threwBindException); + } + + @Override + protected ServerLauncher startServer() { + return startServer(serverCommand); + } + + protected void assertThatProcessIsNotAlive() { — End diff – All unused methods deleted.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132542184

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java —
          @@ -0,0 +1,270 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX;
          +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +
          +import java.io.File;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.net.BindException;
          +import java.util.ArrayList;
          +import java.util.List;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.junit.After;
          +import org.junit.Before;
          +
          +import org.apache.geode.distributed.AbstractLauncher.Status;
          +import org.apache.geode.internal.process.ProcessStreamReader;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +
          +/**
          + * Abstract base class for integration tests of

          {@link ServerLauncher}

          as an application main in a
          + * forked JVM.
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class ServerLauncherRemoteIntegrationTestCase
          + extends ServerLauncherIntegrationTestCase implements UsesServerCommand {
          +
          + private final AtomicBoolean threwBindException = new AtomicBoolean();
          +
          + protected volatile Process process;
          + protected volatile ProcessStreamReader processOutReader;
          + protected volatile ProcessStreamReader processErrReader;
          +
          + private ServerCommand serverCommand;
          +
          + @Before
          + public void setUp() throws Exception

          { + serverCommand = new ServerCommand(this); + }

          +
          + @After
          + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception {
          + if (this.process != null)

          { + this.process.destroy(); + this.process = null; + }

          + if (this.processOutReader != null && this.processOutReader.isRunning())

          { + this.processOutReader.stop(); + }

          + if (this.processErrReader != null && this.processErrReader.isRunning())

          { + this.processErrReader.stop(); + }

          + }
          +
          + @Override
          + public List<String> getJvmArguments()

          { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + }

          +
          + @Override
          + public String getName()

          { + return getUniqueName(); + }

          +
          + @Override
          + public boolean getDisableDefaultServer()

          { + return false; + }

          +
          + protected void assertThatServerThrewBindException()

          { + assertThat(threwBindException.get()).isTrue(); + }
          +
          + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + }

          +
          + protected ServerLauncher startServer(final ServerCommand command)

          { + return awaitStart(command); + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command,
          + final ProcessStreamReader.InputListener outListener,
          + final ProcessStreamReader.InputListener errListener) throws Exception

          { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command) {
          + try

          { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          catch (IOException e)

          { + throw new UncheckedIOException(e); + }
          + }
          +
          + protected ServerLauncher awaitStart(final File workingDirectory) {
          + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + }

          + }
          +
          + @Override
          + protected ServerLauncher awaitStart(final ServerLauncher launcher)

          { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart()

          { + return awaitStart(this.launcher); + }

          +
          + protected void awaitStop()

          { + await().until(() -> assertThat(this.process.isAlive()).isFalse()); + }

          +
          + protected void assertStopOf(final Process process)

          { + await().until(() -> assertThat(process.isAlive()).isFalse()); + }

          +
          + protected Process getServerProcess()

          { + return this.process; + }

          +
          + protected void startServerShouldFail(final ServerCommand command, final InputListener outListener,
          + final InputListener errListener) throws IOException, InterruptedException

          { + executeCommandWithReaders(command.create(), outListener, errListener); + process.waitFor(2, MINUTES); + assertThat(process.isAlive()).isFalse(); + assertThat(process.exitValue()).isEqualTo(1); + }

          +
          + protected void startServerShouldFail(final ServerCommand command)
          + throws IOException, InterruptedException

          { + startServerShouldFail(command, createBindExceptionListener("sysout", threwBindException), + createBindExceptionListener("syserr", threwBindException)); + }

          +
          + protected void startServerShouldFail() throws IOException, InterruptedException

          { + startServerShouldFail(serverCommand); + }

          +
          + private InputListener createBindExceptionListener(final String name,
          + final AtomicBoolean threwBindException)

          { + return createExpectedListener(name, getUniqueName() + "#" + name, BindException.class.getName(), + threwBindException); + }

          +
          + @Override
          + protected ServerLauncher startServer()

          { + return startServer(serverCommand); + }

          +
          + protected void assertThatProcessIsNotAlive()

          { + assertThatProcessIsNotAlive(process); + }

          +
          + protected void assertThatProcessIsNotAlive(final Process process)

          { + assertThat(process.isAlive()).isFalse(); + }

          +
          + protected void assertProcessIsNotAlive() {
          — End diff –

          All unused methods deleted.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132542184 — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java — @@ -0,0 +1,270 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX; +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.net.BindException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.After; +import org.junit.Before; + +import org.apache.geode.distributed.AbstractLauncher.Status; +import org.apache.geode.internal.process.ProcessStreamReader; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; + +/** + * Abstract base class for integration tests of {@link ServerLauncher} as an application main in a + * forked JVM. + * + * @since GemFire 8.0 + */ +public abstract class ServerLauncherRemoteIntegrationTestCase + extends ServerLauncherIntegrationTestCase implements UsesServerCommand { + + private final AtomicBoolean threwBindException = new AtomicBoolean(); + + protected volatile Process process; + protected volatile ProcessStreamReader processOutReader; + protected volatile ProcessStreamReader processErrReader; + + private ServerCommand serverCommand; + + @Before + public void setUp() throws Exception { + serverCommand = new ServerCommand(this); + } + + @After + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception { + if (this.process != null) { + this.process.destroy(); + this.process = null; + } + if (this.processOutReader != null && this.processOutReader.isRunning()) { + this.processOutReader.stop(); + } + if (this.processErrReader != null && this.processErrReader.isRunning()) { + this.processErrReader.stop(); + } + } + + @Override + public List<String> getJvmArguments() { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + } + + @Override + public String getName() { + return getUniqueName(); + } + + @Override + public boolean getDisableDefaultServer() { + return false; + } + + protected void assertThatServerThrewBindException() { + assertThat(threwBindException.get()).isTrue(); + } + + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + } + + protected ServerLauncher startServer(final ServerCommand command) { + return awaitStart(command); + } + + protected ServerLauncher awaitStart(final ServerCommand command, + final ProcessStreamReader.InputListener outListener, + final ProcessStreamReader.InputListener errListener) throws Exception { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart(final ServerCommand command) { + try { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + protected ServerLauncher awaitStart(final File workingDirectory) { + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Override + protected ServerLauncher awaitStart(final ServerLauncher launcher) { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart() { + return awaitStart(this.launcher); + } + + protected void awaitStop() { + await().until(() -> assertThat(this.process.isAlive()).isFalse()); + } + + protected void assertStopOf(final Process process) { + await().until(() -> assertThat(process.isAlive()).isFalse()); + } + + protected Process getServerProcess() { + return this.process; + } + + protected void startServerShouldFail(final ServerCommand command, final InputListener outListener, + final InputListener errListener) throws IOException, InterruptedException { + executeCommandWithReaders(command.create(), outListener, errListener); + process.waitFor(2, MINUTES); + assertThat(process.isAlive()).isFalse(); + assertThat(process.exitValue()).isEqualTo(1); + } + + protected void startServerShouldFail(final ServerCommand command) + throws IOException, InterruptedException { + startServerShouldFail(command, createBindExceptionListener("sysout", threwBindException), + createBindExceptionListener("syserr", threwBindException)); + } + + protected void startServerShouldFail() throws IOException, InterruptedException { + startServerShouldFail(serverCommand); + } + + private InputListener createBindExceptionListener(final String name, + final AtomicBoolean threwBindException) { + return createExpectedListener(name, getUniqueName() + "#" + name, BindException.class.getName(), + threwBindException); + } + + @Override + protected ServerLauncher startServer() { + return startServer(serverCommand); + } + + protected void assertThatProcessIsNotAlive() { + assertThatProcessIsNotAlive(process); + } + + protected void assertThatProcessIsNotAlive(final Process process) { + assertThat(process.isAlive()).isFalse(); + } + + protected void assertProcessIsNotAlive() { — End diff – All unused methods deleted.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132542204

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java —
          @@ -0,0 +1,270 @@
          +/*
          + * 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.geode.distributed;
          +
          +import static java.util.concurrent.TimeUnit.MINUTES;
          +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX;
          +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +
          +import java.io.File;
          +import java.io.IOException;
          +import java.io.UncheckedIOException;
          +import java.net.BindException;
          +import java.util.ArrayList;
          +import java.util.List;
          +import java.util.concurrent.atomic.AtomicBoolean;
          +
          +import org.junit.After;
          +import org.junit.Before;
          +
          +import org.apache.geode.distributed.AbstractLauncher.Status;
          +import org.apache.geode.internal.process.ProcessStreamReader;
          +import org.apache.geode.internal.process.ProcessStreamReader.InputListener;
          +
          +/**
          + * Abstract base class for integration tests of

          {@link ServerLauncher}

          as an application main in a
          + * forked JVM.
          + *
          + * @since GemFire 8.0
          + */
          +public abstract class ServerLauncherRemoteIntegrationTestCase
          + extends ServerLauncherIntegrationTestCase implements UsesServerCommand {
          +
          + private final AtomicBoolean threwBindException = new AtomicBoolean();
          +
          + protected volatile Process process;
          + protected volatile ProcessStreamReader processOutReader;
          + protected volatile ProcessStreamReader processErrReader;
          +
          + private ServerCommand serverCommand;
          +
          + @Before
          + public void setUp() throws Exception

          { + serverCommand = new ServerCommand(this); + }

          +
          + @After
          + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception {
          + if (this.process != null)

          { + this.process.destroy(); + this.process = null; + }

          + if (this.processOutReader != null && this.processOutReader.isRunning())

          { + this.processOutReader.stop(); + }

          + if (this.processErrReader != null && this.processErrReader.isRunning())

          { + this.processErrReader.stop(); + }

          + }
          +
          + @Override
          + public List<String> getJvmArguments()

          { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + }

          +
          + @Override
          + public String getName()

          { + return getUniqueName(); + }

          +
          + @Override
          + public boolean getDisableDefaultServer()

          { + return false; + }

          +
          + protected void assertThatServerThrewBindException()

          { + assertThat(threwBindException.get()).isTrue(); + }
          +
          + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + }

          +
          + protected ServerLauncher startServer(final ServerCommand command)

          { + return awaitStart(command); + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command,
          + final ProcessStreamReader.InputListener outListener,
          + final ProcessStreamReader.InputListener errListener) throws Exception

          { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart(final ServerCommand command) {
          + try

          { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          catch (IOException e)

          { + throw new UncheckedIOException(e); + }
          + }
          +
          + protected ServerLauncher awaitStart(final File workingDirectory) {
          + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + }

          + }
          +
          + @Override
          + protected ServerLauncher awaitStart(final ServerLauncher launcher)

          { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + }

          +
          + protected ServerLauncher awaitStart()

          { + return awaitStart(this.launcher); + }

          +
          + protected void awaitStop()

          { + await().until(() -> assertThat(this.process.isAlive()).isFalse()); + }

          +
          + protected void assertStopOf(final Process process)

          { + await().until(() -> assertThat(process.isAlive()).isFalse()); + }

          +
          + protected Process getServerProcess()

          { + return this.process; + }

          +
          + protected void startServerShouldFail(final ServerCommand command, final InputListener outListener,
          + final InputListener errListener) throws IOException, InterruptedException

          { + executeCommandWithReaders(command.create(), outListener, errListener); + process.waitFor(2, MINUTES); + assertThat(process.isAlive()).isFalse(); + assertThat(process.exitValue()).isEqualTo(1); + }

          +
          + protected void startServerShouldFail(final ServerCommand command)
          + throws IOException, InterruptedException

          { + startServerShouldFail(command, createBindExceptionListener("sysout", threwBindException), + createBindExceptionListener("syserr", threwBindException)); + }

          +
          + protected void startServerShouldFail() throws IOException, InterruptedException

          { + startServerShouldFail(serverCommand); + }

          +
          + private InputListener createBindExceptionListener(final String name,
          + final AtomicBoolean threwBindException)

          { + return createExpectedListener(name, getUniqueName() + "#" + name, BindException.class.getName(), + threwBindException); + }

          +
          + @Override
          + protected ServerLauncher startServer()

          { + return startServer(serverCommand); + }

          +
          + protected void assertThatProcessIsNotAlive()

          { + assertThatProcessIsNotAlive(process); + }

          +
          + protected void assertThatProcessIsNotAlive(final Process process)

          { + assertThat(process.isAlive()).isFalse(); + }
          +
          + protected void assertProcessIsNotAlive() { + assertThat(process.isAlive()).isFalse(); + }

          +
          + protected void assertProcessIsAlive() {
          — End diff –

          All unused methods deleted.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132542204 — Diff: geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherRemoteIntegrationTestCase.java — @@ -0,0 +1,270 @@ +/* + * 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.geode.distributed; + +import static java.util.concurrent.TimeUnit.MINUTES; +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.distributed.internal.DistributionConfig.GEMFIRE_PREFIX; +import static org.apache.geode.internal.cache.AbstractCacheServer.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.net.BindException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.After; +import org.junit.Before; + +import org.apache.geode.distributed.AbstractLauncher.Status; +import org.apache.geode.internal.process.ProcessStreamReader; +import org.apache.geode.internal.process.ProcessStreamReader.InputListener; + +/** + * Abstract base class for integration tests of {@link ServerLauncher} as an application main in a + * forked JVM. + * + * @since GemFire 8.0 + */ +public abstract class ServerLauncherRemoteIntegrationTestCase + extends ServerLauncherIntegrationTestCase implements UsesServerCommand { + + private final AtomicBoolean threwBindException = new AtomicBoolean(); + + protected volatile Process process; + protected volatile ProcessStreamReader processOutReader; + protected volatile ProcessStreamReader processErrReader; + + private ServerCommand serverCommand; + + @Before + public void setUp() throws Exception { + serverCommand = new ServerCommand(this); + } + + @After + public void tearDownAbstractServerLauncherRemoteIntegrationTestCase() throws Exception { + if (this.process != null) { + this.process.destroy(); + this.process = null; + } + if (this.processOutReader != null && this.processOutReader.isRunning()) { + this.processOutReader.stop(); + } + if (this.processErrReader != null && this.processErrReader.isRunning()) { + this.processErrReader.stop(); + } + } + + @Override + public List<String> getJvmArguments() { + List<String> jvmArguments = new ArrayList<>(); + jvmArguments.add("-D" + GEMFIRE_PREFIX + LOG_LEVEL + "=config"); + jvmArguments.add("-D" + GEMFIRE_PREFIX + MCAST_PORT + "=0"); + jvmArguments + .add("-D" + TEST_OVERRIDE_DEFAULT_PORT_PROPERTY + "=" + String.valueOf(defaultServerPort)); + return jvmArguments; + } + + @Override + public String getName() { + return getUniqueName(); + } + + @Override + public boolean getDisableDefaultServer() { + return false; + } + + protected void assertThatServerThrewBindException() { + assertThat(threwBindException.get()).isTrue(); + } + + protected void assertThatServerThrew(final Class<? extends Throwable> throwableClass) { + assertThat(threwBindException.get()).isTrue(); + } + + protected ServerLauncher startServer(final ServerCommand command) { + return awaitStart(command); + } + + protected ServerLauncher awaitStart(final ServerCommand command, + final ProcessStreamReader.InputListener outListener, + final ProcessStreamReader.InputListener errListener) throws Exception { + executeCommandWithReaders(command.create(), outListener, errListener); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart(final ServerCommand command) { + try { + executeCommandWithReaders(command); + ServerLauncher launcher = awaitStart(getWorkingDirectory()); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + protected ServerLauncher awaitStart(final File workingDirectory) { + try { + this.launcher = new ServerLauncher.Builder() + .setWorkingDirectory(workingDirectory.getCanonicalPath()).build(); + ServerLauncher launcher = awaitStart(this.launcher); + assertThat(process.isAlive()).isTrue(); + return launcher; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Override + protected ServerLauncher awaitStart(final ServerLauncher launcher) { + await().until(() -> assertThat(launcher.status().getStatus()).isEqualTo(Status.ONLINE)); + assertThat(process.isAlive()).isTrue(); + return launcher; + } + + protected ServerLauncher awaitStart() { + return awaitStart(this.launcher); + } + + protected void awaitStop() { + await().until(() -> assertThat(this.process.isAlive()).isFalse()); + } + + protected void assertStopOf(final Process process) { + await().until(() -> assertThat(process.isAlive()).isFalse()); + } + + protected Process getServerProcess() { + return this.process; + } + + protected void startServerShouldFail(final ServerCommand command, final InputListener outListener, + final InputListener errListener) throws IOException, InterruptedException { + executeCommandWithReaders(command.create(), outListener, errListener); + process.waitFor(2, MINUTES); + assertThat(process.isAlive()).isFalse(); + assertThat(process.exitValue()).isEqualTo(1); + } + + protected void startServerShouldFail(final ServerCommand command) + throws IOException, InterruptedException { + startServerShouldFail(command, createBindExceptionListener("sysout", threwBindException), + createBindExceptionListener("syserr", threwBindException)); + } + + protected void startServerShouldFail() throws IOException, InterruptedException { + startServerShouldFail(serverCommand); + } + + private InputListener createBindExceptionListener(final String name, + final AtomicBoolean threwBindException) { + return createExpectedListener(name, getUniqueName() + "#" + name, BindException.class.getName(), + threwBindException); + } + + @Override + protected ServerLauncher startServer() { + return startServer(serverCommand); + } + + protected void assertThatProcessIsNotAlive() { + assertThatProcessIsNotAlive(process); + } + + protected void assertThatProcessIsNotAlive(final Process process) { + assertThat(process.isAlive()).isFalse(); + } + + protected void assertProcessIsNotAlive() { + assertThat(process.isAlive()).isFalse(); + } + + protected void assertProcessIsAlive() { — End diff – All unused methods deleted.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132542242

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java —
          @@ -1075,8 +1082,7 @@ private LocatorState stopWithWorkingDirectory() {
          try {
          final ProcessController controller =
          new ProcessControllerFactory().createProcessController(this.controllerParameters,

          • new File(getWorkingDirectory()), ProcessType.LOCATOR.getPidFileName(),
          • READ_PID_FILE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
            + new File(getWorkingDirectory()), ProcessType.LOCATOR.getPidFileName());
            parsedPid = controller.getProcessId();

          // NOTE in-process request will go infinite loop unless we do the following
          — End diff –

          Done.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132542242 — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java — @@ -1075,8 +1082,7 @@ private LocatorState stopWithWorkingDirectory() { try { final ProcessController controller = new ProcessControllerFactory().createProcessController(this.controllerParameters, new File(getWorkingDirectory()), ProcessType.LOCATOR.getPidFileName(), READ_PID_FILE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); + new File(getWorkingDirectory()), ProcessType.LOCATOR.getPidFileName()); parsedPid = controller.getProcessId(); // NOTE in-process request will go infinite loop unless we do the following — End diff – Done.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on the issue:

          https://github.com/apache/geode/pull/699

          These tests have also now been overhauled or rewritten:

          • LauncherMemberMXBeanIntegrationTest
          • ServerLauncherWaitOnServerMultiThreadedTest
          • ServerLauncherWithProviderIntegrationTest -> ServerLauncherWithProviderRegressionTest
          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on the issue: https://github.com/apache/geode/pull/699 These tests have also now been overhauled or rewritten: LauncherMemberMXBeanIntegrationTest ServerLauncherWaitOnServerMultiThreadedTest ServerLauncherWithProviderIntegrationTest -> ServerLauncherWithProviderRegressionTest
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132545900

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/ServerLauncher.java —
          @@ -810,9 +819,6 @@ public void setStatus(final String statusMessage)

          { LocalizedStrings.Launcher_Command_START_PID_UNAVAILABLE_ERROR_MESSAGE.toLocalizedString( getServiceName(), getId(), getWorkingDirectory(), e.getMessage()), e); - }

          catch (ClusterConfigurationNotAvailableException e)

          { - failOnStart(e); - throw e; }

          catch (RuntimeException e) {
          failOnStart(e);
          — End diff –

          Combined.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132545900 — Diff: geode-core/src/main/java/org/apache/geode/distributed/ServerLauncher.java — @@ -810,9 +819,6 @@ public void setStatus(final String statusMessage) { LocalizedStrings.Launcher_Command_START_PID_UNAVAILABLE_ERROR_MESSAGE.toLocalizedString( getServiceName(), getId(), getWorkingDirectory(), e.getMessage()), e); - } catch (ClusterConfigurationNotAvailableException e) { - failOnStart(e); - throw e; } catch (RuntimeException e) { failOnStart(e); — End diff – Combined.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user jaredjstewart commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132585334

          — Diff: geode-core/src/main/java/org/apache/geode/internal/process/LocalProcessLauncher.java —
          @@ -96,33 +117,55 @@ void close() {

          • @throws IOException if unable to create or write to the file
            */
            private void writePid(final boolean force) throws FileAlreadyExistsException, IOException {
          • final boolean created = this.pidFile.createNewFile();
          • if (!created && !force) {
          • int otherPid = 0;
          • try { - otherPid = ProcessUtils.readPid(this.pidFile); - }

            catch (IOException e)

            { - // suppress - } catch (NumberFormatException e) { - // suppress - }
          • boolean ignorePidFile = false;
          • if (otherPid != 0 && !ignoreIsPidAlive()) { - ignorePidFile = !ProcessUtils.isProcessAlive(otherPid); - }
          • if (!ignorePidFile) {
          • throw new FileAlreadyExistsException("Pid file already exists: " + this.pidFile + " for "
          • + (otherPid > 0 ? "process " + otherPid : "unknown process"));
            + if (this.pidFile.exists())
            Unknown macro: { + if (!force) { + checkOtherPid(readOtherPid()); } + this.pidFile.delete(); + }

            +
            + assert !this.pidFile.exists();

              • End diff –

          I saw that you used Apache common's `Validate` class in other places. Would that be good to use here since the default java `assert` won't do anything under normal circumstances?

          Show
          githubbot ASF GitHub Bot added a comment - Github user jaredjstewart commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132585334 — Diff: geode-core/src/main/java/org/apache/geode/internal/process/LocalProcessLauncher.java — @@ -96,33 +117,55 @@ void close() { @throws IOException if unable to create or write to the file */ private void writePid(final boolean force) throws FileAlreadyExistsException, IOException { final boolean created = this.pidFile.createNewFile(); if (!created && !force) { int otherPid = 0; try { - otherPid = ProcessUtils.readPid(this.pidFile); - } catch (IOException e) { - // suppress - } catch (NumberFormatException e) { - // suppress - } boolean ignorePidFile = false; if (otherPid != 0 && !ignoreIsPidAlive()) { - ignorePidFile = !ProcessUtils.isProcessAlive(otherPid); - } if (!ignorePidFile) { throw new FileAlreadyExistsException("Pid file already exists: " + this.pidFile + " for " + (otherPid > 0 ? "process " + otherPid : "unknown process")); + if (this.pidFile.exists()) Unknown macro: { + if (!force) { + checkOtherPid(readOtherPid()); } + this.pidFile.delete(); + } + + assert !this.pidFile.exists(); End diff – I saw that you used Apache common's `Validate` class in other places. Would that be good to use here since the default java `assert` won't do anything under normal circumstances?
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user jaredjstewart commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132585045

          — Diff: geode-core/src/main/java/org/apache/geode/internal/process/FileProcessController.java —
          @@ -112,56 +119,43 @@ private void stop(final File workingDir, final String stopRequestFileName) throw
          private String status(final File workingDir, final String statusRequestFileName,
          final String statusFileName) throws IOException, InterruptedException, TimeoutException {
          // monitor for statusFile

          • final File statusFile = new File(workingDir, statusFileName);
          • final AtomicReference<String> statusRef = new AtomicReference<>();
            -
          • final ControlRequestHandler statusHandler = new ControlRequestHandler() {
          • @Override
          • public void handleRequest() throws IOException {
          • // read the statusFile
          • final BufferedReader reader = new BufferedReader(new FileReader(statusFile));
          • final StringBuilder lines = new StringBuilder();
          • try {
          • String line = null;
          • while ((line = reader.readLine()) != null) { - lines.append(line); - }
          • } finally {
          • statusRef.set(lines.toString());
          • reader.close();
            + File statusFile = new File(workingDir, statusFileName);
            + AtomicReference<String> statusRef = new AtomicReference<>();
            +
            + ControlRequestHandler statusHandler = () -> {
              • End diff –

          This might be a nice simplification:

          ```
          ControlRequestHandler statusHandler = () -> {
          // read the statusFile
          StringBuilder lines = new StringBuilder();
          try (BufferedReader reader = new BufferedReader(new FileReader(statusFile)))

          { reader.lines().forEach(lines::append); }

          finally

          { statusRef.set(lines.toString()); }

          };
          ```

          Show
          githubbot ASF GitHub Bot added a comment - Github user jaredjstewart commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132585045 — Diff: geode-core/src/main/java/org/apache/geode/internal/process/FileProcessController.java — @@ -112,56 +119,43 @@ private void stop(final File workingDir, final String stopRequestFileName) throw private String status(final File workingDir, final String statusRequestFileName, final String statusFileName) throws IOException, InterruptedException, TimeoutException { // monitor for statusFile final File statusFile = new File(workingDir, statusFileName); final AtomicReference<String> statusRef = new AtomicReference<>(); - final ControlRequestHandler statusHandler = new ControlRequestHandler() { @Override public void handleRequest() throws IOException { // read the statusFile final BufferedReader reader = new BufferedReader(new FileReader(statusFile)); final StringBuilder lines = new StringBuilder(); try { String line = null; while ((line = reader.readLine()) != null) { - lines.append(line); - } } finally { statusRef.set(lines.toString()); reader.close(); + File statusFile = new File(workingDir, statusFileName); + AtomicReference<String> statusRef = new AtomicReference<>(); + + ControlRequestHandler statusHandler = () -> { End diff – This might be a nice simplification: ``` ControlRequestHandler statusHandler = () -> { // read the statusFile StringBuilder lines = new StringBuilder(); try (BufferedReader reader = new BufferedReader(new FileReader(statusFile))) { reader.lines().forEach(lines::append); } finally { statusRef.set(lines.toString()); } }; ```
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user jaredjstewart commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132570355

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java —
          @@ -104,6 +109,8 @@
          helpMap.put("bind-address",
          — End diff –

          Since this class is rather large, maybe in the future we can extract the `helpMap` and `usageMap` to a separate class like `LocatorLauncherHelp` whose single responsibility is to provide the help and usage information.

          Show
          githubbot ASF GitHub Bot added a comment - Github user jaredjstewart commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132570355 — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java — @@ -104,6 +109,8 @@ helpMap.put("bind-address", — End diff – Since this class is rather large, maybe in the future we can extract the `helpMap` and `usageMap` to a separate class like `LocatorLauncherHelp` whose single responsibility is to provide the help and usage information.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user jaredjstewart commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132562988

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/AbstractLauncher.java —
          @@ -795,25 +785,25 @@ protected String toString(final Date dateTime) {

          // the value of a Number as a String, or "" if null
          protected String toString(final Number value)

          { - return StringUtils.defaultString(value); + return defaultString(value); }

          // a String concatenation of all values separated by " "
          protected String toString(final Object... values)

          { - return values == null ? "" : StringUtils.join(values, " "); + return values == null ? "" : join(values, " "); }

          // the value of the String, or "" if value is null
          protected String toString(final String value)

          { - return ObjectUtils.defaultIfNull(value, ""); + return defaultIfNull(value, ""); }

          }

          /**

          • The Status enumerated type represents the various lifecycle states of a GemFire service (such
          • as a Cache Server, a Locator or a Manager).
            */
          • public static enum Status {
              • End diff –

          What is the motivation for removing static here? I believe Effective Java advocates for favoring static member classes over non-static.

          Show
          githubbot ASF GitHub Bot added a comment - Github user jaredjstewart commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132562988 — Diff: geode-core/src/main/java/org/apache/geode/distributed/AbstractLauncher.java — @@ -795,25 +785,25 @@ protected String toString(final Date dateTime) { // the value of a Number as a String, or "" if null protected String toString(final Number value) { - return StringUtils.defaultString(value); + return defaultString(value); } // a String concatenation of all values separated by " " protected String toString(final Object... values) { - return values == null ? "" : StringUtils.join(values, " "); + return values == null ? "" : join(values, " "); } // the value of the String, or "" if value is null protected String toString(final String value) { - return ObjectUtils.defaultIfNull(value, ""); + return defaultIfNull(value, ""); } } /** The Status enumerated type represents the various lifecycle states of a GemFire service (such as a Cache Server, a Locator or a Manager). */ public static enum Status { End diff – What is the motivation for removing static here? I believe Effective Java advocates for favoring static member classes over non-static.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user jaredjstewart commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132572256

          — Diff: geode-core/src/main/java/org/apache/geode/internal/process/AttachProcessUtils.java —
          @@ -14,21 +14,28 @@
          */
          package org.apache.geode.internal.process;

          -import org.apache.geode.internal.process.ProcessUtils.InternalProcessUtils;
          +import static org.apache.commons.lang.Validate.isTrue;
          +
          import com.sun.tools.attach.VirtualMachine;
          import com.sun.tools.attach.VirtualMachineDescriptor;

          +import org.apache.geode.internal.process.ProcessUtils.InternalProcessUtils;
          +
          /**

          • Implementation of the {@link ProcessUtils}

            SPI that uses the JDK Attach API.

          • @since GemFire 8.0
            */
            class AttachProcessUtils implements InternalProcessUtils {
          • AttachProcessUtils() {}
            + AttachProcessUtils() {
              • End diff –

          Is there any reason to include this constructor at all?

          Show
          githubbot ASF GitHub Bot added a comment - Github user jaredjstewart commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132572256 — Diff: geode-core/src/main/java/org/apache/geode/internal/process/AttachProcessUtils.java — @@ -14,21 +14,28 @@ */ package org.apache.geode.internal.process; -import org.apache.geode.internal.process.ProcessUtils.InternalProcessUtils; +import static org.apache.commons.lang.Validate.isTrue; + import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.VirtualMachineDescriptor; +import org.apache.geode.internal.process.ProcessUtils.InternalProcessUtils; + /** Implementation of the {@link ProcessUtils} SPI that uses the JDK Attach API. @since GemFire 8.0 */ class AttachProcessUtils implements InternalProcessUtils { AttachProcessUtils() {} + AttachProcessUtils() { End diff – Is there any reason to include this constructor at all?
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user jaredjstewart commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132569537

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java —
          @@ -1781,8 +1782,8 @@ protected void validate() {

          • @see org.apache.geode.distributed.LocatorLauncher.Command#START
            */
            protected void validateOnStart() {
          • if (Command.START.equals(getCommand())) {
          • if (StringUtils.isBlank(getMemberName())
            + if (Command.START == getCommand()) {
              • End diff –

          Cool, I didn't know that `==` could be used safely for enums.

          Show
          githubbot ASF GitHub Bot added a comment - Github user jaredjstewart commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132569537 — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java — @@ -1781,8 +1782,8 @@ protected void validate() { @see org.apache.geode.distributed.LocatorLauncher.Command#START */ protected void validateOnStart() { if (Command.START.equals(getCommand())) { if (StringUtils.isBlank(getMemberName()) + if (Command.START == getCommand()) { End diff – Cool, I didn't know that `==` could be used safely for enums.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user jaredjstewart commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132571788

          — Diff: geode-core/src/main/java/org/apache/geode/internal/config/ClusterConfigurationNotAvailableException.java —
          @@ -0,0 +1,29 @@
          +/*
          + * 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.geode.internal.config;
          +
          +/**
          + * Exception thrown during server startup when it requests the locators for shared configuration and
          + * does not receive it.
          + */
          +public class ClusterConfigurationNotAvailableException
          + extends org.apache.geode.internal.process.ClusterConfigurationNotAvailableException {
          +
          + private static final long serialVersionUID = 771319836094239284L;
          — End diff –

          Since this is a new class and there is no need to worry about backwards compatibility with an autogenerated `serialVersionUID`, I think you can just use `0L`.

          Show
          githubbot ASF GitHub Bot added a comment - Github user jaredjstewart commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132571788 — Diff: geode-core/src/main/java/org/apache/geode/internal/config/ClusterConfigurationNotAvailableException.java — @@ -0,0 +1,29 @@ +/* + * 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.geode.internal.config; + +/** + * Exception thrown during server startup when it requests the locators for shared configuration and + * does not receive it. + */ +public class ClusterConfigurationNotAvailableException + extends org.apache.geode.internal.process.ClusterConfigurationNotAvailableException { + + private static final long serialVersionUID = 771319836094239284L; — End diff – Since this is a new class and there is no need to worry about backwards compatibility with an autogenerated `serialVersionUID`, I think you can just use `0L`.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user jaredjstewart commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132568184

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java —
          @@ -1352,11 +1328,13 @@ protected void parseCommand(final String... args) {

          • @see org.apache.geode.distributed.LocatorLauncher.Command#isCommand(String)
          • @see #parseArguments(String...)
            */
          • protected void parseMemberName(final String[] args) {
          • for (String arg : args) {
          • if (!(arg.startsWith(OPTION_PREFIX) || Command.isCommand(arg))) {
          • setMemberName(arg);
          • break;
            + protected void parseMemberName(final String... args) {
            + if (args != null) {
            + for (String arg : args) {
            + if (!(arg.startsWith(OPTION_PREFIX) || Command.isCommand(arg))) {
              • End diff –

          I believe the behavior of this method may contradicts its javadoc, which says that
          > If the argument does *not* start with '-' or is *not* the name of a Locator launcher command, then the value is presumed to be the member name for the Locator in GemFire.

          Whereas the actual implementation seems to find values which *are* the name of a Locator launcher command. I would guess that the javadoc is correct about the intended behavior.
          <hr>

          P.S. I can't resist writing this in a declarative style with streams
          ```
          protected void parseMemberName(final String... args)

          { if (args == null) return; Arrays.stream(args) .filter(arg -> !(arg.startsWith(OPTION_PREFIX) || Command.isCommand(arg))) .findFirst() .ifPresent(this::setMemberName); }

          ```

          Show
          githubbot ASF GitHub Bot added a comment - Github user jaredjstewart commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132568184 — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java — @@ -1352,11 +1328,13 @@ protected void parseCommand(final String... args) { @see org.apache.geode.distributed.LocatorLauncher.Command#isCommand(String) @see #parseArguments(String...) */ protected void parseMemberName(final String[] args) { for (String arg : args) { if (!(arg.startsWith(OPTION_PREFIX) || Command.isCommand(arg))) { setMemberName(arg); break; + protected void parseMemberName(final String... args) { + if (args != null) { + for (String arg : args) { + if (!(arg.startsWith(OPTION_PREFIX) || Command.isCommand(arg))) { End diff – I believe the behavior of this method may contradicts its javadoc, which says that > If the argument does * not * start with '-' or is * not * the name of a Locator launcher command, then the value is presumed to be the member name for the Locator in GemFire. Whereas the actual implementation seems to find values which * are * the name of a Locator launcher command. I would guess that the javadoc is correct about the intended behavior. <hr> P.S. I can't resist writing this in a declarative style with streams ``` protected void parseMemberName(final String... args) { if (args == null) return; Arrays.stream(args) .filter(arg -> !(arg.startsWith(OPTION_PREFIX) || Command.isCommand(arg))) .findFirst() .ifPresent(this::setMemberName); } ```
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132592102

          — Diff: geode-core/src/test/java/org/apache/geode/internal/process/NonBlockingProcessStreamReaderIntegrationTest.java —
          @@ -0,0 +1,182 @@
          +/*
          + * 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.geode.internal.process;
          +
          +import static org.apache.geode.internal.process.ProcessStreamReader.ReadingMode.NON_BLOCKING;
          +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive;
          +import static org.assertj.core.api.Assertions.assertThat;
          +
          +import org.junit.Before;
          +import org.junit.Test;
          +import org.junit.experimental.categories.Category;
          +
          +import org.apache.geode.internal.process.ProcessStreamReader.Builder;
          +import org.apache.geode.test.junit.categories.IntegrationTest;
          +
          +/**
          + * Functional integration tests for NonBlockingProcessStreamReader which was introduced to fix TRAC
          + * #51967.
          + *
          + * @see BlockingProcessStreamReaderIntegrationTest
          + * @see BlockingProcessStreamReaderWindowsTest
          + *
          + * @since GemFire 8.2
          + */
          +@Category(IntegrationTest.class)
          +public class NonBlockingProcessStreamReaderIntegrationTest
          + extends BaseProcessStreamReaderIntegrationTest {
          +
          + private StringBuffer stdoutBuffer;
          + private StringBuffer stderrBuffer;
          +
          + @Before
          + public void before()

          { + stdoutBuffer = new StringBuffer(); + stderrBuffer = new StringBuffer(); + }

          +
          + /**
          + * This test hangs on Windows if the implementation is blocking instead of non-blocking.
          + */
          + @Test
          + public void canCloseStreamsWhileProcessIsAlive() throws Exception {
          + // arrange
          + process = new ProcessBuilder(createCommandLine(ProcessSleeps.class)).start();
          + stdout = new Builder(process).inputStream(process.getInputStream()).readingMode(NON_BLOCKING)
          + .build().start();
          + stderr = new Builder(process).inputStream(process.getErrorStream()).readingMode(NON_BLOCKING)
          — End diff –

          Done.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132592102 — Diff: geode-core/src/test/java/org/apache/geode/internal/process/NonBlockingProcessStreamReaderIntegrationTest.java — @@ -0,0 +1,182 @@ +/* + * 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.geode.internal.process; + +import static org.apache.geode.internal.process.ProcessStreamReader.ReadingMode.NON_BLOCKING; +import static org.apache.geode.internal.process.ProcessUtils.isProcessAlive; +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import org.apache.geode.internal.process.ProcessStreamReader.Builder; +import org.apache.geode.test.junit.categories.IntegrationTest; + +/** + * Functional integration tests for NonBlockingProcessStreamReader which was introduced to fix TRAC + * #51967. + * + * @see BlockingProcessStreamReaderIntegrationTest + * @see BlockingProcessStreamReaderWindowsTest + * + * @since GemFire 8.2 + */ +@Category(IntegrationTest.class) +public class NonBlockingProcessStreamReaderIntegrationTest + extends BaseProcessStreamReaderIntegrationTest { + + private StringBuffer stdoutBuffer; + private StringBuffer stderrBuffer; + + @Before + public void before() { + stdoutBuffer = new StringBuffer(); + stderrBuffer = new StringBuffer(); + } + + /** + * This test hangs on Windows if the implementation is blocking instead of non-blocking. + */ + @Test + public void canCloseStreamsWhileProcessIsAlive() throws Exception { + // arrange + process = new ProcessBuilder(createCommandLine(ProcessSleeps.class)).start(); + stdout = new Builder(process).inputStream(process.getInputStream()).readingMode(NON_BLOCKING) + .build().start(); + stderr = new Builder(process).inputStream(process.getErrorStream()).readingMode(NON_BLOCKING) — End diff – Done.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132592382

          — Diff: geode-core/src/test/java/org/apache/geode/distributed/LocatorLauncherLocalIntegrationTest.java —
          @@ -14,745 +14,270 @@
          */
          package org.apache.geode.distributed;

          -import org.apache.geode.distributed.AbstractLauncher.Status;
          +import static org.apache.geode.distributed.AbstractLauncher.Status.NOT_RESPONDING;
          +import static org.apache.geode.distributed.AbstractLauncher.Status.ONLINE;
          +import static org.apache.geode.distributed.AbstractLauncher.Status.STOPPED;
          +import static org.apache.geode.distributed.ConfigurationProperties.DISABLE_AUTO_RECONNECT;
          +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL;
          +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
          +import static org.apache.geode.distributed.ConfigurationProperties.NAME;
          +import static org.assertj.core.api.Assertions.assertThat;
          +import static org.assertj.core.api.Assertions.assertThatThrownBy;
          +
          +import java.io.File;
          +import java.net.BindException;
          +import java.net.InetAddress;
          +import java.util.Collections;
          +
          +import org.junit.After;
          +import org.junit.Before;
          +import org.junit.Test;
          +import org.junit.experimental.categories.Category;
          +
          import org.apache.geode.distributed.LocatorLauncher.Builder;
          import org.apache.geode.distributed.LocatorLauncher.LocatorState;
          import org.apache.geode.distributed.internal.InternalLocator;
          -import org.apache.geode.internal.*;
          -import org.apache.geode.internal.net.SocketCreatorFactory;
          +import org.apache.geode.internal.GemFireVersion;
          import org.apache.geode.internal.process.ProcessControllerFactory;
          import org.apache.geode.internal.process.ProcessType;
          -import org.apache.geode.internal.process.ProcessUtils;
          -import org.apache.geode.internal.security.SecurableCommunicationChannel;
          import org.apache.geode.test.junit.categories.IntegrationTest;
          -import org.apache.geode.test.junit.runners.CategoryWithParameterizedRunnerFactory;
          -import org.junit.After;
          -import org.junit.Before;
          -import org.junit.Ignore;
          -import org.junit.Test;
          -import org.junit.experimental.categories.Category;
          -import org.junit.runner.RunWith;
          -import org.junit.runners.Parameterized;
          -
          -import java.io.File;
          -import java.lang.management.ManagementFactory;
          -import java.net.BindException;
          -import java.net.InetAddress;
          -
          -import static org.apache.geode.distributed.ConfigurationProperties.*;
          -import static org.junit.Assert.*;

          /**

          • * Tests usage of LocatorLauncher as a local API in existing JVM.
            + * Integration tests for using {@link LocatorLauncher}

            as an in-process API within an existing JVM.
            *

          • @since GemFire 8.0
            */
            @Category(IntegrationTest.class)
            -@RunWith(Parameterized.class)
            -@Parameterized.UseParametersRunnerFactory(CategoryWithParameterizedRunnerFactory.class)
            -public class LocatorLauncherLocalIntegrationTest
          • extends AbstractLocatorLauncherIntegrationTestCase {
            +public class LocatorLauncherLocalIntegrationTest extends LocatorLauncherIntegrationTestCase {

          @Before

          • public final void setUpLocatorLauncherLocalIntegrationTest() throws Exception {
            + public void setUpLocatorLauncherLocalIntegrationTest() throws Exception { disconnectFromDS(); - System.setProperty(ProcessType.TEST_PREFIX_PROPERTY, getUniqueName() + "-"); + System.setProperty(ProcessType.PROPERTY_TEST_PREFIX, getUniqueName() + "-"); + assertThat(new ProcessControllerFactory().isAttachAPIFound()).isTrue(); }

          @After

          • public final void tearDownLocatorLauncherLocalIntegrationTest() throws Exception {
            + public void tearDownLocatorLauncherLocalIntegrationTest() throws Exception { disconnectFromDS(); }

          @Test

          • public void testBuilderSetProperties() throws Throwable {
          • this.launcher = new Builder().setForce(true).setMemberName(getUniqueName())
          • .setPort(this.locatorPort).setWorkingDirectory(this.workingDirectory)
          • .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory)
          • .set(DISABLE_AUTO_RECONNECT, "true").set(LOG_LEVEL, "config").set(MCAST_PORT, "0").build();
            -
          • try { - assertEquals(Status.ONLINE, this.launcher.start().getStatus()); - waitForLocatorToStart(this.launcher, true); - - final InternalLocator locator = this.launcher.getLocator(); - assertNotNull(locator); - - final DistributedSystem distributedSystem = locator.getDistributedSystem(); - - assertNotNull(distributedSystem); - assertEquals("true", distributedSystem.getProperties().getProperty(DISABLE_AUTO_RECONNECT)); - assertEquals("0", distributedSystem.getProperties().getProperty(MCAST_PORT)); - assertEquals("config", distributedSystem.getProperties().getProperty(LOG_LEVEL)); - assertEquals(getUniqueName(), distributedSystem.getProperties().getProperty(NAME)); - }

            catch (Throwable e)

            { - this.errorCollector.addError(e); - }
            -
            - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - assertNull(this.launcher.getLocator()); - } catch (Throwable e) { - this.errorCollector.addError(e); - }

            + public void usesLocatorPortAsDefaultPort() throws Exception

            { + launcher = givenLocatorLauncher(); + + assertThat(launcher.getPort()).isEqualTo(defaultLocatorPort); }

          @Test

          • public void testIsAttachAPIFound() throws Exception {
          • final ProcessControllerFactory factory = new ProcessControllerFactory();
          • assertTrue(factory.isAttachAPIFound());
            + public void startReturnsOnline() throws Exception { + launcher = givenLocatorLauncher(); + + assertThat(launcher.start().getStatus()).isEqualTo(ONLINE); }

          @Test

          • public void testStartCreatesPidFile() throws Throwable {
          • this.launcher = new Builder().setMemberName(getUniqueName()).setPort(this.locatorPort)
          • .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory)
          • .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config")
          • .build();
            -
          • try { - this.launcher.start(); - waitForLocatorToStart(this.launcher); - assertEquals(Status.ONLINE, this.launcher.status().getStatus()); - - // validate the pid file and its contents - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertTrue(this.pidFile.exists()); - final int pid = readPid(this.pidFile); - assertTrue(pid > 0); - assertTrue(ProcessUtils.isProcessAlive(pid)); - assertEquals(getPid(), pid); - - assertEquals(Status.ONLINE, this.launcher.status().getStatus()); - - }

            catch (Throwable e)

            { - this.errorCollector.addError(e); - }
            -
            - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - waitForFileToDelete(this.pidFile); - } catch (Throwable e) { - this.errorCollector.addError(e); - }

            + public void startWithPortUsesPort() throws Exception

            { + LocatorLauncher launcher = startLocator(newBuilder().setPort(defaultLocatorPort)); + + assertThat(launcher.getLocator().getPort()).isEqualTo(defaultLocatorPort); }

          @Test

          • public void testStartDeletesStaleControlFiles() throws Throwable {
          • // create existing control files
          • this.stopRequestFile =
          • new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getStopRequestFileName());
          • this.stopRequestFile.createNewFile();
          • assertTrue(this.stopRequestFile.exists());
            -
          • this.statusRequestFile =
          • new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getStatusRequestFileName());
          • this.statusRequestFile.createNewFile();
          • assertTrue(this.statusRequestFile.exists());
            -
          • this.statusFile =
          • new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getStatusFileName());
          • this.statusFile.createNewFile();
          • assertTrue(this.statusFile.exists());
            -
          • // build and start the locator
          • final Builder builder = new Builder().setMemberName(getUniqueName()).setPort(this.locatorPort)
          • .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory)
          • .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config");
            -
          • assertFalse(builder.getForce());
          • this.launcher = builder.build();
          • assertFalse(this.launcher.isForcing());
          • this.launcher.start();
            -
          • try { - waitForLocatorToStart(this.launcher); - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            -
            - try { - // validate the pid file and its contents - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertTrue(this.pidFile.exists()); - final int pid = readPid(this.pidFile); - assertTrue(pid > 0); - assertTrue(ProcessUtils.isProcessAlive(pid)); - assertEquals(getPid(), pid); - - // validate stale control files were deleted - assertFalse(stopRequestFile.exists()); - assertFalse(statusRequestFile.exists()); - assertFalse(statusFile.exists()); - - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            -
            - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - waitForFileToDelete(this.pidFile); - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            + public void startWithPortZeroUsesAnEphemeralPort() throws Exception { + LocatorLauncher launcher = startLocator(newBuilder().setPort(0)); + + assertThat(launcher.getLocator().getPort()).isGreaterThan(0); + assertThat(launcher.getLocator().isPeerLocator()).isTrue(); }

            @Test
            - public void testStartOverwritesStalePidFile() throws Throwable {
            - // create existing pid file
            - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName());
            - assertFalse("Integer.MAX_VALUE shouldn't be the same as local pid " + Integer.MAX_VALUE,
            - Integer.MAX_VALUE == ProcessUtils.identifyPid());
            - writePid(this.pidFile, Integer.MAX_VALUE);
            -
            - // build and start the locator
            - final Builder builder = new Builder().setMemberName(getUniqueName()).setPort(this.locatorPort)
            - .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory)
            - .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config");
            -
            - assertFalse(builder.getForce());
            - this.launcher = builder.build();
            - assertFalse(this.launcher.isForcing());
            - this.launcher.start();
            -
            - try { - waitForLocatorToStart(this.launcher); - }

            catch (Throwable e)

            { - this.errorCollector.addError(e); - }
            -
            - try { - // validate the pid file and its contents - assertTrue(this.pidFile.exists()); - final int pid = readPid(this.pidFile); - assertTrue(pid > 0); - assertTrue(ProcessUtils.isProcessAlive(pid)); - assertEquals(getPid(), pid); - } catch (Throwable e) { - this.errorCollector.addError(e); - }

            -

          • try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - waitForFileToDelete(this.pidFile); - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            + public void startUsesBuilderValues() throws Exception { + LocatorLauncher launcher = startLocator(newBuilder().setPort(nonDefaultLocatorPort)); + + InternalLocator locator = launcher.getLocator(); + assertThat(locator.getPort()).isEqualTo(nonDefaultLocatorPort); + + DistributedSystem system = locator.getDistributedSystem(); + assertThat(system.getProperties().getProperty(DISABLE_AUTO_RECONNECT)).isEqualTo("true"); + assertThat(system.getProperties().getProperty(LOG_LEVEL)).isEqualTo("config"); + assertThat(system.getProperties().getProperty(MCAST_PORT)).isEqualTo("0"); + assertThat(system.getProperties().getProperty(NAME)).isEqualTo(getUniqueName()); }

            @Test
            - @Ignore("Need to rewrite this without using dunit.Host")
            - public void testStartUsingForceOverwritesExistingPidFile() throws Throwable {}
            - /*
            - * assertTrue(getUniqueName() + " is broken if PID == Integer.MAX_VALUE",
            - * ProcessUtils.identifyPid() != Integer.MAX_VALUE);
            - *
            - * // create existing pid file this.pidFile = new File(ProcessType.LOCATOR.getPidFileName());
            - * final int realPid = Host.getHost(0).getVM(3).invoke(() -> ProcessUtils.identifyPid());
            - * assertFalse(realPid == ProcessUtils.identifyPid()); writePid(this.pidFile, realPid);
            - *
            - * // build and start the locator final Builder builder = new Builder() .setForce(true)
            - * .setMemberName(getUniqueName()) .setPort(this.locatorPort) .setRedirectOutput(true)
            - *
            - * assertTrue(builder.getForce()); this.launcher = builder.build();
            - * assertTrue(this.launcher.isForcing()); this.launcher.start();
            - *
            - * // collect and throw the FIRST failure Throwable failure = null;
            - *
            - * try { waitForLocatorToStart(this.launcher); - * - * // validate the pid file and its contents assertTrue(this.pidFile.exists()); final int pid = - * readPid(this.pidFile); assertTrue(pid > 0); assertTrue(ProcessUtils.isProcessAlive(pid)); - * assertIndexDetailsEquals(getPid(), pid); - * - * // validate log file was created final String logFileName = getUniqueName()+".log"; - * assertTrue("Log file should exist: " + logFileName, new File(logFileName).exists()); - * - * } catch (Throwable e) { logger.error(e); if (failure == null) { failure = e; } }
            - *
            - * try { assertIndexDetailsEquals(Status.STOPPED, this.launcher.stop().getStatus()); - * waitForFileToDelete(this.pidFile); } catch (Throwable e) { logger.error(e); if (failure ==
            - * null) { failure = e; } }
            - *
            - * if (failure != null) { throw failure; } } // testStartUsingForceOverwritesExistingPidFile
            - */
            + public void startCreatesPidFile() throws Exception { + startLocator(); + + assertThat(getPidFile()).exists(); + }
            +
            + @Test
            + public void pidFileContainsServerPid() throws Exception { + startLocator(); + + assertThat(getLocatorPid()).isEqualTo(localPid); + }
            +
            + @Test
            + public void startDeletesStaleControlFiles() throws Exception { + File stopRequestFile = givenControlFile(getProcessType().getStopRequestFileName()); + File statusRequestFile = givenControlFile(getProcessType().getStatusRequestFileName()); + File statusFile = givenControlFile(getProcessType().getStatusFileName()); + + startLocator(); + + assertDeletionOf(stopRequestFile); + assertDeletionOf(statusRequestFile); + assertDeletionOf(statusFile); + }

            @Test
            - public void testStartWithDefaultPortInUseFails() throws Throwable {
            - // Test makes no sense in this case
            - if (this.locatorPort == 0) { - return; - }
            -
            - this.socket =
            - SocketCreatorFactory.getSocketCreatorForComponent(SecurableCommunicationChannel.CLUSTER)
            - .createServerSocket(this.locatorPort, 50, null, -1);
            - assertTrue(this.socket.isBound());
            - assertFalse(this.socket.isClosed());
            - assertFalse(AvailablePort.isPortAvailable(this.locatorPort, AvailablePort.SOCKET));
            -
            - assertNotNull(System.getProperty(DistributionLocator.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY));
            - assertEquals(this.locatorPort,
            - Integer.valueOf(System.getProperty(DistributionLocator.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY))
            - .intValue());
            - assertFalse(AvailablePort.isPortAvailable(this.locatorPort, AvailablePort.SOCKET));
            -
            - this.launcher = new Builder().setMemberName(getUniqueName()).setRedirectOutput(true)
            - .setWorkingDirectory(this.workingDirectory)
            - .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config")
            - .build();
            -
            - assertEquals(this.locatorPort, this.launcher.getPort().intValue());
            -
            - RuntimeException expected = null;
            - try { - this.launcher.start(); - - // why did it not fail like it's supposed to? - final String property = - System.getProperty(DistributionLocator.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY); - assertNotNull(property); - assertEquals(this.locatorPort, Integer.valueOf(property).intValue()); - assertFalse(AvailablePort.isPortAvailable(this.locatorPort, AvailablePort.SOCKET)); - assertEquals(this.locatorPort, this.launcher.getPort().intValue()); - assertEquals(this.locatorPort, this.socket.getLocalPort()); - assertTrue(this.socket.isBound()); - assertFalse(this.socket.isClosed()); - - fail("LocatorLauncher start should have thrown RuntimeException caused by BindException"); - } catch (RuntimeException e) { - expected = e; - assertNotNull(expected.getMessage()); - // BindException text varies by platform - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            -
            - try { - assertNotNull(expected); - final Throwable cause = expected.getCause(); - assertNotNull(cause); - assertTrue(cause instanceof BindException); - // BindException string varies by platform - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            -
            - try { - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertFalse("Pid file should not exist: " + this.pidFile, this.pidFile.exists()); - - // creation of log file seems to be random -- look into why sometime - final String logFileName = getUniqueName() + ".log"; - assertFalse("Log file should not exist: " + logFileName, - new File(this.temporaryFolder.getRoot(), logFileName).exists()); - - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            -
            - // just in case the launcher started...
            - LocatorState status = null;
            - try { - status = this.launcher.stop(); - } catch (Throwable t) { - // ignore - }
            -
            - try { - waitForFileToDelete(this.pidFile); - assertEquals(getExpectedStopStatusForNotRunning(), status.getStatus()); - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            + public void startOverwritesStalePidFile() throws Exception { + givenPidFile(fakePid); + + startLocator(); + + assertThat(getLocatorPid()).isNotEqualTo(fakePid); }

            @Test
            - @Ignore("Need to rewrite this without using dunit.Host")
            - public void testStartWithExistingPidFileFails()
            - throws Throwable {}/*
            - * // create existing pid file final int realPid =
            - * Host.getHost(0).getVM(3).invoke(() -> ProcessUtils.identifyPid());
            - * assertFalse("Remote pid shouldn't be the same as local pid " + realPid,
            - * realPid == ProcessUtils.identifyPid());
            - *
            - * this.pidFile = new File(ProcessType.LOCATOR.getPidFileName());
            - * writePid(this.pidFile, realPid);
            - *
            - * // build and start the locator final Builder builder = new Builder()
            - * .setMemberName(getUniqueName()) .setPort(this.locatorPort)
            - * .setRedirectOutput(true) .set(logLevel, "config");
            - *
            - * assertFalse(builder.getForce()); this.launcher = builder.build();
            - * assertFalse(this.launcher.isForcing());
            - *
            - * // collect and throw the FIRST failure Throwable failure = null;
            - * RuntimeException expected = null;
            - *
            - * try { this.launcher.start(); - * fail("LocatorLauncher start should have thrown RuntimeException caused by FileAlreadyExistsException" - * ); } catch (RuntimeException e) { expected = e; - * assertNotNull(expected.getMessage()); assertTrue(expected.getMessage(), - * expected.getMessage(). - * contains("A PID file already exists and a Locator may be running in")); - * assertIndexDetailsEquals(RuntimeException.class, expected.getClass()); }
            - * catch (Throwable e) { logger.error(e); if (failure == null) { failure = - * e; } }
            - *
            - * // just in case the launcher started... LocatorState status = null; try
            - * { status = this.launcher.stop(); } catch (Throwable t) { // ignore }
            - *
            - * try { assertNotNull(expected); final Throwable cause = - * expected.getCause(); assertNotNull(cause); assertTrue(cause instanceof - * FileAlreadyExistsException); - * assertTrue(cause.getMessage().contains("Pid file already exists: ")); - * assertTrue(cause.getMessage().contains("vf.gf.locator.pid for process " - * + realPid)); } catch (Throwable e) { logger.error(e); if (failure ==
            - * null) { failure = e; } }
            - *
            - * try { delete(this.pidFile); final Status theStatus = status.getStatus(); - * assertFalse(theStatus == Status.STARTING); assertFalse(theStatus == - * Status.ONLINE); } catch (Throwable e) { logger.error(e); if (failure ==
            - * null) { failure = e; } }
            - *
            - * if (failure != null) { throw failure; } } //
            - * testStartWithExistingPidFileFails
            - */
            + public void startWithDefaultPortInUseFailsWithBindException() throws Exception { + givenLocatorPortInUse(defaultLocatorPort); + + launcher = new Builder().build(); + + assertThatThrownBy(() -> launcher.start()).isInstanceOf(RuntimeException.class) + .hasCauseInstanceOf(BindException.class); + }

            @Test
            - public void testStartUsingPort() throws Throwable {
            - // generate one free port and then use it instead of default
            - final int freeTCPPort = AvailablePortHelper.getRandomAvailableTCPPort();
            - assertTrue(AvailablePort.isPortAvailable(freeTCPPort, AvailablePort.SOCKET));
            -
            - this.launcher = new Builder().setMemberName(getUniqueName()).setPort(freeTCPPort)
            - .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory)
            - .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config")
            - .build();
            -
            - int pid = 0;
            - try { - // if start succeeds without throwing exception then #47778 is fixed - this.launcher.start(); - waitForLocatorToStart(this.launcher); - - // validate the pid file and its contents - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertTrue(pidFile.exists()); - pid = readPid(pidFile); - assertTrue(pid > 0); - assertTrue(ProcessUtils.isProcessAlive(pid)); - assertEquals(getPid(), pid); - - // verify locator did not use default port - assertTrue(AvailablePort.isPortAvailable(this.locatorPort, AvailablePort.SOCKET)); - - final LocatorState status = this.launcher.status(); - final String portString = status.getPort(); - assertEquals("Port should be \"" + freeTCPPort + "\" instead of " + portString, - String.valueOf(freeTCPPort), portString); - } catch (Throwable e) { - this.errorCollector.addError(e); - }
            -
            - // stop the locator
            - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - waitForFileToDelete(this.pidFile); - }

            catch (Throwable e)

            { - this.errorCollector.addError(e); - }
            + public void startWithLocatorPortInUseFailsWithBindException() throws Exception { + givenServerPortInUse(nonDefaultLocatorPort); + + launcher = new Builder().setPort(nonDefaultLocatorPort).build(); + + assertThatThrownBy(() -> this.launcher.start()).isInstanceOf(RuntimeException.class) + .hasCauseInstanceOf(BindException.class); }

            @Test
            - public void testStartUsingPortInUseFails() throws Throwable {
            - // Test makes no sense in this case
            - if (this.locatorPort == 0) { - return; - }
            -
            - // generate one free port and then use it instead of default
            - this.socket =
            - SocketCreatorFactory.getSocketCreatorForComponent(SecurableCommunicationChannel.CLUSTER)
            - .createServerSocket(this.locatorPort, 50, null, -1);
            -
            - this.launcher = new Builder().setMemberName(getUniqueName()).setPort(this.locatorPort)
            - .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory)
            - .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config")
            - .build();
            -
            - RuntimeException expected = null;
            - try { - this.launcher.start(); - fail("LocatorLauncher start should have thrown RuntimeException caused by BindException"); - } catch (RuntimeException e) { - expected = e; - assertNotNull(expected.getMessage()); - // BindException string varies by platform - } catch (Throwable e) { - this.errorCollector.addError(e); - }

            -

          • try { - assertNotNull(expected); - final Throwable cause = expected.getCause(); - assertNotNull(cause); - assertTrue(cause instanceof BindException); - // BindException string varies by platform - }

            catch (Throwable e)

            { - this.errorCollector.addError(e); - }
            -
            - try { - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertFalse("Pid file should not exist: " + this.pidFile, this.pidFile.exists()); - - // creation of log file seems to be random -- look into why sometime - final String logFileName = getUniqueName() + ".log"; - assertFalse("Log file should not exist: " + logFileName, - new File(this.temporaryFolder.getRoot(), logFileName).exists()); - - } catch (Throwable e) { - this.errorCollector.addError(e); - }

            -

          • // just in case the launcher started...
          • LocatorState status = null;
          • try { - status = this.launcher.stop(); - }

            catch (Throwable t)

            { - // ignore - }

            -

          • try { - waitForFileToDelete(this.pidFile); - assertEquals(getExpectedStopStatusForNotRunning(), status.getStatus()); - }

            catch (Throwable e)

            { - this.errorCollector.addError(e); - }

            + public void statusWithPidReturnsOnlineWithDetails() throws Exception {
            + givenRunningLocator();
            +
            + LocatorState locatorState = new Builder().setPid(localPid).build().status();
            +
            + assertThat(locatorState.getStatus()).isEqualTo(ONLINE);
            + assertThat(locatorState.getClasspath()).isEqualTo(getClassPath());
            + assertThat(locatorState.getGemFireVersion()).isEqualTo(GemFireVersion.getGemFireVersion());
            + assertThat(locatorState.getHost()).isEqualTo(InetAddress.getLocalHost().getCanonicalHostName());

              • End diff –

          It could fail in the Geode Nightly Build too. We'll have to keep an eye on this...

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132592382 — Diff: geode-core/src/test/java/org/apache/geode/distributed/LocatorLauncherLocalIntegrationTest.java — @@ -14,745 +14,270 @@ */ package org.apache.geode.distributed; -import org.apache.geode.distributed.AbstractLauncher.Status; +import static org.apache.geode.distributed.AbstractLauncher.Status.NOT_RESPONDING; +import static org.apache.geode.distributed.AbstractLauncher.Status.ONLINE; +import static org.apache.geode.distributed.AbstractLauncher.Status.STOPPED; +import static org.apache.geode.distributed.ConfigurationProperties.DISABLE_AUTO_RECONNECT; +import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL; +import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; +import static org.apache.geode.distributed.ConfigurationProperties.NAME; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.io.File; +import java.net.BindException; +import java.net.InetAddress; +import java.util.Collections; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + import org.apache.geode.distributed.LocatorLauncher.Builder; import org.apache.geode.distributed.LocatorLauncher.LocatorState; import org.apache.geode.distributed.internal.InternalLocator; -import org.apache.geode.internal.*; -import org.apache.geode.internal.net.SocketCreatorFactory; +import org.apache.geode.internal.GemFireVersion; import org.apache.geode.internal.process.ProcessControllerFactory; import org.apache.geode.internal.process.ProcessType; -import org.apache.geode.internal.process.ProcessUtils; -import org.apache.geode.internal.security.SecurableCommunicationChannel; import org.apache.geode.test.junit.categories.IntegrationTest; -import org.apache.geode.test.junit.runners.CategoryWithParameterizedRunnerFactory; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.io.File; -import java.lang.management.ManagementFactory; -import java.net.BindException; -import java.net.InetAddress; - -import static org.apache.geode.distributed.ConfigurationProperties.*; -import static org.junit.Assert.*; /** * Tests usage of LocatorLauncher as a local API in existing JVM. + * Integration tests for using {@link LocatorLauncher} as an in-process API within an existing JVM. * @since GemFire 8.0 */ @Category(IntegrationTest.class) -@RunWith(Parameterized.class) -@Parameterized.UseParametersRunnerFactory(CategoryWithParameterizedRunnerFactory.class) -public class LocatorLauncherLocalIntegrationTest extends AbstractLocatorLauncherIntegrationTestCase { +public class LocatorLauncherLocalIntegrationTest extends LocatorLauncherIntegrationTestCase { @Before public final void setUpLocatorLauncherLocalIntegrationTest() throws Exception { + public void setUpLocatorLauncherLocalIntegrationTest() throws Exception { disconnectFromDS(); - System.setProperty(ProcessType.TEST_PREFIX_PROPERTY, getUniqueName() + "-"); + System.setProperty(ProcessType.PROPERTY_TEST_PREFIX, getUniqueName() + "-"); + assertThat(new ProcessControllerFactory().isAttachAPIFound()).isTrue(); } @After public final void tearDownLocatorLauncherLocalIntegrationTest() throws Exception { + public void tearDownLocatorLauncherLocalIntegrationTest() throws Exception { disconnectFromDS(); } @Test public void testBuilderSetProperties() throws Throwable { this.launcher = new Builder().setForce(true).setMemberName(getUniqueName()) .setPort(this.locatorPort).setWorkingDirectory(this.workingDirectory) .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory) .set(DISABLE_AUTO_RECONNECT, "true").set(LOG_LEVEL, "config").set(MCAST_PORT, "0").build(); - try { - assertEquals(Status.ONLINE, this.launcher.start().getStatus()); - waitForLocatorToStart(this.launcher, true); - - final InternalLocator locator = this.launcher.getLocator(); - assertNotNull(locator); - - final DistributedSystem distributedSystem = locator.getDistributedSystem(); - - assertNotNull(distributedSystem); - assertEquals("true", distributedSystem.getProperties().getProperty(DISABLE_AUTO_RECONNECT)); - assertEquals("0", distributedSystem.getProperties().getProperty(MCAST_PORT)); - assertEquals("config", distributedSystem.getProperties().getProperty(LOG_LEVEL)); - assertEquals(getUniqueName(), distributedSystem.getProperties().getProperty(NAME)); - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - assertNull(this.launcher.getLocator()); - } catch (Throwable e) { - this.errorCollector.addError(e); - } + public void usesLocatorPortAsDefaultPort() throws Exception { + launcher = givenLocatorLauncher(); + + assertThat(launcher.getPort()).isEqualTo(defaultLocatorPort); } @Test public void testIsAttachAPIFound() throws Exception { final ProcessControllerFactory factory = new ProcessControllerFactory(); assertTrue(factory.isAttachAPIFound()); + public void startReturnsOnline() throws Exception { + launcher = givenLocatorLauncher(); + + assertThat(launcher.start().getStatus()).isEqualTo(ONLINE); } @Test public void testStartCreatesPidFile() throws Throwable { this.launcher = new Builder().setMemberName(getUniqueName()).setPort(this.locatorPort) .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory) .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config") .build(); - try { - this.launcher.start(); - waitForLocatorToStart(this.launcher); - assertEquals(Status.ONLINE, this.launcher.status().getStatus()); - - // validate the pid file and its contents - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertTrue(this.pidFile.exists()); - final int pid = readPid(this.pidFile); - assertTrue(pid > 0); - assertTrue(ProcessUtils.isProcessAlive(pid)); - assertEquals(getPid(), pid); - - assertEquals(Status.ONLINE, this.launcher.status().getStatus()); - - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - waitForFileToDelete(this.pidFile); - } catch (Throwable e) { - this.errorCollector.addError(e); - } + public void startWithPortUsesPort() throws Exception { + LocatorLauncher launcher = startLocator(newBuilder().setPort(defaultLocatorPort)); + + assertThat(launcher.getLocator().getPort()).isEqualTo(defaultLocatorPort); } @Test public void testStartDeletesStaleControlFiles() throws Throwable { // create existing control files this.stopRequestFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getStopRequestFileName()); this.stopRequestFile.createNewFile(); assertTrue(this.stopRequestFile.exists()); - this.statusRequestFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getStatusRequestFileName()); this.statusRequestFile.createNewFile(); assertTrue(this.statusRequestFile.exists()); - this.statusFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getStatusFileName()); this.statusFile.createNewFile(); assertTrue(this.statusFile.exists()); - // build and start the locator final Builder builder = new Builder().setMemberName(getUniqueName()).setPort(this.locatorPort) .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory) .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config"); - assertFalse(builder.getForce()); this.launcher = builder.build(); assertFalse(this.launcher.isForcing()); this.launcher.start(); - try { - waitForLocatorToStart(this.launcher); - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - try { - // validate the pid file and its contents - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertTrue(this.pidFile.exists()); - final int pid = readPid(this.pidFile); - assertTrue(pid > 0); - assertTrue(ProcessUtils.isProcessAlive(pid)); - assertEquals(getPid(), pid); - - // validate stale control files were deleted - assertFalse(stopRequestFile.exists()); - assertFalse(statusRequestFile.exists()); - assertFalse(statusFile.exists()); - - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - waitForFileToDelete(this.pidFile); - } catch (Throwable e) { - this.errorCollector.addError(e); - } + public void startWithPortZeroUsesAnEphemeralPort() throws Exception { + LocatorLauncher launcher = startLocator(newBuilder().setPort(0)); + + assertThat(launcher.getLocator().getPort()).isGreaterThan(0); + assertThat(launcher.getLocator().isPeerLocator()).isTrue(); } @Test - public void testStartOverwritesStalePidFile() throws Throwable { - // create existing pid file - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertFalse("Integer.MAX_VALUE shouldn't be the same as local pid " + Integer.MAX_VALUE, - Integer.MAX_VALUE == ProcessUtils.identifyPid()); - writePid(this.pidFile, Integer.MAX_VALUE); - - // build and start the locator - final Builder builder = new Builder().setMemberName(getUniqueName()).setPort(this.locatorPort) - .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory) - .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config"); - - assertFalse(builder.getForce()); - this.launcher = builder.build(); - assertFalse(this.launcher.isForcing()); - this.launcher.start(); - - try { - waitForLocatorToStart(this.launcher); - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - try { - // validate the pid file and its contents - assertTrue(this.pidFile.exists()); - final int pid = readPid(this.pidFile); - assertTrue(pid > 0); - assertTrue(ProcessUtils.isProcessAlive(pid)); - assertEquals(getPid(), pid); - } catch (Throwable e) { - this.errorCollector.addError(e); - } - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - waitForFileToDelete(this.pidFile); - } catch (Throwable e) { - this.errorCollector.addError(e); - } + public void startUsesBuilderValues() throws Exception { + LocatorLauncher launcher = startLocator(newBuilder().setPort(nonDefaultLocatorPort)); + + InternalLocator locator = launcher.getLocator(); + assertThat(locator.getPort()).isEqualTo(nonDefaultLocatorPort); + + DistributedSystem system = locator.getDistributedSystem(); + assertThat(system.getProperties().getProperty(DISABLE_AUTO_RECONNECT)).isEqualTo("true"); + assertThat(system.getProperties().getProperty(LOG_LEVEL)).isEqualTo("config"); + assertThat(system.getProperties().getProperty(MCAST_PORT)).isEqualTo("0"); + assertThat(system.getProperties().getProperty(NAME)).isEqualTo(getUniqueName()); } @Test - @Ignore("Need to rewrite this without using dunit.Host") - public void testStartUsingForceOverwritesExistingPidFile() throws Throwable {} - /* - * assertTrue(getUniqueName() + " is broken if PID == Integer.MAX_VALUE", - * ProcessUtils.identifyPid() != Integer.MAX_VALUE); - * - * // create existing pid file this.pidFile = new File(ProcessType.LOCATOR.getPidFileName()); - * final int realPid = Host.getHost(0).getVM(3).invoke(() -> ProcessUtils.identifyPid()); - * assertFalse(realPid == ProcessUtils.identifyPid()); writePid(this.pidFile, realPid); - * - * // build and start the locator final Builder builder = new Builder() .setForce(true) - * .setMemberName(getUniqueName()) .setPort(this.locatorPort) .setRedirectOutput(true) - * - * assertTrue(builder.getForce()); this.launcher = builder.build(); - * assertTrue(this.launcher.isForcing()); this.launcher.start(); - * - * // collect and throw the FIRST failure Throwable failure = null; - * - * try { waitForLocatorToStart(this.launcher); - * - * // validate the pid file and its contents assertTrue(this.pidFile.exists()); final int pid = - * readPid(this.pidFile); assertTrue(pid > 0); assertTrue(ProcessUtils.isProcessAlive(pid)); - * assertIndexDetailsEquals(getPid(), pid); - * - * // validate log file was created final String logFileName = getUniqueName()+".log"; - * assertTrue("Log file should exist: " + logFileName, new File(logFileName).exists()); - * - * } catch (Throwable e) { logger.error(e); if (failure == null) { failure = e; } } - * - * try { assertIndexDetailsEquals(Status.STOPPED, this.launcher.stop().getStatus()); - * waitForFileToDelete(this.pidFile); } catch (Throwable e) { logger.error(e); if (failure == - * null) { failure = e; } } - * - * if (failure != null) { throw failure; } } // testStartUsingForceOverwritesExistingPidFile - */ + public void startCreatesPidFile() throws Exception { + startLocator(); + + assertThat(getPidFile()).exists(); + } + + @Test + public void pidFileContainsServerPid() throws Exception { + startLocator(); + + assertThat(getLocatorPid()).isEqualTo(localPid); + } + + @Test + public void startDeletesStaleControlFiles() throws Exception { + File stopRequestFile = givenControlFile(getProcessType().getStopRequestFileName()); + File statusRequestFile = givenControlFile(getProcessType().getStatusRequestFileName()); + File statusFile = givenControlFile(getProcessType().getStatusFileName()); + + startLocator(); + + assertDeletionOf(stopRequestFile); + assertDeletionOf(statusRequestFile); + assertDeletionOf(statusFile); + } @Test - public void testStartWithDefaultPortInUseFails() throws Throwable { - // Test makes no sense in this case - if (this.locatorPort == 0) { - return; - } - - this.socket = - SocketCreatorFactory.getSocketCreatorForComponent(SecurableCommunicationChannel.CLUSTER) - .createServerSocket(this.locatorPort, 50, null, -1); - assertTrue(this.socket.isBound()); - assertFalse(this.socket.isClosed()); - assertFalse(AvailablePort.isPortAvailable(this.locatorPort, AvailablePort.SOCKET)); - - assertNotNull(System.getProperty(DistributionLocator.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY)); - assertEquals(this.locatorPort, - Integer.valueOf(System.getProperty(DistributionLocator.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY)) - .intValue()); - assertFalse(AvailablePort.isPortAvailable(this.locatorPort, AvailablePort.SOCKET)); - - this.launcher = new Builder().setMemberName(getUniqueName()).setRedirectOutput(true) - .setWorkingDirectory(this.workingDirectory) - .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config") - .build(); - - assertEquals(this.locatorPort, this.launcher.getPort().intValue()); - - RuntimeException expected = null; - try { - this.launcher.start(); - - // why did it not fail like it's supposed to? - final String property = - System.getProperty(DistributionLocator.TEST_OVERRIDE_DEFAULT_PORT_PROPERTY); - assertNotNull(property); - assertEquals(this.locatorPort, Integer.valueOf(property).intValue()); - assertFalse(AvailablePort.isPortAvailable(this.locatorPort, AvailablePort.SOCKET)); - assertEquals(this.locatorPort, this.launcher.getPort().intValue()); - assertEquals(this.locatorPort, this.socket.getLocalPort()); - assertTrue(this.socket.isBound()); - assertFalse(this.socket.isClosed()); - - fail("LocatorLauncher start should have thrown RuntimeException caused by BindException"); - } catch (RuntimeException e) { - expected = e; - assertNotNull(expected.getMessage()); - // BindException text varies by platform - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - try { - assertNotNull(expected); - final Throwable cause = expected.getCause(); - assertNotNull(cause); - assertTrue(cause instanceof BindException); - // BindException string varies by platform - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - try { - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertFalse("Pid file should not exist: " + this.pidFile, this.pidFile.exists()); - - // creation of log file seems to be random -- look into why sometime - final String logFileName = getUniqueName() + ".log"; - assertFalse("Log file should not exist: " + logFileName, - new File(this.temporaryFolder.getRoot(), logFileName).exists()); - - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - // just in case the launcher started... - LocatorState status = null; - try { - status = this.launcher.stop(); - } catch (Throwable t) { - // ignore - } - - try { - waitForFileToDelete(this.pidFile); - assertEquals(getExpectedStopStatusForNotRunning(), status.getStatus()); - } catch (Throwable e) { - this.errorCollector.addError(e); - } + public void startOverwritesStalePidFile() throws Exception { + givenPidFile(fakePid); + + startLocator(); + + assertThat(getLocatorPid()).isNotEqualTo(fakePid); } @Test - @Ignore("Need to rewrite this without using dunit.Host") - public void testStartWithExistingPidFileFails() - throws Throwable {}/* - * // create existing pid file final int realPid = - * Host.getHost(0).getVM(3).invoke(() -> ProcessUtils.identifyPid()); - * assertFalse("Remote pid shouldn't be the same as local pid " + realPid, - * realPid == ProcessUtils.identifyPid()); - * - * this.pidFile = new File(ProcessType.LOCATOR.getPidFileName()); - * writePid(this.pidFile, realPid); - * - * // build and start the locator final Builder builder = new Builder() - * .setMemberName(getUniqueName()) .setPort(this.locatorPort) - * .setRedirectOutput(true) .set(logLevel, "config"); - * - * assertFalse(builder.getForce()); this.launcher = builder.build(); - * assertFalse(this.launcher.isForcing()); - * - * // collect and throw the FIRST failure Throwable failure = null; - * RuntimeException expected = null; - * - * try { this.launcher.start(); - * fail("LocatorLauncher start should have thrown RuntimeException caused by FileAlreadyExistsException" - * ); } catch (RuntimeException e) { expected = e; - * assertNotNull(expected.getMessage()); assertTrue(expected.getMessage(), - * expected.getMessage(). - * contains("A PID file already exists and a Locator may be running in")); - * assertIndexDetailsEquals(RuntimeException.class, expected.getClass()); } - * catch (Throwable e) { logger.error(e); if (failure == null) { failure = - * e; } } - * - * // just in case the launcher started... LocatorState status = null; try - * { status = this.launcher.stop(); } catch (Throwable t) { // ignore } - * - * try { assertNotNull(expected); final Throwable cause = - * expected.getCause(); assertNotNull(cause); assertTrue(cause instanceof - * FileAlreadyExistsException); - * assertTrue(cause.getMessage().contains("Pid file already exists: ")); - * assertTrue(cause.getMessage().contains("vf.gf.locator.pid for process " - * + realPid)); } catch (Throwable e) { logger.error(e); if (failure == - * null) { failure = e; } } - * - * try { delete(this.pidFile); final Status theStatus = status.getStatus(); - * assertFalse(theStatus == Status.STARTING); assertFalse(theStatus == - * Status.ONLINE); } catch (Throwable e) { logger.error(e); if (failure == - * null) { failure = e; } } - * - * if (failure != null) { throw failure; } } // - * testStartWithExistingPidFileFails - */ + public void startWithDefaultPortInUseFailsWithBindException() throws Exception { + givenLocatorPortInUse(defaultLocatorPort); + + launcher = new Builder().build(); + + assertThatThrownBy(() -> launcher.start()).isInstanceOf(RuntimeException.class) + .hasCauseInstanceOf(BindException.class); + } @Test - public void testStartUsingPort() throws Throwable { - // generate one free port and then use it instead of default - final int freeTCPPort = AvailablePortHelper.getRandomAvailableTCPPort(); - assertTrue(AvailablePort.isPortAvailable(freeTCPPort, AvailablePort.SOCKET)); - - this.launcher = new Builder().setMemberName(getUniqueName()).setPort(freeTCPPort) - .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory) - .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config") - .build(); - - int pid = 0; - try { - // if start succeeds without throwing exception then #47778 is fixed - this.launcher.start(); - waitForLocatorToStart(this.launcher); - - // validate the pid file and its contents - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertTrue(pidFile.exists()); - pid = readPid(pidFile); - assertTrue(pid > 0); - assertTrue(ProcessUtils.isProcessAlive(pid)); - assertEquals(getPid(), pid); - - // verify locator did not use default port - assertTrue(AvailablePort.isPortAvailable(this.locatorPort, AvailablePort.SOCKET)); - - final LocatorState status = this.launcher.status(); - final String portString = status.getPort(); - assertEquals("Port should be \"" + freeTCPPort + "\" instead of " + portString, - String.valueOf(freeTCPPort), portString); - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - // stop the locator - try { - assertEquals(Status.STOPPED, this.launcher.stop().getStatus()); - waitForFileToDelete(this.pidFile); - } catch (Throwable e) { - this.errorCollector.addError(e); - } + public void startWithLocatorPortInUseFailsWithBindException() throws Exception { + givenServerPortInUse(nonDefaultLocatorPort); + + launcher = new Builder().setPort(nonDefaultLocatorPort).build(); + + assertThatThrownBy(() -> this.launcher.start()).isInstanceOf(RuntimeException.class) + .hasCauseInstanceOf(BindException.class); } @Test - public void testStartUsingPortInUseFails() throws Throwable { - // Test makes no sense in this case - if (this.locatorPort == 0) { - return; - } - - // generate one free port and then use it instead of default - this.socket = - SocketCreatorFactory.getSocketCreatorForComponent(SecurableCommunicationChannel.CLUSTER) - .createServerSocket(this.locatorPort, 50, null, -1); - - this.launcher = new Builder().setMemberName(getUniqueName()).setPort(this.locatorPort) - .setRedirectOutput(true).setWorkingDirectory(this.workingDirectory) - .set(CLUSTER_CONFIGURATION_DIR, this.clusterConfigDirectory).set(LOG_LEVEL, "config") - .build(); - - RuntimeException expected = null; - try { - this.launcher.start(); - fail("LocatorLauncher start should have thrown RuntimeException caused by BindException"); - } catch (RuntimeException e) { - expected = e; - assertNotNull(expected.getMessage()); - // BindException string varies by platform - } catch (Throwable e) { - this.errorCollector.addError(e); - } - try { - assertNotNull(expected); - final Throwable cause = expected.getCause(); - assertNotNull(cause); - assertTrue(cause instanceof BindException); - // BindException string varies by platform - } catch (Throwable e) { - this.errorCollector.addError(e); - } - - try { - this.pidFile = new File(this.temporaryFolder.getRoot(), ProcessType.LOCATOR.getPidFileName()); - assertFalse("Pid file should not exist: " + this.pidFile, this.pidFile.exists()); - - // creation of log file seems to be random -- look into why sometime - final String logFileName = getUniqueName() + ".log"; - assertFalse("Log file should not exist: " + logFileName, - new File(this.temporaryFolder.getRoot(), logFileName).exists()); - - } catch (Throwable e) { - this.errorCollector.addError(e); - } - // just in case the launcher started... LocatorState status = null; try { - status = this.launcher.stop(); - } catch (Throwable t) { - // ignore - } - try { - waitForFileToDelete(this.pidFile); - assertEquals(getExpectedStopStatusForNotRunning(), status.getStatus()); - } catch (Throwable e) { - this.errorCollector.addError(e); - } + public void statusWithPidReturnsOnlineWithDetails() throws Exception { + givenRunningLocator(); + + LocatorState locatorState = new Builder().setPid(localPid).build().status(); + + assertThat(locatorState.getStatus()).isEqualTo(ONLINE); + assertThat(locatorState.getClasspath()).isEqualTo(getClassPath()); + assertThat(locatorState.getGemFireVersion()).isEqualTo(GemFireVersion.getGemFireVersion()); + assertThat(locatorState.getHost()).isEqualTo(InetAddress.getLocalHost().getCanonicalHostName()); End diff – It could fail in the Geode Nightly Build too. We'll have to keep an eye on this...
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132598795

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/AbstractLauncher.java —
          @@ -795,25 +785,25 @@ protected String toString(final Date dateTime) {

          // the value of a Number as a String, or "" if null
          protected String toString(final Number value)

          { - return StringUtils.defaultString(value); + return defaultString(value); }

          // a String concatenation of all values separated by " "
          protected String toString(final Object... values)

          { - return values == null ? "" : StringUtils.join(values, " "); + return values == null ? "" : join(values, " "); }

          // the value of the String, or "" if value is null
          protected String toString(final String value)

          { - return ObjectUtils.defaultIfNull(value, ""); + return defaultIfNull(value, ""); }

          }

          /**

          • The Status enumerated type represents the various lifecycle states of a GemFire service (such
          • as a Cache Server, a Locator or a Manager).
            */
          • public static enum Status {
              • End diff –

          It's static with or without the keyword. IntelliJ grays it out so I just deleted it. Similar to public on methods defined in an Interface.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132598795 — Diff: geode-core/src/main/java/org/apache/geode/distributed/AbstractLauncher.java — @@ -795,25 +785,25 @@ protected String toString(final Date dateTime) { // the value of a Number as a String, or "" if null protected String toString(final Number value) { - return StringUtils.defaultString(value); + return defaultString(value); } // a String concatenation of all values separated by " " protected String toString(final Object... values) { - return values == null ? "" : StringUtils.join(values, " "); + return values == null ? "" : join(values, " "); } // the value of the String, or "" if value is null protected String toString(final String value) { - return ObjectUtils.defaultIfNull(value, ""); + return defaultIfNull(value, ""); } } /** The Status enumerated type represents the various lifecycle states of a GemFire service (such as a Cache Server, a Locator or a Manager). */ public static enum Status { End diff – It's static with or without the keyword. IntelliJ grays it out so I just deleted it. Similar to public on methods defined in an Interface.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132598899

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java —
          @@ -104,6 +109,8 @@
          helpMap.put("bind-address",
          — End diff –

          I'd love to break these Launcher classes up into smaller classes. I'd also like to move them from org.apache.geode.distributed – I don't think that pkg really makes sense for these classes to live in.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132598899 — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java — @@ -104,6 +109,8 @@ helpMap.put("bind-address", — End diff – I'd love to break these Launcher classes up into smaller classes. I'd also like to move them from org.apache.geode.distributed – I don't think that pkg really makes sense for these classes to live in.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132599242

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java —
          @@ -1352,11 +1328,13 @@ protected void parseCommand(final String... args) {

          • @see org.apache.geode.distributed.LocatorLauncher.Command#isCommand(String)
          • @see #parseArguments(String...)
            */
          • protected void parseMemberName(final String[] args) {
          • for (String arg : args) {
          • if (!(arg.startsWith(OPTION_PREFIX) || Command.isCommand(arg))) {
          • setMemberName(arg);
          • break;
            + protected void parseMemberName(final String... args) {
            + if (args != null) {
            + for (String arg : args) {
            + if (!(arg.startsWith(OPTION_PREFIX) || Command.isCommand(arg))) {
              • End diff –

          We need to refactor these classes a lot more. I only copied line 1332 from ServerLauncher which then indented the rest of the lines. I made sure that everything was more consistent. LocatorLauncher threw NPE if args was null but ServerLauncher was ok with null.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132599242 — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java — @@ -1352,11 +1328,13 @@ protected void parseCommand(final String... args) { @see org.apache.geode.distributed.LocatorLauncher.Command#isCommand(String) @see #parseArguments(String...) */ protected void parseMemberName(final String[] args) { for (String arg : args) { if (!(arg.startsWith(OPTION_PREFIX) || Command.isCommand(arg))) { setMemberName(arg); break; + protected void parseMemberName(final String... args) { + if (args != null) { + for (String arg : args) { + if (!(arg.startsWith(OPTION_PREFIX) || Command.isCommand(arg))) { End diff – We need to refactor these classes a lot more. I only copied line 1332 from ServerLauncher which then indented the rest of the lines. I made sure that everything was more consistent. LocatorLauncher threw NPE if args was null but ServerLauncher was ok with null.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132599333

          — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java —
          @@ -1781,8 +1782,8 @@ protected void validate() {

          • @see org.apache.geode.distributed.LocatorLauncher.Command#START
            */
            protected void validateOnStart() {
          • if (Command.START.equals(getCommand())) {
          • if (StringUtils.isBlank(getMemberName())
            + if (Command.START == getCommand()) {
              • End diff –

          Yep, IntelliJ has an automated refactoring and inspection for this. I don't even remember making this change unless I was trying to make LocatorLauncher more consistent with ServerLauncher.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132599333 — Diff: geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java — @@ -1781,8 +1782,8 @@ protected void validate() { @see org.apache.geode.distributed.LocatorLauncher.Command#START */ protected void validateOnStart() { if (Command.START.equals(getCommand())) { if (StringUtils.isBlank(getMemberName()) + if (Command.START == getCommand()) { End diff – Yep, IntelliJ has an automated refactoring and inspection for this. I don't even remember making this change unless I was trying to make LocatorLauncher more consistent with ServerLauncher.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132599627

          — Diff: geode-core/src/main/java/org/apache/geode/internal/process/AttachProcessUtils.java —
          @@ -14,21 +14,28 @@
          */
          package org.apache.geode.internal.process;

          -import org.apache.geode.internal.process.ProcessUtils.InternalProcessUtils;
          +import static org.apache.commons.lang.Validate.isTrue;
          +
          import com.sun.tools.attach.VirtualMachine;
          import com.sun.tools.attach.VirtualMachineDescriptor;

          +import org.apache.geode.internal.process.ProcessUtils.InternalProcessUtils;
          +
          /**

          • Implementation of the {@link ProcessUtils}

            SPI that uses the JDK Attach API.

          • @since GemFire 8.0
            */
            class AttachProcessUtils implements InternalProcessUtils {
          • AttachProcessUtils() {}
            + AttachProcessUtils() {
              • End diff –

          Deleted ctor from AttachProcessUtils and NativeProcessUtils.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132599627 — Diff: geode-core/src/main/java/org/apache/geode/internal/process/AttachProcessUtils.java — @@ -14,21 +14,28 @@ */ package org.apache.geode.internal.process; -import org.apache.geode.internal.process.ProcessUtils.InternalProcessUtils; +import static org.apache.commons.lang.Validate.isTrue; + import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.VirtualMachineDescriptor; +import org.apache.geode.internal.process.ProcessUtils.InternalProcessUtils; + /** Implementation of the {@link ProcessUtils} SPI that uses the JDK Attach API. @since GemFire 8.0 */ class AttachProcessUtils implements InternalProcessUtils { AttachProcessUtils() {} + AttachProcessUtils() { End diff – Deleted ctor from AttachProcessUtils and NativeProcessUtils.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132599768

          — Diff: geode-core/src/main/java/org/apache/geode/internal/process/FileProcessController.java —
          @@ -112,56 +119,43 @@ private void stop(final File workingDir, final String stopRequestFileName) throw
          private String status(final File workingDir, final String statusRequestFileName,
          final String statusFileName) throws IOException, InterruptedException, TimeoutException {
          // monitor for statusFile

          • final File statusFile = new File(workingDir, statusFileName);
          • final AtomicReference<String> statusRef = new AtomicReference<>();
            -
          • final ControlRequestHandler statusHandler = new ControlRequestHandler() {
          • @Override
          • public void handleRequest() throws IOException {
          • // read the statusFile
          • final BufferedReader reader = new BufferedReader(new FileReader(statusFile));
          • final StringBuilder lines = new StringBuilder();
          • try {
          • String line = null;
          • while ((line = reader.readLine()) != null) { - lines.append(line); - }
          • } finally {
          • statusRef.set(lines.toString());
          • reader.close();
            + File statusFile = new File(workingDir, statusFileName);
            + AtomicReference<String> statusRef = new AtomicReference<>();
            +
            + ControlRequestHandler statusHandler = () -> {
              • End diff –

          Done.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132599768 — Diff: geode-core/src/main/java/org/apache/geode/internal/process/FileProcessController.java — @@ -112,56 +119,43 @@ private void stop(final File workingDir, final String stopRequestFileName) throw private String status(final File workingDir, final String statusRequestFileName, final String statusFileName) throws IOException, InterruptedException, TimeoutException { // monitor for statusFile final File statusFile = new File(workingDir, statusFileName); final AtomicReference<String> statusRef = new AtomicReference<>(); - final ControlRequestHandler statusHandler = new ControlRequestHandler() { @Override public void handleRequest() throws IOException { // read the statusFile final BufferedReader reader = new BufferedReader(new FileReader(statusFile)); final StringBuilder lines = new StringBuilder(); try { String line = null; while ((line = reader.readLine()) != null) { - lines.append(line); - } } finally { statusRef.set(lines.toString()); reader.close(); + File statusFile = new File(workingDir, statusFileName); + AtomicReference<String> statusRef = new AtomicReference<>(); + + ControlRequestHandler statusHandler = () -> { End diff – Done.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132599897

          — Diff: geode-core/src/main/java/org/apache/geode/internal/process/LocalProcessLauncher.java —
          @@ -96,33 +117,55 @@ void close() {

          • @throws IOException if unable to create or write to the file
            */
            private void writePid(final boolean force) throws FileAlreadyExistsException, IOException {
          • final boolean created = this.pidFile.createNewFile();
          • if (!created && !force) {
          • int otherPid = 0;
          • try { - otherPid = ProcessUtils.readPid(this.pidFile); - }

            catch (IOException e)

            { - // suppress - } catch (NumberFormatException e) { - // suppress - }
          • boolean ignorePidFile = false;
          • if (otherPid != 0 && !ignoreIsPidAlive()) { - ignorePidFile = !ProcessUtils.isProcessAlive(otherPid); - }
          • if (!ignorePidFile) {
          • throw new FileAlreadyExistsException("Pid file already exists: " + this.pidFile + " for "
          • + (otherPid > 0 ? "process " + otherPid : "unknown process"));
            + if (this.pidFile.exists())
            Unknown macro: { + if (!force) { + checkOtherPid(readOtherPid()); } + this.pidFile.delete(); + }

            +
            + assert !this.pidFile.exists();

              • End diff –

          Did you like the use of Validate? I'm not sure how I feel about Validate after using it heavily in this package.

          Jianxia added the asserts when he fixed a bug in this method and I just left them in place. I think we could easily change them to Validate calls or remove them altogether.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132599897 — Diff: geode-core/src/main/java/org/apache/geode/internal/process/LocalProcessLauncher.java — @@ -96,33 +117,55 @@ void close() { @throws IOException if unable to create or write to the file */ private void writePid(final boolean force) throws FileAlreadyExistsException, IOException { final boolean created = this.pidFile.createNewFile(); if (!created && !force) { int otherPid = 0; try { - otherPid = ProcessUtils.readPid(this.pidFile); - } catch (IOException e) { - // suppress - } catch (NumberFormatException e) { - // suppress - } boolean ignorePidFile = false; if (otherPid != 0 && !ignoreIsPidAlive()) { - ignorePidFile = !ProcessUtils.isProcessAlive(otherPid); - } if (!ignorePidFile) { throw new FileAlreadyExistsException("Pid file already exists: " + this.pidFile + " for " + (otherPid > 0 ? "process " + otherPid : "unknown process")); + if (this.pidFile.exists()) Unknown macro: { + if (!force) { + checkOtherPid(readOtherPid()); } + this.pidFile.delete(); + } + + assert !this.pidFile.exists(); End diff – Did you like the use of Validate? I'm not sure how I feel about Validate after using it heavily in this package. Jianxia added the asserts when he fixed a bug in this method and I just left them in place. I think we could easily change them to Validate calls or remove them altogether.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on a diff in the pull request:

          https://github.com/apache/geode/pull/699#discussion_r132600143

          — Diff: geode-core/src/main/java/org/apache/geode/internal/process/LocalProcessLauncher.java —
          @@ -96,33 +117,55 @@ void close() {

          • @throws IOException if unable to create or write to the file
            */
            private void writePid(final boolean force) throws FileAlreadyExistsException, IOException {
          • final boolean created = this.pidFile.createNewFile();
          • if (!created && !force) {
          • int otherPid = 0;
          • try { - otherPid = ProcessUtils.readPid(this.pidFile); - }

            catch (IOException e)

            { - // suppress - } catch (NumberFormatException e) { - // suppress - }
          • boolean ignorePidFile = false;
          • if (otherPid != 0 && !ignoreIsPidAlive()) { - ignorePidFile = !ProcessUtils.isProcessAlive(otherPid); - }
          • if (!ignorePidFile) {
          • throw new FileAlreadyExistsException("Pid file already exists: " + this.pidFile + " for "
          • + (otherPid > 0 ? "process " + otherPid : "unknown process"));
            + if (this.pidFile.exists())
            Unknown macro: { + if (!force) { + checkOtherPid(readOtherPid()); } + this.pidFile.delete(); + }

            +
            + assert !this.pidFile.exists();

              • End diff –

          I deleted them.

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on a diff in the pull request: https://github.com/apache/geode/pull/699#discussion_r132600143 — Diff: geode-core/src/main/java/org/apache/geode/internal/process/LocalProcessLauncher.java — @@ -96,33 +117,55 @@ void close() { @throws IOException if unable to create or write to the file */ private void writePid(final boolean force) throws FileAlreadyExistsException, IOException { final boolean created = this.pidFile.createNewFile(); if (!created && !force) { int otherPid = 0; try { - otherPid = ProcessUtils.readPid(this.pidFile); - } catch (IOException e) { - // suppress - } catch (NumberFormatException e) { - // suppress - } boolean ignorePidFile = false; if (otherPid != 0 && !ignoreIsPidAlive()) { - ignorePidFile = !ProcessUtils.isProcessAlive(otherPid); - } if (!ignorePidFile) { throw new FileAlreadyExistsException("Pid file already exists: " + this.pidFile + " for " + (otherPid > 0 ? "process " + otherPid : "unknown process")); + if (this.pidFile.exists()) Unknown macro: { + if (!force) { + checkOtherPid(readOtherPid()); } + this.pidFile.delete(); + } + + assert !this.pidFile.exists(); End diff – I deleted them.
          Hide
          jira-bot ASF subversion and git services added a comment -

          Commit 894f3ee710e500c83f06be660b852d389cbb94cb in geode's branch refs/heads/develop from Kirk Lund
          [ https://git-wip-us.apache.org/repos/asf?p=geode.git;h=894f3ee ]

          GEODE-3413: overhaul launcher and process classes and tests

          This is primarily an overall of all ServerLauncher and LocatorLauncher
          tests and org.apache.geode.internal.process tests. The main classes in
          org.apachage.geode.internal.process package are also cleaned up.

          In addition, several bugs involving these classes and tests are fixed.

          Here is the complete list of tickets that are resolved in this overhaul:

          • GEODE-1229: LocatorLauncherRemoteJUnitTest.testStartOverwritesStalePidFile
          • GEODE-2791: LocatorLauncherAssemblyIntegrationTest.testLocatorStopsWhenJmxPortIsNonZero fails intermittently with AssertionError
          • GEODE-1308: CI failure: LocatorLauncherTest.testSetBindAddressToNonLocalHost
          • GEODE-1309: CI failure: ServerLauncherTest.testSetServerBindAddressToNonLocalHost
          • GEODE-3193: locator pid file is removed even if there was a problem while shutting down
          • GEODE-3413: Overhaul launcher tests and process tests
          • GEODE-3414: Cleanup org.apache.geode.internal.process package

          Note I moved all useful tests from LocatorLauncherAssemblyIntegrationTest
          into the other launcher tests in geode-core.

          Show
          jira-bot ASF subversion and git services added a comment - Commit 894f3ee710e500c83f06be660b852d389cbb94cb in geode's branch refs/heads/develop from Kirk Lund [ https://git-wip-us.apache.org/repos/asf?p=geode.git;h=894f3ee ] GEODE-3413 : overhaul launcher and process classes and tests This is primarily an overall of all ServerLauncher and LocatorLauncher tests and org.apache.geode.internal.process tests. The main classes in org.apachage.geode.internal.process package are also cleaned up. In addition, several bugs involving these classes and tests are fixed. Here is the complete list of tickets that are resolved in this overhaul: GEODE-1229 : LocatorLauncherRemoteJUnitTest.testStartOverwritesStalePidFile GEODE-2791 : LocatorLauncherAssemblyIntegrationTest.testLocatorStopsWhenJmxPortIsNonZero fails intermittently with AssertionError GEODE-1308 : CI failure: LocatorLauncherTest.testSetBindAddressToNonLocalHost GEODE-1309 : CI failure: ServerLauncherTest.testSetServerBindAddressToNonLocalHost GEODE-3193 : locator pid file is removed even if there was a problem while shutting down GEODE-3413 : Overhaul launcher tests and process tests GEODE-3414 : Cleanup org.apache.geode.internal.process package Note I moved all useful tests from LocatorLauncherAssemblyIntegrationTest into the other launcher tests in geode-core.
          Hide
          jira-bot ASF subversion and git services added a comment -

          Commit 894f3ee710e500c83f06be660b852d389cbb94cb in geode's branch refs/heads/develop from Kirk Lund
          [ https://git-wip-us.apache.org/repos/asf?p=geode.git;h=894f3ee ]

          GEODE-3413: overhaul launcher and process classes and tests

          This is primarily an overall of all ServerLauncher and LocatorLauncher
          tests and org.apache.geode.internal.process tests. The main classes in
          org.apachage.geode.internal.process package are also cleaned up.

          In addition, several bugs involving these classes and tests are fixed.

          Here is the complete list of tickets that are resolved in this overhaul:

          • GEODE-1229: LocatorLauncherRemoteJUnitTest.testStartOverwritesStalePidFile
          • GEODE-2791: LocatorLauncherAssemblyIntegrationTest.testLocatorStopsWhenJmxPortIsNonZero fails intermittently with AssertionError
          • GEODE-1308: CI failure: LocatorLauncherTest.testSetBindAddressToNonLocalHost
          • GEODE-1309: CI failure: ServerLauncherTest.testSetServerBindAddressToNonLocalHost
          • GEODE-3193: locator pid file is removed even if there was a problem while shutting down
          • GEODE-3413: Overhaul launcher tests and process tests
          • GEODE-3414: Cleanup org.apache.geode.internal.process package

          Note I moved all useful tests from LocatorLauncherAssemblyIntegrationTest
          into the other launcher tests in geode-core.

          Show
          jira-bot ASF subversion and git services added a comment - Commit 894f3ee710e500c83f06be660b852d389cbb94cb in geode's branch refs/heads/develop from Kirk Lund [ https://git-wip-us.apache.org/repos/asf?p=geode.git;h=894f3ee ] GEODE-3413 : overhaul launcher and process classes and tests This is primarily an overall of all ServerLauncher and LocatorLauncher tests and org.apache.geode.internal.process tests. The main classes in org.apachage.geode.internal.process package are also cleaned up. In addition, several bugs involving these classes and tests are fixed. Here is the complete list of tickets that are resolved in this overhaul: GEODE-1229 : LocatorLauncherRemoteJUnitTest.testStartOverwritesStalePidFile GEODE-2791 : LocatorLauncherAssemblyIntegrationTest.testLocatorStopsWhenJmxPortIsNonZero fails intermittently with AssertionError GEODE-1308 : CI failure: LocatorLauncherTest.testSetBindAddressToNonLocalHost GEODE-1309 : CI failure: ServerLauncherTest.testSetServerBindAddressToNonLocalHost GEODE-3193 : locator pid file is removed even if there was a problem while shutting down GEODE-3413 : Overhaul launcher tests and process tests GEODE-3414 : Cleanup org.apache.geode.internal.process package Note I moved all useful tests from LocatorLauncherAssemblyIntegrationTest into the other launcher tests in geode-core.
          Hide
          jira-bot ASF subversion and git services added a comment -

          Commit 894f3ee710e500c83f06be660b852d389cbb94cb in geode's branch refs/heads/feature/GEODE-3304 from Kirk Lund
          [ https://git-wip-us.apache.org/repos/asf?p=geode.git;h=894f3ee ]

          GEODE-3413: overhaul launcher and process classes and tests

          This is primarily an overall of all ServerLauncher and LocatorLauncher
          tests and org.apache.geode.internal.process tests. The main classes in
          org.apachage.geode.internal.process package are also cleaned up.

          In addition, several bugs involving these classes and tests are fixed.

          Here is the complete list of tickets that are resolved in this overhaul:

          • GEODE-1229: LocatorLauncherRemoteJUnitTest.testStartOverwritesStalePidFile
          • GEODE-2791: LocatorLauncherAssemblyIntegrationTest.testLocatorStopsWhenJmxPortIsNonZero fails intermittently with AssertionError
          • GEODE-1308: CI failure: LocatorLauncherTest.testSetBindAddressToNonLocalHost
          • GEODE-1309: CI failure: ServerLauncherTest.testSetServerBindAddressToNonLocalHost
          • GEODE-3193: locator pid file is removed even if there was a problem while shutting down
          • GEODE-3413: Overhaul launcher tests and process tests
          • GEODE-3414: Cleanup org.apache.geode.internal.process package

          Note I moved all useful tests from LocatorLauncherAssemblyIntegrationTest
          into the other launcher tests in geode-core.

          Show
          jira-bot ASF subversion and git services added a comment - Commit 894f3ee710e500c83f06be660b852d389cbb94cb in geode's branch refs/heads/feature/ GEODE-3304 from Kirk Lund [ https://git-wip-us.apache.org/repos/asf?p=geode.git;h=894f3ee ] GEODE-3413 : overhaul launcher and process classes and tests This is primarily an overall of all ServerLauncher and LocatorLauncher tests and org.apache.geode.internal.process tests. The main classes in org.apachage.geode.internal.process package are also cleaned up. In addition, several bugs involving these classes and tests are fixed. Here is the complete list of tickets that are resolved in this overhaul: GEODE-1229 : LocatorLauncherRemoteJUnitTest.testStartOverwritesStalePidFile GEODE-2791 : LocatorLauncherAssemblyIntegrationTest.testLocatorStopsWhenJmxPortIsNonZero fails intermittently with AssertionError GEODE-1308 : CI failure: LocatorLauncherTest.testSetBindAddressToNonLocalHost GEODE-1309 : CI failure: ServerLauncherTest.testSetServerBindAddressToNonLocalHost GEODE-3193 : locator pid file is removed even if there was a problem while shutting down GEODE-3413 : Overhaul launcher tests and process tests GEODE-3414 : Cleanup org.apache.geode.internal.process package Note I moved all useful tests from LocatorLauncherAssemblyIntegrationTest into the other launcher tests in geode-core.
          Hide
          jira-bot ASF subversion and git services added a comment -

          Commit 894f3ee710e500c83f06be660b852d389cbb94cb in geode's branch refs/heads/feature/GEODE-3304 from Kirk Lund
          [ https://git-wip-us.apache.org/repos/asf?p=geode.git;h=894f3ee ]

          GEODE-3413: overhaul launcher and process classes and tests

          This is primarily an overall of all ServerLauncher and LocatorLauncher
          tests and org.apache.geode.internal.process tests. The main classes in
          org.apachage.geode.internal.process package are also cleaned up.

          In addition, several bugs involving these classes and tests are fixed.

          Here is the complete list of tickets that are resolved in this overhaul:

          • GEODE-1229: LocatorLauncherRemoteJUnitTest.testStartOverwritesStalePidFile
          • GEODE-2791: LocatorLauncherAssemblyIntegrationTest.testLocatorStopsWhenJmxPortIsNonZero fails intermittently with AssertionError
          • GEODE-1308: CI failure: LocatorLauncherTest.testSetBindAddressToNonLocalHost
          • GEODE-1309: CI failure: ServerLauncherTest.testSetServerBindAddressToNonLocalHost
          • GEODE-3193: locator pid file is removed even if there was a problem while shutting down
          • GEODE-3413: Overhaul launcher tests and process tests
          • GEODE-3414: Cleanup org.apache.geode.internal.process package

          Note I moved all useful tests from LocatorLauncherAssemblyIntegrationTest
          into the other launcher tests in geode-core.

          Show
          jira-bot ASF subversion and git services added a comment - Commit 894f3ee710e500c83f06be660b852d389cbb94cb in geode's branch refs/heads/feature/ GEODE-3304 from Kirk Lund [ https://git-wip-us.apache.org/repos/asf?p=geode.git;h=894f3ee ] GEODE-3413 : overhaul launcher and process classes and tests This is primarily an overall of all ServerLauncher and LocatorLauncher tests and org.apache.geode.internal.process tests. The main classes in org.apachage.geode.internal.process package are also cleaned up. In addition, several bugs involving these classes and tests are fixed. Here is the complete list of tickets that are resolved in this overhaul: GEODE-1229 : LocatorLauncherRemoteJUnitTest.testStartOverwritesStalePidFile GEODE-2791 : LocatorLauncherAssemblyIntegrationTest.testLocatorStopsWhenJmxPortIsNonZero fails intermittently with AssertionError GEODE-1308 : CI failure: LocatorLauncherTest.testSetBindAddressToNonLocalHost GEODE-1309 : CI failure: ServerLauncherTest.testSetServerBindAddressToNonLocalHost GEODE-3193 : locator pid file is removed even if there was a problem while shutting down GEODE-3413 : Overhaul launcher tests and process tests GEODE-3414 : Cleanup org.apache.geode.internal.process package Note I moved all useful tests from LocatorLauncherAssemblyIntegrationTest into the other launcher tests in geode-core.
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund commented on the issue:

          https://github.com/apache/geode/pull/699

          Merged this PR to develop. Done!

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund commented on the issue: https://github.com/apache/geode/pull/699 Merged this PR to develop. Done!
          Hide
          githubbot ASF GitHub Bot added a comment -

          Github user kirklund closed the pull request at:

          https://github.com/apache/geode/pull/699

          Show
          githubbot ASF GitHub Bot added a comment - Github user kirklund closed the pull request at: https://github.com/apache/geode/pull/699

            People

            • Assignee:
              klund Kirk Lund
              Reporter:
              klund Kirk Lund
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development