Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Breaking Bug - Noir Edition

Saúl Díaz
December 02, 2017

Breaking Bug - Noir Edition

Breaking Bug es un development thriller sobre cómo un bug que es capaz de traspasar las barreras de seguridad conocidas es capaz de poner en jaque a toda una app, y cómo un desarrollador tiene que llegar más allá de lo que ha llegado nunca para entender qué está pasando y solucionarlo a tiempo.

(En realidad es un post-mortem de cómo un bug que llegó a producción indetectado, los pasos que se dieron para entender qué estaba pasando, las diferentes estrategias y herramientas que se usaron para su detección, analizar su impacto y el coste de arreglarlo)

Saúl Díaz

December 02, 2017
Tweet

More Decks by Saúl Díaz

Other Decks in Programming

Transcript

  1. “ Por favor, ayúdame, la aplicación no carga. Es como

    si no tuviera internet, pero en realidad sí es así”
  2. ite Testing + CI TESTING No es perfecto; pero bastante

    sólida Domain JUnit E2E, ~65% cobertura UI Junit & Robolectric, ~43% cobertura Enfocado a los componentes clave
  3. ite Dogfooding & Q&A MANUAL QA & DOGFOODING El equipo

    prueba la app Lanzamos internamente en una amplia variedad de dispositivos y APIs
  4. Deployment STAGED ROLLOUTS Al menos 24 horas en staged rollout

    con monitorización constante antes de ir a full CONTINOUS DELIVERY Releasear es nuestro punto fuerte
  5. Heisenbug En argot de desarrolladores, un Heisenbug es un bug

    del software que desaparece o cambia su comportamiento cuando se intenta estudiarlo
  6. Place your screenshot here NETWORKING OkHttp + Retrofit USE CASES

    Covered by tests PRESENTATION Bus-backed UI ProgressSwitcher
  7. Oct 12 08:21:15 android INFO MainActivity [Data successful] hello world!_

    userId: sefford, installation:1234512345 Samsung Sm-j700f 6.0.1(api 23) build:110105_ date logtag comp. info user id installation id device info API level build nº
  8. Jul 03 17:31:25 android: ERROR MainActivity [ProgressSwitcher] feed arrived successfully

    with 0 elements Build:109402 Jul 03 17:42:38 android: ERROR MainActivity [ProgressSwitcher] feed arrived successfully with 0 elements Build:109402 Jul 03 17:54:44 android: ERROR MainActivity [ProgressSwitcher] feed arrived successfully with 0 elements Build:109402 Jul 03 18:02:56 android: ERROR MainActivity [ProgressSwitcher] feed arrived successfully with 0 elements Build:109402 Jul 03 18:04:11 android: ERROR MainActivity [ProgressSwitcher] feed arrived successfully with 0 elements Build:109402 Jul 03 18:09:21 android: ERROR MainActivity [ProgressSwitcher] feed arrived successfully with 0 elements Build:109402 Jul 03 18:23:57 android: ERROR MainActivity [ProgressSwitcher] feed arrived successfully with 0 elements Build:109402 Jul 03 18:37:33 android: ERROR MainActivity [ProgressSwitcher] feed arrived successfully with 0 elements Build:109402 Jul 03 18:38:03 android: ERROR MainActivity [ProgressSwitcher] feed arrived successfully with 0 elements Build:109402 Jul 03 18:45:38 android: ERROR MainActivity [ProgressSwitcher] feed arrived successfully with 0 elements Build:109402 Jul 03 18:54:49 android: ERROR MainActivity [ProgressSwitcher] feed arrived successfully with 0 elements Build:109402 Build:109402
  9. --- a/app/src/main/java/com/chicisimo/common/injection/ApiModule.java +++ b/app/src/main/java/com/chicisimo/common/injection/ApiModule.java @@ -104,7 +104,7 @@ public class

    ApiModule { .addNetworkInterceptor(responseInterceptor) - .connectTimeout(60, TimeUnit.SECONDS) + .connectTimeout(00, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS); }
  10. Mejorando la batería de tests ▣ Pasar de usar mocks

    a usar llamadas reales a la API con MockWebServer. ▣ Segmentar errores de conexión con timeouts, errores en los handshake de SSL, etc... ▣ Mejor comprensión de cómo se comporta la app en relación con la red.
  11. VYSOR.IO “Ójala hubiera una manera de ir hasta Brasil, conectarme

    a sus teléfonos y debugarlos como dios manda”
  12. ERR: connection from chicisimo.api failed:SocketTimeoutException: closed after 120000ms ERR: connection

    from chicisimo.api failed:SocketTimeoutException: closed after 120000ms ERR: connection from chicisimo.api failed:SocketTimeoutException: closed after 60000ms ERR: connection from chicisimo.api failed:SocketTimeoutException: closed after 60000ms ERR: connection from chicisimo.api failed:SocketTimeoutException: closed after 40000ms ERR: connection from chicisimo.api failed:SocketTimeoutException: closed after 40000ms ERR: connection from chicisimo.api failed:SocketTimeoutException: closed after 20000ms ERR: connection from chicisimo.api failed:SocketTimeoutException: closed after 20000ms
  13. # NumSamples = 453938; Min = 0.00; Max = 97885.00

    # Mean = 1642.091535; Variance = 18645635.742440; SD = 4318.059256; Median 765.000000 # each ∎ represents a count of 5360 0 - 2000 [402006]: ∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎ (88.56%) 2000 - 3000 [ 21361]: ∎∎∎ (4.71%) 3000 - 4000 [ 5650]: ∎ (1.24%) 4000 - 5000 [ 2682]: (0.59%) 5000 - 6000 [ 1575]: (0.35%) 6000 - 7000 [ 1514]: (0.33%) 7000 - 8000 [ 931]: (0.21%) 8000 - 9000 [ 620]: (0.14%) 9000 - 10000 [ 356]: (0.08%) 10000 - 20000 [ 1678]: (0.37%) 20000 - 97885 [ 15565]: ∎∎ (3.43%) https://github.com/bitly/data_hacks
  14. Jul 17 18:21:48 android chicisimo: INFO [Network] get '/albums/82603' server:10.0.0.255_

    dns:253ms ssl:752ms connection:670ms installation:1234512345 user:sefford endpoint server DNS SSL connection
  15. Una víctima inesperada “Esta aplicación va como la m****a tío,

    todo tarda en cargar un siglo” -J. Barroso, diseñador
  16. public class IpV4PriorizerDns implements Dns { public static final Comparator<InetAddress>

    INET_ADDRESS_COMPARATOR = new Comparator<InetAddress>() { @Override public int compare(InetAddress left, InetAddress right) { if (left instanceof Inet4Address) { return -1; } else if (right instanceof Inet4Address) { return 1; } return 0; } }; @Override public List<InetAddress> lookup(String hostname) throws UnknownHostException { if (hostname == null) { throw new UnknownHostException( "hostname == null"); } else { final List<InetAddress> inetAddresses = new ArrayList<>( Arrays.asList(InetAddress.getAllByName(hostname))); Collections. sort(inetAddresses, INET_ADDRESS_COMPARATOR); return inetAddresses; } } } El fix de cliente
  17. 4 semanas de trabajo Eso es un montón de pasta...

    0.03 de rating perdido Todavía nos quedan 0.009 por recuperar! 15.656 users menos … y un montón de usuarios
  18. Mejoramos los test ¡Y nuestra UX! Aprendimos un h**vo Comprendemos

    mucho mejor esa parte y somos mas eficaces Muchas herramientas Incrementamos mucho las estrategias que podemos utilizar
  19. Moraleja ▣ Los bugs son como escenas del crimen ▣

    Resolver un bug es como una partida de ajedrez ▣ Mantén la calma y usa el método científico
  20. Credits Special thanks to all the people who made and

    released these awesome resources for free: ▣ Presentation template by SlidesCarnival ▣ http://y2u.be/bKJnbqYHMPs ▣ All the people from the community who helped over this endeavor