Déboguer son package qui a échoué sur CRAN grâce à {rhub}

Déboguer votre paquet qui a échoué sur CRAN avec {rhub}

Si vous avez envoyé des paquets sur CRAN, vous avez peut-être rencontré des échecs sur différentes configurations de systèmes d’exploitation dont vous n’aviez jamais entendu parler auparavant : Solaris, debian clang, fedora gcc, … Le package {rhub} permet de tester votre paquet sur certains d’entre eux, avant de l’envoyer sur le CRAN. Mais, comment déboguer sur cette infrastructure directement pour pouvoir reproduire et corriger les erreurs ?

Pas l’temps de tout lire…

  • Choisissez l’image Docker sur laquelle vous souhaitez travailler
  • Exécuter localement
    • Notez le nom du conteneur affiché dans la console. Quelque chose comme 8f5553b1-6e87-4330-8e3a-324dbacf3394-1

Dans la console R

# List images available
rhub::local_check_linux_images()
# Run on debian
rhub::local_check_linux(image = "rhub/debian-clang-devel")
  • Obtenez l’ID du conteneur Docker
  • Créez une nouvelle image à partir de celui-ci
  • Entrez dans le conteneur
  • Trouvez vos sources de paquets
  • Ouvrir R dans le conteneur

Dans le Terminal

docker ps -a
CONTAINER ID   IMAGE                     COMMAND                  CREATED        STATUS                      PORTS     NAMES
d31d52e7761a   8aee372b8b95   "bash /root/sysreqs.…"   22 hours ago   Exited (0) 22 hours ago               8f5553b1-6e87-4330-8e3a-324dbacf3394-1

# Commit the stopped image
docker commit d31d52e7761a debug/debian

# create a new container from the "broken" image
docker run -it --rm --entrypoint bash debug/debian

# Find your package source
cd /tmp/artifacts

# Untar the source
tar -xvf yourpackage_x.x.x.tar.gz

# Launch R 
/opt/R-devel/bin/R
  • Changer .libPaths() et vous pouvez exécuter vos tests et “check”

Dans la session R dans le Terminal

# Change libPaths
.libPaths(c(.libPaths(), "~/R"))

# Change working directory for your package
setwd("/tmp/artifacts/yourpackage")

# Check and debug
rcmdcheck::rcmdcheck()
  • Quitter R

Dans la session R dans le Terminal

q()
  • Nettoyer votre Docker à la fin du process

Dans le Terminal

# Exit Docker container
exit
# delete the container and the image
docker image rm debug/debian

La même chose avec un peu plus d’explications

Les images Docker {rhub} sont construites et sauvegardées sur DockerHub. Elles sont accessibles avec docker pull rhub/<image-name>. En utilisant rhub::local_check_linux(), l’image Docker est téléchargée sur votre ordinateur. Le script de lancement installe les dépendances du système, les dépendances des paquets et votre paquet à l’intérieur du conteneur, puis exécute les “check”. Comme expliqué dans la vignette rhub sur le débogage local, l’image est toujours disponible après les vérifications, avec l’installation complète. Cependant, les vérifications sont terminées et le conteneur s’est arrêté.

Nous allons voir comment le rouvrir et exécuter du code R à l’intérieur.

Images Docker de {rhub}

La liste des images Docker disponibles grâce à {rhub} est disponible avec rhub::rhub::local_check_linux_images() dans votre console R.
Choisissez l’image <image-name> dans la liste et lancez rhub::local_check_linux(image = "rhub/<image-name>"). Cela peut prendre beaucoup de temps en fonction du nombre de dépendances nécessaires à l’installation de votre paquet. Soyez patient.

Ici je teste {fusen} avec debian-clang-devel. Je devrais voir les mêmes avertissements et erreurs que ceux émis par le CRAN dans ce cas.

Dans la console R

# Run on debian
rhub::local_check_linux(image = "rhub/debian-clang-devel")

Notez le nom du containeur a55df815-38f2-4854-a3bc-29cdcac878cc-2 que nous allons utiliser juste après.

Entrer dans le conteneur arrêté

Comme vous avez lancé rhub::local_check_linux(), l’image est prête avec toutes les dépendances. Mais le conteneur s’est arrêté et vous ne pouvez pas y accéder en utilisant le classique docker exec. Par conséquent, vous devrez créer une nouvelle image à partir de l’image arrêtée et l’exécuter en utilisant un point d’entrée.

Trouvons le CONTAINER ID lié au nom du conteneur que nous avons gardé à l’esprit ci-dessus. La commande docker ps -a est exécutée dans un Terminal. Si vous utilisez RStudio, vous pouvez exécuter la ligne suivante en utilisant CTRL + ALT + Entrée, elle ira directement dans le Terminal.

Dans le Terminal

docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS                      PORTS     NAMES
26515d1d9a18   5e135229a572   "/bin/bash -l /tmp/b…"   38 minutes ago   Exited (0) 21 minutes ago             a55df815-38f2-4854-a3bc-29cdcac878cc-2

Notez le CONTAINER ID: 26515d1d9a18

Nous créons une nouvelle image basée sur l’image {rhub} dans son état actuel avec docker commit. Nous appelons cette nouvelle image debug/debian-clang-devel. Cela signifie que les dépendances système et R sont installées, et que les sources de votre paquet sont à l’intérieur. Ensuite, nous créons un nouveau conteneur pour entrer à l’intérieur en utilisant un point d’entrée. Ainsi nous pourrons exécuter du code à l’intérieur, même si les instructions de l’image originale disaient de s’arrêter une fois terminé.

Dans le Terminal

# Commit the stopped image
docker commit 26515d1d9a18 debug/debian-clang-devel

# create a new container from the "broken" image
docker run -it --rm --entrypoint bash debug/debian-clang-devel

Nous sommes maintenant à l’intérieur du conteneur !

Trouver les sources de développement de votre paquet

Nous allons devoir trouver où se trouve la source de notre paquet R afin de pouvoir exécuter des tests sur celui-ci.

Vous pouvez trouver la source de votre paquet dans “tmp/artifacts”.

Dans le Terminal

cd /tmp/artifacts
ls -l
-rw-r--r-- 1 docker docker   311711 Jul 29 07:46 fusen_0.2.3_R_x86_64-pc-linux-gnu.tar.gz
-rw-r--r-- 1 docker docker   303424 Jul 29 07:46 fusen_0.2.3.tar.gz
drwxr-xr-x 5 docker docker     4096 Jul 29 07:47 fusen.Rcheck

Ici, {fusen} apparaît trois fois :

  • fusen_0.2.3_R_x86_64-pc-linux-gnu.tar.gz est l’archive prête à être installée
  • fusen_0.2.3.tar.gz est la source. Le contenu de votre package en développement qui nous intéresse
  • fusen.Rcheck est le résultat des vérifications effectuées sur votre paquet.

Nous aurons besoin de décompresser notre source pour avoir accès au répertoire de développement.

Dans le Terminal

# untar sources
tar -xvf fusen_0.2.3.tar.gz
# get inside sources
cd fusen
# list files
ls -l

Trouver R, exécuter vos tests et déboguer votre code

Nous devons trouver où R est installé dans le conteneur, nous assurer que toutes les dépendances sont déjà installées, pour éviter d’attendre à nouveau. Ensuite, nous pourrons déboguer notre code avec tous les outils que vous connaissez sûrement déjà.

R est probablement installé dans le répertoire /opt/.

Dans le Terminal

# list files
ls -l /opt

Les dépendances sont probablement installées dans le répertoire “/home/docker/R”.

Dans le Terminal

# list files
ls -l /home/docker/R

Lancer R

Dans le Terminal

# Launch R
/opt/R-devel/bin/R

Vous êtes dans une session R à l’intérieur du conteneur arrêté !

Modifiez .libPaths() pour avoir accès à tous les paquets installés.

Dans la session R à l’intérieur du Terminal

# Change libPaths
.libPaths(c(.libPaths(), "~/R"))

Allez dans le répertoire de votre paquet de développement et exécutez les contrôles pour vérifier que les erreurs peuvent être reproduites.

Dans la session R dans le Terminal

# Change working directory
setwd("/tmp/artifacts/fusen")
# Run checks
rcmdcheck::rcmdcheck()

L’erreur est toujours présente. Je peux déboguer maintenant.

Arrêtez la session quand vous êtes ok

Dans la session R dans le Terminal

# quit R
q()

Nettoyer le Docker à la fin de votre session

Dans le Terminal

# Exit the container
exit
# delete the container and the image
docker image rm debug/debian-clang-devel

Vous devriez être prêt pour un autre tour !

Déboguer avec des systèmes spécifiques

Voici une liste des plateformes CRAN testées pour {fusen} :

À ce jour, {rhub} propose plusieurs versions de systèmes d’exploitation qui correspondent partiellement à celles du CRAN.

rhub::local_check_linux_images()
## rhub/debian-clang-devel:
##   Debian Linux, R-devel, clang, ISO-8859-15 locale
## rhub/debian-gcc-devel:
##   Debian Linux, R-devel, GCC
## rhub/debian-gcc-devel-nold:
##   Debian Linux, R-devel, GCC, no long double
## rhub/debian-gcc-patched:
##   Debian Linux, R-patched, GCC
## rhub/debian-gcc-release:
##   Debian Linux, R-release, GCC
## rhub/fedora-clang-devel:
##   Fedora Linux, R-devel, clang, gfortran
## rhub/fedora-gcc-devel:
##   Fedora Linux, R-devel, GCC
## rhub/centos-epel:
##   CentOS 8, stock R from EPEL
## rhub/rocker-gcc-san:
##   Debian Linux, R-devel, GCC ASAN/UBSAN
## rhub/ubuntu-gcc-devel:
##   Ubuntu Linux 20.04.1 LTS, R-devel, GCC
## rhub/ubuntu-gcc-release:
##   Ubuntu Linux 20.04.1 LTS, R-release, GCC
## rhub/ubuntu-rchk:
##   Ubuntu Linux 20.04.1 LTS, R-devel with rchk

Dans certains cas, il y a des platesformes supplémentaires testées comme vous pouvez le voir dans la liste ci-dessous :

Il semble que vous pouvez utiliser {r-debug} pour reproduire partiellement ces vérifications CRAN supplémentaires en suivant les instructions ici : https://github.com/wch/r-debug. Je n’ai pas testé.

Ressources

Encore une fois, les tests unitaires ont permis d’identifier les problèmes sur des plateformes spécifiques. Cela peut être pénible de penser et de tester sur toutes ces plateformes, mais à un moment donné, cela permet de partager son travail avec d’autres. Même s’ils ne travaillent pas exactement dans les mêmes conditions que votre propre ordinateur.

Utilisez des images Docker :

Developper un package et l’envoyer sur le CRAN :

Traduit avec www.DeepL.com/Translator (version gratuite)



Citation :

Merci de citer ce travail avec :
Rochette Sébastien. (2021, juil.. 29). "Déboguer son package qui a échoué sur CRAN grâce à {rhub}". Retrieved from https://statnmap.com/fr/2021-07-29-debug-your-package-that-failed-on-solaris-and-others-on-cran-with-rhub/.


Citation BibTex :
@misc{Roche2021Débog,
    author = {Rochette Sébastien},
    title = {Déboguer son package qui a échoué sur CRAN grâce à {rhub}},
    url = {https://statnmap.com/fr/2021-07-29-debug-your-package-that-failed-on-solaris-and-others-on-cran-with-rhub/},
    year = {2021}
  }