Тестирование JUnit Cassandra со встроенным сервером

Каков наилучший подход для написания модульных тестов для кода, который сохраняет данные в хранилище данных nosql, в нашем случае cassandra?

= > Мы используем встроенный серверный подход, используя утилиту из git hub (https://github.com/hector-client/hector/blob/master/test/src/main/java/me/prettyprint/hector/testutils/EmbeddedServerHelper.java). Однако я видел некоторые проблемы с этим. 1) Он сохраняет данные в нескольких тестовых случаях, что затрудняет нам проверку данных в тестовых примерах тестового класса. Я попытался вызвать cleanUp @После каждого тестового примера, но это не похоже на очистку данных. 2) У нас заканчивается память, так как мы добавляем больше тестов, и это может быть из-за 1, но я пока не уверен в этом. У меня в настоящее время размер кучи 1G для запуска моей сборки.

= > Другой подход, о котором я думал, состоит в том, чтобы издеваться над хранилищем cassandra. Но это может привести к утечке некоторых проблем в схеме cassandra, поскольку мы часто находили, что вышеупомянутый подход ловит проблемы с тем, как данные хранятся в cassandra.

Пожалуйста, дайте мне знать ваши мысли об этом, и если кто-то использовал EmbeddedServerHelper и знакомы с проблемами, о которых я упоминал.


Просто обновление. Я смог решить 2) исчерпание проблемы с кучей java-пространства при запуске сборки путем изменения параметра in_memory_compaction_limit_in_mb до 32 в файле cassandra.yaml, используемом встроенным сервером тестирования. Следующая ссылка помогла мне http://www.datastax.com/docs/0.7/configuration/storage_configuration#in-memory-compaction-limit-in-mb. Это было 64 года, и он начал неуспешно во время уплотнения.

Ответы

Ответ 1

Мы используем встроенный сервер Cassandra, и я думаю, что это лучший подход при тестировании Cassandra, поэтому насмешка над API Cassandra слишком подвержена ошибкам.

EmbeddedServerHelper.cleanup() просто удаляет файлы из файловой системы, но данные все еще могут существовать в памяти.

В EmbeddedServerHelper метод teardown(), но я не уверен, насколько это эффективно, поскольку в cassandra много статических синглетонов, состояние которых не очищается teardown()

Что мы делаем, у нас есть метод, который вызывает усечение для каждого семейства столбцов между тестами. Это удалит все данные.

Ответ 3

Я использую плагин Mojo Cassandra Maven.

Вот пример конфигурации плагина, который я использую для раскрутки сервера Cassandra для использования моими модульными тестами:

 <build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>cassandra-maven-plugin</artifactId>
            <version>1.1.0-1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>start</goal>
                        <goal>flush</goal>
                        <goal>cleanup</goal>
                    </goals>
                    <phase>compile</phase>
                </execution>
            </executions>
        </plugin>
     <plugins>
  <build>

Мне удалось заставить работать вспомогательный класс встроенного сервера Hector, что может быть очень полезно, однако я столкнулся с конфликтами загрузчиков классов из-за этой ошибки.

Ответ 4

Вы не можете перезапустить экземпляр Cassandra внутри одной виртуальной машины - у Cassandra есть "выключение для каждой политики убийства" из-за использования неполадок, которые они используют.

Вам также не нужно перезапускать Casandra, просто удалите все семейства столбцов (CF). Чтобы удалить CF, вам нужно сначала очистить данные, сжать его и после этого вы можете его удалить.

Этот код подключится к встроенной Cassandra и выполнит требуемый cleaup:

private void cleanAndCompact() throws Exception {
    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
    ObjectName ssn = new ObjectName("org.apache.cassandra.db:type=StorageService");
    StorageServiceMBean ssmb = JMX.newMBeanProxy(mbs, ssn, StorageServiceMBean.class);

    List<String> keyspaces = ssmb.getKeyspaces();
    if (keyspaces == null) {
        LOG.info("No keysaces to cleanup");
        return;
    }

    for (String keyspace : keyspaces) {
        if (keyspace.equalsIgnoreCase("system")) {
            continue;
        }
        execCleanup(ssmb, keyspace);
    }

}

private void execCleanup(StorageServiceMBean ssmb, String keyspace) throws Exception {
    LOG.info("Cleaning up keyspace: " + keyspace);

    ssmb.invalidateKeyCaches(keyspace, new String[0]);
    ssmb.invalidateRowCaches(keyspace, new String[0]);
    ssmb.forceTableFlush(keyspace, new String[0]);
    ssmb.forceTableCompaction(keyspace, new String[0]);
    ssmb.forceTableCleanup(keyspace, new String[0]);
}

Теперь выполните сброс CLI CF script:

CliMain.main(new String[] { "-host", host, "-port", Integer.toString(rpcPort), "-f", "/my/script/path/script.txt","-username", "myUser", "-password", "123456" });

и script.txt могут иметь:

use ExampleTestSpace;
drop column family ExampleCF;

Ответ 5

Под "не кажется, что очищает данные", что именно вы имеете в виду? Что вы все еще видите ваши данные в базе данных?

Эта проблема может быть вызвана тем, что Cassandra не удаляет "значения" мгновенно, но только после того, как прошло gc_grace_seconds секунд (обычно по умолчанию - 10 дней). Кассандра отмечает значения, которые нужно удалить.

Ответ 6

В дополнение к тому, что было опубликовано, есть случаи, когда вы хотите протестировать обработку ошибок - как ваше приложение ведет себя, когда запрос Cassandra выходит из строя.

Есть несколько библиотек, которые могут вам помочь:

Я автор cassandra-spy и написал ему, чтобы помочь мне проверить эти случаи.