mirror of https://github.com/rancher/dashboard.git
198 lines
6.9 KiB
TypeScript
198 lines
6.9 KiB
TypeScript
import { nextTick } from 'vue';
|
|
import { shallowMount } from '@vue/test-utils';
|
|
import ContainerLogs from '@shell/components/nav/WindowManager/ContainerLogs.vue';
|
|
import { base64Encode } from '@shell/utils/crypto';
|
|
import { Buffer } from 'buffer';
|
|
import { addEventListener } from '@shell/utils/socket';
|
|
// import VirtualList from 'vue3-virtual-scroll-list';
|
|
|
|
jest.mock('@shell/utils/socket');
|
|
// jest.mock(VirtualList, () => {});
|
|
|
|
const mockMyMethod = jest.fn();
|
|
|
|
jest.mock('vue3-virtual-scroll-list', () => ({ myMethod: () => mockMyMethod() }));
|
|
|
|
const getDefaultOptions = () => {
|
|
return {
|
|
propsData: {
|
|
tab: {},
|
|
active: true,
|
|
height: 100,
|
|
pod: {
|
|
spec: { nodeName: 'nodeId' },
|
|
links: { view: 'url' },
|
|
os: 'linux'
|
|
},
|
|
},
|
|
data() {
|
|
return { range: '30 minute' };
|
|
},
|
|
global: {
|
|
mocks: {
|
|
$store: {
|
|
getters: {
|
|
'prefs/get': jest.fn(),
|
|
'i18n/t': jest.fn(),
|
|
currentProduct: { inStore: 'cluster' }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
};
|
|
};
|
|
|
|
// eslint-disable-next-line jest/no-disabled-tests
|
|
describe('component: ContainerLogs', () => {
|
|
it('should receive messages correctly', async() => {
|
|
jest.clearAllMocks();
|
|
const wrapper = await shallowMount(ContainerLogs, getDefaultOptions());
|
|
|
|
const data1 = 'container logs test1\n';
|
|
const messageCallback = addEventListener.mock.calls.find(([e]) => e === 'message')[1];
|
|
|
|
messageCallback({ detail: { data: base64Encode(data1) } });
|
|
|
|
await nextTick();
|
|
expect(wrapper.vm.backlog).toHaveLength(1);
|
|
expect(wrapper.vm.backlog[0].rawMsg).toBe(data1.trimEnd());
|
|
const data2 = 'container logs test2 中文日志内容测试\n';
|
|
|
|
messageCallback({ detail: { data: base64Encode(data2) } });
|
|
await nextTick();
|
|
expect(wrapper.vm.backlog).toHaveLength(2);
|
|
expect(wrapper.vm.backlog[1].rawMsg).toBe(data2.trimEnd());
|
|
});
|
|
|
|
it('should not fail for an empty message/string', async() => {
|
|
jest.clearAllMocks();
|
|
const wrapper = await shallowMount(ContainerLogs, getDefaultOptions());
|
|
|
|
const data1 = '';
|
|
const messageCallback = addEventListener.mock.calls.find(([e]) => e === 'message')[1];
|
|
|
|
messageCallback({ detail: { data: base64Encode(data1) } });
|
|
await nextTick();
|
|
expect(wrapper.vm.backlog).toHaveLength(0);
|
|
expect(wrapper.vm.filtered).toHaveLength(0);
|
|
});
|
|
|
|
it('should merge the message which be truncated line', async() => {
|
|
jest.clearAllMocks();
|
|
const wrapper = await shallowMount(ContainerLogs, getDefaultOptions());
|
|
const part1 = 'container logs part1';
|
|
const messageCallback = addEventListener.mock.calls.find(([e]) => e === 'message')[1];
|
|
|
|
messageCallback({ detail: { data: base64Encode(part1) } });
|
|
await nextTick();
|
|
|
|
expect(wrapper.vm.backlog).toHaveLength(0);
|
|
const part2 = 'container logs part2\n';
|
|
|
|
messageCallback({ detail: { data: base64Encode(part2) } });
|
|
await nextTick();
|
|
expect(wrapper.vm.backlog).toHaveLength(1);
|
|
expect(wrapper.vm.backlog[0].rawMsg).toBe(`${ part1 }${ part2 }`.trimEnd());
|
|
});
|
|
|
|
it('should merge truncated 2-byte utf-8 character messages', async() => {
|
|
jest.clearAllMocks();
|
|
const wrapper = await shallowMount(ContainerLogs, getDefaultOptions());
|
|
// Contains 2-byte utf-8 character message with one character truncation
|
|
const message = '¡¢£¤¥\n';
|
|
const arr = Buffer.from(message);
|
|
|
|
const part1 = arr.slice(0, 3).toString('base64');
|
|
const part2 = arr.slice(3).toString('base64');
|
|
|
|
const messageCallback = addEventListener.mock.calls.find(([e]) => e === 'message')[1];
|
|
|
|
messageCallback({ detail: { data: part1 } });
|
|
await nextTick();
|
|
expect(wrapper.vm.backlog).toHaveLength(0);
|
|
messageCallback({ detail: { data: part2 } });
|
|
await nextTick();
|
|
expect(wrapper.vm.backlog).toHaveLength(1);
|
|
expect(wrapper.vm.backlog[0].rawMsg).toBe(message.trimEnd());
|
|
});
|
|
it('should merge truncated 3-byte utf-8 character messages', async() => {
|
|
jest.clearAllMocks();
|
|
const wrapper = await shallowMount(ContainerLogs, getDefaultOptions());
|
|
// Contains 3-byte utf-8 character message with one character truncation
|
|
const message = 'ࠀࠁࠂࠃ\n';
|
|
const arr = Buffer.from(message);
|
|
// Truncate at the fourth byte
|
|
const part1 = arr.slice(0, 4).toString('base64');
|
|
const part2 = arr.slice(4).toString('base64');
|
|
|
|
const messageCallback = addEventListener.mock.calls.find(([e]) => e === 'message')[1];
|
|
|
|
messageCallback({ detail: { data: part1 } });
|
|
await nextTick();
|
|
expect(wrapper.vm.backlog).toHaveLength(0);
|
|
messageCallback({ detail: { data: part2 } });
|
|
await nextTick();
|
|
expect(wrapper.vm.backlog).toHaveLength(1);
|
|
expect(wrapper.vm.backlog[0].rawMsg).toBe(message.trimEnd());
|
|
|
|
// Truncate at the fifth byte
|
|
const part3 = arr.slice(0, 5).toString('base64');
|
|
const part4 = arr.slice(5).toString('base64');
|
|
|
|
messageCallback({ detail: { data: part3 } });
|
|
await nextTick();
|
|
expect(wrapper.vm.backlog).toHaveLength(1);
|
|
messageCallback({ detail: { data: part4 } });
|
|
await nextTick();
|
|
expect(wrapper.vm.backlog).toHaveLength(2);
|
|
expect(wrapper.vm.backlog[1].rawMsg).toBe(message.trimEnd());
|
|
});
|
|
|
|
it('should merge truncated 4-byte utf-8 character messages', async() => {
|
|
jest.clearAllMocks();
|
|
const wrapper = await shallowMount(ContainerLogs, getDefaultOptions());
|
|
// Contains 4-byte utf-8 character message with one character truncation
|
|
const message = '𐀀𐀁𐀂𐀃\n';
|
|
const arr = Buffer.from(message);
|
|
|
|
// Truncate at the fifth byte
|
|
const part1 = arr.slice(0, 5).toString('base64');
|
|
const part2 = arr.slice(5).toString('base64');
|
|
|
|
const messageCallback = addEventListener.mock.calls.find(([e]) => e === 'message')[1];
|
|
|
|
messageCallback({ detail: { data: part1 } });
|
|
await nextTick();
|
|
expect(wrapper.vm.backlog).toHaveLength(0);
|
|
messageCallback({ detail: { data: part2 } });
|
|
await nextTick();
|
|
expect(wrapper.vm.backlog).toHaveLength(1);
|
|
expect(wrapper.vm.backlog[0].rawMsg).toBe(message.trimEnd());
|
|
|
|
// Truncate at the sixth byte
|
|
const part3 = arr.slice(0, 6).toString('base64');
|
|
const part4 = arr.slice(6).toString('base64');
|
|
|
|
messageCallback({ detail: { data: part3 } });
|
|
await nextTick();
|
|
expect(wrapper.vm.backlog).toHaveLength(1);
|
|
messageCallback({ detail: { data: part4 } });
|
|
await nextTick();
|
|
expect(wrapper.vm.backlog).toHaveLength(2);
|
|
expect(wrapper.vm.backlog[1].rawMsg).toBe(message.trimEnd());
|
|
|
|
// Truncate at the seventh byte
|
|
const part5 = arr.slice(0, 7).toString('base64');
|
|
const part6 = arr.slice(7).toString('base64');
|
|
|
|
messageCallback({ detail: { data: part5 } });
|
|
await nextTick();
|
|
expect(wrapper.vm.backlog).toHaveLength(2);
|
|
messageCallback({ detail: { data: part6 } });
|
|
await nextTick();
|
|
expect(wrapper.vm.backlog).toHaveLength(3);
|
|
expect(wrapper.vm.backlog[2].rawMsg).toBe(message.trimEnd());
|
|
});
|
|
});
|