public static Write write() {
    // 1000 for batch size is good enough in many cases,
    // ex: if document size is large, around 10KB, the request's size will be around 10MB
    // if document size is small, around 1KB, the request's size will be around 1MB
    return new AutoValue_SolrIO_Write.Builder().setMaxBatchSize(1000).build();
  }
@Test
  public void testWriteRetry() throws Throwable {
    thrown.expect(IOException.class);
    thrown.expectMessage("Error writing to Solr");

    // entry state of the release tracker to ensure we only unregister newly created objects
    @SuppressWarnings("unchecked")
    Set<Object> entryState = ImmutableSet.copyOf(ObjectReleaseTracker.OBJECTS.keySet());

    SolrIO.Write write =
        SolrIO.write()
            .withConnectionConfiguration(connectionConfiguration)
            .withRetryConfiguration(
                SolrIO.RetryConfiguration.create(3, Duration.standardMinutes(3))
                    .withRetryPredicate(new LenientRetryPredicate()))
            .to("wrong-collection");

    List<SolrInputDocument> data = SolrIOTestUtils.createDocuments(NUM_DOCS);
    pipeline.apply(Create.of(data)).apply(write);

    try {
      pipeline.run();
    } catch (final Pipeline.PipelineExecutionException e) {
      // Hack: await all worker threads completing (https://github.com/apache/beam/issues/18893)
      int waitAttempts = 30; // defensive coding
      while (namedThreadIsAlive("direct-runner-worker") && waitAttempts-- >= 0) {
        LOG.info("Pausing to allow direct-runner-worker threads to finish");
        Thread.sleep(1000);
      }

      // remove solrClients created by us as there are no guarantees on Teardown here
      for (Object o : ObjectReleaseTracker.OBJECTS.keySet()) {
        if (o instanceof SolrZkClient && !entryState.contains(o)) {
          LOG.info("Removing unreleased SolrZkClient");
          ObjectReleaseTracker.release(o);
        }
      }

      // check 2 retries were initiated by inspecting the log before passing on the exception
      expectedLogs.verifyWarn(String.format(SolrIO.Write.WriteFn.RETRY_ATTEMPT_LOG, 1));
      expectedLogs.verifyWarn(String.format(SolrIO.Write.WriteFn.RETRY_ATTEMPT_LOG, 2));

      throw e.getCause();
    }

    fail("Pipeline should not have run to completion");
  }