Add tests for error reporting
This commit is contained in:
@@ -14,6 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import fs from 'fs';
|
||||
import type {
|
||||
BlobUploadCommonResponse,
|
||||
ContainerGetPropertiesResponse,
|
||||
} from '@azure/storage-blob';
|
||||
|
||||
export class BlockBlobClient {
|
||||
private readonly blobName;
|
||||
@@ -22,23 +26,29 @@ export class BlockBlobClient {
|
||||
this.blobName = blobName;
|
||||
}
|
||||
|
||||
uploadFile(source: string) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!fs.existsSync(source)) {
|
||||
reject('');
|
||||
} else {
|
||||
resolve('');
|
||||
}
|
||||
uploadFile(source: string): Promise<BlobUploadCommonResponse> {
|
||||
return Promise.resolve({
|
||||
_response: {
|
||||
request: {} as any,
|
||||
status: 200,
|
||||
headers: {} as any,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
exists() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (fs.existsSync(this.blobName)) {
|
||||
resolve(true);
|
||||
} else {
|
||||
reject({ message: 'The object doest not exist !' });
|
||||
}
|
||||
return Promise.resolve(fs.existsSync(this.blobName));
|
||||
}
|
||||
}
|
||||
|
||||
class BlockBlobClientFailUpload extends BlockBlobClient {
|
||||
uploadFile(source: string): Promise<BlobUploadCommonResponse> {
|
||||
return Promise.resolve({
|
||||
_response: {
|
||||
request: {} as any,
|
||||
status: 500,
|
||||
headers: {} as any,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -50,9 +60,14 @@ export class ContainerClient {
|
||||
this.containerName = containerName;
|
||||
}
|
||||
|
||||
getProperties() {
|
||||
return new Promise(resolve => {
|
||||
resolve('');
|
||||
getProperties(): Promise<ContainerGetPropertiesResponse> {
|
||||
return Promise.resolve({
|
||||
_response: {
|
||||
request: {} as any,
|
||||
status: 200,
|
||||
headers: {} as any,
|
||||
parsedHeaders: {},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -61,6 +76,25 @@ export class ContainerClient {
|
||||
}
|
||||
}
|
||||
|
||||
class ContainerClientFailGetProperties extends ContainerClient {
|
||||
getProperties(): Promise<ContainerGetPropertiesResponse> {
|
||||
return Promise.resolve({
|
||||
_response: {
|
||||
request: {} as any,
|
||||
status: 404,
|
||||
headers: {} as any,
|
||||
parsedHeaders: {},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class ContainerClientFailUpload extends ContainerClient {
|
||||
getBlockBlobClient(blobName: string) {
|
||||
return new BlockBlobClientFailUpload(blobName);
|
||||
}
|
||||
}
|
||||
|
||||
export class BlobServiceClient {
|
||||
private readonly url;
|
||||
private readonly credential;
|
||||
@@ -71,6 +105,12 @@ export class BlobServiceClient {
|
||||
}
|
||||
|
||||
getContainerClient(containerName: string) {
|
||||
if (containerName === 'bad_container') {
|
||||
return new ContainerClientFailGetProperties(containerName);
|
||||
}
|
||||
if (this.credential.accountName === 'failupload') {
|
||||
return new ContainerClientFailUpload(containerName);
|
||||
}
|
||||
return new ContainerClient(containerName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,51 +154,71 @@ describe('publishing with valid credentials', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('attempting to publish with invalid credentials', () => {
|
||||
let logger: Logger;
|
||||
|
||||
describe('accountKey is not specified', () => {
|
||||
beforeEach(async () => {
|
||||
const mockConfig = new ConfigReader({
|
||||
techdocs: {
|
||||
requestUrl: 'http://localhost:7000',
|
||||
publisher: {
|
||||
type: 'azureBlobStorage',
|
||||
azureBlobStorage: {
|
||||
credentials: {
|
||||
accountName: 'accountName',
|
||||
},
|
||||
containerName: 'containerName',
|
||||
describe('error reporting', () => {
|
||||
it('reports an error when unable to read container properties', async () => {
|
||||
const mockConfig = new ConfigReader({
|
||||
techdocs: {
|
||||
requestUrl: 'http://localhost:7000',
|
||||
publisher: {
|
||||
type: 'azureBlobStorage',
|
||||
azureBlobStorage: {
|
||||
credentials: {
|
||||
accountName: 'accountName',
|
||||
},
|
||||
containerName: 'bad_container',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
logger = createLogger();
|
||||
|
||||
publisher = await AzureBlobStoragePublish.fromConfig(mockConfig, logger);
|
||||
},
|
||||
});
|
||||
|
||||
describe('without Azure environment variables', () => {
|
||||
it('should log an error', async () => {
|
||||
const entity = createMockEntity();
|
||||
const entityRootDir = getEntityRootDir(entity);
|
||||
const logger = createLogger();
|
||||
|
||||
mockFs({
|
||||
[entityRootDir]: {
|
||||
'index.html': '',
|
||||
publisher = await AzureBlobStoragePublish.fromConfig(mockConfig, logger);
|
||||
|
||||
expect(logger.error).toHaveBeenCalledWith(
|
||||
`Could not read Azure Blob Storage container properties`,
|
||||
);
|
||||
});
|
||||
|
||||
it('reports an error when bad account credentials', async () => {
|
||||
const mockConfig = new ConfigReader({
|
||||
techdocs: {
|
||||
requestUrl: 'http://localhost:7000',
|
||||
publisher: {
|
||||
type: 'azureBlobStorage',
|
||||
azureBlobStorage: {
|
||||
credentials: {
|
||||
accountName: 'failupload',
|
||||
accountKey: 'accountKey',
|
||||
},
|
||||
containerName: 'containerName',
|
||||
},
|
||||
});
|
||||
|
||||
await publisher.publish({
|
||||
entity,
|
||||
directory: entityRootDir,
|
||||
});
|
||||
|
||||
expect(logger.error).toHaveBeenCalled();
|
||||
|
||||
mockFs.restore();
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const logger = createLogger();
|
||||
|
||||
publisher = await AzureBlobStoragePublish.fromConfig(mockConfig, logger);
|
||||
|
||||
const entity = createMockEntity();
|
||||
const entityRootDir = getEntityRootDir(entity);
|
||||
|
||||
mockFs({
|
||||
[entityRootDir]: {
|
||||
'index.html': '',
|
||||
},
|
||||
});
|
||||
|
||||
await publisher.publish({
|
||||
entity,
|
||||
directory: entityRootDir,
|
||||
});
|
||||
|
||||
expect(logger.error).toHaveBeenCalledWith(
|
||||
`Unable to upload 1 file(s) to Azure Blob Storage.`,
|
||||
);
|
||||
|
||||
mockFs.restore();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -82,10 +82,16 @@ export class AzureBlobStoragePublish implements PublisherBase {
|
||||
await storageClient
|
||||
.getContainerClient(containerName)
|
||||
.getProperties()
|
||||
.then(() => {
|
||||
logger.info(
|
||||
`Successfully connected to the Azure Blob Storage container ${containerName}.`,
|
||||
);
|
||||
.then(result => {
|
||||
if (result?._response?.status >= 400) {
|
||||
logger.error(
|
||||
'Could not read Azure Blob Storage container properties',
|
||||
);
|
||||
} else {
|
||||
logger.info(
|
||||
`Successfully connected to the Azure Blob Storage container ${containerName}.`,
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(reason => {
|
||||
logger.error(
|
||||
@@ -145,16 +151,23 @@ export class AzureBlobStoragePublish implements PublisherBase {
|
||||
});
|
||||
});
|
||||
|
||||
await Promise.all(promises).then(() => {
|
||||
let responses: BlobUploadCommonResponse[] = [];
|
||||
|
||||
responses = await Promise.all(promises);
|
||||
|
||||
const failed = responses.filter(r => r?._response?.status >= 400);
|
||||
if (failed.length === 0) {
|
||||
this.logger.info(
|
||||
`Successfully uploaded all the generated files for Entity ${entity.metadata.name}. Total number of files: ${allFilesToUpload.length}`,
|
||||
);
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
const errorMessage = `Unable to upload ${failed.length} file(s) to Azure Blob Storage.`;
|
||||
this.logger.error(errorMessage);
|
||||
}
|
||||
} catch (e) {
|
||||
const errorMessage = `Unable to upload file(s) to Azure Blob Storage. Error ${e.message}`;
|
||||
this.logger.error(errorMessage);
|
||||
throw new Error(errorMessage);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,19 +250,11 @@ export class AzureBlobStoragePublish implements PublisherBase {
|
||||
* A helper function which checks if index.html of an Entity's docs site is available. This
|
||||
* can be used to verify if there are any pre-generated docs available to serve.
|
||||
*/
|
||||
async hasDocsBeenGenerated(entity: Entity): Promise<boolean> {
|
||||
return new Promise(resolve => {
|
||||
const entityRootDir = `${entity.metadata.namespace}/${entity.kind}/${entity.metadata.name}`;
|
||||
this.storageClient
|
||||
.getContainerClient(this.containerName)
|
||||
.getBlockBlobClient(`${entityRootDir}/index.html`)
|
||||
.exists()
|
||||
.then((response: boolean) => {
|
||||
resolve(response);
|
||||
})
|
||||
.catch(() => {
|
||||
resolve(false);
|
||||
});
|
||||
});
|
||||
hasDocsBeenGenerated(entity: Entity): Promise<boolean> {
|
||||
const entityRootDir = `${entity.metadata.namespace}/${entity.kind}/${entity.metadata.name}`;
|
||||
return this.storageClient
|
||||
.getContainerClient(this.containerName)
|
||||
.getBlockBlobClient(`${entityRootDir}/index.html`)
|
||||
.exists();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user