Тестирование 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()
Что мы делаем, у нас есть метод, который вызывает усечение для каждого семейства столбцов между тестами. Это удалит все данные.
Ответ 2
Я думаю, вы можете взглянуть на блок cassandra: https://github.com/jsevellec/cassandra-unit/wiki
Ответ 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 и написал ему, чтобы помочь мне проверить эти случаи.