|
| 1 | +const fsasync = require('fs').promises; |
| 2 | +const fs = require('fs'); |
| 3 | +const path = require('path'); |
| 4 | + |
| 5 | +const samplesRootPath = path.join(__dirname, '..'); |
| 6 | + |
| 7 | +// These directories are excluded from samples tests |
| 8 | +const excludedDirectories = [ |
| 9 | + path.join(samplesRootPath, '__tests__', '**').toUpperCase(), |
| 10 | + path.join(samplesRootPath, 'GuestConfiguration', 'package-samples', '**').toUpperCase(), |
| 11 | + path.join(samplesRootPath, 'KubernetesService', '**').toUpperCase() |
| 12 | +]; |
| 13 | + |
| 14 | +// Directories with these file type are excluded from samples tests |
| 15 | +const excludedFileExtensions = [ |
| 16 | + '.REGO' |
| 17 | +]; |
| 18 | + |
| 19 | +const samplesDirectories = []; |
| 20 | + |
| 21 | +function getFilePaths(rootDirPath) { |
| 22 | + const entryPaths = fs.readdirSync(rootDirPath).map(entry => path.join(rootDirPath, entry)); |
| 23 | + const filePaths = entryPaths.filter(entryPath => fs.statSync(entryPath).isFile()); |
| 24 | + const dirPaths = entryPaths.filter(entryPath => !filePaths.includes(entryPath)); |
| 25 | + const dirFiles = dirPaths.reduce((prev, curr) => prev.concat(getFilePaths(curr)), []); |
| 26 | + return [...filePaths, ...dirFiles]; |
| 27 | +} |
| 28 | + |
| 29 | +// Get the full set of directory paths containing policy samples |
| 30 | +let allSamplesFiles = getFilePaths(samplesRootPath); |
| 31 | +let samplesDirectoriesByPath = {}; |
| 32 | +allSamplesFiles.forEach(filePath => { |
| 33 | + let containingDirPath = path.dirname(filePath); |
| 34 | + |
| 35 | + // Exclude some directories and files that are deemed 'special content' |
| 36 | + for (const excludedDir of excludedDirectories) { |
| 37 | + if ((excludedDir.endsWith('**') && containingDirPath.toUpperCase().startsWith(excludedDir.substr(0, excludedDir.length - 3))) || containingDirPath.toUpperCase() === excludedDir) { |
| 38 | + return; |
| 39 | + } |
| 40 | + } |
| 41 | + |
| 42 | + if (excludedFileExtensions.includes(path.extname(filePath).toUpperCase())) { |
| 43 | + return; |
| 44 | + } |
| 45 | + |
| 46 | + if (!samplesDirectoriesByPath[containingDirPath]) { |
| 47 | + samplesDirectoriesByPath[containingDirPath] = [filePath]; |
| 48 | + } else { |
| 49 | + samplesDirectoriesByPath[containingDirPath].push(filePath); |
| 50 | + } |
| 51 | +}); |
| 52 | + |
| 53 | +for (const dirPath in samplesDirectoriesByPath) { |
| 54 | + samplesDirectories.push([dirPath, samplesDirectoriesByPath[dirPath]]); |
| 55 | +} |
| 56 | + |
| 57 | +// Validates that each samples directory contains the expected files |
| 58 | +test.each(samplesDirectories)('Validate directory structure: %s', (dirPath, filePaths) => { |
| 59 | + const expectedPolicyDefinitionFiles = [ |
| 60 | + path.join(dirPath, 'azurepolicy.json'), |
| 61 | + path.join(dirPath, 'azurepolicy.parameters.json'), |
| 62 | + path.join(dirPath, 'azurepolicy.rules.json'), |
| 63 | + path.join(dirPath, 'README.md') |
| 64 | + ]; |
| 65 | + |
| 66 | + const expectedPolicySetFiles = [ |
| 67 | + path.join(dirPath, 'azurepolicyset.json'), |
| 68 | + path.join(dirPath, 'azurepolicyset.parameters.json'), |
| 69 | + path.join(dirPath, 'azurepolicyset.definitions.json'), |
| 70 | + path.join(dirPath, 'README.md') |
| 71 | + ]; |
| 72 | + |
| 73 | + // Special case samples dirs that only contain markdown |
| 74 | + if (filePaths.every(filePath => path.extname(filePath).toUpperCase() === '.MD')) { |
| 75 | + return; |
| 76 | + } |
| 77 | + |
| 78 | + if (filePaths.some(filePath => path.basename(filePath, '.json').toUpperCase() === 'AZUREPOLICYSET')) { |
| 79 | + expect(filePaths).toEqual(expect.arrayContaining(expectedPolicySetFiles)); |
| 80 | + } else { |
| 81 | + expect(filePaths).toEqual(expect.arrayContaining(expectedPolicyDefinitionFiles)); |
| 82 | + } |
| 83 | +}); |
| 84 | + |
| 85 | +// Validates that all JSON files are valid JSON (not necessarily valid policy entities though) |
| 86 | +test.each(samplesDirectories.map(dirSet => dirSet[1]))('Validate JSON can be parsed: %s', async (filePath) => { |
| 87 | + if (path.extname(filePath).toUpperCase() !== '.JSON') { |
| 88 | + return; |
| 89 | + } |
| 90 | + |
| 91 | + let fileContent = await fsasync.readFile(filePath); |
| 92 | + JSON.parse(fileContent); |
| 93 | +}); |
0 commit comments