summaryrefslogtreecommitdiff
path: root/tests/bindings
diff options
context:
space:
mode:
authorJosh Haberman <jhaberman@gmail.com>2014-09-01 02:23:56 -0700
committerJosh Haberman <jhaberman@gmail.com>2014-09-01 02:23:56 -0700
commit3461a5113e5b131dfa7514308559f7e0f025e5a5 (patch)
treedd84b240529cfbbed64e8c2cdc7939c3f6c80331 /tests/bindings
parent6ed916653f67b93eba27e6594c0ff1b526de8ad9 (diff)
Enable more Travis configurations.
Diffstat (limited to 'tests/bindings')
-rw-r--r--tests/bindings/googlepb/test_vs_proto2.cc159
1 files changed, 159 insertions, 0 deletions
diff --git a/tests/bindings/googlepb/test_vs_proto2.cc b/tests/bindings/googlepb/test_vs_proto2.cc
new file mode 100644
index 0000000..2d53f80
--- /dev/null
+++ b/tests/bindings/googlepb/test_vs_proto2.cc
@@ -0,0 +1,159 @@
+/*
+ * upb - a minimalist implementation of protocol buffers.
+ *
+ * Copyright (c) 2011-2012 Google Inc. See LICENSE for details.
+ *
+ * A test that verifies that our results are identical to proto2 for a
+ * given proto type and input protobuf.
+ */
+
+#define __STDC_LIMIT_MACROS // So we get UINT32_MAX
+#include <assert.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/wire_format_lite.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "benchmarks/google_messages.pb.h"
+#include "tests/upb_test.h"
+#include "upb/bindings/googlepb/bridge.h"
+#include "upb/def.h"
+#include "upb/handlers.h"
+#include "upb/pb/decoder.h"
+#include "upb/pb/glue.h"
+#include "upb/pb/varint.int.h"
+
+static const char message_data[] = {
+#include MESSAGE_DATA_HFILE
+};
+
+void compare_metadata(const google::protobuf::Descriptor* d,
+ const upb::MessageDef *upb_md) {
+ ASSERT(d->field_count() == upb_md->field_count());
+ for (upb::MessageDef::const_iterator i = upb_md->begin(); i != upb_md->end();
+ ++i) {
+ const upb::FieldDef* upb_f = *i;
+ const google::protobuf::FieldDescriptor *proto2_f =
+ d->FindFieldByNumber(upb_f->number());
+ ASSERT(upb_f);
+ ASSERT(proto2_f);
+ ASSERT(upb_f->number() == proto2_f->number());
+ ASSERT(std::string(upb_f->name()) == proto2_f->name());
+ ASSERT(upb_f->descriptor_type() ==
+ static_cast<upb::FieldDef::DescriptorType>(proto2_f->type()));
+ ASSERT(upb_f->IsSequence() == proto2_f->is_repeated());
+ }
+}
+
+void print_diff(const google::protobuf::Message& msg1,
+ const google::protobuf::Message& msg2) {
+ std::string text_str1;
+ std::string text_str2;
+ google::protobuf::TextFormat::PrintToString(msg1, &text_str1);
+ google::protobuf::TextFormat::PrintToString(msg2, &text_str2);
+ fprintf(stderr, "str1: %s, str2: %s\n", text_str1.c_str(), text_str2.c_str());
+}
+
+void parse_and_compare(google::protobuf::Message *msg1,
+ google::protobuf::Message *msg2,
+ const upb::Handlers *protomsg_handlers,
+ const char *str, size_t len, bool allow_jit) {
+ // Parse to both proto2 and upb.
+ ASSERT(msg1->ParseFromArray(str, len));
+
+ upb::pb::CodeCache cache;
+ ASSERT(cache.set_allow_jit(allow_jit));
+ upb::reffed_ptr<const upb::pb::DecoderMethod> decoder_method(
+ cache.GetDecoderMethod(upb::pb::DecoderMethodOptions(protomsg_handlers)));
+
+ upb::Status status;
+ upb::pb::Decoder decoder(decoder_method.get(), &status);
+ upb::Sink protomsg_sink(protomsg_handlers, msg2);
+
+ decoder.ResetOutput(&protomsg_sink);
+
+ msg2->Clear();
+ bool ok = upb::BufferSource::PutBuffer(str, len, decoder.input());
+ if (!ok) {
+ fprintf(stderr, "error parsing: %s\n", status.error_message());
+ print_diff(*msg1, *msg2);
+ }
+ ASSERT(ok);
+ ASSERT(status.ok());
+
+ // Would like to just compare the message objects themselves, but
+ // unfortunately MessageDifferencer is not part of the open-source release of
+ // proto2, so we compare their serialized strings, which we expect will be
+ // equivalent.
+ std::string str1;
+ std::string str2;
+ msg1->SerializeToString(&str1);
+ msg2->SerializeToString(&str2);
+ if (str1 != str2) {
+ print_diff(*msg1, *msg2);
+ }
+ ASSERT(str1 == str2);
+ ASSERT(std::string(str, len) == str2);
+}
+
+void test_zig_zag() {
+ for (uint64_t num = 5; num * 1.5 < UINT64_MAX; num *= 1.5) {
+ ASSERT(upb_zzenc_64(num) ==
+ google::protobuf::internal::WireFormatLite::ZigZagEncode64(num));
+ if (num < UINT32_MAX) {
+ ASSERT(upb_zzenc_32(num) ==
+ google::protobuf::internal::WireFormatLite::ZigZagEncode32(num));
+ }
+ }
+
+}
+
+extern "C" {
+
+int run_tests(int argc, char *argv[]) {
+ UPB_UNUSED(argc);
+ UPB_UNUSED(argv);
+ size_t len = sizeof(message_data);
+ const char *str = message_data;
+
+ MESSAGE_CIDENT msg1;
+ MESSAGE_CIDENT msg2;
+
+ upb::reffed_ptr<const upb::Handlers> h(
+ upb::googlepb::WriteHandlers::New(msg1));
+
+ compare_metadata(msg1.GetDescriptor(), h->message_def());
+
+ // Run twice to test proper object reuse.
+ parse_and_compare(&msg1, &msg2, h.get(), str, len, false);
+ parse_and_compare(&msg1, &msg2, h.get(), str, len, true);
+ parse_and_compare(&msg1, &msg2, h.get(), str, len, false);
+ parse_and_compare(&msg1, &msg2, h.get(), str, len, true);
+
+ // Test with DynamicMessage.
+ google::protobuf::DynamicMessageFactory* factory =
+ new google::protobuf::DynamicMessageFactory;
+ const google::protobuf::Message* prototype =
+ factory->GetPrototype(msg1.descriptor());
+ google::protobuf::Message* dyn_msg1 = prototype->New();
+ google::protobuf::Message* dyn_msg2 = prototype->New();
+ h = upb::googlepb::WriteHandlers::New(*dyn_msg1);
+ parse_and_compare(dyn_msg1, dyn_msg2, h.get(), str, len, false);
+ parse_and_compare(dyn_msg1, dyn_msg2, h.get(), str, len, true);
+ delete dyn_msg1;
+ delete dyn_msg2;
+ delete factory;
+
+ test_zig_zag();
+
+ printf("All tests passed, %d assertions.\n", num_assertions);
+
+ google::protobuf::ShutdownProtobufLibrary();
+ return 0;
+}
+
+}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback