add unit tests fetching pod metrics and clean up code

Signed-off-by: Mengnan Gong <namco1992@gmail.com>
This commit is contained in:
Mengnan Gong
2022-10-09 21:47:13 +08:00
parent cbf5d11fdf
commit cc9749a88e
7 changed files with 597 additions and 407 deletions
+4 -2
View File
@@ -1,8 +1,10 @@
---
'@backstage/plugin-kubernetes-backend': minor
'@backstage/plugin-kubernetes-common': minor
'@backstage/plugin-kubernetes-common': patch
---
The Kubernetes errors when fetching pod metrics are now captured and returned to the frontend.
Include the `PodStatusFetchResponse` into the `FetchResponse` union type. Now the method `fetchPodMetricsByNamespaces` accepts a set of namespaces and returns a `FetchResponseWrapper`, just like other public fetch methods in the fetcher.
- **BREAKING** The method `fetchPodMetricsByNamespace` in the interface `KubernetesFetcher` is changed to `fetchPodMetricsByNamespaces`. It now accepts a set of namespace strings and returns `Promise<FetchResponseWrapper>`.
- Add the `PodStatusFetchResponse` to the `FetchResponse` union type.
- Add `NOT_FOUND` to the `KubernetesErrorTypes` union type, the HTTP error with status code 404 will be mapped to this error.
@@ -675,6 +675,82 @@ describe('getKubernetesObjectsByEntity', () => {
],
});
});
it('retrieve objects for two clusters, one fails to fetch pod metrics', async () => {
getClustersByEntity.mockImplementation(() =>
Promise.resolve({
clusters: [
{
name: 'test-cluster',
authProvider: 'serviceAccount',
dashboardUrl: 'https://k8s.foo.coom',
},
{
name: 'other-cluster',
authProvider: 'google',
},
],
}),
);
mockFetch(fetchObjectsForService);
// To simulate the partial failure, return a valid response for the first call,
// and an error for the second call.
fetchPodMetricsByNamespaces
.mockImplementationOnce(
(clusterDetails: ClusterDetails, namespaces: Set<string>) =>
Promise.resolve(generatePodStatus(clusterDetails.name, namespaces)),
)
.mockResolvedValueOnce({
errors: [
{
errorType: 'NOT_FOUND',
resourcePath: '/some/path',
statusCode: 404,
},
],
responses: [],
});
const sut = getKubernetesFanOutHandler([]);
const result = await sut.getKubernetesObjectsByEntity({
entity,
auth: {
google: 'google_token_123',
},
});
expect(getClustersByEntity.mock.calls.length).toBe(1);
expect(fetchObjectsForService.mock.calls.length).toBe(2);
expect(result).toStrictEqual({
items: [
{
cluster: {
dashboardUrl: 'https://k8s.foo.coom',
name: 'test-cluster',
},
errors: [],
podMetrics: [POD_METRICS_FIXTURE],
resources: resourcesByCluster('test-cluster'),
},
{
cluster: {
name: 'other-cluster',
},
errors: [
{
errorType: 'NOT_FOUND',
resourcePath: '/some/path',
statusCode: 404,
},
],
podMetrics: [],
resources: resourcesByCluster('other-cluster'),
},
],
});
});
});
describe('getCustomResourcesByEntity', () => {
@@ -358,7 +358,7 @@ export class KubernetesFanOutHandler {
namespaces,
);
result.errors.concat(podMetrics.errors);
result.errors.push(...podMetrics.errors);
return [result, podMetrics.responses as PodStatusFetchResponse[]];
}
File diff suppressed because it is too large Load Diff
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { CoreV1Api, topPods } from '@kubernetes/client-node';
import { topPods } from '@kubernetes/client-node';
import lodash, { Dictionary } from 'lodash';
import { Logger } from 'winston';
import {
@@ -33,10 +33,6 @@ import {
} from '@backstage/plugin-kubernetes-common';
import { KubernetesClientProvider } from './KubernetesClientProvider';
export interface Clients {
core: CoreV1Api;
}
export interface KubernetesClientBasedFetcherOptions {
kubernetesClientProvider: KubernetesClientProvider;
logger: Logger;
@@ -66,6 +62,8 @@ const statusCodeToErrorType = (statusCode: number): KubernetesErrorTypes => {
return 'BAD_REQUEST';
case 401:
return 'UNAUTHORIZED_ERROR';
case 404:
return 'NOT_FOUND';
case 500:
return 'SYSTEM_ERROR';
default:
+1
View File
@@ -179,6 +179,7 @@ export interface JobsFetchResponse {
export type KubernetesErrorTypes =
| 'BAD_REQUEST'
| 'UNAUTHORIZED_ERROR'
| 'NOT_FOUND'
| 'SYSTEM_ERROR'
| 'UNKNOWN_ERROR';
+1
View File
@@ -233,6 +233,7 @@ export interface KubernetesFetchError {
export type KubernetesErrorTypes =
| 'BAD_REQUEST'
| 'UNAUTHORIZED_ERROR'
| 'NOT_FOUND'
| 'SYSTEM_ERROR'
| 'UNKNOWN_ERROR';