"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
const _promises = require("fs/promises");
const _path = require("path");
const _os = require("os");
const _shared = require("./shared");
const _trace = require("./trace");
describe("Trace", ()=>{
    beforeEach(()=>{
        (0, _trace.initializeTraceState)({
            lastId: 0,
            shouldSaveTraceEvents: true
        });
        (0, _trace.clearTraceEvents)();
    });
    describe("Tracer", ()=>{
        it("traces a block of code", async ()=>{
            const tmpDir = await (0, _promises.mkdtemp)((0, _path.join)((0, _os.tmpdir)(), "json-reporter"));
            (0, _shared.setGlobal)("distDir", tmpDir);
            (0, _shared.setGlobal)("phase", "anything");
            const root = (0, _trace.trace)("root-span", undefined, {
                "some-tag": "some-value"
            });
            root.traceChild("child-span").traceFn(()=>null);
            await root.traceChild("async-child-span").traceAsyncFn(async ()=>{
                const delayedPromise = new Promise((resolve)=>{
                    setTimeout(resolve, 100);
                });
                await delayedPromise;
            });
            root.stop();
            const traceEvents = (0, _trace.getTraceEvents)();
            expect(traceEvents.length).toEqual(3);
            expect(traceEvents[0].name).toEqual("child-span");
            expect(traceEvents[1].name).toEqual("async-child-span");
            expect(traceEvents[2].name).toEqual("root-span");
            // Check that the serialized .next/trace file looks correct.
            await (0, _trace.flushAllTraces)();
            const traceFilename = (0, _path.join)(tmpDir, "trace");
            const serializedTraces = JSON.parse(await (0, _promises.readFile)(traceFilename, "utf-8"));
            expect(serializedTraces).toMatchObject([
                {
                    id: 2,
                    name: "child-span",
                    parentId: 1,
                    startTime: expect.any(Number),
                    timestamp: expect.any(Number),
                    duration: expect.any(Number),
                    tags: {}
                },
                {
                    id: 3,
                    name: "async-child-span",
                    parentId: 1,
                    startTime: expect.any(Number),
                    timestamp: expect.any(Number),
                    duration: expect.any(Number),
                    tags: {}
                },
                {
                    id: 1,
                    name: "root-span",
                    startTime: expect.any(Number),
                    timestamp: expect.any(Number),
                    duration: expect.any(Number),
                    tags: {
                        "some-tag": "some-value"
                    }
                }
            ]);
        });
    });
    describe("Worker", ()=>{
        it("exports and initializes trace state", ()=>{
            const root = (0, _trace.trace)("root-span");
            expect(root.getId()).toEqual(1);
            const traceState = (0, _trace.exportTraceState)();
            expect(traceState.lastId).toEqual(1);
            (0, _trace.initializeTraceState)({
                lastId: 101
            });
            const span = (0, _trace.trace)("another-span");
            expect(span.getId()).toEqual(102);
        });
        it("trace data is serializable to a worker", async ()=>{
            const root = (0, _trace.trace)("root-span");
            root.traceChild("child-span").traceFn(()=>null);
            root.stop();
            const traceEvents = (0, _trace.getTraceEvents)();
            expect(traceEvents.length).toEqual(2);
            // This is a proxy check to make sure the object would be serializable
            // to a worker. It will fail if the data contains some unserializable
            // objects like BigInt.
            const clone = JSON.parse(JSON.stringify(traceEvents));
            expect(clone).toEqual(traceEvents);
        });
        it("correctly reports trace data from multiple workers", ()=>{
            // This test simulates workers creating traces and propagating them
            // back to the main process for recording. It doesn't use
            // actual workers since they are more difficult to set up in tests.
            (0, _trace.initializeTraceState)({
                lastId: 5,
                defaultParentSpanId: 1,
                shouldSaveTraceEvents: true
            });
            const worker1Span = (0, _trace.trace)("worker1");
            worker1Span.traceChild("webpack-compilation1").traceFn(()=>null);
            worker1Span.stop();
            const worker1Traces = (0, _trace.getTraceEvents)();
            expect(worker1Traces.length).toEqual(2);
            // Repeat for a second worker.
            (0, _trace.clearTraceEvents)();
            (0, _trace.initializeTraceState)({
                lastId: 10,
                defaultParentSpanId: 1,
                shouldSaveTraceEvents: true
            });
            const worker2Span = (0, _trace.trace)("worker2");
            worker2Span.traceChild("webpack-compilation2").traceFn(()=>null);
            worker2Span.stop();
            const worker2Traces = (0, _trace.getTraceEvents)();
            expect(worker2Traces.length).toEqual(2);
            // Now simulate the traces in the main process and record the traces
            // from each worker.
            (0, _trace.clearTraceEvents)();
            (0, _trace.initializeTraceState)({
                lastId: 0,
                shouldSaveTraceEvents: true
            });
            const root = (0, _trace.trace)("next-build");
            root.traceChild("some-child-span").traceFn(()=>null);
            (0, _trace.recordTraceEvents)(worker1Traces);
            expect((0, _trace.exportTraceState)().lastId).toEqual(8);
            (0, _trace.recordTraceEvents)(worker2Traces);
            expect((0, _trace.exportTraceState)().lastId).toEqual(13);
            root.traceChild("another-child-span").traceFn(()=>null);
            root.stop();
            // Check that the final output looks correct.
            const allTraces = (0, _trace.getTraceEvents)();
            expect(allTraces.length).toEqual(7);
            const firstSpan = allTraces[0];
            expect(firstSpan.name).toEqual("some-child-span");
            expect(firstSpan.id).toEqual(2);
            expect(firstSpan.parentId).toEqual(1);
            const worker1Child = allTraces[1];
            expect(worker1Child.name).toEqual("webpack-compilation1");
            expect(worker1Child.id).toEqual(7);
            expect(worker1Child.parentId).toEqual(6);
            const worker1Root = allTraces[2];
            expect(worker1Root.name).toEqual("worker1");
            expect(worker1Root.id).toEqual(6);
            expect(worker1Root.parentId).toEqual(1);
            const worker2Child = allTraces[3];
            expect(worker2Child.name).toEqual("webpack-compilation2");
            expect(worker2Child.id).toEqual(12);
            expect(worker2Child.parentId).toEqual(11);
            const worker2Root = allTraces[4];
            expect(worker2Root.name).toEqual("worker2");
            expect(worker2Root.id).toEqual(11);
            expect(worker2Root.parentId).toEqual(1);
            const lastChildSpan = allTraces[5];
            expect(lastChildSpan.name).toEqual("another-child-span");
            expect(lastChildSpan.id).toEqual(14);
            expect(lastChildSpan.parentId).toEqual(1);
            const rootSpan = allTraces[6];
            expect(rootSpan.name).toEqual("next-build");
            expect(rootSpan.id).toEqual(1);
            expect(rootSpan.parentId).toBeUndefined();
        });
    });
});

//# sourceMappingURL=trace.test.js.map