All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.stargate.it.cql.SchemaChangesTest Maven / Gradle / Ivy

package io.stargate.it.cql;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.verify;

import com.datastax.oss.driver.api.core.CqlIdentifier;
import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.CqlSessionBuilder;
import com.datastax.oss.driver.api.core.metadata.schema.SchemaChangeListener;
import com.datastax.oss.driver.api.core.metadata.schema.TableMetadata;
import com.datastax.oss.driver.api.core.servererrors.AlreadyExistsException;
import com.datastax.oss.driver.api.core.servererrors.InvalidQueryException;
import io.stargate.it.BaseIntegrationTest;
import io.stargate.it.driver.CqlSessionExtension;
import io.stargate.it.driver.CqlSessionSpec;
import io.stargate.it.driver.TestKeyspace;
import io.stargate.it.driver.WithProtocolVersion;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
@ExtendWith(CqlSessionExtension.class)
@CqlSessionSpec(customBuilder = "registerListener")
public abstract class SchemaChangesTest extends BaseIntegrationTest {

  private static SchemaChangeListener schemaChanges;
  @Captor ArgumentCaptor tableCaptor;
  @Captor ArgumentCaptor previousTableCaptor;

  public static CqlSessionBuilder registerListener(CqlSessionBuilder builder) {
    schemaChanges = Mockito.mock(SchemaChangeListener.class);
    return builder.withSchemaChangeListener(schemaChanges);
  }

  @Test
  @DisplayName("Should notify of schema changes")
  public void schemaChangesTest(CqlSession session, @TestKeyspace CqlIdentifier keyspaceId) {
    // This is not an extensive coverage of the driver's schema metadata, we just want to check that
    // the schema events on the control connection are wired correctly.
    session.execute("CREATE TABLE foo(k int PRIMARY KEY)");
    verify(schemaChanges).onTableCreated(tableCaptor.capture());
    TableMetadata createdTable = tableCaptor.getValue();
    assertThat(createdTable.getName().asInternal()).isEqualTo("foo");

    assertThat(session.getMetadata().getKeyspace(keyspaceId).flatMap(ks -> ks.getTable("foo")))
        .hasValue(createdTable);

    session.execute("ALTER TABLE foo ADD v int");
    verify(schemaChanges).onTableUpdated(tableCaptor.capture(), previousTableCaptor.capture());
    TableMetadata previousTable = previousTableCaptor.getValue();
    assertThat(previousTable).isEqualTo(createdTable);
    TableMetadata updatedTable = tableCaptor.getValue();
    assertThat(updatedTable.getName().asInternal()).isEqualTo("foo");
    assertThat(updatedTable.getColumns().keySet())
        .containsExactly(CqlIdentifier.fromInternal("k"), CqlIdentifier.fromInternal("v"));

    assertThat(session.getMetadata().getKeyspace(keyspaceId).flatMap(ks -> ks.getTable("foo")))
        .hasValue(updatedTable);

    session.execute("DROP TABLE foo");
    verify(schemaChanges).onTableDropped(tableCaptor.capture());
    TableMetadata droppedTable = tableCaptor.getValue();
    assertThat(droppedTable.getName().asInternal()).isEqualTo("foo");

    assertThat(session.getMetadata().getKeyspace(keyspaceId))
        .hasValueSatisfying(ks -> assertThat(ks.getTable("foo")).isEmpty());
  }

  @Test
  @DisplayName("Should fail when trying to create schema elements that already exist")
  public void alreadyExistsErrors(CqlSession session, @TestKeyspace CqlIdentifier keyspaceId) {
    assertThatThrownBy(
            () ->
                session.execute(
                    String.format(
                        "CREATE KEYSPACE %s WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 }",
                        keyspaceId.asCql(false))))
        .isInstanceOf(AlreadyExistsException.class)
        .hasMessageContaining("Keyspace ")
        .hasMessageContaining("already exists");

    session.execute("CREATE TABLE foo(k int PRIMARY KEY)");
    assertThatThrownBy(() -> session.execute("CREATE TABLE foo(k int PRIMARY KEY)"))
        .isInstanceOf(AlreadyExistsException.class)
        .hasMessageContaining("Object ")
        .hasMessageContaining("already exists");

    session.execute("CREATE TYPE t(i int)");
    assertThatThrownBy(() -> session.execute("CREATE TYPE t(i int)"))
        .isInstanceOf(InvalidQueryException.class)
        .hasMessageContaining("A user type ")
        .hasMessageContaining("already exists");
  }

  @WithProtocolVersion("V4")
  public static class WithV4ProtocolVersionTest extends SchemaChangesTest {}

  @WithProtocolVersion("V5")
  public static class WithV5ProtocolVersionTest extends SchemaChangesTest {}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy