Skip to content

Commit

Permalink
fix(app-upload): More consistent logging during up/download of Sense …
Browse files Browse the repository at this point in the history
…apps
  • Loading branch information
Göran Sander committed Mar 8, 2024
1 parent 6baccc0 commit 32f6d70
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 158 deletions.
292 changes: 146 additions & 146 deletions src/__tests__/app_export_cert.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import path from 'path';
import exportAppToFile from '../lib/cmd/exportapp.js';

const options = {
// logLevel: process.env.CTRL_Q_LOG_LEVEL || 'info',
logLevel: process.env.CTRL_Q_LOG_LEVEL || 'verbose',
logLevel: process.env.CTRL_Q_LOG_LEVEL || 'info',
// logLevel: process.env.CTRL_Q_LOG_LEVEL || 'verbose',
authType: process.env.CTRL_Q_AUTH_TYPE || 'cert',
authCertFile: process.env.CTRL_Q_AUTH_CERT_FILE || './cert/client.pem',
authCertKeyFile: process.env.CTRL_Q_AUTH_CERT_KEY_FILE || './cert/client_key.pem',
Expand Down Expand Up @@ -63,150 +63,150 @@ describe('export apps to QVF files (cert auth)', () => {
expect(files.length).toBeGreaterThan(0);

// Delete output dir
// fs.rmSync(exportDir, { recursive: true });
fs.rmSync(exportDir, { recursive: true });
});

// /**
// * Two tags, overwrite
// *
// * --output-dir qvfs
// * --app-tag apiCreated 'Ctrl-Q import'
// * --exclude-app-data true
// * --qvf-name-format app-id app-name export-date export-time
// * --qvf-name-separator _
// * --qvf-overwrite true
// */
// test('export apps, two tags', async () => {
// options.outputDir = 'qvfs_tmp';
// options.appTag = ['apiCreated', 'Ctrl-Q import'];
// options.excludeAppData = 'true';
// options.qvfNameFormat = ['app-id', 'app-name', 'export-date', 'export-time'];
// options.qvfNameSeparator = '_';
// options.qvfOverwrite = true;

// const result = await exportAppToFile(options);
// expect(result).toBe(true);

// // Verify that output folder contains at least one file
// const exportDir = path.resolve(options.outputDir);
// const files = fs.readdirSync(exportDir);
// expect(files.length).toBeGreaterThan(0);

// // Delete output dir
// fs.rmSync(exportDir, { recursive: true });
// });

// /**
// * Two tags, one ID, overwrite
// *
// * --output-dir qvfs
// * --app-tag apiCreated 'Ctrl-Q import'
// * --app-id eb3ab049-d007-43d3-93da-5962f9208c65
// * --exclude-app-data true
// * --qvf-name-format app-id app-name export-date export-time
// * --qvf-name-separator _
// * --qvf-overwrite true
// */
// test('export apps, two tags, one id', async () => {
// options.outputDir = 'qvfs_tmp';
// options.appTag = ['apiCreated', 'Ctrl-Q import'];
// options.appId = ['eb3ab049-d007-43d3-93da-5962f9208c65'];
// options.excludeAppData = 'true';
// options.qvfNameFormat = ['export-date', 'export-time', 'app-id', 'app-name'];
// options.qvfNameSeparator = '_';
// options.qvfOverwrite = true;

// const result = await exportAppToFile(options);
// expect(result).toBe(true);

// // Verify that output folder contains at least one file
// const exportDir = path.resolve(options.outputDir);
// const files = fs.readdirSync(exportDir);
// expect(files.length).toBeGreaterThan(0);

// // Delete output dir
// fs.rmSync(exportDir, { recursive: true });
// });

// /**
// * Two tags, two IDs, overwrite
// *
// * --output-dir qvfs
// * --app-tag apiCreated 'Ctrl-Q import'
// * --app-id eb3ab049-d007-43d3-93da-5962f9208c65
// * --exclude-app-data true
// * --qvf-name-format app-id app-name export-date export-time
// * --qvf-name-separator _
// * --qvf-overwrite true
// */
// test('export apps, two tags, two ids', async () => {
// options.outputDir = 'qvfs_tmp';
// options.appTag = ['apiCreated', 'Ctrl-Q import'];
// options.appId = ['eb3ab049-d007-43d3-93da-5962f9208c65', '2933711d-6638-41d4-a2d2-6dd2d965208b'];
// options.excludeAppData = 'true';
// options.qvfNameFormat = ['export-date', 'export-time', 'app-id', 'app-name'];
// options.qvfNameSeparator = '_';
// options.qvfOverwrite = true;

// const result = await exportAppToFile(options);
// expect(result).toBe(true);

// // Verify that output folder contains at least one file
// const exportDir = path.resolve(options.outputDir);
// const files = fs.readdirSync(exportDir);
// expect(files.length).toBeGreaterThan(0);

// // Delete output dir
// fs.rmSync(exportDir, { recursive: true });
// });

// /**
// * Two tags, two IDs, overwrite. Export metadata to Excel file
// *
// * --output-dir qvfs
// * --app-tag apiCreated 'Ctrl-Q import'
// * --app-id eb3ab049-d007-43d3-93da-5962f9208c65
// * --exclude-app-data true
// * --qvf-name-format app-id app-name export-date export-time
// * --qvf-name-separator _
// * --qvf-overwrite true
// */
// test('export apps, two tags, two ids, export metadata', async () => {
// options.outputDir = 'qvfs_tmp';
// options.appTag = ['apiCreated', 'Ctrl-Q import'];
// options.appId = ['eb3ab049-d007-43d3-93da-5962f9208c65', '2933711d-6638-41d4-a2d2-6dd2d965208b'];
// options.excludeAppData = 'true';
// options.qvfNameFormat = ['export-date', 'export-time', 'app-id', 'app-name'];
// options.qvfNameSeparator = '_';
// options.qvfOverwrite = true;

// options.metadataFileCreate = true;
// options.metadataFileName = 'app-export.xlsx';
// options.metadataFileFormat = 'excel';
// options.metadataFileOverwrite = true;

// const result = await exportAppToFile(options);
// expect(result).toBe(true);

// // Verify that output folder contains at least one file
// const exportDir = path.resolve(options.outputDir);
// const files = fs.readdirSync(exportDir);
// expect(files.length).toBeGreaterThan(0);

// // Verify that output Excel file has been created
// // Get all files in output folder
// const files2 = fs.readdirSync(exportDir);

// // Filter out Excel files
// const excelFiles = files2.filter((file) => file.endsWith('.xlsx'));
// expect(excelFiles.length).toBe(1);

// // Size of Exel file should be > 0
// const excelFile = path.resolve(exportDir, excelFiles[0]);
// const stats = fs.statSync(excelFile);
// expect(stats.size).toBeGreaterThan(0);

// // Delete output dir
// fs.rmSync(exportDir, { recursive: true });
// });
/**
* Two tags, overwrite
*
* --output-dir qvfs
* --app-tag apiCreated 'Ctrl-Q import'
* --exclude-app-data true
* --qvf-name-format app-id app-name export-date export-time
* --qvf-name-separator _
* --qvf-overwrite true
*/
test('export apps, two tags', async () => {
options.outputDir = 'qvfs_tmp';
options.appTag = ['apiCreated', 'Ctrl-Q import'];
options.excludeAppData = 'true';
options.qvfNameFormat = ['app-id', 'app-name', 'export-date', 'export-time'];
options.qvfNameSeparator = '_';
options.qvfOverwrite = true;

const result = await exportAppToFile(options);
expect(result).toBe(true);

// Verify that output folder contains at least one file
const exportDir = path.resolve(options.outputDir);
const files = fs.readdirSync(exportDir);
expect(files.length).toBeGreaterThan(0);

// Delete output dir
fs.rmSync(exportDir, { recursive: true });
});

/**
* Two tags, one ID, overwrite
*
* --output-dir qvfs
* --app-tag apiCreated 'Ctrl-Q import'
* --app-id eb3ab049-d007-43d3-93da-5962f9208c65
* --exclude-app-data true
* --qvf-name-format app-id app-name export-date export-time
* --qvf-name-separator _
* --qvf-overwrite true
*/
test('export apps, two tags, one id', async () => {
options.outputDir = 'qvfs_tmp';
options.appTag = ['apiCreated', 'Ctrl-Q import'];
options.appId = ['eb3ab049-d007-43d3-93da-5962f9208c65'];
options.excludeAppData = 'true';
options.qvfNameFormat = ['export-date', 'export-time', 'app-id', 'app-name'];
options.qvfNameSeparator = '_';
options.qvfOverwrite = true;

const result = await exportAppToFile(options);
expect(result).toBe(true);

// Verify that output folder contains at least one file
const exportDir = path.resolve(options.outputDir);
const files = fs.readdirSync(exportDir);
expect(files.length).toBeGreaterThan(0);

// Delete output dir
fs.rmSync(exportDir, { recursive: true });
});

/**
* Two tags, two IDs, overwrite
*
* --output-dir qvfs
* --app-tag apiCreated 'Ctrl-Q import'
* --app-id eb3ab049-d007-43d3-93da-5962f9208c65
* --exclude-app-data true
* --qvf-name-format app-id app-name export-date export-time
* --qvf-name-separator _
* --qvf-overwrite true
*/
test('export apps, two tags, two ids', async () => {
options.outputDir = 'qvfs_tmp';
options.appTag = ['apiCreated', 'Ctrl-Q import'];
options.appId = ['eb3ab049-d007-43d3-93da-5962f9208c65', '2933711d-6638-41d4-a2d2-6dd2d965208b'];
options.excludeAppData = 'true';
options.qvfNameFormat = ['export-date', 'export-time', 'app-id', 'app-name'];
options.qvfNameSeparator = '_';
options.qvfOverwrite = true;

const result = await exportAppToFile(options);
expect(result).toBe(true);

// Verify that output folder contains at least one file
const exportDir = path.resolve(options.outputDir);
const files = fs.readdirSync(exportDir);
expect(files.length).toBeGreaterThan(0);

// Delete output dir
fs.rmSync(exportDir, { recursive: true });
});

/**
* Two tags, two IDs, overwrite. Export metadata to Excel file
*
* --output-dir qvfs
* --app-tag apiCreated 'Ctrl-Q import'
* --app-id eb3ab049-d007-43d3-93da-5962f9208c65
* --exclude-app-data true
* --qvf-name-format app-id app-name export-date export-time
* --qvf-name-separator _
* --qvf-overwrite true
*/
test('export apps, two tags, two ids, export metadata', async () => {
options.outputDir = 'qvfs_tmp';
options.appTag = ['apiCreated', 'Ctrl-Q import'];
options.appId = ['eb3ab049-d007-43d3-93da-5962f9208c65', '2933711d-6638-41d4-a2d2-6dd2d965208b'];
options.excludeAppData = 'true';
options.qvfNameFormat = ['export-date', 'export-time', 'app-id', 'app-name'];
options.qvfNameSeparator = '_';
options.qvfOverwrite = true;

options.metadataFileCreate = true;
options.metadataFileName = 'app-export.xlsx';
options.metadataFileFormat = 'excel';
options.metadataFileOverwrite = true;

const result = await exportAppToFile(options);
expect(result).toBe(true);

// Verify that output folder contains at least one file
const exportDir = path.resolve(options.outputDir);
const files = fs.readdirSync(exportDir);
expect(files.length).toBeGreaterThan(0);

// Verify that output Excel file has been created
// Get all files in output folder
const files2 = fs.readdirSync(exportDir);

// Filter out Excel files
const excelFiles = files2.filter((file) => file.endsWith('.xlsx'));
expect(excelFiles.length).toBe(1);

// Size of Exel file should be > 0
const excelFile = path.resolve(exportDir, excelFiles[0]);
const stats = fs.statSync(excelFile);
expect(stats.size).toBeGreaterThan(0);

// Delete output dir
fs.rmSync(exportDir, { recursive: true });
});
});
31 changes: 21 additions & 10 deletions src/globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,24 +74,35 @@ export const setLoggingLevel = (newLevel) => {
logTransports.find((transport) => transport.name === 'console').level = newLevel;
};

export const verifyFileExists = async (file) => {
export const verifyFileExists = async (file, silent = false) => {
let exists = false;
try {
await Fs.stat(file);
exists = true;
} catch (err) {
if (isPkg) {
if (err.message) {
logger.error(`Error while checking if file ${file} exists: ${err.message}`);
if (!silent) {
if (isPkg) {
if (err.message) {
// Make message a bit nicer than what's returned from stat()
if (err.message.includes('no such file or directory')) {
logger.error(`File "${file}" does not exist.`);
} else {
logger.error(`Error while checking if file ${file} exists: ${err.message}`);
}
} else {
logger.error(`Error while checking if file ${file} exists: ${err}`);
}
} else if (err.message) {
if (err.message.includes('no such file or directory')) {
logger.error(`File "${file}" does not exist.`);
} else {
logger.error(`Error while checking if file ${file} exists: ${err.message}`);
}
} else if (err.stack) {
logger.error(`Error while checking if file ${file} exists: ${err.stack}`);
} else {
logger.error(`Error while checking if file ${file} exists: ${err}`);
}
} else if (err.stack) {
logger.error(`Error while checking if file ${file} exists: ${err.stack}`);
} else if (err.message) {
logger.error(`Error while checking if file ${file} exists: ${err.message}`);
} else {
logger.error(`Error while checking if file ${file} exists: ${err}`);
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/lib/app/class_allapps.js
Original file line number Diff line number Diff line change
Expand Up @@ -1344,7 +1344,8 @@ class QlikSenseApps {
logger.verbose(`Full path to QVF: ${fileName}`);

// Check if destination QVF file already exists
const fileExists = await verifyFileExists(fileName);
// 2nd parameter controls whether to log info or not about file's existence
const fileExists = await verifyFileExists(fileName, true);
let fileSkipped = false;
let writer;

Expand Down
3 changes: 2 additions & 1 deletion src/lib/cmd/exportapp.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ const exportAppToFile = async (options) => {
logger.verbose(`Full path to app metadata file: ${fileName}`);

// Check if app metadata file already exists
const fileExists = await verifyFileExists(fileName);
// 2nd parameter = true => don't output anything to log
const fileExists = await verifyFileExists(fileName, true);

logger.info('------------------------------------');

Expand Down

0 comments on commit 32f6d70

Please sign in to comment.