123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- import {ChromeTraceProfile} from 'sentry/utils/profiling/profile/chromeTraceProfile';
- import {EventedProfile} from 'sentry/utils/profiling/profile/eventedProfile';
- import {
- importDroppedProfile,
- importProfile,
- } from 'sentry/utils/profiling/profile/importProfile';
- import {JSSelfProfile} from 'sentry/utils/profiling/profile/jsSelfProfile';
- import {SampledProfile} from 'sentry/utils/profiling/profile/sampledProfile';
- import {SentrySampledProfile} from './sentrySampledProfile';
- import {makeSentrySampledProfile} from './sentrySampledProfile.spec';
- describe('importProfile', () => {
- it('imports evented profile', () => {
- const eventedProfile: Profiling.EventedProfile = {
- name: 'profile',
- startValue: 0,
- endValue: 1000,
- threadID: 0,
- unit: 'milliseconds',
- type: 'evented',
- events: [],
- };
- const imported = importProfile(
- {
- activeProfileIndex: 0,
- profileID: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
- profiles: [eventedProfile],
- projectID: 1,
- shared: {
- frames: [],
- },
- metadata: {} as Profiling.Schema['metadata'],
- },
- ''
- );
- expect(imported.profiles[0]).toBeInstanceOf(EventedProfile);
- });
- it('imports sampled profile', () => {
- const sampledProfile: Profiling.SampledProfile = {
- name: 'profile',
- startValue: 0,
- endValue: 1000,
- threadID: 0,
- unit: 'milliseconds',
- type: 'sampled',
- weights: [],
- samples: [],
- };
- const imported = importProfile(
- {
- activeProfileIndex: 0,
- profileID: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
- profiles: [sampledProfile],
- projectID: 1,
- shared: {
- frames: [],
- },
- metadata: {} as Profiling.Schema['metadata'],
- },
- ''
- );
- expect(imported.profiles[0]).toBeInstanceOf(SampledProfile);
- });
- it('imports typescript profile', () => {
- const typescriptProfile: ChromeTrace.ArrayFormat = [
- {
- ph: 'B',
- ts: 1000,
- cat: 'program',
- pid: 0,
- tid: 0,
- name: 'createProgram',
- args: {configFilePath: '/Users/jonasbadalic/Work/sentry/tsconfig.json'},
- },
- {
- ph: 'E',
- ts: 2000,
- cat: 'program',
- pid: 0,
- tid: 0,
- name: 'createProgram',
- args: {configFilePath: '/Users/jonasbadalic/Work/sentry/tsconfig.json'},
- },
- ];
- const imported = importProfile(typescriptProfile, '');
- expect(imported.profiles[0]).toBeInstanceOf(ChromeTraceProfile);
- });
- it('imports a nodejs profile', () => {
- const nodeProfile: Profiling.NodeProfile = {
- name: 'profile',
- startValue: 0,
- endValue: 1000,
- threadID: 0,
- unit: 'milliseconds',
- type: 'sampled',
- weights: [],
- samples: [],
- frames: [],
- };
- const imported = importProfile([nodeProfile, {}], '');
- expect(imported.profiles[0]).toBeInstanceOf(SampledProfile);
- });
- it('imports JS self profile from schema', () => {
- const jsSelfProfile: JSSelfProfiling.Trace = {
- resources: ['app.js', 'vendor.js'],
- frames: [{name: 'ReactDOM.render', line: 1, column: 1, resourceId: 0}],
- samples: [
- {
- timestamp: 0,
- },
- {
- timestamp: 1000,
- stackId: 0,
- },
- ],
- stacks: [
- {
- frameId: 0,
- },
- ],
- };
- const imported = importProfile(
- {
- activeProfileIndex: 0,
- profileID: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
- profiles: [jsSelfProfile],
- projectID: 1,
- metadata: {} as Profiling.Schema['metadata'],
- shared: {
- frames: [],
- },
- },
- ''
- );
- expect(imported.profiles[0]).toBeInstanceOf(JSSelfProfile);
- });
- it('imports JS self profile from raw Profiling output', () => {
- const jsSelfProfile: JSSelfProfiling.Trace = {
- resources: ['app.js', 'vendor.js'],
- frames: [{name: 'ReactDOM.render', line: 1, column: 1, resourceId: 0}],
- samples: [
- {
- timestamp: 0,
- },
- {
- timestamp: 1000,
- stackId: 0,
- },
- ],
- stacks: [
- {
- frameId: 0,
- },
- ],
- };
- const imported = importProfile(jsSelfProfile, 'profile');
- expect(imported.profiles[0]).toBeInstanceOf(JSSelfProfile);
- });
- it('imports sentry sampled profile', () => {
- const sentrySampledProfile = makeSentrySampledProfile();
- const imported = importProfile(sentrySampledProfile, 'profile');
- expect(imported.profiles[0]).toBeInstanceOf(SentrySampledProfile);
- });
- it('throws on unrecognized profile type', () => {
- expect(() =>
- importProfile(
- // @ts-ignore
- {name: 'profile', activeProfileIndex: 0, profiles: [{type: 'unrecognized'}]},
- ''
- )
- ).toThrow();
- });
- });
- describe('importDroppedProfile', () => {
- beforeEach(() => {
- jest.restoreAllMocks();
- });
- it('throws if file has no string contents', async () => {
- // @ts-ignore we are just setting null on the file, we are not actually reading it because our event is mocked
- const file = new File([null], 'test.tsx');
- const reader = new FileReader();
- jest.spyOn(window, 'FileReader').mockImplementation(() => reader);
- jest.spyOn(reader, 'readAsText').mockImplementation(() => {
- const loadEvent = new CustomEvent('load', {
- detail: {target: {result: null}},
- });
- reader.dispatchEvent(loadEvent);
- });
- await expect(importDroppedProfile(file)).rejects.toEqual(
- 'Failed to read string contents of input file'
- );
- });
- it('throws if FileReader errors', async () => {
- const file = new File(['{json: true}'], 'test.tsx');
- const reader = new FileReader();
- jest.spyOn(window, 'FileReader').mockImplementation(() => reader);
- jest.spyOn(reader, 'readAsText').mockImplementation(() => {
- const loadEvent = new CustomEvent('error', {
- detail: {target: {result: null}},
- });
- reader.dispatchEvent(loadEvent);
- });
- await expect(importDroppedProfile(file)).rejects.toEqual(
- 'Failed to read string contents of input file'
- );
- });
- it('throws if contents are not valid JSON', async () => {
- const file = new File(['{"json": true'], 'test.tsx');
- await expect(importDroppedProfile(file)).rejects.toBeInstanceOf(Error);
- });
- it('imports dropped schema file', async () => {
- const schema: Profiling.Schema = {
- activeProfileIndex: 0,
- profileID: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
- profiles: [
- {
- name: 'profile',
- startValue: 0,
- endValue: 1000,
- threadID: 0,
- unit: 'milliseconds',
- type: 'sampled',
- weights: [],
- samples: [],
- },
- ],
- projectID: 1,
- shared: {
- frames: [],
- },
- metadata: {} as Profiling.Schema['metadata'],
- };
- const file = new File([JSON.stringify(schema)], 'test.tsx');
- const imported = await importDroppedProfile(file);
- expect(imported.profiles[0]).toBeInstanceOf(SampledProfile);
- });
- it('imports dropped typescript profile', async () => {
- const typescriptProfile: ChromeTrace.ArrayFormat = [
- {
- ph: 'B',
- ts: 1000,
- cat: 'program',
- pid: 0,
- tid: 0,
- name: 'createProgram',
- args: {configFilePath: '/Users/jonasbadalic/Work/sentry/tsconfig.json'},
- },
- {
- ph: 'E',
- ts: 2000,
- cat: 'program',
- pid: 0,
- tid: 0,
- name: 'createProgram',
- args: {configFilePath: '/Users/jonasbadalic/Work/sentry/tsconfig.json'},
- },
- ];
- const file = new File([JSON.stringify(typescriptProfile)], 'test.tsx');
- const imported = await importDroppedProfile(file);
- expect(imported.profiles[0]).toBeInstanceOf(ChromeTraceProfile);
- });
- it('imports dropped JS self profile', async () => {
- const jsSelfProfile: JSSelfProfiling.Trace = {
- resources: ['app.js', 'vendor.js'],
- frames: [{name: 'ReactDOM.render', line: 1, column: 1, resourceId: 0}],
- samples: [
- {
- timestamp: 0,
- },
- {
- timestamp: 1000,
- stackId: 0,
- },
- ],
- stacks: [
- {
- frameId: 0,
- },
- ],
- };
- const file = new File([JSON.stringify(jsSelfProfile)], 'test.tsx');
- const imported = await importDroppedProfile(file);
- expect(imported.profiles[0]).toBeInstanceOf(JSSelfProfile);
- });
- });
|