-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathexecutor.ts
More file actions
99 lines (95 loc) · 3.01 KB
/
executor.ts
File metadata and controls
99 lines (95 loc) · 3.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Copyright 2024-2026 Buf Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import {
create,
createFileRegistry,
fromBinary,
type Registry,
toBinary,
} from "@bufbuild/protobuf";
import {
TestConformanceRequestSchema,
TestConformanceResponseSchema,
TestResultSchema,
} from "./gen/buf/validate/conformance/harness/harness_pb.js";
import { type Any, anyUnpack } from "@bufbuild/protobuf/wkt";
import * as process from "node:process";
import {
createValidator,
CompilationError,
RuntimeError,
violationsToProto,
} from "@bufbuild/protovalidate";
const request = fromBinary(TestConformanceRequestSchema, await readStdin());
if (!request.fdset) {
throw new Error(`Empty request field "fdset"`);
}
const registry = createFileRegistry(request.fdset);
const validator = createValidator({ registry });
const response = create(TestConformanceResponseSchema);
for (const [name, any] of Object.entries(request.cases)) {
const testResult = create(TestResultSchema);
const unpacked = unpackTest(any, registry);
if (unpacked) {
const result = validator.validate(unpacked.schema, unpacked.message);
switch (result.kind) {
case "valid":
testResult.result = { case: "success", value: true };
break;
case "invalid":
testResult.result = {
case: "validationError",
value: violationsToProto(result.violations)[0],
};
break;
case "error":
if (result.error instanceof CompilationError) {
testResult.result = {
case: "compilationError",
value: String(result.error),
};
} else if (result.error instanceof RuntimeError) {
testResult.result = {
case: "runtimeError",
value: String(result.error),
};
}
break;
}
} else {
testResult.result = {
case: "unexpectedError",
value: `Unable to unpack Any with type_url "${any.typeUrl}"`,
};
}
response.results[name] = testResult;
}
process.stdout.write(toBinary(TestConformanceResponseSchema, response));
function unpackTest(any: Any, registry: Registry) {
const message = anyUnpack(any, registry);
if (message) {
const schema = registry.getMessage(message.$typeName);
if (schema) {
return { message, schema };
}
}
return undefined;
}
async function readStdin(): Promise<Uint8Array> {
const chunks: Uint8Array[] = [];
for await (const chunk of process.stdin) {
chunks.push(chunk as Uint8Array);
}
return Buffer.concat(chunks);
}