public async refreshTestData()

in src/client/testing/testController/unittest/unittestController.ts [108:241]


    public async refreshTestData(testController: TestController, uri: Uri, token?: CancellationToken): Promise<void> {
        sendTelemetryEvent(EventName.UNITTEST_DISCOVERING, undefined, { tool: 'unittest' });
        const workspace = this.workspaceService.getWorkspaceFolder(uri);
        if (workspace) {
            // Discovery is expensive. So if it is already running then use the promise
            // from the last run
            const previous = this.discovering.get(workspace.uri.fsPath);
            if (previous) {
                return previous.promise;
            }

            const settings = this.configService.getSettings(workspace.uri);
            const options: TestDiscoveryOptions = {
                workspaceFolder: workspace.uri,
                cwd:
                    settings.testing.cwd && settings.testing.cwd.length > 0
                        ? settings.testing.cwd
                        : workspace.uri.fsPath,
                args: settings.testing.unittestArgs,
                ignoreCache: true,
                token,
            };

            const startDir = unittestGetTestFolders(options.args)[0];
            const pattern = unittestGetTestPattern(options.args);
            let testDir = startDir;
            if (path.isAbsolute(startDir)) {
                const relative = path.relative(options.cwd, startDir);
                testDir = relative.length > 0 ? relative : '.';
            }

            const runOptions: Options = {
                // unittest needs to load modules in the workspace
                // isolating it breaks unittest discovery
                args: unittestDiscovery([startDir, pattern]),
                cwd: options.cwd,
                workspaceFolder: options.workspaceFolder,
                token: options.token,
                outChannel: options.outChannel,
            };

            const deferred = createDeferred<void>();
            this.discovering.set(workspace.uri.fsPath, deferred);

            let rawTestData: RawDiscoveredTests | undefined;
            try {
                const content = await this.discoveryRunner.run(UNITTEST_PROVIDER, runOptions);
                rawTestData = await testDiscoveryParser(options.cwd, testDir, getTestIds(content), options.token);
                this.testData.set(workspace.uri.fsPath, rawTestData);

                const exceptions = getTestDiscoveryExceptions(content);
                if (exceptions.length === 0) {
                    // Remove error node
                    testController.items.delete(`DiscoveryError:${workspace.uri.fsPath}`);
                } else {
                    traceError('Error discovering unittest tests:\r\n', exceptions.join('\r\n\r\n'));

                    let errorNode = testController.items.get(`DiscoveryError:${workspace.uri.fsPath}`);
                    const message = util.format(
                        'Error discovering unittest tests (see Output > Python):\r\n',
                        exceptions.join('\r\n\r\n'),
                    );
                    if (errorNode === undefined) {
                        errorNode = createErrorTestItem(testController, {
                            id: `DiscoveryError:${workspace.uri.fsPath}`,
                            label: `Unittest Discovery Error [${path.basename(workspace.uri.fsPath)}]`,
                            error: message,
                        });
                        errorNode.canResolveChildren = false;
                        testController.items.add(errorNode);
                    }
                    errorNode.error = message;
                }

                deferred.resolve();
            } catch (ex) {
                sendTelemetryEvent(EventName.UNITTEST_DISCOVERY_DONE, undefined, { tool: 'unittest', failed: true });
                const cancel = options.token?.isCancellationRequested ? 'Cancelled' : 'Error';
                traceError(`${cancel} discovering unittest tests:\r\n`, ex);

                // Report also on the test view.
                testController.items.add(
                    createErrorTestItem(testController, {
                        id: `DiscoveryError:${workspace.uri.fsPath}`,
                        label: `Unittest Discovery Error [${path.basename(workspace.uri.fsPath)}]`,
                        error: util.format(`${cancel} discovering unittest tests (see Output > Python):\r\n`, ex),
                    }),
                );

                deferred.reject(ex as Error);
            } finally {
                // Discovery has finished running we have the raw test data at this point.
                this.discovering.delete(workspace.uri.fsPath);
            }

            if (!rawTestData) {
                // No test data is available
                return Promise.resolve();
            }

            const workspaceNode = testController.items.get(rawTestData.root);
            if (workspaceNode) {
                if (uri.fsPath === workspace.uri.fsPath) {
                    // this is a workspace level refresh
                    // This is an existing workspace test node. Just update the children
                    await this.resolveChildren(testController, workspaceNode, token);
                } else {
                    // This is a child node refresh
                    const testNode = getNodeByUri(workspaceNode, uri);
                    if (testNode) {
                        // We found the node to update
                        await this.resolveChildren(testController, testNode, token);
                    } else {
                        // update the entire workspace tree
                        await this.resolveChildren(testController, workspaceNode, token);
                    }
                }
            } else if (rawTestData.tests.length > 0) {
                // This is a new workspace with tests.
                const newItem = createWorkspaceRootTestItem(testController, this.idToRawData, {
                    id: rawTestData.root,
                    label: path.basename(rawTestData.root),
                    uri: Uri.file(rawTestData.root),
                    runId: rawTestData.root === '.' ? workspace.uri.fsPath : rawTestData.root,
                    rawId: rawTestData.rootid,
                });
                testController.items.add(newItem);

                await this.resolveChildren(testController, newItem, token);
            }
        }
        sendTelemetryEvent(EventName.UNITTEST_DISCOVERY_DONE, undefined, { tool: 'unittest', failed: false });
        return Promise.resolve();
    }