Esta semana, los usuarios de Hacker News
decidieron discutir la pregunta "¿Cuál es la cantidad máxima de código malo, pero que sigue funcionando, que has visto?" (
usuarios posteriores de
Reddit se unieron a ellos). En los comentarios, se contaron muchas historias "divertidas" sobre cosas que encontramos de vez en cuando; pero la historia sobre el código "DBMS avanzado utilizado por la mayoría de las compañías Fortune 100" atrajo la mayor atención.
El ganador de la nominación de Lovecraft Horror fue merecidamente la
historia de un ex desarrollador de Oracle que trabajó en Oracle Database durante el desarrollo de la versión 12.2. La base del código del DBMS en ese momento era de 25 millones de líneas en C, y tan pronto como cambió solo una de estas líneas, se rompieron
miles de pruebas escritas anteriormente.
A lo largo de los años, varias generaciones de programadores han trabajado en el código, que fueron perseguidos regularmente por plazos estrictos, y gracias a esto, el código podría convertirse en una verdadera pesadilla. Hoy consiste en "partes" complejas de código que son responsables de la lógica, la administración de la memoria, el cambio de contexto y mucho más; están conectados entre sí utilizando
miles de banderas diferentes. Todo el código está interconectado por una macro misteriosa que no se puede descifrar sin recurrir a un cuaderno, en el que debe escribir lo que hacen las partes relevantes de la macro. Como resultado, un desarrollador puede tomar uno o dos días solo para descubrir qué hace realmente la macro.
Para predecir el comportamiento del código en uno u otro caso, debe comprender y recordar qué valores y consecuencias pueden tener 20 (o incluso cien) indicadores. La situación se ve agravada por el hecho de que varios desarrolladores usaron sus propios tipos, que eran esencialmente lo mismo (por ejemplo, int32), y casi nadie se arriesgaría a tocar ese legado (podemos decir con certeza que este fue el caso en Base de código Oracle 8i).
Surge la pregunta: ¿cómo, con todo esto, Oracle Database todavía puede mantenerse en pie? El secreto está en millones de pruebas. Su implementación completa puede llevar de 20 a 30 horas (al mismo tiempo que se realizan distribuidos en un clúster de prueba de 100-200 servidores).
El equipo que trabajó en el producto a finales de los 90 y se adhirió a las ideas de TDD (desarrollo basado en pruebas), tuvo la siguiente opinión: "las pruebas automatizadas significan que no es necesario que escriba un código que se pueda entender; en su lugar, debe pensar en las pruebas ". En el futuro, los desarrolladores se vieron obligados a adherirse a los principios establecidos por ellos, y ahora estamos presenciando en la práctica en qué se convirtió esta idea a largo plazo, con todas sus ventajas y desventajas.
Hoy, el proceso de reparación de un nuevo error en la base de datos Oracle lleva de varias semanas a varios meses. Al principio, el desarrollador tiene que pasar varios días solo para descubrir las banderas que necesita (la interacción misteriosa que causa un error), después de lo cual a menudo tiene que agregar su propia bandera, que será responsable de procesar un script específico que causó el error.
Luego envía el código para la prueba, y al día siguiente cambia tranquilamente a otra tarea, esperando que el clúster de prueba ensamble un nuevo ensamblaje de Oracle DB y ejecute todas las pruebas en él. Si el desarrollador tiene suerte, cerca de 100 pruebas se "sonrojarán"; si no (y esta opción ocurre con más frecuencia), alrededor de 1000, y tendrá que verificar cuáles de sus suposiciones sobre el funcionamiento del código existente resultaron ser incorrectas; es muy posible que descubra que necesita estudiar una docena de banderas diferentes, que de manera obvia participaron en el trabajo del código que cambió.
Tendrá que repetir este proceso durante un par de semanas antes de que la suerte finalmente le sonría y todas las pruebas finalmente pasen. Después de lo cual tendrá que escribir varias docenas de pruebas, para asegurarse de que el desarrollador, que alterará su código en el futuro, no romperá su "solución". Luego, las mejoras se enviarán a una revisión, que puede llevar de varias semanas a un par de meses, después de lo cual el error finalmente se fusionará con la rama de trabajo principal.
Debido al hecho de que lleva al menos un día construir el DBMS y ejecutar las pruebas, se espera que cada desarrollador trabaje simultáneamente en 2-3 errores y cambie entre ellos mientras espera los resultados de la prueba.
Si pensabas que la vida de los desarrolladores que agregan nuevas funcionalidades al DBMS es más fácil, entonces eres en vano. Agregar incluso una nueva característica pequeña como un nuevo modo de autenticación puede llevar de 6 meses a un año, en casos especialmente avanzados, hasta dos años.
En el caso descrito, TDD permite no desmoronar el código "spaghetti", en el que ya es extremadamente difícil entender algo y tener un producto que funcione en la salida. Al mismo tiempo, los costos continúan creciendo y la calidad del nuevo código a menudo deja mucho que desear. No solo un equipo de desarrolladores de los EE. UU., Sino también un equipo de la India está trabajando en el DBMS, por lo que algunos desarrolladores de Oracle, de acuerdo con la tradición establecida, culpan a la calidad del código. Otros no están de acuerdo con ellos y, según el registro de cambios, dicen que la calidad del código no depende de la geografía del equipo, y que el código incorrecto periódicamente "vuela" desde ambos equipos. Un problema realmente serio para el producto son los desarrolladores que perciben el proyecto como "entrando en la industria" y han estado trabajando en el DBMS por no más de 1-2 años; Durante este tiempo es imposible comprender significativamente las complejidades del proyecto.
Según otro desarrollador que estaba transfiriendo la base de código Oracle 8i a una de las versiones de Unix a finales de los 90, el código ya en ese momento era una bola de "espagueti" que era completamente imposible de entender por completo. Otro desarrollador que trabajó con el código DBMS a finales de los años 80 afirma que la base del código era un gran grupo de fuentes C y un conjunto de archivos MAKE para ensamblar, muchos de los cuales eran mucho más complicados que el código del núcleo. Por supuesto, vale la pena ser realista: apenas la situación es mejor en productos similares, líderes de la industria, cuyo desarrollo se ha llevado a cabo durante varias décadas.