Fix non-determinism in code generator

This commit is contained in:
Stanley Cheung 2020-10-05 15:15:23 -07:00 committed by Stanley Cheung
parent 4a4923f928
commit 0c62fe8a3a
2 changed files with 65 additions and 36 deletions

View File

@ -529,15 +529,17 @@ string GetBasename(string filename) {
return basename;
}
// Finds all message types used in all services in the file.
std::set<const Descriptor*> GetAllMessages(const FileDescriptor* file) {
std::set<const Descriptor*> messages;
// Finds all message types used in all services in the file. Return results as a
// map of full names to descriptors to get sorted results and deterministic
// build outputs.
std::map<string, const Descriptor*> GetAllMessages(const FileDescriptor* file) {
std::map<string, const Descriptor*> messages;
for (int s = 0; s < file->service_count(); ++s) {
const ServiceDescriptor* service = file->service(s);
for (int m = 0; m < service->method_count(); ++m) {
const MethodDescriptor *method = service->method(m);
messages.insert(method->input_type());
messages.insert(method->output_type());
messages[method->input_type()->full_name()] = method->input_type();
messages[method->output_type()->full_name()] = method->output_type();
}
}
@ -545,10 +547,10 @@ std::set<const Descriptor*> GetAllMessages(const FileDescriptor* file) {
}
void PrintClosureDependencies(Printer* printer, const FileDescriptor* file) {
for (const Descriptor* message : GetAllMessages(file)) {
for (const auto &entry : GetAllMessages(file)) {
printer->Print(
"goog.require('proto.$full_name$');\n",
"full_name", message->full_name());
"full_name", entry.second->full_name());
}
printer->Print("\n\n\n");
}
@ -604,8 +606,8 @@ void PrintES6Imports(Printer* printer, const FileDescriptor* file) {
printer->Print("import * as grpcWeb from 'grpc-web';\n\n");
std::set<string> imports;
for (const Descriptor* message : GetAllMessages(file)) {
const string& name = message->file()->name();
for (const auto &entry : GetAllMessages(file)) {
const string& name = entry.second->file()->name();
string dep_filename = GetRootPath(file->name(), name) + StripProto(name);
if (imports.find(dep_filename) != imports.end()) {
continue;

View File

@ -19,27 +19,27 @@ goog.module('grpc.web.GrpcWebClientBaseTest');
goog.setTestOnly('grpc.web.GrpcWebClientBaseTest');
const ClientReadableStream = goog.require('grpc.web.ClientReadableStream');
var EventType = goog.require('goog.net.EventType');
var GrpcWebClientBase = goog.require('grpc.web.GrpcWebClientBase');
var Map = goog.require('goog.structs.Map');
var googCrypt = goog.require('goog.crypt.base64');
var googEvents = goog.require('goog.events');
var testSuite = goog.require('goog.testing.testSuite');
const EventType = goog.require('goog.net.EventType');
const GrpcWebClientBase = goog.require('grpc.web.GrpcWebClientBase');
const Map = goog.require('goog.structs.Map');
const googCrypt = goog.require('goog.crypt.base64');
const googEvents = goog.require('goog.events');
const testSuite = goog.require('goog.testing.testSuite');
const {StreamInterceptor} = goog.require('grpc.web.Interceptor');
goog.require('goog.testing.jsunit');
var REQUEST_BYTES = [1, 2, 3];
var FAKE_METHOD = 'fake-method';
var PROTO_FIELD_VALUE = 'meow';
var EXPECTED_HEADERS;
var EXPECTED_HEADER_VALUES;
var EXPECTED_UNARY_HEADERS =
const REQUEST_BYTES = [1, 2, 3];
const FAKE_METHOD = 'fake-method';
const PROTO_FIELD_VALUE = 'meow';
const DEFAULT_UNARY_HEADERS =
['Content-Type', 'Accept', 'X-User-Agent', 'X-Grpc-Web'];
var EXPECTED_UNARY_HEADER_VALUES = [
const DEFAULT_UNARY_HEADER_VALUES = [
'application/grpc-web-text', 'application/grpc-web-text',
'grpc-web-javascript/0.1', '1'
];
var dataCallback;
let dataCallback;
let expectedHeaders;
let expectedHeaderValues;
testSuite({
@ -53,8 +53,8 @@ testSuite({
},
tearDown: function() {
EXPECTED_HEADERS = null;
EXPECTED_HEADER_VALUES = null;
expectedHeaders = null;
expectedHeaderValues = null;
},
testRpcResponse: function() {
@ -69,7 +69,7 @@ testSuite({
expectUnaryHeaders();
client.rpcCall(
FAKE_METHOD, {}, {}, {
FAKE_METHOD, /** requestMessage */ {}, /** metadata */ {}, {
requestSerializeFn: function(request) {
return REQUEST_BYTES;
},
@ -85,6 +85,28 @@ testSuite({
dataCallback();
},
testDeadline: function() {
const client = new GrpcWebClientBase();
client.newXhr_ = function() {
return new MockXhr({
deadline: true,
response: googCrypt.encodeByteArray(new Uint8Array(0)),
});
};
expectUnaryHeaders();
const deadline = new Date();
deadline.setSeconds(deadline.getSeconds() + 1);
client.rpcCall(
FAKE_METHOD, /** requestMessage */ {}, {'deadline': deadline}, {
requestSerializeFn: (request) => REQUEST_BYTES,
responseDeserializeFn: (bytes) => {},
},
(error, response) => assertNull(error));
dataCallback();
},
testStreamInterceptor: function() {
var interceptor = new StreamResponseInterceptor();
var client = new GrpcWebClientBase({'streamInterceptors': [interceptor]});
@ -180,8 +202,8 @@ testSuite({
/** Sets expected headers as the unary response headers */
function expectUnaryHeaders() {
EXPECTED_HEADERS = EXPECTED_UNARY_HEADERS;
EXPECTED_HEADER_VALUES = EXPECTED_UNARY_HEADER_VALUES;
expectedHeaders = [...DEFAULT_UNARY_HEADERS];
expectedHeaderValues = [...DEFAULT_UNARY_HEADER_VALUES];
}
@ -198,18 +220,23 @@ class MockXhr {
/**
* @param {string} url
* @param {string=} opt_method
* @param {string=} opt_content
* @param {string=} opt_headers
* @param {string=} method
* @param {string=} content
* @param {string=} headers
*/
send(url, opt_method, opt_content, opt_headers) {
send(url, method, content, headers) {
assertEquals(FAKE_METHOD, url);
assertEquals('POST', opt_method);
assertEquals('POST', method);
assertElementsEquals(
googCrypt.encodeByteArray(new Uint8Array([0, 0, 0, 0, 3, 1, 2, 3])),
opt_content);
assertElementsEquals(EXPECTED_HEADERS, this.headers.getKeys());
assertElementsEquals(EXPECTED_HEADER_VALUES, this.headers.getValues());
content);
if (!this.mockValues.deadline) {
assertElementsEquals(expectedHeaders, this.headers.getKeys());
assertElementsEquals(expectedHeaderValues, this.headers.getValues());
} else {
expectedHeaders.push('grpc-timeout');
assertElementsEquals(expectedHeaders, this.headers.getKeys());
}
}
/**