Esempio n. 1
0
File: test_def.c Progetto: atdt/upb
static void test_oneofs() {
  upb_status s = UPB_STATUS_INIT;
  bool ok = true;
  upb_def *subm_defs[1];
  upb_symtab *symtab = upb_symtab_new(&symtab);
  upb_msgdef *subm = upb_msgdef_newnamed("SubMessage", &symtab);
  upb_msgdef *m = upb_msgdef_newnamed("TestMessage", &symtab);
  upb_oneofdef *o = upb_oneofdef_new(&o);
  const upb_oneofdef *lookup_o;
  const upb_fielddef *lookup_field;
  upb_def *defs[1];

  ASSERT(symtab != NULL);

  /* Create a test message for fields to refer to. */
  upb_msgdef_addfield(subm, newfield("field1", 1, UPB_TYPE_INT32,
                                     UPB_LABEL_OPTIONAL, NULL, &symtab),
                      &symtab, NULL);
  subm_defs[0] = upb_msgdef_upcast_mutable(subm);
  ASSERT_STATUS(upb_symtab_add(symtab, subm_defs, 1, &symtab, &s), &s);

  ASSERT(upb_msgdef_numoneofs(m) == 0);

  ASSERT(upb_oneofdef_numfields(o) == 0);
  ASSERT(upb_oneofdef_name(o) == NULL);

  ok = upb_oneofdef_setname(o, "test_oneof", &s);
  ASSERT_STATUS(ok, &s);

  ok = upb_oneofdef_addfield(o, newfield("field1", 1, UPB_TYPE_INT32,
                                         UPB_LABEL_OPTIONAL, NULL, &symtab),
                             &symtab, NULL);
  ASSERT_STATUS(ok, &s);
  ok = upb_oneofdef_addfield(o, newfield("field2", 2, UPB_TYPE_MESSAGE,
                                         UPB_LABEL_OPTIONAL, ".SubMessage",
                                         &symtab),
                             &symtab, NULL);
  ASSERT_STATUS(ok, &s);

  ok = upb_msgdef_addoneof(m, o, NULL, &s);
  ASSERT_STATUS(ok, &s);

  defs[0] = upb_msgdef_upcast_mutable(m);
  ASSERT_STATUS(upb_symtab_add(symtab, defs, 1, &symtab, &s), &s);

  ASSERT(upb_msgdef_numoneofs(m) == 1);
  lookup_o = upb_msgdef_ntooz(m, "test_oneof");
  ASSERT(lookup_o == o);

  lookup_field = upb_oneofdef_ntofz(o, "field1");
  ASSERT(lookup_field != NULL && upb_fielddef_number(lookup_field) == 1);

  upb_symtab_unref(symtab, &symtab);
  upb_oneofdef_unref(o, &o);
}
Esempio n. 2
0
File: test_def.c Progetto: atdt/upb
static void test_freeze_free() {
  bool ok;

  /* Test that freeze frees defs that were only being kept alive by virtue of
   * sharing a group with other defs that are being frozen. */
  upb_msgdef *m1 = upb_msgdef_newnamed("M1", &m1);
  upb_msgdef *m2 = upb_msgdef_newnamed("M2", &m2);
  upb_msgdef *m3 = upb_msgdef_newnamed("M3", &m3);
  upb_msgdef *m4 = upb_msgdef_newnamed("M4", &m4);
  upb_fielddef *f = upb_fielddef_new(&f);

  /* Freeze M4 and make M1 point to it. */
  upb_def_freeze((upb_def*const*)&m4, 1, NULL);

  upb_fielddef_settype(f, UPB_TYPE_MESSAGE);
  ASSERT(upb_fielddef_setnumber(f, 1, NULL));
  ASSERT(upb_fielddef_setname(f, "foo", NULL));
  ASSERT(upb_fielddef_setmsgsubdef(f, m4, NULL));

  ASSERT(upb_msgdef_addfield(m1, f, &f, NULL));

  /* After this unref, M1 is the only thing keeping M4 alive. */
  upb_msgdef_unref(m4, &m4);

  /* Force M1/M2/M3 into a single mutable refcounting group. */
  f = upb_fielddef_new(&f);
  upb_fielddef_settype(f, UPB_TYPE_MESSAGE);
  ASSERT(upb_fielddef_setnumber(f, 1, NULL));
  ASSERT(upb_fielddef_setname(f, "foo", NULL));

  ASSERT(upb_fielddef_setmsgsubdef(f, m1, NULL));
  ASSERT(upb_fielddef_setmsgsubdef(f, m2, NULL));
  ASSERT(upb_fielddef_setmsgsubdef(f, m3, NULL));

  /* Make M3 cyclic with itself. */
  ASSERT(upb_msgdef_addfield(m3, f, &f, NULL));

  /* These will be kept alive since they are in the same refcounting group as
   * M3, which still has a ref.  Note: this behavior is not guaranteed by the
   * API, but true in practice with its current implementation. */
  upb_msgdef_unref(m1, &m1);
  upb_msgdef_unref(m2, &m2);

  /* Test that they are still alive (NOT allowed by the API). */
  ok = strcmp("M1", upb_msgdef_fullname(m1)) == 0;
  ASSERT(ok);
  ok = strcmp("M2", upb_msgdef_fullname(m2)) == 0;
  ASSERT(ok);

  /* Freeze M3.  If the test leaked no memory, then freeing m1 and m2 was
   * successful. */
  ASSERT(upb_def_freeze((upb_def*const*)&m3, 1, NULL));

  upb_msgdef_unref(m3, &m3);
}
Esempio n. 3
0
File: test_def.c Progetto: atdt/upb
static void test_replacement() {
  upb_symtab *s = upb_symtab_new(&s);
  upb_enumdef *e2;
  upb_msgdef *m2;
  upb_enumdef *e;
  upb_status status = UPB_STATUS_INIT;
  upb_def *newdefs[3];
  upb_def *newdefs2[1];
  const upb_msgdef *m3;

  upb_msgdef *m = upb_msgdef_newnamed("MyMessage", &s);
  upb_msgdef_addfield(m, newfield("field1", 1, UPB_TYPE_ENUM,
                                  UPB_LABEL_OPTIONAL, ".MyEnum", &s),
                      &s, NULL);
  m2 = upb_msgdef_newnamed("MyMessage2", &s);
  e = upb_enumdef_newnamed("MyEnum", &s);
  ASSERT_STATUS(upb_enumdef_addval(e, "VAL1", 1, &status), &status);

  newdefs[0] = upb_msgdef_upcast_mutable(m);
  newdefs[1] = upb_msgdef_upcast_mutable(m2);
  newdefs[2] = upb_enumdef_upcast_mutable(e);
  ASSERT_STATUS(upb_symtab_add(s, newdefs, 3, &s, &status), &status);

  /* Try adding a new definition of MyEnum, MyMessage should get replaced with
   * a new version. */
  e2 = upb_enumdef_newnamed("MyEnum", &s);
  ASSERT_STATUS(upb_enumdef_addval(e2, "VAL1", 1, &status), &status);
  newdefs2[0] = upb_enumdef_upcast_mutable(e2);
  ASSERT_STATUS(upb_symtab_add(s, newdefs2, 1, &s, &status), &status);

  m3 = upb_symtab_lookupmsg(s, "MyMessage");
  ASSERT(m3);
  /* Must be different because it points to MyEnum which was replaced. */
  ASSERT(m3 != m);

  m3 = upb_symtab_lookupmsg(s, "MyMessage2");
  /* Should be the same because it was not replaced, nor were any defs that
   * are reachable from it. */
  ASSERT(m3 == m2);

  upb_symtab_unref(s, &s);
}
Esempio n. 4
0
static void test_cycles_in_replacement() {
  upb_symtab *s = upb_symtab_new(&s);
  upb_msgdef *m = upb_msgdef_newnamed("M", &s);
  upb_status status = UPB_STATUS_INIT;

  upb_msgdef_addfield(m, newfield("m", 1, UPB_TYPE_MESSAGE,
                                  UPB_LABEL_OPTIONAL, ".M", &s),
                      &s, NULL);
  ASSERT_STATUS(upb_symtab_add(s, (upb_def**)&m, 1, &s, &status), &status);
  ASSERT_STATUS(upb_symtab_add(s, NULL, 0, &s, &status), &status);
}
Esempio n. 5
0
File: test_def.c Progetto: atdt/upb
static void test_partial_freeze() {
  /* Test that freeze of only part of the graph correctly adjusts objects that
   * point to the newly-frozen objects. */
  upb_msgdef *m1 = upb_msgdef_newnamed("M1", &m1);
  upb_msgdef *m2 = upb_msgdef_newnamed("M2", &m2);
  upb_msgdef *m3 = upb_msgdef_newnamed("M3", &m3);
  upb_fielddef *f1 = upb_fielddef_new(&f1);
  upb_fielddef *f2 = upb_fielddef_new(&f2);
  upb_def *defs[2];
  defs[0] = upb_msgdef_upcast_mutable(m1);
  defs[1] = upb_msgdef_upcast_mutable(m2);

  upb_fielddef_settype(f1, UPB_TYPE_MESSAGE);
  ASSERT(upb_fielddef_setnumber(f1, 1, NULL));
  ASSERT(upb_fielddef_setname(f1, "f1", NULL));
  ASSERT(upb_fielddef_setmsgsubdef(f1, m1, NULL));

  upb_fielddef_settype(f2, UPB_TYPE_MESSAGE);
  ASSERT(upb_fielddef_setnumber(f2, 2, NULL));
  ASSERT(upb_fielddef_setname(f2, "f2", NULL));
  ASSERT(upb_fielddef_setmsgsubdef(f2, m2, NULL));

  ASSERT(upb_msgdef_addfield(m3, f1, &f1, NULL));
  ASSERT(upb_msgdef_addfield(m3, f2, &f2, NULL));

  /* Freeze M1 and M2, which should cause the group to be split
   * and m3 (left mutable) to take references on m1 and m2. */
  ASSERT(upb_def_freeze(defs, 2, NULL));

  ASSERT(upb_msgdef_isfrozen(m1));
  ASSERT(upb_msgdef_isfrozen(m2));
  ASSERT(!upb_msgdef_isfrozen(m3));

  upb_msgdef_unref(m1, &m1);
  upb_msgdef_unref(m2, &m2);
  upb_msgdef_unref(m3, &m3);
}