Repository: open-telemetry/opentelemetry-java
File: sdk/trace/src/test/java/io/opentelemetry/sdk/trace/export/BatchSpanProcessorTest.java (Java)

Code before:
        .isInstanceOf(NullPointerException.class)
        .hasMessage("unit");
    assertThatThrownBy(() -> BatchSpanProcessor.builder(mockSpanExporter).setExporterTimeout(null))
        .isInstanceOf(NullPointerException.class)
        .hasMessage("timeout");
    assertThatThrownBy(() -> BatchSpanProcessor.builder(mockSpanExporter).setMaxQueueSize(0))
        .isInstanceOf(IllegalArgumentException.class)
        .hasMessage("maxQueueSize must be positive.");
  }

  @Test
  void builderAdjustMaxBatchSize() {
    SpanExporter dummyExporter = new CompletableSpanExporter();

    BatchSpanProcessorBuilder smallQueueBuilder =
        BatchSpanProcessor.builder(dummyExporter).setMaxQueueSize(1).setMaxExportBatchSize(1000);
    smallQueueBuilder.build();

    assertThat(smallQueueBuilder.getMaxExportBatchSize()).isEqualTo(1);

    BatchSpanProcessorBuilder largeBatchBuilder =
        BatchSpanProcessor.builder(dummyExporter).setMaxQueueSize(513).setMaxExportBatchSize(1000);
    largeBatchBuilder.build();

    assertThat(largeBatchBuilder.getMaxExportBatchSize())
        .isEqualTo(BatchSpanProcessorBuilder.DEFAULT_MAX_EXPORT_BATCH_SIZE);
  }

  @Test
  void startEndRequirements() {
    BatchSpanProcessor spansProcessor =
        BatchSpanProcessor.builder(new WaitingSpanExporter(0, CompletableResultCode.ofSuccess()))
            .build();
    assertThat(spansProcessor.isStartRequired()).isFalse();
    assertThat(spansProcessor.isEndRequired()).isTrue();
  }

  @Test
  void exportDifferentSampledSpans() {
    WaitingSpanExporter waitingSpanExporter =
        new WaitingSpanExporter(2, CompletableResultCode.ofSuccess());
    sdkTracerProvider =
        SdkTracerProvider.builder()
            .addSpanProcessor(
                BatchSpanProcessor.builder(waitingSpanExporter)
                    .setScheduleDelay(MAX_SCHEDULE_DELAY_MILLIS, TimeUnit.MILLISECONDS)
                    .build())
            .build();

    ReadableSpan span1 = createEndedSpan(SPAN_NAME_1);
    ReadableSpan span2 = createEndedSpan(SPAN_NAME_2);

Review comment (performance):
could we split this into two separate tests? aka one where it selects `maxQueueSize` and another where it selects `DEFAULT_MAX_EXPORT_BATCH_SIZE`

Code after:
        .hasMessage("timeout must be non-negative");
    assertThatThrownBy(
            () -> BatchSpanProcessor.builder(mockSpanExporter).setExporterTimeout(1, null))
        .isInstanceOf(NullPointerException.class)
        .hasMessage("unit");
    assertThatThrownBy(() -> BatchSpanProcessor.builder(mockSpanExporter).setExporterTimeout(null))
        .isInstanceOf(NullPointerException.class)
        .hasMessage("timeout");
    assertThatThrownBy(() -> BatchSpanProcessor.builder(mockSpanExporter).setMaxQueueSize(0))
        .isInstanceOf(IllegalArgumentException.class)
        .hasMessage("maxQueueSize must be positive.");
  }

  @Test
  void builderAdjustMaxBatchSize() {
    SpanExporter dummyExporter = new CompletableSpanExporter();

    BatchSpanProcessorBuilder builder =
        BatchSpanProcessor.builder(dummyExporter).setMaxQueueSize(513).setMaxExportBatchSize(1000);
    builder.build();

    assertThat(builder.getMaxExportBatchSize()).isEqualTo(513);
    assertThat(builder.getMaxQueueSize()).isEqualTo(513);
  }

  @Test
  void maxExportBatchSizeExceedsQueueSize() throws InterruptedException {
    // Given a processor configured with a maxExportBatchSize > maxQueueSize, ensure that after n =
    // maxQueueSize spans are ended, export is triggered and that the queue is fully drained and
    // exported.
    int maxQueueSize = 2048;
    when(mockSpanExporter.export(any())).thenReturn(CompletableResultCode.ofSuccess());
    sdkTracerProvider =
        SdkTracerProvider.builder()
            .addSpanProcessor(
                BatchSpanProcessor.builder(mockSpanExporter)
                    .setScheduleDelay(Duration.ofSeconds(Integer.MAX_VALUE))
                    .setMaxExportBatchSize(2049)
                    .setMaxQueueSize(maxQueueSize)
                    .build())
            .build();

    for (int i = 0; i < maxQueueSize; i++) {
      createEndedSpan("span " + i);
    }

    Thread.sleep(10);

    await().untilAsserted(() -> verify(mockSpanExporter, times(1)).export(any()));
  }