diff --git a/packages/core/upload/server/services/__tests__/metrics.js b/packages/core/upload/server/services/__tests__/metrics.js new file mode 100644 index 0000000000..01dd0c2e09 --- /dev/null +++ b/packages/core/upload/server/services/__tests__/metrics.js @@ -0,0 +1,105 @@ +'use strict'; + +const metricsService = require('../metrics'); + +describe('metrics', () => { + describe('computeWeeklyMetrics', () => { + test.each([ + [[], 0, [0, 0, 0, 0, 0]], + [ + [ + [1, 1], + [2, 1], + [3, 1], + [4, 1], + ], + 1, + [1, 4, 2.5, 4, 1], + ], + [ + [ + [1, 1], + [2, 1], + [3, 100], + ], + 4, + [4, 3, 2.971, 102, 0.058], + ], + ])('folders: %s, assets: %s => %s', async (folderLevels, assetsNumber, expectedResults) => { + const count = jest.fn(() => Promise.resolve(assetsNumber)); + const raw = jest.fn(() => ''); + const strapi = { + getModel() { + return { + collectionName: () => 'upload_folders', + }; + }, + entityService: { + count, + }, + db: { + metadata: { + get: () => ({ attributes: { path: { columnName: 'path' } } }), + }, + connection() { + return { + select() { + return { + groupBy: () => folderLevels.map(info => ({ depth: info[0], occurence: info[1] })), + }; + }, + }; + }, + }, + }; + strapi.db.connection.raw = raw; + + const { computeWeeklyMetrics } = metricsService({ strapi }); + + const results = await computeWeeklyMetrics(); + const [ + assetNumber, + maxDepth, + averageDepth, + folderNumber, + averageDeviationDepth, + ] = expectedResults; + + expect( + raw + ).toHaveBeenCalledWith( + 'LENGTH(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(??, ?, ?), ?, ?), ?, ?), ?, ?), ?, ?), ?, ?), ?, ?), ?, ?), ?, ?), ?, ?)) as depth, count(*) as occurence', + [ + 'path', + '0', + '', + '1', + '', + '2', + '', + '3', + '', + '4', + '', + '5', + '', + '6', + '', + '7', + '', + '8', + '', + '9', + '', + ] + ); + expect(results).toMatchObject({ + assetNumber, + folderNumber, + averageDepth: expect.closeTo(averageDepth, 3), + maxDepth, + averageDeviationDepth: expect.closeTo(averageDeviationDepth, 3), + }); + }); + }); +}); diff --git a/packages/core/upload/server/services/metrics.js b/packages/core/upload/server/services/metrics.js index 8fc1c6824e..d6c8e44e30 100644 --- a/packages/core/upload/server/services/metrics.js +++ b/packages/core/upload/server/services/metrics.js @@ -11,7 +11,7 @@ module.exports = ({ strapi }) => { let running = false; return { - async computeMetrics() { + async computeWeeklyMetrics() { // Folder metrics const pathColName = strapi.db.metadata.get(FOLDER_MODEL_UID).attributes.path.columnName; const folderTable = strapi.getModel(FOLDER_MODEL_UID).collectionName; @@ -45,13 +45,14 @@ module.exports = ({ strapi }) => { maxDepth = folderLevel.depth; } } - const averageDepth = product / folderNumber; + const averageDepth = folderNumber !== 0 ? product / folderNumber : 0; let sumOfDeviation = 0; for (const folderLevel of folderLevelsArray) { - sumOfDeviation += Math.abs(folderLevel.depth * folderLevel.occurence - averageDepth); + sumOfDeviation += Math.abs(folderLevel.depth - averageDepth) * folderLevel.occurence; } - const averageDeviationDepth = sumOfDeviation / folderNumber; + + const averageDeviationDepth = folderNumber !== 0 ? sumOfDeviation / folderNumber : 0; // File metrics const assetNumber = await strapi.entityService.count(FILE_MODEL_UID); @@ -72,7 +73,7 @@ module.exports = ({ strapi }) => { running = true; const pingCron = scheduleJob(getCronRandomWeekly(), async () => { - const metrics = await this.computeMetrics(); + const metrics = await this.computeWeeklyMetrics(); strapi.telemetry.send('didSendUploadPropertiesOnceAWeek', metrics); }); diff --git a/yarn.lock b/yarn.lock index 7e97bc7f83..ac18c38e02 100644 --- a/yarn.lock +++ b/yarn.lock @@ -250,7 +250,7 @@ json5 "^2.2.1" semver "^6.3.0" -"@babel/generator@7.18.7", "@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.16.7", "@babel/generator@^7.17.9", "@babel/generator@^7.18.2", "@babel/generator@^7.18.6", "@babel/generator@^7.18.7", "@babel/generator@^7.7.2": +"@babel/generator@7.18.7", "@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.18.2", "@babel/generator@^7.18.6", "@babel/generator@^7.18.7", "@babel/generator@^7.7.2": version "7.18.7" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.7.tgz#2aa78da3c05aadfc82dbac16c99552fc802284bd" integrity sha512-shck+7VLlY72a2w9c3zYWuE1pwOKEiQHV7GTUbSnhyl5eu3i04t30tBY82ZRWrDfo3gkakCFtevExnxbkf2a3A== @@ -259,6 +259,15 @@ "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" +"@babel/generator@^7.16.7", "@babel/generator@^7.17.9": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.9.tgz#f4af9fd38fa8de143c29fce3f71852406fc1e2fc" + integrity sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ== + dependencies: + "@babel/types" "^7.17.0" + jsesc "^2.5.1" + source-map "^0.5.0" + "@babel/helper-annotate-as-pure@^7.16.0", "@babel/helper-annotate-as-pure@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" @@ -598,7 +607,12 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== -"@babel/helper-validator-option@^7.16.7", "@babel/helper-validator-option@^7.18.6": +"@babel/helper-validator-option@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" + integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== + +"@babel/helper-validator-option@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== @@ -658,7 +672,7 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@7.18.6", "@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.9", "@babel/parser@^7.18.5", "@babel/parser@^7.7.0", "@babel/parser@^7.8.3": +"@babel/parser@7.18.6", "@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.9", "@babel/parser@^7.18.5", "@babel/parser@^7.18.6", "@babel/parser@^7.7.0", "@babel/parser@^7.8.3": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.6.tgz#845338edecad65ebffef058d3be851f1d28a63bc" integrity sha512-uQVSa9jJUe/G/304lXspfWVpKpK4euFLgGiMQFOCpM/bgcAdeoHwi/OQz23O9GK2osz26ZiXRRV9aV+Yl1O8tw== @@ -668,7 +682,7 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.4.tgz#6774231779dd700e0af29f6ad8d479582d7ce5ef" integrity sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow== -"@babel/parser@^7.18.6", "@babel/parser@^7.18.8": +"@babel/parser@^7.18.8": version "7.18.8" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.8.tgz#822146080ac9c62dac0823bb3489622e0bc1cbdf" integrity sha512-RSKRfYX20dyH+elbJK2uqAkVyucL+xXzhqlMD5/ZXx+dAAwpyB7HsvnHe/ZUGOF+xLr5Wx9/JoXVTj6BQE2/oA== @@ -2081,7 +2095,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.18.0", "@babel/types@^7.18.2", "@babel/types@^7.18.4", "@babel/types@^7.18.6", "@babel/types@^7.18.7", "@babel/types@^7.18.8", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": +"@babel/types@^7.0.0", "@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.18.0", "@babel/types@^7.18.2", "@babel/types@^7.18.4", "@babel/types@^7.18.8", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": version "7.18.8" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.8.tgz#c5af199951bf41ba4a6a9a6d0d8ad722b30cd42f" integrity sha512-qwpdsmraq0aJ3osLJRApsc2ouSJCdnMeZwB0DhbtHAtRpZNZCdlbRnHIgcRKzdE1g0iOGg644fzjOBcdOz9cPw== @@ -2089,6 +2103,14 @@ "@babel/helper-validator-identifier" "^7.18.6" to-fast-properties "^2.0.0" +"@babel/types@^7.18.6", "@babel/types@^7.18.7": + version "7.18.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.7.tgz#a4a2c910c15040ea52cdd1ddb1614a65c8041726" + integrity sha512-QG3yxTcTIBoAcQmkCs+wAPYZhu7Dk9rXKacINfNbdJDNERTbLQbHGyVG8q/YGMPeCJRIhSY0+fTc5+xuh6WPSQ== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + to-fast-properties "^2.0.0" + "@base2/pretty-print-object@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" @@ -20311,11 +20333,16 @@ prr@~1.0.1: resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== -psl@^1.1.28, psl@^1.1.33: +psl@^1.1.28: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== +psl@^1.1.33: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + public-encrypt@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0"