Jest: condition de concurrence d'écriture du cache entre les processus

Créé le 7 sept. 2017  ·  79Commentaires  ·  Source: facebook/jest

Voulez-vous demander une fonctionnalité ou signaler un bogue ?
punaise

Quel est le comportement actuel?
Lors de l'exécution de tests en parallèle avec la nouvelle écriture du cache atomique, nous obtenons des erreurs de renommage lorsque plusieurs processus essaient d'écrire dans les mêmes fichiers. Même avec l'option --no-cache définie, des erreurs de changement de nom se produisent toujours car il essaie toujours d'écrire dans les fichiers.

Quel est le comportement attendu?

  1. Je pense que --no-cache ne devrait pas écrire de fichiers de cache
  2. La mise en cache sur plusieurs processus ne doit pas entrer en conflit ou doit pouvoir redémarrer le test.

Veuillez fournir votre configuration Jest exacte et mentionner votre Jest, votre nœud, votre version de fil / npm et votre système d'exploitation.

{
    "clearMocks": true,
    "collectCoverageFrom": [
        "packages/**/src/**/*.{ts,tsx}",
        "!packages/sf-lint/**",
        "!**/*.d.ts"
    ],
    "coverageReporters": [
        "text-summary"
    ],
    "moduleFileExtensions": [
        "ts",
        "tsx",
        "js",
        "json"
    ],
    "setupTestFrameworkScriptFile": "<rootDir>/jestEnvironment.js",
    "transform": {
        "\\.(ts|tsx)$": "<rootDir>/scripts/preprocessTypescript.js",
        "\\.(less|css|svg|gif|png|jpg|jpeg)$": "<rootDir>/scripts/preprocessText.js"
    },
    "testRegex": "(Spec|.spec).tsx?$"
}

plaisanterie 21.0.1
nœud 6.9.2
fil 0.27.x / 1.0.0
OS Windows

Help Wanted Windows

Commentaire le plus utile

juste pour participer - je vois cela avec jest 23.6 sur un serveur Windows Jenkins CI.

  • --runInBand fonctionne, mais double le temps de test, donc ce n'est pas génial, et comme nous avons des tests exécutés avant le push, je ne peux pas activer cela sans rendre les membres de mon équipe super tristes
  • le remplacement graceful-fs dans package.json , comme mentionné par @jsheetzati (https://github.com/facebook/jest/issues/4444#issuecomment-370533355) fonctionne, mais c'est un peu un hack.

Puisque graceful-fs ne fait pas grand-chose à ce sujet (https://github.com/isaacs/node-graceful-fs/pull/131 n'a pas vu d'action depuis juillet de l'année dernière), il est peut-être temps de bifurquer ? J'ai ajouté un petit commentaire là-bas, mais je ne m'attends pas à ce que quelqu'un saute soudainement au tri) ':

Tous les 79 commentaires

Je ne crois pas. Je pense que le cas que nous voyons dans notre dépôt est le même fichier qui se moque de 2 processus différents (tout en s'exécutant en parallèle), ce qui entraîne l'échec de l'opération d'écriture du cache car un processus a le fichier verrouillé. Ce ticket ressemble plus à des fichiers différents avec le même contenu. Nous n'avons aucun de ces cas dans les référentiels que nous hébergeons que nous avons rencontré ce problème.

Nous rencontrons essentiellement le même problème avec nos tests. Un moyen simple de se reproduire était de supprimer jest cacheDirectory pour forcer la génération du cache lors de la prochaine exécution.
`` La suite de tests n'a pas pu s'exécuter

jest: failed to cache transform results in:

C: / myniceproject / src / jest-cache / jest-transform-cache-b2e8f1f700b9bd266a0d27bb01b47a2b-34a7e3d71d38ff01f65fdb5abdf5126b / 3f / settingsProvider_3f1439e55275a95c8bdb
Message d'échec: EPERM: opération non autorisée, renommer
'C: \ myniceproject \ srcjest-cachejest-transform-cache-b2e8f1f700b9bd266a0d27bb01b47a2b-34a7e3d71d38ff01f65fdb5abdf5126b \ 3f \ settingsProvider_3f1439e55275a95cfdb329
->
'C: \ myniceproject \ srcjest-cachejest-transform-cache-b2e8f1f700b9bd266a0d27bb01b47a2b-34a7e3d71d38ff01f65fdb5abdf5126b \ 3f \ settingsProvider_3f1439e55275a95cecfdb32

Avoir le même problème et ne peut pas trouver un moyen de le contourner. Jest est fondamentalement inutilisable pour nous comme ça.

Nous essayons de mettre à jour vers 21.2.0 à partir de 20.0.4 et nous avons maintenant l'erreur suivante sur nos serveurs de build:

Test suite failed to run
[13:46:50]
[13:46:50]    jest: failed to cache transform results in: C:/TeamCity/buildAgent/temp/buildTmp/jest/jest-transform-cache-c60bb8ad55f1dbc29115038800657f2f-4895fc34da3cd9ad1e120af622bca745/3b/fe-selectors_3b56db772e798e2e4d0c9fc7c9e4a770
[13:46:50]    Failure message: EPERM: operation not permitted, rename '...\jest\jest-transform-cache-c60bb8ad55f1dbc29115038800657f2f-4895fc34da3cd9ad1e120af622bca745\3b\fe-selectors_3b56db772e798e2e4d0c9fc7c9e4a770.1701848979' -> '...\jest\jest-transform-cache-c60bb8ad55f1dbc29115038800657f2f-4895fc34da3cd9ad1e120af622bca745\3b\fe-selectors_3b56db772e798e2e4d0c9fc7c9e4a770'
[13:46:50]      
[13:46:50]      at Object.fs.renameSync (fs.js:772:18)
[13:46:50]      at Function.writeFileSync [as sync] (node_modules/write-file-atomic/index.js:192:8)

J'ai maintenant le même problème que les tests sont interrompus au hasard.

Si j'exécute les tests avec l'indicateur --runInBand, tout va bien.

Je peux voir le même problème de manière assez cohérente:

  ● Test suite failed to run

    jest: failed to cache transform results in: .../jest-transform-cache-...
    Failure message: EPERM: operation not permitted, rename '...' -> '...'
        at Error (native)

      at Object.fs.renameSync (fs.js:810:18)
      at Function.writeFileSync [as sync] (node_modules/write-file-atomic/index.js:192:8)

plaisanterie 21.2.1
nœud 6.11.1
OS Windows

--no-cache n'aide pas et jest-transform-cache est toujours en cours d'écriture. La seule chose qui aide est --runInBand , ce qui n'est guère acceptable pour les grands projets.

Que pouvons-nous faire pour vous aider à diagnostiquer le problème? Dois-je créer un cas de repro?

Cette erreur est-elle critique? Peut-il être traité comme un avertissement plutôt que de supprimer toute la suite de tests? Existe-t-il un moyen de reculer et de réessayer?

Avoir un petit repro serait génial

Voici le repro: https://github.com/asapach/jest-cache-issue/
Il exécute efficacement lodash-es via babel-jest pour remplir le cache de transformation.
Cela échoue pour moi 80% du temps sur deux machines différentes (Win8.1 et Win10).
Si vous supprimez --no-cache cela échoue 100% du temps. Ajouter --runInBand ramène à 0%.

(Par curiosité, j'ai essayé de l'exécuter dans WSL sur Win10 et le problème n'est pas reproductible à l'aide de l'API Posix)

Cela se produit-il uniquement sous Windows? Je n'ai pas accès aux machines Windows au-delà des machines virtuelles, donc ce n'est pas le plus facile à déboguer pour moi ...

@jeanlauliac vous avez ajouté write-file-atomic dans # 4088, seriez-vous en mesure de nous aider?

Je viens d'exécuter une trace

Heure de la journée | Nom du processus | PID | Opération | Chemin | Résultat | Détail
- | - | - | - | - | - | -
16: 54: 43.2304011 | node.exe | 7624 | SetRenameInformationFile | ... \ constant_ee286bbcf367680ce61a90e506522f92.82986661 | SUCCÈS | ReplaceIfExists: True, FileName: ... \ constant_ee286bbcf367680ce61a90e506522f92
16: 54: 43.2305499 | node.exe | 8208 | SetRenameInformationFile | ... \ constant_ee286bbcf367680ce61a90e506522f92.103872574 | ACCÈS REFUSÉ | ReplaceIfExists: True, FileName: ... \ constant_ee286bbcf367680ce61a90e506522f92

Comme vous pouvez le voir, deux processus tentent de renommer le même fichier à moins de 1 ms l'un de l'autre et le second échoue.

Je pense que npm / write-file-atomic # 22 aborde la version asynchrone de writeFile() , mais writeFileSync() est toujours affecté.

Serait-il possible de créer une repro montrant que le simple fait d'utiliser write-file-atomic dans worker-farm contre le même fichier échoue d'une manière ou d'une autre? Ce serait formidable d'ouvrir un problème contre ce projet, car je pense que c'est là que le correctif devrait être.

Ou si vous pouviez écrire un test dans jest qui montre la même erreur (nous avons appveyor CI), cela pourrait également être un début?

Je ne sais même pas quel comportement nous voulons en cas d'erreur. Réessayer l'écriture? Réexécuter le test? L'ensemble du fichier de test?

OK, je vais essayer de créer une autre repro. Je ne suis pas sûr qu'il soit possible de créer un test de plaisanterie, car cela nécessiterait de générer plusieurs processus, de désactiver / nettoyer le cache et de continuer à fonctionner jusqu'à ce qu'il échoue.

Je ne sais même pas quel comportement nous voulons en cas d'erreur.

Eh bien, premièrement, le problème ne devrait même pas se produire lorsque --no-cache est activé, car le cache ne doit pas être rempli.
Deuxièmement, je ne suis pas sûr qu'il soit possible de réessayer correctement l'opération de synchronisation - est-il possible d'utiliser writeFile() au lieu de writeFileSync() ? De cette façon, write-file-atomic devrait réessayer automatiquement (je vais créer un test pour confirmer).

Eh bien, premièrement, le problème ne devrait même pas se produire lorsque --no-cache est activé, car le cache ne doit pas être rempli.

C'est un bon point et devrait être corrigé séparément. De cette façon, --no-cache peut au moins être une solution de contournement.

Deuxièmement, je ne suis pas sûr qu'il soit possible de réessayer correctement l'opération de synchronisation - est-il possible d'utiliser writeFile() au lieu de writeFileSync() ?

@cpojer pense à faire en sorte que ce ne soit pas synchronisé? Je ne sais pas comment cela évolue. Ou si vous avez une autre idée sur la façon de résoudre ce problème

  • --no-cache ressemble plus à --reset-cache fait. Cela signifie qu'il n'utilisera pas le cache existant, mais qu'il écrira toujours le cache. J'aimerais conserver cela.
  • Ces opérations doivent être synchronisées, car elles se produisent pendant les appels require dans le code utilisateur, nous ne pouvons donc pas changer cela.

Voici l'autre repro avec worker-farm et write-file-atomic : https://github.com/asapach/write-atomic-issue

Résultats jusqu'à présent: la version de synchronisation échoue comme prévu, mais étonnamment, la version asynchrone échoue également. Cela signifie qu'ils implémentent probablement une file d'attente de relance uniquement lorsqu'elle s'exécute dans le même processus, ce qui n'aide pas dans notre cas.

J'aimerais conserver cela.

Nouveau drapeau? C'est un nom très trompeur. Et sur par exemple CI, vous voulez rarement le cache de toute façon, donc c'est juste des ressources gaspillées. Ou un cache généré au cours d'une seule exécution de test est-il utilisé pendant --no-cache , et il ignore uniquement les caches existants?

Voici l'autre repro avec worker-farm et write-file-atomic

Impressionnant! Pourriez-vous ouvrir un problème contre write-file-atomic? On a l'impression qu'un correctif devrait y aller, et sinon (ils ne veulent pas prendre en charge plusieurs processus d'écriture à la fois), nous pouvons revenir de notre côté. WDYT?

Un correctif que j'ai essayé localement et qui semblait fonctionner ignore l'erreur si elle provient d'une tentative de renommer un fichier avec le même contenu. Comme cela signifie simplement qu'un autre processus a «gagné» la course, nous pouvons l'ignorer et passer à autre chose.

const cacheWriteErrorSafeToIgnore = (
  e: Error,
  cachePath: Path,
  fileData: string,
) => {
  if (
    e.message &&
    e.message.indexOf('EPERM: operation not permitted, rename') > -1
  ) {
    try {
      const currentContent = fs.readFileSync(cachePath, 'utf8');
      return fileData === currentContent;
    } catch (e) {
    }
  }
  return false;
};

@SimenB , bien sûr, je vais déposer un problème.

@cpojer , cette erreur peut-elle être avalée / ignorée et traitée comme un avertissement? Cela implique que le fichier a déjà été écrit et qu'aucune donnée ne doit être perdue.

Problème en amont: npm / write-file-atomic # 28

Je pense que cela signifie que "renommer" n'est pas une opération atomique sous Windows, donc cela rompt l'hypothèse faite par write-file-atomic . À moins qu'un indicateur ne puisse être activé au niveau de l'API Windows, cela pourrait signifier qu'il est impossible d'avoir des écritures / renommées atomiques sous Windows.

@jwbay votre solution me semble raisonnable! 👍 Au lieu d'utiliser indexOf cependant, j'utiliserais e.code === 'EPERM' (plus robuste, ne dépend pas du message spécifique). Je ne pense pas que nous devrions relire le fichier pour vérifier la valeur, car cela pourrait introduire des problèmes de concurrence supplémentaires (par exemple, si le fichier est écrit par un autre processus en même temps). Pourriez-vous envoyer un PR, s'il vous plaît?

J'étais sur le point de commencer à travailler sur un PR pour write-file-atomic du type "si on nous demande d'écrire une synchronisation de fichier mais qu'il est déjà dans la file d'attente pour être écrit async, renflouez" (peut-être avec une option pour activer le comportement). Mais si nous sommes heureux de gérer cela au niveau Jest, je ne me dépêcherai pas. cc @jeanlauliac

J'étais sur le point de commencer à travailler sur un PR pour write-file-atomic du type "si on nous demande d'écrire un fichier sync mais qu'il est déjà dans la file d'attente pour être écrit async, renflouez" (peut-être avec une option pour activer le comportement).

Je pense que l'ajout de cette logique (file d'attente locale) ne résoudrait pas le problème, car cela se produit principalement lorsque différents processus essaient d'écrire (renommer) dans le même fichier.

Pour résoudre les problèmes de concurrence une fois pour toutes, nous devrons peut-être reconsidérer la façon dont nous faisons la mise en cache, par exemple avoir un seul processus qui accède au cache, avec lequel nous communiquons via une sorte d'IPC. Les systèmes de stockage de clés / valeurs existants peuvent être utiles, tels que memcached .

Je pense que l'ajout de cette logique (file d'attente locale) ne résoudrait pas le problème, car cela se produit principalement lorsque différents processus essaient d'écrire (renommer) dans le même fichier.

Ah, j'ai peut-être mal compris la question alors. La façon dont je la lis, la bibliothèque a déjà un mécanisme de mise en file d'attente qui fonctionne bien pour les demandes asynchrones, mais si vous mélangez les demandes de synchronisation _ aussi bien_ vous pouvez obtenir des collisions.

Ma demande d'extraction référencée ci-dessus devrait résoudre ce problème. Au moins ça l'a fait pour moi!

@mekwall , je pense qu'ils utilisent rename() dans la version asynchrone de writeFile() , et cela échoue toujours dans mon test: https://github.com/asapach/write-atomic-issue. Pourriez-vous s'il vous plaît essayer d'exécuter ma repro? Je pense que votre changement pourrait minimiser la probabilité que ce problème se produise, mais ne l'élimine pas complètement.

@asapach Avez-vous essayé mes modifications? Parce que j'ai essayé plusieurs fois, et je n'ai jamais eu EPERM: operation not permitted, rename avec mes modifications tout en l'obtenant à chaque fois sans.

@mekwall ,

Ou plutôt techniquement, cela n'échoue pas (car le flux de synchronisation n'est pas interrompu), mais la console est toujours parsemée d'erreurs EPERM.

@asapach J'ai trouvé le problème que vous rencontrez. C'est dans le polyfill graceful-fs . J'ai publié un correctif dans ce PR: https://github.com/isaacs/node-graceful-fs/pull/119

@mekwall , oui, cela semble résoudre le problème - plus d'erreurs dans les versions sync et async.
Le problème maintenant est que les fichiers temporaires ne sont pas supprimés, car fs.unlinkSync(tmpfile) n'est jamais appelé: https://github.com/npm/write-file-atomic/pull/29/files#diff -168726dbe96b3ce427e7fedce31bb0bcR198

@asapach J'ai ajouté un lien à graceful-fs renommer, mais je ne suis pas sûr que ce soit la bonne voie à suivre. Afaik fs.rename utilise la fonction MoveFile et cela ne doit pas copier la source vers la destination. La source doit simplement changer de nom et la source et la destination ne doivent jamais exister en même temps.

@mekwall , cela aide un peu, mais dans certains cas, si le worker est arrêté tôt (car tout le travail est fait), certains fichiers ne sont pas nettoyés, car il n'attend pas le nettoyage. La version asynchrone semble fonctionner correctement.

@asapach Cela ne fonctionne pas du tout comme prévu. Je dois plonger dans les entrailles de node pour comprendre comment cela fonctionne réellement et quel devrait être le comportement prévu. Je pense que tout l'intérêt de graceful-fs est de le faire fonctionner de la même manière sur toutes les plates-formes, donc je vais approfondir cela. Au moins, nous avons trouvé le coupable :)

@asapach J'ai réalisé que mon PR pour write-file-atomic ne fonctionnerait pas, alors j'ai adopté une autre approche en ajoutant fs.renameSync dans graceful-fs avec les mêmes solutions de contournement que fs.rename mais bloquant. Cela permet à votre test de fonctionner comme prévu!

@mekwall , Merci, j'ai vérifié vos modifications sur mes deux cas de repro et aucun d'entre eux n'a échoué.
Je pense qu'en revanche, je vois une utilisation accrue du processeur et du disque pour la synchronisation, mais c'est probablement prévu.

Merci à beaucoup de gens d'avoir pris ce problème et d'avoir aidé à le réparer. Très appréciée! ❤️ Espérons que le correctif de graceful-fs est le bon, et qu'il sera publié.

@SimenB De rien ! Nous sommes peinés par cela au travail, alors j'ai eu le temps d'enquêter sur cela par mon équipe. Les modifications affecteront de nombreux packages, il leur faudra donc probablement du temps pour l'accepter: /

Une idée du moment où cette solution de contournement aboutira à une version?

@cpojer pourriez-vous fournir plus d'informations sur les raisons de sa fermeture? y a-t-il un correctif fourni? Nous avons toujours ce problème

Toutes mes excuses, il semble que le correctif n'ait pas encore atterri dans graceful-fs :(

Plusieurs personnes peuvent-elles confirmer que l'utilisation de https://github.com/isaacs/node-graceful-fs/pull/119 résout leurs problèmes?

Vous pouvez utiliser la fourchette en utilisant des résolutions de fil, voir https://yarnpkg.com/en/docs/selective-version-resolutions , ce qui devrait vous permettre de déployer le correctif sur CI, etc.

par exemple

{
  "resolutions": {
    "graceful-fs": "mekwall/node-graceful-fs#a10aa576f771d7cf3dfaee523f2e02d6eb11a89f"
  }
}

@SimenB Cela résout le problème pour moi, au moins 😄

+1 Pour moi aussi.

@SimenB a également résolu mon problème et je suis maintenant capable d'utiliser jest 22 sur Windows. (Nous étions coincés sur 20 avant cela).

Edit: En fait, cela a fonctionné sur mon ordinateur portable de développement, mais n'a pas fonctionné sur le serveur de construction. Mais c'est du fil 1.2.1, c'est peut-être pourquoi?

[16:47:55][Step 5/8]     jest: failed to read cache file: D:/TeamCity/buildAgent2/temp/buildTmp/jest/jest-transform-cache-c39254d365b4bcb2c90f133d4b359d91-56a1804d8d831b3401a35a7e81857f3b/7e/rafPolyfill_7e7a83ed3f2680ba9aec0e45f59ade5d
[16:47:55][Step 5/8]     Failure message: EPERM: operation not permitted, open 'D:\TeamCity\buildAgent2\temp\buildTmp\jest\jest-transform-cache-c39254d365b4bcb2c90f133d4b359d91-56a1804d8d831b3401a35a7e81857f3b\7e\rafPolyfill_7e7a83ed3f2680ba9aec0e45f59ade5d'
[16:47:55][Step 5/8]       
[16:47:55][Step 5/8]       at readCacheFile (node_modules/jest-runtime/build/script_transformer.js:465:60)

Yarn 1.0.0 devrait suffire, mais il vaut la peine d'essayer la mise à niveau

J'ai juste essayé de mettre la résolution, mais cela échoue toujours pour moi. Cependant, j'ai des violations ENOENT et EPERM:

    jest: failed to read cache file: C:/Users/dev/AppData/Local/Temp/jest/jest-transform-cache-857f905b2da01d52a9d1d17b6772ea4a-3a91587e29d4fef23c6e0cf16b2f5679/7d/index_7d0afc82f0b29ec31c4b5f296cbdee74
    Failure message: ENOENT: no such file or directory, open 'C:\Users\dev\AppData\Local\Temp\jest\jest-transform-cache-857f905b2da01d52a9d1d17b6772ea4a-3a91587e29d4fef23c6e0cf16b2f5679\7d\index_7d0afc82f0b29ec31c4b5f296cbdee74'

      at Object.fs.openSync (../fs.js:653:18)
      at Object.fs.readFileSync (../fs.js:554:33)

et

    jest: failed to read cache file: C:/Users/dev/AppData/Local/Temp/jest/jest-transform-cache-857f905b2da01d52a9d1d17b6772ea4a-3a91587e29d4fef23c6e0cf16b2f5679/c4/std_pb_c403e6e7645c904896b66f44a3e43606
    Failure message: EPERM: operation not permitted, open 'C:\Users\dev\AppData\Local\Temp\jest\jest-transform-cache-857f905b2da01d52a9d1d17b6772ea4a-3a91587e29d4fef23c6e0cf16b2f5679\c4\std_pb_c403e6e7645c904896b66f44a3e43606'

      at Object.fs.openSync (../fs.js:653:18)
      at Object.fs.readFileSync (../fs.js:554:33)

@mreishus Votre serveur de build graceful-fs ne cibleront que Windows, mais cela ne devrait pas se produire sur un système d'exploitation basé sur Linux.

@mekwall oui, Windows - mais c'est Windows Server 2012 R2

C'est un problème majeur pour moi et rien ne s'est passé avec graceful-fs depuis novembre 2016 de ce que je peux voir. Je suis donc assez pessimiste quant au fait que le correctif @mekwall fourni ne sera pas fusionné de sitôt. Existe-t-il une solution temporaire que nous pouvons utiliser autre que l'indicateur -i et la solution de contournement de résolution?

--RunInBand ne fonctionne-t-il pas pour vous @frenic?

C'est la même chose que -i et oui, cela fonctionne. Mais malheureusement, ce n'est pas viable à long terme pour les grands projets.

Je suppose que nous pourrions créer un fork et publier le nôtre, mais il ne semble pas que le correctif fonctionne pour tout le monde

Je suis dans la même situation, mais dans mon cas, --runInBand ne fonctionne pas.

J'ai vérifié le remplacement graceful-fs avec la dernière version de Jest et malheureusement, il ne semble plus fonctionner de manière aussi fiable depuis que je l'ai testé pour la dernière fois. Il y a toujours une chance non nulle qu'il se heurte à une condition de concurrence sur de grandes suites de tests.

Après avoir parcouru ce fil, j'ai trouvé une résolution en utilisant yarn . Existe-t-il une résolution utilisant npm place?

Nous avons eu assez de chance jusqu'à présent en ajoutant la version corrigée de graceful-fs à notre package.json. Fonctionne pour nous avec npm et fil.

"graceful-fs": "https://github.com/mekwall/node-graceful-fs.git#patch-1",

Salut,

Pour une raison quelconque, nous n'obtenons cette erreur que lors de l'exécution à partir de Jenkins, pas lors de l'exécution locale (même sur la même machine / dossier, etc.)
La solution de @jsheetzati fonctionne aussi pour nous (en utilisant npm), mais c'est un patch après tout. Existe-t-il un ETA pour résoudre ce problème de manière permanente?

Merci,
Mor

Nous avons également ce problème lors de l'exécution de jest à partir de Jenkins. --runInBand option
Pour contourner le problème, nous utilisons le plugin de ressources verrouillables pour nous assurer qu'un seul processus jest est exécuté en même temps en gardant l'option --runInBand .
J'espère que ce commentaire sera utile pour quelqu'un.

@nyrkovalex Ce que nous faisons pour éviter le problème que vous décrivez est d'utiliser l'option de répertoire de cache de Jest pour nous assurer que le cache n'est pas partagé entre les espaces de travail.

Nous le faisons en publiant un préréglage Jest qui définit cacheDirectory: '<rootDir>/.jest-cache' et en nous assurant que tous les packages l'utilisent. Dans ce cas, assurez-vous d'ajouter .jest-cache à .gitignore .

Avant d'ajouter cette option, nous rencontrerions plusieurs problèmes en raison du partage d'un cache Jest global entre 16 exécuteurs par agent Jenkins. L'utilisation de ressources verrouillables évitera également les problèmes comme vous l'avez mentionné, mais c'est un gaspillage car vous n'utilisez pas votre agent Jenkins à son potentiel (car les tests Jest deviennent un goulot d'étranglement).

@ anescobar1991 Cette option est certainement une meilleure solution, nous envisagerons de l'utiliser.
Merci pour un conseil!

Salut,

nous utilisons gradle pour exécuter npm (ne demandez pas pourquoi :)) et la combinaison de cela avec Jenkins est un tueur.
Nous avons essayé:

  1. définir le cache pour qu'il se trouve dans le répertoire local au lieu du cache global
  2. en utilisant --runInBand
  3. un seul travail en cours d'exécution sur l'agent - pas de travaux parallèles
  4. exécuter le test gradle --max-workers 1 (et ne pas utiliser --parallel)

Tous échouent avec la même erreur.
La seule solution qui fonctionne pour nous est celle de @jsheetzati - j'aimerais que cela soit formellement corrigé.

Nous pourrions probablement fork et publier avec ce correctif

ce serait génial...

J'ai beaucoup de problèmes et le correctif pour les fs gracieux a fonctionné pour moi. J'apprécierais donc ce correctif.

Pour contourner le problème avec graceful-fs, ne pourriez-vous pas simplement donner à chaque processus de travail / thread son propre répertoire de cache pour éviter la condition de concurrence?

C'est probablement lent, mais nous devons utiliser --runInBand sur notre serveur CI et c'est bien pire.

Si quelqu'un peut me diriger vers les bons fichiers à regarder, je pourrais même essayer d'écrire un correctif. J'ai vraiment du mal à naviguer dans la source de la plaisanterie.

Je ne suis pas sûr de ce que c'est, mais cela fait quelques semaines peut-être quelques mois et je n'ai plus observé l'échec. Nous utilisons jest 22.4.2 depuis un certain temps et avons récemment mis à niveau vers 22.4.4. Nous avons également mis à jour divers autres packages.

juste pour participer - je vois cela avec jest 23.6 sur un serveur Windows Jenkins CI.

  • --runInBand fonctionne, mais double le temps de test, donc ce n'est pas génial, et comme nous avons des tests exécutés avant le push, je ne peux pas activer cela sans rendre les membres de mon équipe super tristes
  • le remplacement graceful-fs dans package.json , comme mentionné par @jsheetzati (https://github.com/facebook/jest/issues/4444#issuecomment-370533355) fonctionne, mais c'est un peu un hack.

Puisque graceful-fs ne fait pas grand-chose à ce sujet (https://github.com/isaacs/node-graceful-fs/pull/131 n'a pas vu d'action depuis juillet de l'année dernière), il est peut-être temps de bifurquer ? J'ai ajouté un petit commentaire là-bas, mais je ne m'attends pas à ce que quelqu'un saute soudainement au tri) ':

J'ai le même problème mais le message d'erreur est différent
Failure message: EBADF: bad file descriptor, close

jest: failed to cache transform results in: C:/agent/_work/_temp/jest/jest-transform-cache-2a12bf9796741cb06fb97a276aa09712-7d718cda2d798ae78eb741b3feff799e/7b/test-setup_7bdb1937d8dbbf5088142bc21e74a530
2019-01-24T13:44:55.5496091Z     Failure message: EBADF: bad file descriptor, close

Il semble qu'exécuter jest avec --runInBand ne résout pas le problème la première fois, mais seulement après une autre exécution, il s'exécute sans erreur.

Exécution sur Windows 10 Enterprise VM dans le cadre d'une build TFS.

@EthanSankin pouvez-vous également tester avec le PR lié graceful-fs?

Je travaille sur un remplacement de graceful-fs qui devrait résoudre ces problèmes. Il est actuellement en version alpha, mais ce serait génial d'avoir quelques premiers utilisateurs: https://github.com/mekwall/normalized-fs

le retour à l'ancienne version de write-file-atomic a résolu le problème.

@moizgh de quelle version à quelle version?

@moizgh de quelle version à quelle version?

2.4.2 à 2.3.0

@iarna semble avoir introduit une régression.

Vous rencontrez également ce problème, avez-vous des informations sur un correctif meilleur / permanent?

Cela a recommencé pour nous au cours des deux derniers mois - fenêtres - très intermittent.

write-file-atomic n'utilise plus graceful-fs - peut-être que cela a quelque chose à voir avec ça?

Cette page vous a été utile?
0 / 5 - 0 notes