1--[[-------------------------------------------------------------------------- 2 3Protocol Buffers - Google's data interchange format 4Copyright 2023 Google LLC. All rights reserved. 5 6Use of this source code is governed by a BSD-style 7license that can be found in the LICENSE file or at 8https://developers.google.com/open-source/licenses/bsd 9 10--]]-------------------------------------------------------------------------- 11 12local upb = require "lupb" 13local lunit = require "lunit" 14local upb_test = require "lua.test_pb" 15local test_messages_proto3 = require "google.protobuf.test_messages_proto3_pb" 16local test_messages_proto2 = require "google.protobuf.test_messages_proto2_pb" 17local descriptor = require "google.protobuf.descriptor_pb" 18local empty = require "google.protobuf.empty_pb" 19 20if _VERSION >= 'Lua 5.2' then 21 _ENV = lunit.module("testupb", "seeall") 22else 23 module("testupb", lunit.testcase, package.seeall) 24end 25 26function iter_to_array(iter) 27 local arr = {} 28 for v in iter do 29 arr[#arr + 1] = v 30 end 31 return arr 32end 33 34function test_def_readers() 35 local m = test_messages_proto3.TestAllTypesProto3 36 assert_equal("TestAllTypesProto3", m:name()) 37 assert_equal("protobuf_test_messages.proto3.TestAllTypesProto3", m:full_name()) 38 39 -- field 40 local f = m:field("optional_int32") 41 local f2 = m:field(1) 42 assert_equal(f, f2) 43 assert_equal(1, f:number()) 44 assert_equal("optional_int32", f:name()) 45 assert_equal(upb.LABEL_OPTIONAL, f:label()) 46 assert_equal(upb.DESCRIPTOR_TYPE_INT32, f:descriptor_type()) 47 assert_equal(upb.TYPE_INT32, f:type()) 48 assert_nil(f:containing_oneof()) 49 assert_equal(m, f:containing_type()) 50 assert_equal(0, f:default()) 51 local message_field_count = 0 52 for field in m:fields() do 53 message_field_count = message_field_count + 1 54 end 55 assert_equal(message_field_count, #m) 56 57 local message_oneof_count = 0 58 for oneof in m:oneofs() do 59 message_oneof_count = message_oneof_count + 1 60 end 61 assert_equal(message_oneof_count, m:oneof_count()) 62 63 -- oneof 64 local o = m:lookup_name("oneof_field") 65 assert_equal("oneof_field", o:name()) 66 assert_equal(m, o:containing_type()) 67 local oneof_field_count = 0 68 for field in o:fields() do 69 oneof_field_count = oneof_field_count + 1 70 end 71 assert_equal(oneof_field_count, #o) 72 73 -- enum 74 local e = test_messages_proto3['TestAllTypesProto3.NestedEnum'] 75 assert_true(#e > 3 and #e < 10) 76 assert_equal(2, e:value("BAZ"):number()) 77end 78 79function test_msg_map() 80 msg = test_messages_proto3.TestAllTypesProto3() 81 msg.map_int32_int32[5] = 10 82 msg.map_int32_int32[6] = 12 83 assert_equal(10, msg.map_int32_int32[5]) 84 assert_equal(12, msg.map_int32_int32[6]) 85 86 -- Test overwrite. 87 msg.map_int32_int32[5] = 20 88 assert_equal(20, msg.map_int32_int32[5]) 89 assert_equal(12, msg.map_int32_int32[6]) 90 msg.map_int32_int32[5] = 10 91 92 -- Test delete. 93 msg.map_int32_int32[5] = nil 94 assert_nil(msg.map_int32_int32[5]) 95 assert_equal(12, msg.map_int32_int32[6]) 96 msg.map_int32_int32[5] = 10 97 98 local serialized = upb.encode(msg) 99 assert_true(#serialized > 0) 100 local msg2 = upb.decode(test_messages_proto3.TestAllTypesProto3, serialized) 101 assert_equal(10, msg2.map_int32_int32[5]) 102 assert_equal(12, msg2.map_int32_int32[6]) 103end 104 105function test_map_sorting() 106 function msg_with_int32_entries(start, expand) 107 local msg = test_messages_proto3.TestAllTypesProto3() 108 for i=start,start + 8 do 109 msg.map_int32_int32[i] = i * 2 110 end 111 112 if expand then 113 for i=start+20,200 do 114 msg.map_int32_int32[i] = i 115 end 116 for i=start+20,200 do 117 msg.map_int32_int32[i] = nil 118 end 119 end 120 return msg 121 end 122 123 function msg_with_msg_entries(expand) 124 local msg = test_messages_proto3.TestAllTypesProto3() 125 -- 8! = 40320 possible orderings makes it overwhelmingly likely that two 126 -- random orderings will be different. 127 for i=1,8 do 128 local submsg = test_messages_proto3.TestAllTypesProto3.NestedMessage() 129 submsg.corecursive = msg_with_int32_entries(i, expand) 130 msg.map_string_nested_message[tostring(i)] = submsg 131 end 132 133 expand = false 134 if expand then 135 for i=21,2000 do 136 local submsg = test_messages_proto3.TestAllTypesProto3.NestedMessage() 137 submsg.corecursive = msg_with_int32_entries(i, expand) 138 msg.map_string_nested_message[tostring(i)] = submsg 139 end 140 for i=21,2000 do 141 msg.map_string_nested_message[tostring(i)] = nil 142 end 143 end 144 return msg 145 end 146 147 -- Create two messages with the same contents but (hopefully) different 148 -- map table orderings. 149 local msg = msg_with_msg_entries(false) 150 local msg2 = msg_with_msg_entries(true) 151 152 local text1 = upb.text_encode(msg) 153 local text2 = upb.text_encode(msg2) 154 assert_equal(text1, text2) 155 156 local binary1 = upb.encode(msg, {upb.ENCODE_DETERMINISTIC}) 157 local binary2 = upb.encode(msg2, {upb.ENCODE_DETERMINISTIC}) 158 assert_equal(binary1, binary2) 159 160 -- Non-sorted map should compare different. 161 local text3 = upb.text_encode(msg, {upb.TXTENC_NOSORT}) 162 assert_not_equal(text1, text3) 163 164 local binary3 = upb.encode(msg) 165 assert_not_equal(binary1, binary3) 166end 167 168function test_utf8() 169 local proto2_msg = test_messages_proto2.TestAllTypesProto2() 170 proto2_msg.optional_string = "\xff" 171 local serialized = upb.encode(proto2_msg) 172 173 -- Decoding invalid UTF-8 succeeds in proto2. 174 upb.decode(test_messages_proto2.TestAllTypesProto2, serialized) 175 176 -- Decoding invalid UTF-8 fails in proto2. 177 assert_error_match("Error decoding protobuf", function() 178 upb.decode(test_messages_proto3.TestAllTypesProto3, serialized) 179 end) 180 181 -- TODO: should proto3 accessors also check UTF-8 at set time? 182end 183 184function test_string_double_map() 185 msg = upb_test.MapTest() 186 msg.map_string_double["one"] = 1.0 187 msg.map_string_double["two point five"] = 2.5 188 assert_equal(1, msg.map_string_double["one"]) 189 assert_equal(2.5, msg.map_string_double["two point five"]) 190 191 -- Test overwrite. 192 msg.map_string_double["one"] = 2 193 assert_equal(2, msg.map_string_double["one"]) 194 assert_equal(2.5, msg.map_string_double["two point five"]) 195 msg.map_string_double["one"] = 1.0 196 197 -- Test delete. 198 msg.map_string_double["one"] = nil 199 assert_nil(msg.map_string_double["one"]) 200 assert_equal(2.5, msg.map_string_double["two point five"]) 201 msg.map_string_double["one"] = 1 202 203 local serialized = upb.encode(msg) 204 assert_true(#serialized > 0) 205 local msg2 = upb.decode(upb_test.MapTest, serialized) 206 assert_equal(1, msg2.map_string_double["one"]) 207 assert_equal(2.5, msg2.map_string_double["two point five"]) 208end 209 210function test_string_double_map() 211 local function fill_msg(msg) 212 msg.i32_packed[1] = 100 213 msg.i32_packed[2] = 200 214 msg.i32_packed[3] = 50000 215 216 msg.i64_packed[1] = 101 217 msg.i64_packed[2] = 201 218 msg.i64_packed[3] = 50001 219 220 msg.f32_packed[1] = 102 221 msg.f32_packed[2] = 202 222 msg.f32_packed[3] = 50002 223 224 msg.f64_packed[1] = 103 225 msg.f64_packed[2] = 203 226 msg.f64_packed[3] = 50003 227 end 228 229 local function check_msg(msg) 230 assert_equal(100, msg.i32_packed[1]) 231 assert_equal(200, msg.i32_packed[2]) 232 assert_equal(50000, msg.i32_packed[3]) 233 assert_equal(3, #msg.i32_packed) 234 235 assert_equal(101, msg.i64_packed[1]) 236 assert_equal(201, msg.i64_packed[2]) 237 assert_equal(50001, msg.i64_packed[3]) 238 assert_equal(3, #msg.i64_packed) 239 240 assert_equal(102, msg.f32_packed[1]) 241 assert_equal(202, msg.f32_packed[2]) 242 assert_equal(50002, msg.f32_packed[3]) 243 assert_equal(3, #msg.f32_packed) 244 245 assert_equal(103, msg.f64_packed[1]) 246 assert_equal(203, msg.f64_packed[2]) 247 assert_equal(50003, msg.f64_packed[3]) 248 assert_equal(3, #msg.f64_packed) 249 end 250 251 local msg = upb_test.PackedTest() 252 fill_msg(msg) 253 check_msg(msg) 254 255 local serialized_packed = upb.encode(msg) 256 local msg2 = upb.decode(upb_test.PackedTest, serialized_packed) 257 local msg3 = upb.decode(upb_test.UnpackedTest, serialized_packed) 258 check_msg(msg2) 259 check_msg(msg3) 260 261 serialized_unpacked = upb.encode(msg3) 262 local msg4 = upb.decode(upb_test.PackedTest, serialized_unpacked) 263 local msg5 = upb.decode(upb_test.PackedTest, serialized_unpacked) 264 check_msg(msg4) 265 check_msg(msg5) 266 267end 268 269function test_msg_string_map() 270 msg = test_messages_proto3.TestAllTypesProto3() 271 msg.map_string_string["foo"] = "bar" 272 msg.map_string_string["baz"] = "quux" 273 assert_nil(msg.map_string_string["abc"]) 274 assert_equal("bar", msg.map_string_string["foo"]) 275 assert_equal("quux", msg.map_string_string["baz"]) 276 277 -- Test overwrite. 278 msg.map_string_string["foo"] = "123" 279 assert_equal("123", msg.map_string_string["foo"]) 280 assert_equal("quux", msg.map_string_string["baz"]) 281 msg.map_string_string["foo"] = "bar" 282 283 -- Test delete 284 msg.map_string_string["foo"] = nil 285 assert_nil(msg.map_string_string["foo"]) 286 assert_equal("quux", msg.map_string_string["baz"]) 287 msg.map_string_string["foo"] = "bar" 288 289 local serialized = upb.encode(msg) 290 assert_true(#serialized > 0) 291 local msg2 = upb.decode(test_messages_proto3.TestAllTypesProto3, serialized) 292 assert_equal("bar", msg2.map_string_string["foo"]) 293 assert_equal("quux", msg2.map_string_string["baz"]) 294end 295 296function test_msg_array() 297 msg = test_messages_proto3.TestAllTypesProto3() 298 299 assert_not_nil(msg.repeated_int32) 300 assert_equal(msg.repeated_int32, msg.repeated_int32) 301 assert_equal(0, #msg.repeated_int32) 302 303 msg.repeated_int32[1] = 2 304 assert_equal(1, #msg.repeated_int32); 305 assert_equal(2, msg.repeated_int32[1]); 306 307 -- Can't assign a scalar; array is expected. 308 assert_error_match("lupb.array expected", function() msg.repeated_int32 = 5 end) 309 310 -- Can't assign array of the wrong type. 311 local function assign_int64() 312 msg.repeated_int32 = upb.Array(upb.TYPE_INT64) 313 end 314 assert_error_match("array type mismatch", assign_int64) 315 316 local arr = upb.Array(upb.TYPE_INT32) 317 arr[1] = 6 318 assert_equal(1, #arr) 319 msg.repeated_int32 = arr 320 assert_equal(msg.repeated_int32, msg.repeated_int32) 321 assert_equal(arr, msg.repeated_int32) 322 assert_equal(1, #msg.repeated_int32) 323 assert_equal(6, msg.repeated_int32[1]) 324 325 -- Can't assign other Lua types. 326 assert_error_match("array expected", function() msg.repeated_int32 = "abc" end) 327 assert_error_match("array expected", function() msg.repeated_int32 = true end) 328 assert_error_match("array expected", function() msg.repeated_int32 = false end) 329 assert_error_match("array expected", function() msg.repeated_int32 = nil end) 330 assert_error_match("array expected", function() msg.repeated_int32 = {} end) 331 assert_error_match("array expected", function() msg.repeated_int32 = print end) 332end 333 334function test_array_append() 335 local arr = upb.Array(upb.TYPE_INT32) 336 for i=1,200000 do 337 arr[i] = i 338 end 339 for i=1,200000 do 340 assert_equal(i, arr[i]) 341 end 342end 343 344function test_msg_submsg() 345 --msg = test_messages_proto3.TestAllTypesProto3() 346 msg = test_messages_proto3['TestAllTypesProto3']() 347 348 assert_nil(msg.optional_nested_message) 349 350 -- Can't assign message of the wrong type. 351 local function assign_int64() 352 msg.optional_nested_message = test_messages_proto3.TestAllTypesProto3() 353 end 354 assert_error_match("message type mismatch", assign_int64) 355 356 local nested = test_messages_proto3['TestAllTypesProto3.NestedMessage']() 357 msg.optional_nested_message = nested 358 assert_equal(nested, msg.optional_nested_message) 359 360 -- Can't assign other Lua types. 361 assert_error_match("msg expected", function() msg.optional_nested_message = "abc" end) 362 assert_error_match("msg expected", function() msg.optional_nested_message = true end) 363 assert_error_match("msg expected", function() msg.optional_nested_message = false end) 364 assert_error_match("msg expected", function() msg.optional_nested_message = nil end) 365 assert_error_match("msg expected", function() msg.optional_nested_message = {} end) 366 assert_error_match("msg expected", function() msg.optional_nested_message = print end) 367end 368 369-- Lua 5.1 and 5.2 have slightly different semantics for how a finalizer 370-- can be defined in Lua. 371if _VERSION >= 'Lua 5.2' then 372 function defer(fn) 373 setmetatable({}, { __gc = fn }) 374 end 375else 376 function defer(fn) 377 getmetatable(newproxy(true)).__gc = fn 378 end 379end 380 381function test_finalizer() 382 -- Tests that we correctly handle a call into an already-finalized object. 383 -- Collectible objects are finalized in the opposite order of creation. 384 do 385 local t = {} 386 defer(function() 387 assert_error_match("called into dead object", function() 388 -- Generic def call. 389 t[1]:lookup_msg("abc") 390 end) 391 end) 392 t = { 393 upb.DefPool(), 394 } 395 end 396 collectgarbage() 397end 398 399-- in-range of 64-bit types but not exactly representable as double 400local bad64 = 2^68 - 1 401 402local numeric_types = { 403 [upb.TYPE_UINT32] = { 404 valid_val = 2^32 - 1, 405 too_big = 2^32, 406 too_small = -1, 407 other_bad = 5.1 408 }, 409 [upb.TYPE_UINT64] = { 410 valid_val = 2^63, 411 too_big = 2^64, 412 too_small = -1, 413 other_bad = bad64 414 }, 415 [upb.TYPE_INT32] = { 416 valid_val = 2^31 - 1, 417 too_big = 2^31, 418 too_small = -2^31 - 1, 419 other_bad = 5.1 420 }, 421 -- Enums don't exist at a language level in Lua, so we just represent enum 422 -- values as int32s. 423 [upb.TYPE_ENUM] = { 424 valid_val = 2^31 - 1, 425 too_big = 2^31, 426 too_small = -2^31 - 1, 427 other_bad = 5.1 428 }, 429 [upb.TYPE_INT64] = { 430 valid_val = 2^62, 431 too_big = 2^63, 432 too_small = -2^64, 433 other_bad = bad64 434 }, 435 [upb.TYPE_FLOAT] = { 436 valid_val = 340282306073709652508363335590014353408 437 }, 438 [upb.TYPE_DOUBLE] = { 439 valid_val = 10^101 440 }, 441} 442 443function test_utf8() 444 local invalid_utf8 = "\xff" 445 local proto2_msg = test_messages_proto2.TestAllTypesProto2{ 446 optional_string = invalid_utf8, 447 } 448 449 -- As proto2, invalid UTF-8 parses and serializes fine. 450 local serialized = upb.encode(proto2_msg) 451 local proto2_msg2 = upb.decode(test_messages_proto2.TestAllTypesProto2, serialized) 452 453 -- Decoding as proto3 fails. 454 assert_error(function() 455 upb.decode(test_messages_proto3.TestAllTypesProto3, serialized) 456 end) 457end 458 459function test_msg_primitives() 460 local msg = test_messages_proto3.TestAllTypesProto3{ 461 optional_int32 = 10, 462 optional_uint32 = 20, 463 optional_int64 = 30, 464 optional_uint64 = 40, 465 optional_double = 50, 466 optional_float = 60, 467 optional_sint32 = 70, 468 optional_sint64 = 80, 469 optional_fixed32 = 90, 470 optional_fixed64 = 100, 471 optional_sfixed32 = 110, 472 optional_sfixed64 = 120, 473 optional_bool = true, 474 optional_string = "abc", 475 optional_nested_message = test_messages_proto3['TestAllTypesProto3.NestedMessage']{a = 123}, 476 } 477 478 -- Attempts to access non-existent fields fail. 479 assert_error_match("no such field", function() msg.no_such = 1 end) 480 481 assert_equal(10, msg.optional_int32) 482 assert_equal(20, msg.optional_uint32) 483 assert_equal(30, msg.optional_int64) 484 assert_equal(40, msg.optional_uint64) 485 assert_equal(50, msg.optional_double) 486 assert_equal(60, msg.optional_float) 487 assert_equal(70, msg.optional_sint32) 488 assert_equal(80, msg.optional_sint64) 489 assert_equal(90, msg.optional_fixed32) 490 assert_equal(100, msg.optional_fixed64) 491 assert_equal(110, msg.optional_sfixed32) 492 assert_equal(120, msg.optional_sfixed64) 493 assert_equal(true, msg.optional_bool) 494 assert_equal("abc", msg.optional_string) 495 assert_equal(123, msg.optional_nested_message.a) 496end 497 498 499function test_string_array() 500 local function test_for_string_type(upb_type) 501 local array = upb.Array(upb_type) 502 assert_equal(0, #array) 503 504 -- 0 is never a valid index in Lua. 505 assert_error_match("array index", function() return array[0] end) 506 -- Past the end of the array. 507 assert_error_match("array index", function() return array[1] end) 508 509 array[1] = "foo" 510 assert_equal("foo", array[1]) 511 assert_equal(1, #array) 512 -- Past the end of the array. 513 assert_error_match("array index", function() return array[2] end) 514 515 local array2 = upb.Array(upb_type) 516 assert_equal(0, #array2) 517 518 array[2] = "bar" 519 assert_equal("foo", array[1]) 520 assert_equal("bar", array[2]) 521 assert_equal(2, #array) 522 -- Past the end of the array. 523 assert_error_match("array index", function() return array[3] end) 524 525 -- Can't assign other Lua types. 526 assert_error_match("Expected string", function() array[3] = 123 end) 527 assert_error_match("Expected string", function() array[3] = true end) 528 assert_error_match("Expected string", function() array[3] = false end) 529 assert_error_match("Expected string", function() array[3] = nil end) 530 assert_error_match("Expected string", function() array[3] = {} end) 531 assert_error_match("Expected string", function() array[3] = print end) 532 assert_error_match("Expected string", function() array[3] = array end) 533 end 534 535 test_for_string_type(upb.TYPE_STRING) 536 test_for_string_type(upb.TYPE_BYTES) 537end 538 539function test_numeric_array() 540 local function test_for_numeric_type(upb_type) 541 local array = upb.Array(upb_type) 542 local vals = numeric_types[upb_type] 543 assert_equal(0, #array) 544 545 -- 0 is never a valid index in Lua. 546 assert_error_match("array index", function() return array[0] end) 547 -- Past the end of the array. 548 assert_error_match("array index", function() return array[1] end) 549 550 array[1] = vals.valid_val 551 assert_equal(vals.valid_val, array[1]) 552 assert_equal(1, #array) 553 assert_equal(vals.valid_val, array[1]) 554 -- Past the end of the array. 555 assert_error_match("array index", function() return array[2] end) 556 557 array[2] = 10 558 assert_equal(vals.valid_val, array[1]) 559 assert_equal(10, array[2]) 560 assert_equal(2, #array) 561 -- Past the end of the array. 562 assert_error_match("array index", function() return array[3] end) 563 564 -- Values that are out of range. 565 local errmsg = "not an integer or out of range" 566 if vals.too_small then 567 assert_error_match(errmsg, function() array[3] = vals.too_small end) 568 end 569 if vals.too_big then 570 assert_error_match(errmsg, function() array[3] = vals.too_big end) 571 end 572 if vals.other_bad then 573 assert_error_match(errmsg, function() array[3] = vals.other_bad end) 574 end 575 576 -- Can't assign other Lua types. 577 errmsg = "bad argument #3" 578 assert_error_match(errmsg, function() array[3] = "abc" end) 579 assert_error_match(errmsg, function() array[3] = true end) 580 assert_error_match(errmsg, function() array[3] = false end) 581 assert_error_match(errmsg, function() array[3] = nil end) 582 assert_error_match(errmsg, function() array[3] = {} end) 583 assert_error_match(errmsg, function() array[3] = print end) 584 assert_error_match(errmsg, function() array[3] = array end) 585 end 586 587 for k in pairs(numeric_types) do 588 test_for_numeric_type(k) 589 end 590end 591 592function test_numeric_map() 593 local function test_for_numeric_types(key_type, val_type) 594 local map = upb.Map(key_type, val_type) 595 local key_vals = numeric_types[key_type] 596 local val_vals = numeric_types[val_type] 597 598 assert_equal(0, #map) 599 600 -- Unset keys return nil 601 assert_nil(map[key_vals.valid_val]) 602 603 map[key_vals.valid_val] = val_vals.valid_val 604 assert_equal(1, #map) 605 assert_equal(val_vals.valid_val, map[key_vals.valid_val]) 606 607 i = 0 608 for k, v in pairs(map) do 609 assert_equal(key_vals.valid_val, k) 610 assert_equal(val_vals.valid_val, v) 611 end 612 613 -- Out of range key/val 614 local errmsg = "not an integer or out of range" 615 if key_vals.too_small then 616 assert_error_match(errmsg, function() map[key_vals.too_small] = 1 end) 617 end 618 if key_vals.too_big then 619 assert_error_match(errmsg, function() map[key_vals.too_big] = 1 end) 620 end 621 if key_vals.other_bad then 622 assert_error_match(errmsg, function() map[key_vals.other_bad] = 1 end) 623 end 624 625 if val_vals.too_small then 626 assert_error_match(errmsg, function() map[1] = val_vals.too_small end) 627 end 628 if val_vals.too_big then 629 assert_error_match(errmsg, function() map[1] = val_vals.too_big end) 630 end 631 if val_vals.other_bad then 632 assert_error_match(errmsg, function() map[1] = val_vals.other_bad end) 633 end 634 end 635 636 for k in pairs(numeric_types) do 637 for v in pairs(numeric_types) do 638 test_for_numeric_types(k, v) 639 end 640 end 641end 642 643function test_unknown() 644 local bytes = string.rep("\x38\x00", 1000) 645 for i=1,1000 do 646 local msg = upb.decode(test_messages_proto3.TestAllTypesProto3, bytes) 647 end 648end 649 650function test_foo() 651 local defpool = upb.DefPool() 652 local filename = "external/com_google_protobuf/src/google/protobuf/descriptor_proto-descriptor-set.proto.bin" 653 local alternate_filename = "src/google/protobuf/descriptor_proto-descriptor-set.proto.bin" 654 local file = io.open(filename, "rb") or io.open("bazel-bin/" .. filename, "rb") or io.open(alternate_filename, "rb") 655 assert_not_nil(file) 656 local descriptor = file:read("*a") 657 assert_true(#descriptor > 0) 658 defpool:add_set(descriptor) 659 local FileDescriptorSet = defpool:lookup_msg("google.protobuf.FileDescriptorSet") 660 assert_not_nil(FileDescriptorSet) 661 set = FileDescriptorSet() 662 assert_equal(#set.file, 0) 663 assert_error_match("lupb.array expected", function () set.file = 1 end) 664 665 set = upb.decode(FileDescriptorSet, descriptor) 666 667 -- Test that we can at least call this without crashing. 668 set_textformat = tostring(set) 669 670 -- print(set_textformat) 671 assert_equal(#set.file, 1) 672 assert_equal(set.file[1].name, "google/protobuf/descriptor.proto") 673end 674 675function test_descriptor() 676 local defpool = upb.DefPool() 677 local file_proto = descriptor.FileDescriptorProto { 678 name = "test.proto", 679 message_type = upb.Array(descriptor.DescriptorProto, { 680 descriptor.DescriptorProto{ 681 name = "ABC", 682 }, 683 }) 684 } 685 local file = defpool:add_file(upb.encode(file_proto)) 686 assert_equal(file:defpool(), defpool) 687end 688 689function test_descriptor_error() 690 local defpool = upb.DefPool() 691 local file = descriptor.FileDescriptorProto() 692 file.name = "test.proto" 693 file.message_type[1] = descriptor.DescriptorProto{ 694 name = "ABC" 695 } 696 file.message_type[2] = descriptor.DescriptorProto{ 697 name = "BC." 698 } 699 assert_error(function () defpool:add_file(upb.encode(file)) end) 700 assert_nil(defpool:lookup_msg("ABC")) 701end 702 703function test_duplicate_enumval() 704 local defpool = upb.DefPool() 705 local file_proto = descriptor.FileDescriptorProto { 706 name = "test.proto", 707 message_type = upb.Array(descriptor.DescriptorProto, { 708 descriptor.DescriptorProto{ 709 name = "ABC", 710 }, 711 }), 712 enum_type = upb.Array(descriptor.EnumDescriptorProto, { 713 descriptor.EnumDescriptorProto{ 714 name = "MyEnum", 715 value = upb.Array(descriptor.EnumValueDescriptorProto, { 716 descriptor.EnumValueDescriptorProto{ 717 name = "ABC", 718 number = 1, 719 } 720 }), 721 }, 722 }) 723 } 724 assert_error(function () defpool:add_file(upb.encode(file_proto)) end) 725end 726 727function test_duplicate_filename_error() 728 local defpool = upb.DefPool() 729 local file = descriptor.FileDescriptorProto() 730 file.name = "test.proto" 731 defpool:add_file(upb.encode(file)) 732 -- Second add with the same filename fails. 733 assert_error(function () defpool:add_file(upb.encode(file)) end) 734end 735 736function test_encode_skipunknown() 737 -- Test that upb.ENCODE_SKIPUNKNOWN does not encode unknown fields. 738 local msg = test_messages_proto3.TestAllTypesProto3{ 739 optional_int32 = 10, 740 optional_uint32 = 20, 741 optional_int64 = 30, 742 } 743 -- SKIPUNKNOWN here tests that it does *not* affect regular fields. 744 local serialized = upb.encode(msg, {upb.ENCODE_SKIPUNKNOWN}) 745 assert_true(#serialized > 0) 746 local empty_with_unknown = upb.decode(empty.Empty, serialized) 747 assert_true(#upb.encode(empty_with_unknown) > 0) 748 -- Verify that unknown fields are not serialized. 749 assert_true(#upb.encode(empty_with_unknown, {upb.ENCODE_SKIPUNKNOWN}) == 0) 750end 751 752function test_json_emit_defaults() 753 local msg = test_messages_proto3.TestAllTypesProto3() 754 local json = upb.json_encode(msg, {upb.JSONENC_EMITDEFAULTS}) 755end 756 757function test_json_locale() 758 local msg = test_messages_proto3.TestAllTypesProto3() 759 msg.optional_double = 1.1 760 local original_locale = os.setlocale(nil) 761 os.setlocale("C") 762 local json = upb.json_encode(msg) 763 os.setlocale("de_DE.utf8") 764 assert_equal(json, upb.json_encode(msg)) 765 os.setlocale(original_locale) -- Restore. 766end 767 768function test_encode_depth_limit() 769 local msg = test_messages_proto3.TestAllTypesProto3() 770 msg.recursive_message = msg 771 assert_error(function() upb.encode(msg) end) 772end 773 774function test_large_field_number() 775 local msg = upb_test.TestLargeFieldNumber() 776 msg.i32 = 5 777 local serialized = upb.encode(msg) 778 local msg2 = upb.decode(upb_test.TestLargeFieldNumber, serialized) 779 assert_equal(msg.i32, msg2.i32) 780end 781 782function test_timestamp_minutes() 783 local msg = upb.json_decode(upb_test.TestTimestamp, '{"ts": "2000-01-01T00:00:00-06:59"}') 784 assert_equal(msg.ts.seconds, 946684800 + ((6 * 60) + 59) * 60) 785end 786 787function test_gc() 788 local top = test_messages_proto3.TestAllTypesProto3() 789 local n = 100 790 local m 791 792 for i=1,n do 793 local inner = test_messages_proto3.TestAllTypesProto3() 794 m = inner 795 for j=1,n do 796 local tmp = m 797 m = test_messages_proto3.TestAllTypesProto3() 798 -- This will cause the arenas to fuse. But we stop referring to the child, 799 -- so the Lua object is eligible for collection (and therefore its original 800 -- arena can be collected too). Only the fusing will keep the C mem alivd. 801 m.recursive_message = tmp 802 803 end 804 top.recursive_message = m 805 end 806 807 collectgarbage() 808 809 for i=1,n do 810 -- Verify we can touch all the messages again and without accessing freed 811 -- memory. 812 m = m.recursive_message 813 assert_not_nil(m) 814 end 815end 816 817function test_b9440() 818 local m = upb_test.HelloRequest() 819 m.id = 8 820 assert_equal(8, m.id) 821 m.version = "1" 822 assert_equal(8, m.id) 823end 824 825local stats = lunit.main() 826 827if stats.failed > 0 or stats.errors > 0 then 828 error("One or more errors in test suite") 829end 830