mirror of
https://github.com/podman-desktop/podman-desktop
synced 2026-05-24 02:08:24 +00:00
Add complete object from contexts informers (#6116)
* refactor: use index signature for resources counts Signed-off-by: Philippe Martin <phmartin@redhat.com> * refactor: send complete objects instead of counts Signed-off-by: Philippe Martin <phmartin@redhat.com> * test: fix badge tests Signed-off-by: Philippe Martin <phmartin@redhat.com>
This commit is contained in:
parent
c93c53656c
commit
1ec4bd4305
5 changed files with 84 additions and 40 deletions
|
|
@ -88,14 +88,14 @@ function fakeMakeInformer(
|
|||
case '/api/v1/namespaces/ns2/pods':
|
||||
return new FakeInformer(2, connectResult);
|
||||
case '/api/v1/namespaces/default/pods':
|
||||
return new FakeInformer(9, connectResult);
|
||||
return new FakeInformer(3, connectResult);
|
||||
|
||||
case '/apis/apps/v1/namespaces/ns1/deployments':
|
||||
return new FakeInformer(11, connectResult);
|
||||
return new FakeInformer(4, connectResult);
|
||||
case '/apis/apps/v1/namespaces/ns2/deployments':
|
||||
return new FakeInformer(12, connectResult);
|
||||
return new FakeInformer(5, connectResult);
|
||||
case '/apis/apps/v1/namespaces/default/deployments':
|
||||
return new FakeInformer(19, connectResult);
|
||||
return new FakeInformer(6, connectResult);
|
||||
}
|
||||
return new FakeInformer(0, connectResult);
|
||||
}
|
||||
|
|
@ -167,26 +167,34 @@ test('should send info of resources in all reachable contexts and nothing in non
|
|||
expectedMap.set('context1', {
|
||||
reachable: false,
|
||||
error: 'Error: connection error',
|
||||
podsCount: 0,
|
||||
deploymentsCount: 0,
|
||||
resources: {
|
||||
pods: [],
|
||||
deployments: [],
|
||||
},
|
||||
} as ContextState);
|
||||
expectedMap.set('context2', {
|
||||
reachable: true,
|
||||
error: undefined,
|
||||
podsCount: 9,
|
||||
deploymentsCount: 19,
|
||||
resources: {
|
||||
pods: [{}, {}, {}],
|
||||
deployments: [{}, {}, {}, {}, {}, {}],
|
||||
},
|
||||
} as ContextState);
|
||||
expectedMap.set('context2-1', {
|
||||
reachable: true,
|
||||
error: undefined,
|
||||
podsCount: 1,
|
||||
deploymentsCount: 11,
|
||||
resources: {
|
||||
pods: [{}],
|
||||
deployments: [{}, {}, {}, {}],
|
||||
},
|
||||
} as ContextState);
|
||||
expectedMap.set('context2-2', {
|
||||
reachable: true,
|
||||
error: undefined,
|
||||
podsCount: 2,
|
||||
deploymentsCount: 12,
|
||||
resources: {
|
||||
pods: [{}, {}],
|
||||
deployments: [{}, {}, {}, {}, {}],
|
||||
},
|
||||
} as ContextState);
|
||||
await new Promise(resolve => setTimeout(resolve, 1200));
|
||||
expect(apiSenderSendMock).toHaveBeenCalledWith('kubernetes-contexts-state-update', expectedMap);
|
||||
|
|
@ -232,13 +240,17 @@ test('should send info of resources in all reachable contexts and nothing in non
|
|||
expectedMap = new Map<string, ContextState>();
|
||||
expectedMap.set('context2', {
|
||||
reachable: true,
|
||||
podsCount: 9,
|
||||
deploymentsCount: 19,
|
||||
resources: {
|
||||
pods: [{}, {}, {}],
|
||||
deployments: [{}, {}, {}, {}, {}, {}],
|
||||
},
|
||||
} as ContextState);
|
||||
expectedMap.set('context2-1', {
|
||||
reachable: true,
|
||||
podsCount: 1,
|
||||
deploymentsCount: 11,
|
||||
resources: {
|
||||
pods: [{}],
|
||||
deployments: [{}, {}, {}, {}],
|
||||
},
|
||||
} as ContextState);
|
||||
await new Promise(resolve => setTimeout(resolve, 1200));
|
||||
expect(apiSenderSendMock).toHaveBeenLastCalledWith('kubernetes-contexts-state-update', expectedMap);
|
||||
|
|
|
|||
|
|
@ -39,10 +39,15 @@ interface ContextInternalState {
|
|||
export interface ContextState {
|
||||
error?: string;
|
||||
reachable: boolean;
|
||||
podsCount: number;
|
||||
deploymentsCount: number;
|
||||
resources: ContextStateResources;
|
||||
}
|
||||
|
||||
type ResourceName = 'pods' | 'deployments';
|
||||
|
||||
export type ContextStateResources = {
|
||||
[resourceName in ResourceName]: KubernetesObject[];
|
||||
};
|
||||
|
||||
interface CreateInformerOptions<T> {
|
||||
checkReachable?: boolean;
|
||||
onAdd?: (obj: T) => void;
|
||||
|
|
@ -107,8 +112,10 @@ class ContextsStates {
|
|||
this.published.set(name, {
|
||||
error: undefined,
|
||||
reachable: false,
|
||||
podsCount: 0,
|
||||
deploymentsCount: 0,
|
||||
resources: {
|
||||
pods: [],
|
||||
deployments: [],
|
||||
},
|
||||
});
|
||||
}
|
||||
const val = this.published.get(name);
|
||||
|
|
@ -193,8 +200,12 @@ export class ContextsManager {
|
|||
return this.createInformer<V1Pod>(kc, context, path, listFn, {
|
||||
timer: this.podTimer,
|
||||
backoff: new Backoff(1000, 60_000, 300),
|
||||
onAdd: _obj => this.setStateAndDispatch(context.name, state => state.podsCount++),
|
||||
onDelete: _obj => this.setStateAndDispatch(context.name, state => state.podsCount--),
|
||||
onAdd: obj => this.setStateAndDispatch(context.name, state => state.resources.pods.push(obj)),
|
||||
onDelete: obj =>
|
||||
this.setStateAndDispatch(
|
||||
context.name,
|
||||
state => (state.resources.pods = state.resources.pods.filter(d => d.metadata?.uid !== obj.metadata?.uid)),
|
||||
),
|
||||
onReachable: reachable =>
|
||||
this.setStateAndDispatch(context.name, state => {
|
||||
state.reachable = reachable;
|
||||
|
|
@ -215,8 +226,15 @@ export class ContextsManager {
|
|||
return this.createInformer<V1Deployment>(kc, context, path, listFn, {
|
||||
timer: this.deploymentTimer,
|
||||
backoff: new Backoff(1000, 60_000, 300),
|
||||
onAdd: _obj => this.setStateAndDispatch(context.name, state => state.deploymentsCount++),
|
||||
onDelete: _obj => this.setStateAndDispatch(context.name, state => state.deploymentsCount--),
|
||||
onAdd: obj => this.setStateAndDispatch(context.name, state => state.resources.deployments.push(obj)),
|
||||
onDelete: obj =>
|
||||
this.setStateAndDispatch(
|
||||
context.name,
|
||||
state =>
|
||||
(state.resources.deployments = state.resources.deployments.filter(
|
||||
d => d.metadata?.uid !== obj.metadata?.uid,
|
||||
)),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -152,13 +152,17 @@ test('state and resources counts are displayed in contexts', () => {
|
|||
const state: Map<string, ContextState> = new Map();
|
||||
state.set('context-name', {
|
||||
reachable: true,
|
||||
podsCount: 1,
|
||||
deploymentsCount: 2,
|
||||
resources: {
|
||||
pods: [{}],
|
||||
deployments: [{}, {}],
|
||||
},
|
||||
});
|
||||
state.set('context-name2', {
|
||||
reachable: false,
|
||||
podsCount: 0,
|
||||
deploymentsCount: 0,
|
||||
resources: {
|
||||
pods: [],
|
||||
deployments: [],
|
||||
},
|
||||
});
|
||||
vi.mocked(kubernetesContextsState).kubernetesContextsState = readable<Map<string, ContextState>>(state);
|
||||
render(PreferencesKubernetesContextsRendering, {});
|
||||
|
|
|
|||
|
|
@ -108,13 +108,13 @@ async function handleDeleteContext(contextName: string) {
|
|||
<div class="text-center">
|
||||
<div class="font-bold text-[9px] text-gray-800">PODS</div>
|
||||
<div class="text-[16px] text-white" aria-label="context-pods-count">
|
||||
{$kubernetesContextsState.get(context.name)?.podsCount}
|
||||
{$kubernetesContextsState.get(context.name)?.resources.pods.length}
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<div class="font-bold text-[9px] text-gray-800">DEPLOYMENTS</div>
|
||||
<div class="text-[16px] text-white" aria-label="context-deployments-count">
|
||||
{$kubernetesContextsState.get(context.name)?.deploymentsCount}
|
||||
{$kubernetesContextsState.get(context.name)?.resources.deployments.length}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -62,8 +62,10 @@ test('expect badges to show as there is a context', async () => {
|
|||
mocks.getCurrentKubeContextState.mockReturnValue({
|
||||
error: undefined,
|
||||
reachable: true,
|
||||
deploymentsCount: 0,
|
||||
podsCount: 0,
|
||||
resources: {
|
||||
pods: [],
|
||||
deployments: [],
|
||||
},
|
||||
} as ContextState); // no current ContextState
|
||||
render(KubernetesCurrentContextConnectionBadge);
|
||||
|
||||
|
|
@ -76,8 +78,10 @@ test('expect badges to be green when reachable', async () => {
|
|||
mocks.getCurrentKubeContextState.mockReturnValue({
|
||||
error: undefined,
|
||||
reachable: true,
|
||||
deploymentsCount: 0,
|
||||
podsCount: 0,
|
||||
resources: {
|
||||
pods: [],
|
||||
deployments: [],
|
||||
},
|
||||
} as ContextState); // no current ContextState
|
||||
render(KubernetesCurrentContextConnectionBadge);
|
||||
|
||||
|
|
@ -90,8 +94,10 @@ test('expect badges to be gray when not reachable', async () => {
|
|||
mocks.getCurrentKubeContextState.mockReturnValue({
|
||||
error: undefined,
|
||||
reachable: false,
|
||||
deploymentsCount: 0,
|
||||
podsCount: 0,
|
||||
resources: {
|
||||
pods: [],
|
||||
deployments: [],
|
||||
},
|
||||
} as ContextState); // no current ContextState
|
||||
render(KubernetesCurrentContextConnectionBadge);
|
||||
|
||||
|
|
@ -104,8 +110,10 @@ test('expect no tooltip when no error', async () => {
|
|||
mocks.getCurrentKubeContextState.mockReturnValue({
|
||||
error: undefined,
|
||||
reachable: false,
|
||||
deploymentsCount: 0,
|
||||
podsCount: 0,
|
||||
resources: {
|
||||
pods: [],
|
||||
deployments: [],
|
||||
},
|
||||
} as ContextState); // no current ContextState
|
||||
render(KubernetesCurrentContextConnectionBadge);
|
||||
|
||||
|
|
@ -118,8 +126,10 @@ test('expect tooltip when error', async () => {
|
|||
mocks.getCurrentKubeContextState.mockReturnValue({
|
||||
error: 'error message',
|
||||
reachable: false,
|
||||
deploymentsCount: 0,
|
||||
podsCount: 0,
|
||||
resources: {
|
||||
pods: [],
|
||||
deployments: [],
|
||||
},
|
||||
} as ContextState); // no current ContextState
|
||||
render(KubernetesCurrentContextConnectionBadge);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue