Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/test/simulation/workbench/stores/testRun.ts
13399 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as fs from 'fs';
7
import * as mobx from 'mobx';
8
import * as path from 'path';
9
import { INLINE_STATE_TAG, InterceptedRequest, ISerializedFileEdit, ISerializedNesUserEditsHistory, IWorkspaceState, IWrittenFile, NES_LOG_CONTEXT_TAG, NES_USER_EDITS_HISTORY_TAG, NEXT_EDIT_SUGGESTION_TAG, OutputAnnotation, REQUESTS_TAG } from '../../shared/sharedTypes';
10
import { ObservablePromise } from '../utils/utils';
11
import { EvaluationError } from './amlResults';
12
import { InitialWorkspaceState, InteractionWorkspaceState, WorkspaceState } from './simulationWorkspaceState';
13
14
15
export class TestRun {
16
17
@mobx.observable
18
public errorsOnlyInBefore: EvaluationError[] | undefined = undefined;
19
20
@mobx.observable
21
public errorsOnlyInAfter: any[] | undefined = undefined;
22
23
@mobx.observable
24
public stdout: string | undefined = undefined;
25
26
@mobx.observable
27
public stderr: string | undefined = undefined;
28
29
@mobx.observable
30
public pass: boolean;
31
32
@mobx.observable
33
public error: string | undefined;
34
35
@mobx.observable
36
public generatedTestCaseCount: number | undefined = undefined;
37
38
@mobx.observable
39
public generatedAssertCount: number | undefined = undefined;
40
41
@mobx.observable
42
public expectedDiff: string | undefined = undefined;
43
44
@mobx.computed
45
public get hasInlineState(): boolean {
46
return this.writtenFiles.some(f => f.tag === INLINE_STATE_TAG);
47
}
48
49
@mobx.computed
50
public get nextEditSuggestion(): ObservablePromise<ISerializedFileEdit | undefined> {
51
return new ObservablePromise(this._getNextEditSuggestion(), undefined);
52
}
53
54
@mobx.computed
55
public get nesUserEditsHistory(): ObservablePromise<ISerializedNesUserEditsHistory | undefined> {
56
return new ObservablePromise(this._getNesUserEditsHistory(), undefined);
57
}
58
59
@mobx.computed
60
public get nesLogContext(): ObservablePromise<string | undefined> {
61
return new ObservablePromise(this._getNesLogContext(), undefined);
62
}
63
64
@mobx.computed
65
public get inlineChatWorkspaceStates(): ObservablePromise<WorkspaceState[]> {
66
return new ObservablePromise(this._getInlineState(), []);
67
}
68
69
@mobx.computed
70
public get requests(): ObservablePromise<InterceptedRequest[]> {
71
return new ObservablePromise(this._getInterceptedRequests(), []);
72
}
73
74
constructor(
75
public readonly runNumber: number,
76
pass: boolean, // this is mutable because it may be set later/lazily
77
public readonly explicitScore: number | undefined,
78
error: string | undefined,
79
public readonly duration: number,
80
public readonly writtenFilesBaseDir: string,
81
public readonly writtenFiles: IWrittenFile[],
82
public readonly averageRequestDuration: number | undefined,
83
public readonly requestCount: number | undefined,
84
public readonly hasCacheMiss: boolean | undefined,
85
public readonly annotations: OutputAnnotation[] = [],
86
) {
87
this.pass = pass;
88
this.error = error;
89
mobx.makeObservable(this);
90
}
91
92
private _inlineStatePromise: Promise<WorkspaceState[]> | undefined;
93
private async _getInlineState(): Promise<WorkspaceState[]> {
94
if (!this._inlineStatePromise) {
95
this._inlineStatePromise = this._doGetInlineState();
96
}
97
return this._inlineStatePromise;
98
}
99
100
private async _doGetInlineState(): Promise<WorkspaceState[]> {
101
const contents = await this.getWrittenFileByTag(INLINE_STATE_TAG);
102
if (!contents) {
103
return [];
104
}
105
const result = JSON.parse(contents) as IWorkspaceState[];
106
return result.map((el) => {
107
if (el.kind === 'initial') {
108
return new InitialWorkspaceState(el, this.writtenFilesBaseDir);
109
}
110
return new InteractionWorkspaceState(el, this.writtenFilesBaseDir);
111
});
112
}
113
114
private _nextEditSuggestionPromise: Promise<ISerializedFileEdit | undefined> | undefined;
115
private _getNextEditSuggestion(): Promise<ISerializedFileEdit | undefined> {
116
if (!this._nextEditSuggestionPromise) {
117
this._nextEditSuggestionPromise = this._doGetNextEditSuggestion();
118
}
119
return this._nextEditSuggestionPromise;
120
}
121
122
private async _doGetNextEditSuggestion(): Promise<ISerializedFileEdit | undefined> {
123
const contents = await this.getWrittenFileByTag(NEXT_EDIT_SUGGESTION_TAG);
124
if (!contents) {
125
return undefined;
126
}
127
return JSON.parse(contents) as ISerializedFileEdit;
128
}
129
130
private _nesUserEditsHistoryPromise: Promise<ISerializedNesUserEditsHistory | undefined> | undefined = undefined;
131
private _getNesUserEditsHistory(): Promise<ISerializedNesUserEditsHistory | undefined> {
132
if (this._nesUserEditsHistoryPromise === undefined) {
133
this._nesUserEditsHistoryPromise = this._doGetNesUserEditsHistory();
134
}
135
return this._nesUserEditsHistoryPromise;
136
}
137
138
private async _doGetNesUserEditsHistory(): Promise<ISerializedNesUserEditsHistory | undefined> {
139
const contents = await this.getWrittenFileByTag(NES_USER_EDITS_HISTORY_TAG);
140
if (!contents) {
141
return undefined;
142
}
143
return JSON.parse(contents) as ISerializedNesUserEditsHistory;
144
}
145
146
private _nesLogContext: Promise<string | undefined> | undefined = undefined;
147
private _getNesLogContext(): Promise<string | undefined> {
148
if (this._nesLogContext === undefined) {
149
this._nesLogContext = this._doGetNesLogContext();
150
}
151
return this._nesLogContext;
152
}
153
154
private async _doGetNesLogContext(): Promise<string | undefined> {
155
const contents = await this.getWrittenFileByTag(NES_LOG_CONTEXT_TAG);
156
if (!contents) {
157
return undefined;
158
}
159
return JSON.parse(contents);
160
}
161
162
private _interceptedRequestsPromise: Promise<InterceptedRequest[]> | undefined;
163
private async _getInterceptedRequests(): Promise<InterceptedRequest[]> {
164
if (!this._interceptedRequestsPromise) {
165
this._interceptedRequestsPromise = this._doGetInterceptedRequests();
166
}
167
return this._interceptedRequestsPromise;
168
}
169
170
private async _doGetInterceptedRequests(): Promise<InterceptedRequest[]> {
171
const contents = await this.getWrittenFileByTag(REQUESTS_TAG);
172
if (!contents) {
173
return [];
174
}
175
const result = JSON.parse(contents);
176
if (Array.isArray(result)) {
177
return result.map(InterceptedRequest.fromJSON);
178
}
179
return [];
180
}
181
182
private async getWrittenFileByTag(tag: string): Promise<string | undefined> {
183
const writtenFile = this.writtenFiles.find(f => f.tag === tag);
184
if (!writtenFile) {
185
return undefined;
186
}
187
const contents = await fs.promises.readFile(path.join(this.writtenFilesBaseDir, writtenFile.relativePath), 'utf8');
188
return contents;
189
}
190
}
191
192