// Path: zipkin-storage/cassandra/src/test/java/zipkin2/storage/cassandra/InternalForTests.java
// static void writeDependencyLinks(
//   CassandraStorage storage, List<DependencyLink> links, long midnightUTC) {
//   CqlSession session = storage.session();
//   PreparedStatement prepared = session.prepare("INSERT INTO " + Schema.TABLE_DEPENDENCY
//     + " (day,parent,child,calls,errors)"
//     + " VALUES (?,?,?,?,?)");
//   LocalDate day = Instant.ofEpochMilli(midnightUTC).atZone(ZoneOffset.UTC).toLocalDate();
//   for (DependencyLink link : links) {
//     int i = 0;
//     storage.session().execute(prepared.bind()
//       .setLocalDate(i++, day)
//       .setString(i++, link.parent())
//       .setString(i++, link.child())
//       .setLong(i++, link.callCount())
//       .setLong(i, link.errorCount()));
//   }
// }


import static zipkin2.storage.cassandra.InternalForTests.writeDependencyLinks;
import com.datastax.oss.driver.api.core.CqlSession;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.RegisterExtension;
import zipkin2.Span;
import zipkin2.storage.QueryRequest;
import static org.assertj.core.api.Assertions.assertThat;
import static zipkin2.TestObjects.DAY;
import static zipkin2.TestObjects.FRONTEND;
import static zipkin2.TestObjects.appendSuffix;
import static zipkin2.TestObjects.newTrace;
import static zipkin2.storage.ITDependencies.aggregateLinks;
      CassandraStorageExtension.blockWhileInFlight(storage);
    }

    @Override public void clear() {
      // Intentionally don't clean up as each method runs in an isolated keyspace. This prevents
      // adding more load to the shared Cassandra instance used for all tests.
    }

    @Test void overFetchesToCompensateForDuplicateIndexData(TestInfo testInfo) throws Exception {
      String testSuffix = testSuffix(testInfo);
      int traceCount = 2000;

      List<Span> spans = new ArrayList<>();
      for (int i = 0; i < traceCount; i++) {
        final long delta = i * 1000; // all timestamps happen a millisecond later
        for (Span s : newTrace(testSuffix)) {
          Span.Builder builder = s.toBuilder()
            .timestamp(s.timestampAsLong() + delta)
            .clearAnnotations();
          s.annotations().forEach(a -> builder.addAnnotation(a.timestamp() + delta, a.value()));
          spans.add(builder.build());
        }
      }

      accept(spans.toArray(new Span[0]));

      // Index ends up containing more rows than services * trace count, and cannot be de-duped
      // in a server-side query.
      int localServiceCount = storage.serviceAndSpanNames().getServiceNames().execute().size();
      assertThat(storage
// Path: zipkin-storage/cassandra/src/test/java/zipkin2/storage/cassandra/InternalForTests.java
// static void writeDependencyLinks(
//   CassandraStorage storage, List<DependencyLink> links, long midnightUTC) {
//   CqlSession session = storage.session();
//   PreparedStatement prepared = session.prepare("INSERT INTO " + Schema.TABLE_DEPENDENCY
//     + " (day,parent,child,calls,errors)"
//     + " VALUES (?,?,?,?,?)");
//   LocalDate day = Instant.ofEpochMilli(midnightUTC).atZone(ZoneOffset.UTC).toLocalDate();
//   for (DependencyLink link : links) {
//     int i = 0;
//     storage.session().execute(prepared.bind()
//       .setLocalDate(i++, day)
//       .setString(i++, link.parent())
//       .setString(i++, link.child())
//       .setLong(i++, link.callCount())
//       .setLong(i, link.errorCount()));
//   }
// }


// Path: zipkin-storage/cassandra/src/test/java/zipkin2/storage/cassandra/ITCassandraStorageHeavy.java
import static zipkin2.storage.cassandra.InternalForTests.writeDependencyLinks;
import com.datastax.oss.driver.api.core.CqlSession;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.RegisterExtension;
import zipkin2.Span;
import zipkin2.storage.QueryRequest;
import static org.assertj.core.api.Assertions.assertThat;
import static zipkin2.TestObjects.DAY;
import static zipkin2.TestObjects.FRONTEND;
import static zipkin2.TestObjects.appendSuffix;
import static zipkin2.TestObjects.newTrace;
import static zipkin2.storage.ITDependencies.aggregateLinks;

      CassandraStorageExtension.blockWhileInFlight(storage);
    }

    @Override public void clear() {
      // Intentionally don't clean up as each method runs in an isolated keyspace. This prevents
      // adding more load to the shared Cassandra instance used for all tests.
    }

    @Test void overFetchesToCompensateForDuplicateIndexData(TestInfo testInfo) throws Exception {
      String testSuffix = testSuffix(testInfo);
      int traceCount = 2000;

      List<Span> spans = new ArrayList<>();
      for (int i = 0; i < traceCount; i++) {
        final long delta = i * 1000; // all timestamps happen a millisecond later
        for (Span s : newTrace(testSuffix)) {
          Span.Builder builder = s.toBuilder()
            .timestamp(s.timestampAsLong() + delta)
            .clearAnnotations();
          s.annotations().forEach(a -> builder.addAnnotation(a.timestamp() + delta, a.value()));
          spans.add(builder.build());
        }
      }

      accept(spans.toArray(new Span[0]));

      // Index ends up containing more rows than services * trace count, and cannot be de-duped
      // in a server-side query.
      int localServiceCount = storage.serviceAndSpanNames().getServiceNames().execute().size();
      assertThat(storage
        .session()