2010-01-22 14 views
5

Estoy intentando crear una prueba que simule una falla del sistema para garantizar la integridad de una base de datos Oracle Berkeley DB XML. Actualmente, se está experimentando la pérdida de datos durante una operación de inserción, por lo que me gustaría configurar una prueba que comience a insertar una cantidad arbitraria de documentos y que saque el proceso a lo largo del camino (similar a cuando alguien tira del cable de alimentación). Después de que el proceso muera, quiero generar un nuevo proceso y abrir la base de datos para garantizar que se abra correctamente.JUnit prueba una falla en la base de datos?

La prueba de unidad es una de muchas en una compilación maven y esta prueba debe ejecutarse en entornos Linux y Windows XP. Mi proceso de pensamiento actual es elaborar un script para ambos sistemas operativos ya que puedo usar el script para matar el proceso y comenzar uno nuevo en su lugar. ¿Tengo alguna otra opción? ¿Puedo crear un espacio de proceso/máquina virtual usando JUnit?

+0

¿Quiere probar la base de datos? ¿O quieres probar tu código que usa esa base de datos? –

+0

Quiero que pruebe mi código ya que la base de datos en cuestión está incrustada. La corrupción de datos durante una falla del sistema es un problema conocido con Berkeley DB XML no transaccional (que tenemos que usar). Estoy implementando algunas verificaciones de cordura en mi código contenedor para mitigar la corrupción. – toddk

+8

Luego, querrá escribir pruebas unitarias para demostrar que sus controles de cordura hacen lo que se supone que deben hacer. Puede escribir un simulacro de la interfaz DB y simular varias fallas para que tenga un comportamiento determinista. El problema fundamental es probar que los controles de cordura que implementaste realmente evitan la corrupción que describes. No haría esto en una prueba unitaria a menos que las fallas sean reproducibles en cada ejecución de prueba. Si no lo son, trataría la prueba como una prueba de rendimiento/estabilidad en su lugar. – ShabbyDoo

Respuesta

1

No consideraría este tipo de prueba una prueba unitaria, pero sin embargo, es posible que pueda hacer algo como esto.

  1. Utilice la clase ProcessBuilder para construir e iniciar el proceso, almacene el objeto de proceso devuelto.
  2. Comience a insertar registros.
  3. En algún momento destroy() el proceso.

Tenga en cuenta los comentarios anteriores sobre la naturaleza no determinista de esta prueba.

Me he encontrado con el SQLite team also doing a simulated failure strategy como parte de su conjunto de pruebas automáticas.

0

Este tipo de comportamiento es perfecto para las transacciones. Si su código fuera a iniciar una transacción, la base de datos sabría cómo mantener la coherencia de los datos cuando se cancelara una transacción debido a la muerte de un proceso. Puede que estés reinventando la rueda aquí. The Daily WTF tiene un buen ejemplo de cómo nos engañamos a nosotros mismos en reinventing the wheel.

Eche un buen vistazo a su primera revisión y dígate a ti mismo, "guantes".

+4

Estás predicando al coro. Me dijeron que no podíamos usar la versión transaccional del DB ... así que creo que tendré que preguntar "¿por qué no?" antes de ir mucho más allá. – toddk

0

¿Qué pasa con el uso de los hilos insead de todo el proceso? Por ejemplo:

  • Puede crear un hilo de trabajador en segundo plano y darle un montón de trabajo.
  • Luego, en el hilo de la prueba principal espere un número aleatorio de milisegundos. Entonces mata el hilo.
  • Entonces quizás quiera esperar nuevamente para guardar en caché los datos almacenados (o no, dependiendo de lo que está probando)
  • Luego ejecute su cordura. ¡Si está lanzando, la prueba fallará aquí cuando lo necesite!
  • Aquí listo.

Preferiría llamar a la prueba anterior una prueba de integración. De todos modos, hará lo que necesites. Se ejecutará varias veces se probará el caso de corrupción de datos diferentes en cada ejecución.

0

No lo consideraría adecuado para una prueba UNIT. en pruebas unitarias, usted quiere probar secciones pequeñas de código, por ejemplo, su código de cordura, posiblemente con una base de prueba simulada. o llamando solo a una parte de tu código. Lo que te refieres es una prueba más complicada que vale la pena hacer pero no necesariamente vale la pena automatizar y ejecutar repetidamente como parte de las pruebas de tu unidad que presumiblemente ejecutas con bastante frecuencia (en compilación o cada noche o cuando sea). Agregar este tipo de prueba también probablemente ralentizará las pruebas de su unidad e impondrá las restricciones en el entorno donde se pueden ejecutar las pruebas de su unidad. Sugiero escribir pruebas de unidades más pequeñas y probar todo junto por separado.

Me.

Cuestiones relacionadas