Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-cloned / deps / grpc / third_party / upb / tests / conformance_upb.c
1 /* This is a upb implementation of the upb conformance tests, see:
2  *   https://github.com/google/protobuf/tree/master/conformance
3  */
4
5 #include <errno.h>
6 #include <stdarg.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10
11 #include "conformance/conformance.upb.h"
12 #include "src/google/protobuf/test_messages_proto3.upb.h"
13
14 int test_count = 0;
15
16 bool CheckedRead(int fd, void *buf, size_t len) {
17   size_t ofs = 0;
18   while (len > 0) {
19     ssize_t bytes_read = read(fd, (char*)buf + ofs, len);
20
21     if (bytes_read == 0) return false;
22
23     if (bytes_read < 0) {
24       perror("reading from test runner");
25       exit(1);
26     }
27
28     len -= bytes_read;
29     ofs += bytes_read;
30   }
31
32   return true;
33 }
34
35 void CheckedWrite(int fd, const void *buf, size_t len) {
36   if ((size_t)write(fd, buf, len) != len) {
37     perror("writing to test runner");
38     exit(1);
39   }
40 }
41
42 bool strview_eql(upb_strview view, const char *str) {
43   return view.size == strlen(str) && memcmp(view.data, str, view.size) == 0;
44 }
45
46 static const char *proto3_msg =
47     "protobuf_test_messages.proto3.TestAllTypesProto3";
48
49 void DoTest(
50     const conformance_ConformanceRequest* request,
51     conformance_ConformanceResponse *response,
52     upb_arena *arena) {
53   protobuf_test_messages_proto3_TestAllTypesProto3 *test_message;
54
55   if (!strview_eql(conformance_ConformanceRequest_message_type(request),
56                    proto3_msg)) {
57     static const char msg[] = "Only proto3 for now.";
58     conformance_ConformanceResponse_set_skipped(
59         response, upb_strview_make(msg, sizeof(msg)));
60     return;
61   }
62
63   switch (conformance_ConformanceRequest_payload_case(request)) {
64     case conformance_ConformanceRequest_payload_protobuf_payload: {
65       upb_strview payload = conformance_ConformanceRequest_protobuf_payload(request);
66       test_message = protobuf_test_messages_proto3_TestAllTypesProto3_parse(
67           payload.data, payload.size, arena);
68
69       if (!test_message) {
70         static const char msg[] = "Parse error";
71         conformance_ConformanceResponse_set_parse_error(
72             response, upb_strview_make(msg, sizeof(msg)));
73         return;
74       }
75       break;
76     }
77
78     case conformance_ConformanceRequest_payload_NOT_SET:
79       fprintf(stderr, "conformance_upb: Request didn't have payload.\n");
80       return;
81
82     default: {
83       static const char msg[] = "Unsupported input format.";
84       conformance_ConformanceResponse_set_skipped(
85           response, upb_strview_make(msg, sizeof(msg)));
86       return;
87     }
88   }
89
90   switch (conformance_ConformanceRequest_requested_output_format(request)) {
91     case conformance_UNSPECIFIED:
92       fprintf(stderr, "conformance_upb: Unspecified output format.\n");
93       exit(1);
94
95     case conformance_PROTOBUF: {
96       size_t serialized_len;
97       char *serialized =
98           protobuf_test_messages_proto3_TestAllTypesProto3_serialize(
99               test_message, arena, &serialized_len);
100       if (!serialized) {
101         static const char msg[] = "Error serializing.";
102         conformance_ConformanceResponse_set_serialize_error(
103             response, upb_strview_make(msg, sizeof(msg)));
104         return;
105       }
106       conformance_ConformanceResponse_set_protobuf_payload(
107           response, upb_strview_make(serialized, serialized_len));
108       break;
109     }
110
111     default: {
112       static const char msg[] = "Unsupported output format.";
113       conformance_ConformanceResponse_set_skipped(
114           response, upb_strview_make(msg, sizeof(msg)));
115       return;
116     }
117   }
118
119   return;
120 }
121
122 bool DoTestIo(void) {
123   upb_arena *arena;
124   upb_alloc *alloc;
125   upb_status status;
126   char *serialized_input;
127   char *serialized_output;
128   uint32_t input_size;
129   size_t output_size;
130   conformance_ConformanceRequest *request;
131   conformance_ConformanceResponse *response;
132
133   if (!CheckedRead(STDIN_FILENO, &input_size, sizeof(uint32_t))) {
134     /* EOF. */
135     return false;
136   }
137
138   arena = upb_arena_new();
139   alloc = upb_arena_alloc(arena);
140   serialized_input = upb_malloc(alloc, input_size);
141
142   if (!CheckedRead(STDIN_FILENO, serialized_input, input_size)) {
143     fprintf(stderr, "conformance_upb: unexpected EOF on stdin.\n");
144     exit(1);
145   }
146
147   request =
148       conformance_ConformanceRequest_parse(serialized_input, input_size, arena);
149   response = conformance_ConformanceResponse_new(arena);
150
151   if (request) {
152     DoTest(request, response, arena);
153   } else {
154     fprintf(stderr, "conformance_upb: parse of ConformanceRequest failed: %s\n",
155             upb_status_errmsg(&status));
156   }
157
158   serialized_output = conformance_ConformanceResponse_serialize(
159       response, arena, &output_size);
160
161   CheckedWrite(STDOUT_FILENO, &output_size, sizeof(uint32_t));
162   CheckedWrite(STDOUT_FILENO, serialized_output, output_size);
163
164   test_count++;
165
166   upb_arena_free(arena);
167
168   return true;
169 }
170
171 int main(void) {
172   while (1) {
173     if (!DoTestIo()) {
174       fprintf(stderr, "conformance_upb: received EOF from test runner "
175                       "after %d tests, exiting\n", test_count);
176       return 0;
177     }
178   }
179 }