La fábula del pastor y el jefe de proyectos

Paseaba un día un jefe de proyectos por el campo. Tras años de rayos catódicos era su primer paseo por el páramo castellano en mucho tiempo. Lo necesitaba. La ocasión merecía los pantalones y las botas que estrenaba, recién compradas en la tienda de Timberland del aeropuerto. Iba pensando en lo bucólico del paisaje y la paz que se respiraba y lo lejos que estaba ahora de las reuniones ‘tressesenta’ , cuando vio, en la lejanía, para un informático 350 metros son la lejanía, un pastor de ovejas con rebaño de discreto tamaño. No más de cincuenta recursos eran los que el pastor gestionaba.

En ese preciso instante el modesto pastor vio al ‘pimpollo’ y pensó… vaya, otro que estrena botas, mañana con ampollas… mientras arrancaba un lasca de queso con su navaja. En esto el ‘pinpollo’ ya estaba a su lado. El pastor levanto la cabeza, miro a nuestro jefe de proyecto y le tendió un trozo de queso. Ya se sabe, que en la castilla profunda, la hospitalidad se muestra más de gesto que de palabra.

El jefe de proyecto cogió el queso, sin poder evitar pensar: ‘que uñas más negras’. Y se sentó junto al pastor. La botas le estaban matando. Degusto el queso, que le supo como le sabía el queso cuando tenía forma de queso y no forma de triángulo metido en un plástico. Y ya se sabe, un buen queso puede tener efectos tan alucinógenos como el LSD. Sobre todo si no se ha probado en años… y no sale de la máquina de la sala de café después de poner dos euros y pulsar sesenta y siete.

Así que embriagado por los aromas de aquel queso, el jefe de proyecto no pudo evitar decir: ‘señor pastor, lo suyo si que es vida’. El pastor le miro, sin decir nada. ‘Todo el día dedicado a usted mismo, con sus fieles recursos que nunca se oponen a su voluntad, que saben lo que deben hacer sin que nadie se lo diga, que no están todo el día exigiendo y pensando en irse a su hora a casa. Lo que daría yo por estar en su situación… ‘ continuó el jefe.

El pastor le miró y con la simpleza que solo da la verdadera sabiduría dijo: ‘no sabe usted de lo que habla, amigo’. Y tiro un largo trago de bota. El jefe de proyecto no se iba a amilanar, así que espetó: ‘Usted si que no sabe nada de lo duro que es mi trabajo, seguro que yo cuidaría mejor de sus ovejas que usted de mi equipo de desarrolladores’. El pastor le miró fijamente y dijo ‘hecho, escriba aquí la dirección de su empresa y avise de que voy’. Le tendió la bota al jefe, en un gesto que decía claramente que si bebía, el trato estaba cerrado. Y claro, el jefe bebió mientras pensaba, ‘que cojones, aquí el que tiene el MBA soy yo’.

El pastor se levantó, silbó a su perro y le dijo, ‘dentro de unas semana vuelvo, de mientras, obedece a este pinpollo’… El perro le miró con incredulidad y acatamiento. Le dio el petate al ‘pipollo’ y marcho a conocer a su nuevo rebaño. No se sabe quien estaba más acojonado, si el jefe de proyecto o el pastor.

Pasado el estupor inicial, el jefe penso: ‘bueno se trata de gestionar recursos ¿no? Llevo haciendo eso años. Seguro que las ovejas saben hacer mejor su trabajo que los desarrolladores. Tengo claro el objetivo, que den lana, y solo necesito crear un plan y exigir su cumplimento’. Con un buen plan y mano férrea seguro que lograba cumplir sus objetivos. El jefe respiró tranquilo cuando recordó que llevaba su flamante PDA y que tenia Project y Excel versión requetemini. Todo estaba solucionado. Dedicó esa noche a trazar un plan. Fue una dura noche, lloviendo y tronando. Las ovejas durmieron a la intemperie, pero no pasaba nada, el tenía ‘el plan’. 50 recursos de tipo oveja, a 50 kilos de lana por recurso, 2500 kilos de lana. Un proyecto rentable sin duda…

Al día siguiente el jefe reunió al rebaño. ‘Tengo un plan que nos va a llevar a completar el proyecto de manera exitosa. Ya me he comprometido con el señor alcalde, cacique local y comerciante de lana, a entregarle 2500 kilos de la mejor lana en el plazo de dos meses. El alcalde me ha hecho saber su satisfacción y su plena confianza en que conmigo al frente, MBA y gestor de recursos experto, el proyecto va a ser todo un éxito.’ Las ovejas no entendían nada. Ellas sabían que el alcalde solía preocuparse más por la leche que por la lana, pero quizás las cosas habían cambiado, que sabían ellas, meros recursos productores de ¿lana? ¿leche?… En cualquier caso, la ovejas, no habían nunca producido tanta lana en tan poco tiempo pero con un buen gestor al mando quizás se obrase el milagro. El project que el jefe tenía era muy bonito… que barritas azules más iguales, oye.

Pasaron veinte días y el jefe de proyecto reunió de nuevo a las ovejas. ‘Queridas ovejas, vamos retrasados respecto mi plan. No dudo de que haréis lo necesario para asegurar que producís la lana al ritmo necesario. Espero que todas arriméis el hombro y que no os vayáis a casa sin cumplir con vuestro trabajo. Ya he hablado con el alcalde y le he dicho que no se preocupe que apretaremos nuestro culo bobino y recuperaremos el tiempo perdido’. Las ovejas no entendían nada, ya se sabe que no es un animal demasiado listo… apretaron su ovino culo y se fueron a pastar. Al fin y al cabo no sabían como hacer crecer la lana más rápido… y parecía que el jefe tampoco.

Otros veinte días después, el jefe de proyecto reunió de nuevo al rebaño. ‘Malditas ovejas. Os pedí un esfuerzo y no habéis hecho nada. Yo hice el plan y vosotras estáis haciendo que fracase. Como no os apliquéis más algunas de vosotras vais a ir a la puta calle. Y ya sabéis la crisis que hay… puedo encontrar cincuenta como vosotras en cualquier ETT’. La ovejas, una vez más, no entendieron nada. Ya le habían dicho al jefe de proyecto que el que no las metiese en el corral por las noches y que no las hubiese cambiado de prado en todo el tiempo no era muy beneficioso para su lana. Habían pensado que a lo mejor si se movían por el campo como hacían con el pastor, la producción de lana mejorase. También sugerían que el jefe las ordeñase, sabían que el alcalde siempre quería leche… ‘Estas ovejas, siempre quejándose de chorradas, ya sabía yo que no eran muy diferentes a los desarrolladores. Que sigan el plan y dejen de quejarse y pensar, para eso ya estoy yo. ¡No hay manera de hacer que trabajen!’ había pensado el jefe de proyecto.

Otros veinte días después el alcalde llegó y preguntó al jefe por su lana… el jefe solo tenía 1000 kilos, la ovejas resultaron no ser tan expertas como ponía en su curriculum, inaceptable… que podría haber hecho él… ‘No pasa nada jefe’, dijo el alcalde, ‘tendremos mucha leche entonces’. El jefe se puso rojo y dijo ‘leche, que leche, en el contrato no decía nada de leche’… El alcalde dijo, ‘me la sopla lo que diga el contrato, lo de la leche se da por supuesto, vaya fracaso del proyecto, no vas a ver un puto duro…’.

En esas llegó el pastor… seguro que el también la habría cagado. ‘Mal de muchos, consuelo de tontos, pero consuelo al fin y al cabo’ pensó el jefe… ‘¿Qué tal pastor? ¿Duro el trabajo?’ dijo con tonillo de sorna. El pastor contesto, con su simpleza natural: ‘Todo ha ido sobre ruedas. Al fin y al cabo los desarrolladores son como ovejas ¿no? Seguro que a ti también te ha ido bien. Los desarrolladores incluso me han regalado un GPS para que marque donde comen mejor mis ovejas… ¡y donde hay setas!. Creo que me han cogido cariño los jodidos, que majetes’. El jefe no salía de su asombro. Los recursos eran agradecidos y todo. ¡Cuéntame que has hecho, por favor!, dijo al pastor.

‘Ha sido fácil. Al fin y al cabo los desarrolladores son mucho más comunicativos que las ovejas y cuesta menos reunirlos. Todas las mañanas, sin perro ni nada, les tenía localizados. Además, pensé, no pueden ser muy diferentes que las ovejas, son individualistas y gregarios a la vez. Seguro que si cuido de ellos como hago con mis ovejas obtendré los resultados esperados y a eso me he dedicado estas semanas.’

El pastor continuo ‘me pidieron que les consiguiese un servidor de 64 bits para no se que pruebas de rendimiento y de compatibilidad. Yo no tenía ni idea de qué es eso, pero parecía importante para ellos, así que lo conseguí. ¿No busco los mejores pastos para mi ovejas? No es tan diferente…’ El jefe de proyecto flipaba, ¿desde cuándo se logra algo de los recursos atendiendo a sus caprichos?…

Luego prosiguió el pastor contando otra situación: ‘Un día, los desarrolladores dijeron que no lograban que el rendimiento fuese el adecuado, y que en su opinión lo mejor era tirar de un experto. Así que eso hice busque un experto que les ayudase y les formase. ¿No llevo a mis ovejas al veterinario cuando tienen problemas?’. Ahora sí que el jefe de proyecto no se lo podía creer, ¡formar a los recursos es caro! Y luego se van a la competencia en cuanto saben.

‘Me acuerdo de otra cosa curiosa’, dijo el pastor: ‘Otro día los desarrolladores me contaron que no lograban avanzar. Eso me preocupó. ¿Se supone que los desarrolladores deben avanzar en la funcionalidad, es su lana y su leche, no?. El problema, contaron, es que los comerciales estaban continuamente demandando pequeñas modificaciones, visitas a clientes, que atendiesen llamadas… Parece que los lobos acechan, pensé yo. Así que puse un poco de orden y deje claro que a mi rebaño no se le molesta’.

El pastor concluyo: ‘la verdad es que no he hecho mucho ¿no?. Los desarrolladores son como las ovejas, si dejas que hagan su trabajo y pones las condiciones para que lo hagan, al final puedes recoger los resultados’.

En estas despertó el jefe de proyecto y pensó: ‘joder, como pega el vino del pastor, vaya siesta y vaya sueño más raro’, mientras veía al pastor perderse por el horizonte con su rebaño.

Yo me pregunto: ¿A que se parece más el trabajo de Scrum Master, cuyo principal cometido es eliminar los impedimentos que encuentra el equipo, al de un Jefe de Proyecto clásico o al de un pastor?.

Ya lo dijeron DeMarco y Lister en su imprescidible Peopleware, el trabajo del gestor de proyectos no es hacer que la gente trabaje, sino construir el entorno en el que trabajar sea posible.

¡Chewbacca, toda la potencia y velocidad al TFS Build! que diría Han Solo…

Una de las carácteriscas más desconocidas de TfsBuild (y de MsBuild) introducida en la versión 2008 es la posibilidad de compilar varios proyectos en paralelo. Esta carácterística puede acelerar nuestras builds de manera significativa. Sobre todo teniendo en cuenta que el número de procesadores disponibles en las máquinas es cada vez mayor. Para activar esta caracteristica es necesario seguir los siguientes pasos.

1) Debemos modificar Microsoft.TeamFoundation.Build.targets para que se construyan en paralelo diferentes configuraciones (p.e. las típicas de Release y Debug):

 

  <MSBuild BuildInParallel=«true«

        Projects=«@(ConfigurationList)«

        Targets=«CompileConfiguration«

        StopOnFirstFailure=«$(StopOnFirstFailure)«>

    <Output TaskParameter=«TargetOutputs« ItemName=«CompilationOutputs« />

  </MSBuild>

 

2) Debemos modificar Microsoft.TeamFoundation.Build.targets para que se construyan en paralelo diferentes soluciones:

 

  <MSBuild BuildInParallel=«true«

          Projects=«@(SolutionList)«

          Targets=«CompileSolution«

          StopOnFirstFailure=«$(StopOnFirstFailure)«>

    <Output TaskParameter=«TargetOutputs« ItemName=«CompilationOutputs« />

  </MSBuild>

3) Modificar   TfsBuildService.exe.config (generalmente ubicado en %ProgramFiles%Microsoft Visual Studio 9.0Common7IDEPrivateAssemblies) y añadir una entrada MaxProcesses que especifica el número de proceso de MsBuild que se levantarán en paralelo:

  <!– MaxProcesses

  Set this value to the maximum number of processes MSBuild.exe should

  use for builds started by agents hosted by this executable.

  –>

  <add key=«MaxProcesses« value=«1« />

Después de estos cambios, es necesario reiniciar el servicio de TFS Build (net stop vstfbuild y net start vstfbuild). A partir de este momento la builds se ejecutarán en paralelo.

Para que esa parelelización funcione debemos usar referencias a proyecto. Usando referencias de proyecto, MsBuild puede, analizando esta información de dependencias, saber en que orden construir los proyectos y si es posible paralelizar la construcción de un determinado proyecto. Si estamos referenciando binarios, MsBuild no podrá deducir esa información, con lo que si paralelizamos la construcción podríamos sufrir errores de compilación.

El requeteframework

Comenta Julio en el post Maldivas Arquitectura 1 – El sentido común del amigo Juan Irigoyen, «me ha sorprendido ver a gente de Plain Concepts «sonreirse» cuando le comentas algo del framework, no te dicen nada pero no están muy en su favor»

Me voy a permitir hablar en nombre de Plain Concepts, ya que en mi tarjeta pone Software Architect y estamos hablando de arquitectura… conste que esto en sí es un atrevimiento gordo, pues hay muchas visiones sobre el tema de los framework en Plain Concepts y gente que, aun teniendo otra visión, es tan arquitecto como yo o más. Además, no hay balas de plata.

Podría resumir el sentimiento general sobre el tema en lo siguiente…

No somos amigos de los frameworks generalistas que quieren solucionar todos los problemas y que añaden una capa de abstracción adicional, a veces demasiado compleja y pesada, sobre el framework de .Net. Ya tenemos un framework generalista que funciona muy bien: el .Net Framwork. Lease: generalmente no nos gusta Enterprise Library para proyectos ‘in house’. Cuando tienes un solo proyecto, la curva de aprendizaje de Enterprise Library es muy significativa y rara vez se ve compensada por la reutilización y la flexibilidad que aporta.

Pongamos un ejemplo: Enterprise Library permite posponer la decisión sobre donde tiras tus logs a tiempo de despliegue de la aplicación. Evidentemente esto es algo que en si mismo, si no se cuenta el precio que hay que pagar es una excelente idea. Es algo que si no se valoran los costes adicionales todos ‘compramos’. Es fácil ver solo reutilización y flexibilidad y obviar otras cuestiones relevantes: coste de aprendizaje, complejidad, perdida de control, fugas de abstracción etc… Por no decir que obligas a quien despliega ha realizar una configuración adicional que es propensa a errores. No todo tiene que ser configurable. Configurar tiene costes y riesgos asociados que una buena arquitectura centrada en el problema nos puede evitar.

Además parece que la flexibilidad y la reutilización son valores en si mismos, y no es cierto. La flexibilidad y la reutilización solo son importantes si es algo que necesitas. No son un valor en si mismas, y sobre todo ¡no son gratis!.

La simplicidad si que es un valor por si misma. Tal y como yo entiendo mi trabajo de arquitecto del software, y en gran parte como lo entendemos en Plain Concepts, este consiste en lograr la arquitectura más simple posible que cumple los requisitos marcados. Generalmente cuando utilizas un framework generalista arrastras mucha funcionalidad que nunca jamás vas a utilizar y que sin embargo vas a ‘sufrir’. Yo no quiero que mi sistema de traceo sea capaz de salir a 27 fuentes diferentes. Yo quiero saber que necesidades de traceo tengo y buscar la arquitectura más simple que cubre esas necesidades.

Yo creo en los framework de dominio especifico que surgen de la continua refactorización y de necesidades reales. Creo en la arquitectura emergente. Creo en el enfoque de Juan, que ve su necesidad concreta y automatiza y simplifica todo lo que puede el trabajo repetitivo que aparece en su proyecto. Que crea abstracciones concretas para sus necesidades concretas. No creo que los ‘frameworks’ que se venden con lemas del estilo de ‘genera 10000 líneas de código con un solo click de ratón’… no creo en esto hasta que el lema sea ‘mantén 10000 líneas de código con un solo click de ratón’. Escribir código es la parte más barata del proceso de desarrollo de software. Los costes están en mantenerlo, evolucionarlo, probarlo, ponerlo en producción… esto se obvia a menudo. Estos costes son directamente proporcionales a la complejidad de tu base de código. No quiero 10000 líneas de código que no necisito solo por que Enterprise Library o un generador me las de gratis, es una complejidad que no quiero pagar.

Cuando usas un framework generalista esta cediendo control a una abstracción. Lo problemas empiezan cuando esa abstracción fuga detalles y tu no entiendes que pasa o no puedes recuperar un control que necesitas. Esto no significa que las abstracciones sean malas, sino que tienen un precio. Joel Spolsky lo explica como nadie en su excelente The Law of Leaky Abstraccions.

Lógicamente hay situaciones, como factorías de software donde las oportunidades de reutilización son muchísimo más altas que en el desarrollo de software ‘in house’. Hay es posible que los costes de mantener un framework generalista si sean interesantes, por que un framework de dominio, debería adaptarse a tantas situaciones que acabaría siendo un framework generalista.

¡Por eso cuando oímos hablar de frameworks nos sonreímos!

Ejecutar nuestras pruebas web simulando diferentes navegadores

El proceso para simular diferentes navegadores pasa por grabar nuestro web tests y ejecutarlo como una una prueba de carga. Configuraremos la prueba de carga para que haga dos peticiones por cada. El wizard nos permite elegir que clientes queremos añadir. Por defecto aparecen IE x.x y FF 2.0 pero se pueden añadir los que se quieran, simplemente conociendo el User-Agent.

image

El proceso sería grabar una interacción usando IE y luego crear una prueba de carga que ejecute ese test tantas veces como diferentes navegadores queramos simular.

Otra opción es grabar el test desde Inernet Explorer y otro desde Firefox (o cualquier otro navegador).

Otra opción que es más compleja es añadir un header a las peticiones web y establecer el user-header y luego vincularlo a datos. El problema es que hay que hacerlo a mano para cada petición, aunque siempre se podría hacer una macro de Visual Studio.

clip_image004

También, lógicamente, se podría hacer un plugin de webtest que añadiese el header a cada petición. Un plugin de tipo WebTestRequest nos permite modificar las peticiones antes de enviarlas y añadir la cabecera (propiedad Headers) User-Agent que más nos convenga. Para ello usaríamos el módelo de objetos de plugins de pruebas web:

Por último otra opción sería generar el código de la prueba y cambiar la cabecera User-Agent nosotros desde el código de la prueba. Podemos modificar el método GetRequestEnumerator de la prueba web para añadir la cabecera User-Agent de los navegardores que nos interesen y devolver un objeto request adicional por cada navegador configurado con la cabecera adecuada. Añadir la cabecera en código es muy simple gracias a la clase WebTestRequestHeader.

WebTestRequest request1 = new WebTestRequest(«http://geeks.ms/«);
request1.Headers.Add(new WebTestRequestHeader(«User-Agent», «»));

Hay que señalar que las pruebas web no ejecutan Javascript, por lo tanto la técnica aquí descrita sirve para probar diferencias en servidor derivadas de usar diferentes clientes, pero no para probar diferencias de comportamiento entre navegadores en lo que a la ejecución de Javascript se refiere.

Ejecutar todas las pruebas bajo un directorio

Resulta que la manera en que la build y Visual Studio ejecutan las pruebas, no es exactamente la misma. Esto nos lleva a que a veces, pruebas que pasan perfectamente desde Visual Studio no se ejecutan igual de bien cuando corre la build. Una manera de depurar este tipo de problemas es ejecutar estas pruebas usando MSTest.


Para esto resulta muy útil ejecutar todas las pruebas bajo un determinado directorio. Hay otros escenarios en los que esto puede ser útil. Podemos usar dos enfoques para conseguir nuestro proposito, ambos invocando MSTest, bien mediante MSBuild o bien mediante PowerShell.


Para hacerlo mediante MSBuild basta crear un fichero, llamado por ejemplo RunTestContainer.proj, con el siguiente contenido:



<Project xmlns=«http://schemas.microsoft.com/developer/msbuild/2003«>


<ItemGroup


        <TestContainers


          Include=«$(MSBuildStartupDirectory)***.test.dll«/>


    </ItemGroup>


 


    <Target Name=«RunTestContainers«>


      <Exec Command=mstest /testcontainer:»%(TestContainers.FullPath)» />


    </Target>


</Project>


Luego lo podemos ejecutar RunTestContainer.proj con MSBuild sin más: msbuild RunTestContainer.proj


Con PowerShell basta usar la siguiente linea de comandos: Get-ChildItem -filter *.test.dll -recursive | ForEach-Object { mstest /t:$_ }


En ambos casos asumo que los ficheros que contienen los test son aquellos que siguen el patrón *.test.dll y que MSTest.exe se encuentra en la variable de entorno PATH.


No deja de sorprenderme la potencia de MSBuild y de PowerShell, sobre todo la de este último.


¡Espero que os sea útil!