Merge remote-tracking branch 'upstream/master'

Signed-off-by: Matteo Silvestri <matteosilv@gmail.com>
This commit is contained in:
Matteo Silvestri
2022-09-01 12:13:28 +02:00
600 changed files with 32104 additions and 165333 deletions
+2 -2
View File
@@ -65,7 +65,7 @@ describe('CacheManager', () => {
const config = new ConfigReader({ backend: {} });
expect(() => {
CacheManager.fromConfig(config);
}).not.toThrowError();
}).not.toThrow();
});
it('throws on unknown cache store', () => {
@@ -74,7 +74,7 @@ describe('CacheManager', () => {
});
expect(() => {
CacheManager.fromConfig(config);
}).toThrowError();
}).toThrow();
});
});
@@ -37,12 +37,12 @@ describe('AbortContext', () => {
expect(child.abortSignal.aborted).toBe(false);
expect(Math.abs(+child.deadline! - deadline)).toBeLessThan(50);
expect(childListener).toBeCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(0);
jest.advanceTimersByTime(timeout + 1);
expect(child.abortSignal.aborted).toBe(true);
expect(childListener).toBeCalledTimes(1);
expect(childListener).toHaveBeenCalledTimes(1);
});
it('results in minimum deadline when parent triggers sooner', async () => {
@@ -66,15 +66,15 @@ describe('AbortContext', () => {
expect(child.abortSignal.aborted).toBe(false);
expect(Math.abs(+parent.deadline! - parentDeadline)).toBeLessThan(50);
expect(Math.abs(+child.deadline! - childDeadline)).toBeLessThan(50);
expect(parentListener).toBeCalledTimes(0);
expect(childListener).toBeCalledTimes(0);
expect(parentListener).toHaveBeenCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(0);
jest.advanceTimersByTime(parentTimeout + 1);
expect(parent.abortSignal.aborted).toBe(true);
expect(child.abortSignal.aborted).toBe(true);
expect(parentListener).toBeCalledTimes(1);
expect(childListener).toBeCalledTimes(1);
expect(parentListener).toHaveBeenCalledTimes(1);
expect(childListener).toHaveBeenCalledTimes(1);
});
it('results in minimum deadline when child triggers sooner', async () => {
@@ -98,22 +98,22 @@ describe('AbortContext', () => {
expect(child.abortSignal.aborted).toBe(false);
expect(Math.abs(+parent.deadline! - parentDeadline)).toBeLessThan(50);
expect(Math.abs(+child.deadline! - childDeadline)).toBeLessThan(50);
expect(parentListener).toBeCalledTimes(0);
expect(childListener).toBeCalledTimes(0);
expect(parentListener).toHaveBeenCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(0);
jest.advanceTimersByTime(childTimeout + 1);
expect(parent.abortSignal.aborted).toBe(false);
expect(child.abortSignal.aborted).toBe(true);
expect(parentListener).toBeCalledTimes(0);
expect(childListener).toBeCalledTimes(1);
expect(parentListener).toHaveBeenCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(1);
jest.advanceTimersByTime(parentTimeout - childTimeout + 1);
expect(parent.abortSignal.aborted).toBe(true);
expect(child.abortSignal.aborted).toBe(true);
expect(parentListener).toBeCalledTimes(1);
expect(childListener).toBeCalledTimes(1);
expect(parentListener).toHaveBeenCalledTimes(1);
expect(childListener).toHaveBeenCalledTimes(1);
});
it('child carries over parent signal state if parent was already aborted and had no deadline', async () => {
@@ -133,13 +133,13 @@ describe('AbortContext', () => {
child.abortSignal.addEventListener('abort', childListener);
expect(child.abortSignal.aborted).toBe(true);
expect(childListener).toBeCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(0);
expect(Math.abs(+child.deadline! - childDeadline)).toBeLessThan(50);
jest.advanceTimersByTime(childTimeout + 1);
expect(child.abortSignal.aborted).toBe(true);
expect(childListener).toBeCalledTimes(0); // still
expect(childListener).toHaveBeenCalledTimes(0); // still
});
it('child carries over parent signal state if parent was already aborted and had a deadline', async () => {
@@ -175,15 +175,15 @@ describe('AbortContext', () => {
expect(parent.abortSignal.aborted).toBe(false);
expect(child.abortSignal.aborted).toBe(false);
expect(parentListener).toBeCalledTimes(0);
expect(childListener).toBeCalledTimes(0);
expect(parentListener).toHaveBeenCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(0);
parentController.abort();
expect(parent.abortSignal.aborted).toBe(true);
expect(child.abortSignal.aborted).toBe(true);
expect(parentListener).toBeCalledTimes(1);
expect(childListener).toBeCalledTimes(1);
expect(parentListener).toHaveBeenCalledTimes(1);
expect(childListener).toHaveBeenCalledTimes(1);
});
it('does not signal parent when child is aborted', async () => {
@@ -201,15 +201,15 @@ describe('AbortContext', () => {
expect(parent.abortSignal.aborted).toBe(false);
expect(child.abortSignal.aborted).toBe(false);
expect(parentListener).toBeCalledTimes(0);
expect(childListener).toBeCalledTimes(0);
expect(parentListener).toHaveBeenCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(0);
childController.abort();
expect(parent.abortSignal.aborted).toBe(false);
expect(child.abortSignal.aborted).toBe(true);
expect(parentListener).toBeCalledTimes(0);
expect(childListener).toBeCalledTimes(1);
expect(parentListener).toHaveBeenCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(1);
});
it('child carries over parent signal state if parent was already aborted', async () => {
@@ -227,13 +227,13 @@ describe('AbortContext', () => {
expect(parent.abortSignal.aborted).toBe(true);
expect(child.abortSignal.aborted).toBe(true);
expect(childListener).toBeCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(0);
childController.abort();
expect(parent.abortSignal.aborted).toBe(true);
expect(child.abortSignal.aborted).toBe(true);
expect(childListener).toBeCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(0);
});
it('child carries over given signal state if it was already aborted', async () => {
@@ -247,7 +247,7 @@ describe('AbortContext', () => {
child.abortSignal.addEventListener('abort', childListener);
expect(child.abortSignal.aborted).toBe(true);
expect(childListener).toBeCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(0);
});
});
@@ -267,15 +267,15 @@ describe('AbortContext', () => {
expect(parent.abortSignal.aborted).toBe(false);
expect(child.abortSignal.aborted).toBe(false);
expect(parentListener).toBeCalledTimes(0);
expect(childListener).toBeCalledTimes(0);
expect(parentListener).toHaveBeenCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(0);
parentController.abort();
expect(parent.abortSignal.aborted).toBe(true);
expect(child.abortSignal.aborted).toBe(true);
expect(parentListener).toBeCalledTimes(1);
expect(childListener).toBeCalledTimes(1);
expect(parentListener).toHaveBeenCalledTimes(1);
expect(childListener).toHaveBeenCalledTimes(1);
});
it('does not signal parent when child is aborted', async () => {
@@ -293,15 +293,15 @@ describe('AbortContext', () => {
expect(parent.abortSignal.aborted).toBe(false);
expect(child.abortSignal.aborted).toBe(false);
expect(parentListener).toBeCalledTimes(0);
expect(childListener).toBeCalledTimes(0);
expect(parentListener).toHaveBeenCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(0);
childController.abort();
expect(parent.abortSignal.aborted).toBe(false);
expect(child.abortSignal.aborted).toBe(true);
expect(parentListener).toBeCalledTimes(0);
expect(childListener).toBeCalledTimes(1);
expect(parentListener).toHaveBeenCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(1);
});
it('child carries over parent signal state if parent was already aborted', async () => {
@@ -319,13 +319,13 @@ describe('AbortContext', () => {
expect(parent.abortSignal.aborted).toBe(true);
expect(child.abortSignal.aborted).toBe(true);
expect(childListener).toBeCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(0);
childController.abort();
expect(parent.abortSignal.aborted).toBe(true);
expect(child.abortSignal.aborted).toBe(true);
expect(childListener).toBeCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(0);
});
it('child carries over given signal state if it was already aborted', async () => {
@@ -339,7 +339,7 @@ describe('AbortContext', () => {
child.abortSignal.addEventListener('abort', childListener);
expect(child.abortSignal.aborted).toBe(true);
expect(childListener).toBeCalledTimes(0);
expect(childListener).toHaveBeenCalledTimes(0);
});
});
});
@@ -29,6 +29,8 @@ import {
} from './connection';
import { PluginDatabaseManager } from './types';
import path from 'path';
import { Logger } from 'winston';
import { stringifyError } from '@backstage/errors';
/**
* Provides a config lookup path for a plugin's config block.
@@ -44,6 +46,7 @@ function pluginPath(pluginId: string): string {
*/
export type DatabaseManagerOptions = {
migrations?: PluginDatabaseManager['migrations'];
logger?: Logger;
};
/**
@@ -339,6 +342,31 @@ export class DatabaseManager {
schemaOverrides,
);
return createDatabaseClient(pluginConfig, databaseClientOverrides);
const client = createDatabaseClient(pluginConfig, databaseClientOverrides);
this.startKeepaliveLoop(pluginId, client);
return client;
}
private startKeepaliveLoop(pluginId: string, client: Knex): void {
let lastKeepaliveFailed = false;
setInterval(() => {
client.raw('select 1').then(
() => {
lastKeepaliveFailed = false;
},
(error: unknown) => {
if (!lastKeepaliveFailed) {
lastKeepaliveFailed = true;
this.options?.logger?.warn(
`Database keepalive failed for plugin ${pluginId}, ${stringifyError(
error,
)}`,
);
}
},
);
}, 60 * 1000);
}
}
@@ -110,7 +110,7 @@ describe('database connection', () => {
connection: '',
}),
),
).toThrowError();
).toThrow();
});
it('throws an error without a connection', () => {
@@ -120,7 +120,7 @@ describe('database connection', () => {
client: 'pg',
}),
),
).toThrowError();
).toThrow();
});
});
@@ -147,7 +147,7 @@ describe('database connection', () => {
});
it('throws an error for unknown connection', () => {
expect(() => createNameOverride('unknown', 'testname')).toThrowError();
expect(() => createNameOverride('unknown', 'testname')).toThrow();
});
});
@@ -194,7 +194,7 @@ describe('postgres', () => {
'postgresql://postgres:pass@localhost:5432/dbname?sslrootcert=/path/to/file',
),
),
).toThrowError(/no such file or directory/);
).toThrow(/no such file or directory/);
});
});
@@ -34,7 +34,7 @@ export function requestLoggingHandler(logger?: Logger): RequestHandler {
return morgan('combined', {
stream: {
write(message: String) {
actualLogger.info(message.trimRight());
actualLogger.info(message.trimEnd());
},
},
});
@@ -551,7 +551,7 @@ describe('GithubUrlReader', () => {
credentialsProvider: mockCredentialsProvider,
},
);
}).toThrowError('must configure an explicit apiBaseUrl');
}).toThrow('must configure an explicit apiBaseUrl');
});
});
@@ -127,7 +127,7 @@ describe('GcsUrlReader', () => {
it('throws if search url looks truly glob-y', async () => {
const glob = 'https://storage.cloud.google.com/bucket/**/path*';
await expect(() => reader.search(glob)).rejects.toThrowError(
await expect(() => reader.search(glob)).rejects.toThrow(
'GcsUrlReader only supports prefix-based searches',
);
});
@@ -55,7 +55,7 @@ describe('ReadUrlResponseFactory', () => {
it('buffer cannot be called after stream is called', async () => {
const response = await ReadUrlResponseFactory.fromReadable(readable);
response.stream!();
expect(() => response.buffer()).toThrowError(ConflictError);
expect(() => response.buffer()).toThrow(ConflictError);
});
it('stream returns expected data', async () => {
@@ -68,7 +68,7 @@ describe('ReadUrlResponseFactory', () => {
it('stream cannot be called after buffer is called', async () => {
const response = await ReadUrlResponseFactory.fromReadable(readable);
response.buffer();
expect(() => response.stream!()).toThrowError(ConflictError);
expect(() => response.stream!()).toThrow(ConflictError);
});
});
@@ -64,7 +64,7 @@ describe('UrlReaderPredicateMux', () => {
it('throws an error if no predicate matches', async () => {
const mux = new UrlReaderPredicateMux(getVoidLogger());
await expect(mux.readUrl('http://foo/1')).rejects.toThrowError(
await expect(mux.readUrl('http://foo/1')).rejects.toThrow(
/^Reading from 'http:\/\/foo\/1' is not allowed. You may/,
);
@@ -80,7 +80,7 @@ describe('UrlReaderPredicateMux', () => {
await expect(mux.readUrl('http://foo/1')).resolves.toBeUndefined();
await expect(mux.readUrl('http://bar/1')).rejects.toThrowError(
await expect(mux.readUrl('http://bar/1')).rejects.toThrow(
/^Reading from 'http:\/\/bar\/1' is not allowed. You may/,
);
});
@@ -66,9 +66,9 @@ describe('ServerTokenManager', () => {
const tokenManager = ServerTokenManager.fromConfig(configWithSecret, {
logger,
});
await expect(
tokenManager.authenticate('random-string'),
).rejects.toThrowError(/invalid server token/i);
await expect(tokenManager.authenticate('random-string')).rejects.toThrow(
/invalid server token/i,
);
});
it('should validate server tokens created by a different instance using the same secret', async () => {
@@ -129,7 +129,7 @@ describe('ServerTokenManager', () => {
const { token } = await tokenManager1.getToken();
await expect(tokenManager2.authenticate(token)).rejects.toThrowError(
await expect(tokenManager2.authenticate(token)).rejects.toThrow(
/invalid server token/i,
);
});
@@ -145,7 +145,7 @@ describe('ServerTokenManager', () => {
const { token } = await noopTokenManager.getToken();
await expect(tokenManager.authenticate(token)).rejects.toThrowError(
await expect(tokenManager.authenticate(token)).rejects.toThrow(
/invalid server token/i,
);
});
@@ -164,7 +164,7 @@ describe('ServerTokenManager', () => {
const { token } = await tokenManager2.getToken();
await expect(tokenManager1.authenticate(token)).rejects.toThrowError(
await expect(tokenManager1.authenticate(token)).rejects.toThrow(
/invalid server token/i,
);
});