/** Tests concurrent grid initialization */
  public void testConcurrentGridGetOrStartCon() throws Exception {
    final IgniteConfiguration cfg = getConfiguration(null);

    final AtomicReference<Ignite> ref = new AtomicReference<>();

    try {
      GridTestUtils.runMultiThreaded(
          new Runnable() {
            @Override
            public void run() {
              // must return same instance in each thread

              try {
                Ignite ignite = Ignition.getOrStart(cfg);

                boolean set = ref.compareAndSet(null, ignite);

                if (!set) assertEquals(ref.get(), ignite);
              } catch (IgniteException e) {
                throw new RuntimeException("Ignite error", e);
              }
            }
          },
          CONCURRENCY,
          "GridCreatorThread");
    } catch (Exception ignored) {
      fail("Exception is not expected");
    }

    G.stopAll(true);

    assertTrue(G.allGrids().isEmpty());
  }
  /** @throws Exception If failed. */
  public void testStartMultipleNonDefaultGrids() throws Exception {
    try {
      multithreaded(
          new Callable<Object>() {
            @Nullable
            @Override
            public Object call() throws Exception {
              try {
                IgniteConfiguration cfg = new IgniteConfiguration();

                cfg.setGridName("TEST_NAME");
                cfg.setConnectorConfiguration(null);

                G.start(cfg);
              } catch (Throwable t) {
                error("Caught exception while starting grid.", t);
              }

              info("Thread finished.");

              return null;
            }
          },
          5,
          "grid-starter");

      assert G.allGrids().size() == 1;

      assert G.ignite("TEST_NAME") != null;
    } finally {
      G.stopAll(true);
    }
  }
 /** @throws Exception If failed. */
 @Override
 protected void afterTest() throws Exception {
   G.stopAll(false);
 }
  /**
   * @param gridName Grid name ({@code null} for default grid).
   * @throws Exception If failed.
   */
  private void checkConcurrentStartStop(@Nullable final String gridName) throws Exception {
    final AtomicInteger startedCnt = new AtomicInteger();
    final AtomicInteger stoppedCnt = new AtomicInteger();

    IgnitionListener lsnr =
        new IgnitionListener() {
          @SuppressWarnings("StringEquality")
          @Override
          public void onStateChange(@Nullable String name, IgniteState state) {
            assert name == gridName;

            info("On state change fired: " + state);

            if (state == STARTED) startedCnt.incrementAndGet();
            else {
              assert state == STOPPED : "Unexpected state: " + state;

              stoppedCnt.incrementAndGet();
            }
          }
        };

    G.addListener(lsnr);

    try {
      final int iterCnt = 3;

      multithreaded(
          new Callable<Object>() {
            @Nullable
            @Override
            public Object call() throws Exception {
              for (int i = 0; i < iterCnt; i++) {
                try {
                  IgniteConfiguration cfg = getConfiguration(gridName);

                  G.start(cfg);
                } catch (Exception e) {
                  String msg = e.getMessage();

                  if (msg != null
                      && (msg.contains("Default Ignite instance has already been started.")
                          || msg.contains(
                              "Ignite instance with this name has already been started:")))
                    info("Caught expected exception: " + msg);
                  else throw e; // Unexpected exception.
                } finally {
                  stopGrid(gridName);
                }
              }

              info("Thread finished.");

              return null;
            }
          },
          5,
          "tester");

      assert G.allGrids().isEmpty();

      assert startedCnt.get() == iterCnt;
      assert stoppedCnt.get() == iterCnt;
    } finally {
      G.removeListener(lsnr);

      G.stopAll(true);
    }
  }
 /** {@inheritDoc} */
 @Override
 protected void afterTestsStopped() throws Exception {
   G.stopAll(true);
 }