@After
 public void tearDown() throws Exception {
   super.tearDown();
   if (readerContext != null) {
     readerContext.reader().close();
   }
   writer.close();
 }
  @Test
  public void verifyThreadNames() throws Exception {

    ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
    Set<String> preNodeStartThreadNames = Sets.newHashSet();
    for (long l : threadBean.getAllThreadIds()) {
      ThreadInfo threadInfo = threadBean.getThreadInfo(l);
      if (threadInfo != null) {
        preNodeStartThreadNames.add(threadInfo.getThreadName());
      }
    }
    logger.info("pre node threads are {}", preNodeStartThreadNames);
    String node = internalCluster().startNode();
    logger.info("do some indexing, flushing, optimize, and searches");
    int numDocs = randomIntBetween(2, 100);
    IndexRequestBuilder[] builders = new IndexRequestBuilder[numDocs];
    for (int i = 0; i < numDocs; ++i) {
      builders[i] =
          client()
              .prepareIndex("idx", "type")
              .setSource(
                  jsonBuilder()
                      .startObject()
                      .field("str_value", "s" + i)
                      .field("str_values", new String[] {"s" + (i * 2), "s" + (i * 2 + 1)})
                      .field("l_value", i)
                      .field("l_values", new int[] {i * 2, i * 2 + 1})
                      .field("d_value", i)
                      .field("d_values", new double[] {i * 2, i * 2 + 1})
                      .endObject());
    }
    indexRandom(true, builders);
    int numSearches = randomIntBetween(2, 100);
    for (int i = 0; i < numSearches; i++) {
      assertNoFailures(
          client()
              .prepareSearch("idx")
              .setQuery(QueryBuilders.termQuery("str_value", "s" + i))
              .get());
      assertNoFailures(
          client().prepareSearch("idx").setQuery(QueryBuilders.termQuery("l_value", i)).get());
    }
    Set<String> threadNames = Sets.newHashSet();
    for (long l : threadBean.getAllThreadIds()) {
      ThreadInfo threadInfo = threadBean.getThreadInfo(l);
      if (threadInfo != null) {
        threadNames.add(threadInfo.getThreadName());
      }
    }
    logger.info("post node threads are {}", threadNames);
    threadNames.removeAll(preNodeStartThreadNames);
    logger.info("post node *new* threads are {}", threadNames);
    for (String threadName : threadNames) {
      // ignore some shared threads we know that are created within the same VM, like the shared
      // discovery one
      // or the ones that are occasionally come up from ElasticsearchSingleNodeTest
      if (threadName.contains("[" + MulticastChannel.SHARED_CHANNEL_NAME + "]")
          || threadName.contains("[" + ElasticsearchSingleNodeTest.nodeName() + "]")
          || threadName.contains("Keep-Alive-Timer")) {
        continue;
      }
      String nodePrefix =
          "("
              + Pattern.quote(InternalTestCluster.TRANSPORT_CLIENT_PREFIX)
              + ")?("
              + Pattern.quote(ElasticsearchIntegrationTest.SUITE_CLUSTER_NODE_PREFIX)
              + "|"
              + Pattern.quote(ElasticsearchIntegrationTest.TEST_CLUSTER_NODE_PREFIX)
              + "|"
              + Pattern.quote(TribeTests.SECOND_CLUSTER_NODE_PREFIX)
              + ")";
      assertThat(threadName, RegexMatcher.matches("\\[" + nodePrefix + "\\d+\\]"));
    }
  }