Exemple #1
0
int test_main(int, char **)
{
	{
		ion::metadata_t metadata_ = ion::empty_metadata();
		TEST_ASSERT(ion::is_valid(metadata_), "");
		TEST_VALUE(ion::get_metadata_string(metadata_), "{}\n");
	}

	{
		ion::metadata_optional_t metadata_ = ion::parse_metadata("}{");
		TEST_ASSERT(!metadata_, "");
	}

	{
		ion::metadata_optional_t metadata_ = ion::parse_metadata("5");
		TEST_ASSERT(!metadata_, "");
	}

	{
		ion::metadata_optional_t metadata_ = ion::parse_metadata("");
		TEST_ASSERT(metadata_, "");
		TEST_ASSERT(ion::is_valid(*metadata_), "");
		TEST_VALUE(ion::get_metadata_string(*metadata_), "{}\n");
	}

	{
		ion::metadata_optional_t metadata_ = ion::parse_metadata("{\"a\" : 5}");
		TEST_ASSERT(metadata_, "");
		TEST_ASSERT(ion::is_valid(*metadata_), "");
		TEST_VALUE(ion::get_metadata_value(*metadata_, "a", 0), 5);
		TEST_VALUE(ion::get_metadata_value(*metadata_, "b", 121), 121);
	}

	return 0;
}
Exemple #2
0
Commodity Database::parseCommodity(std::string str)
{
  TEST_VALUE(PORK);
  TEST_VALUE(GOLD);
  TEST_VALUE(RICE);
  TEST_VALUE(SILV);
  TEST_VALUE(OIL);
  return UNKNOWN_COMMODITY;
}
Exemple #3
0
Dealer Database::parseDealer(std::string str)
{
  TEST_VALUE(BARX);
  TEST_VALUE(BOFA);
  TEST_VALUE(CITI);
  TEST_VALUE(DB);
  TEST_VALUE(HSBC);
  TEST_VALUE(JPM);
  TEST_VALUE(MS);
  TEST_VALUE(RBC);
  TEST_VALUE(RBS);
  TEST_VALUE(UBS);
  return UNKNOWN_DEALER;
}
Exemple #4
0
TEST basic_test_lrem(int _commit)
{
	int retval;
	unsigned char *key = UNSIGN("my key");
	long keylen = strlen((char *)key);
	unsigned char *value1 = UNSIGN("AA"), *value2 = UNSIGN("BB");
	long valuelen = 2, deleted;
	long size;
	unsigned char **values;
	long *valueslen;

	rlite *db = NULL;
	RL_CALL_VERBOSE(setup_db, RL_OK, &db, _commit, 1);

	long i, times = 100;

	for (i = 0; i < times; i++) {
		RL_CALL_VERBOSE(rl_push, RL_OK, db, key, keylen, 1, 1, 1, &value2, &valuelen, NULL);
		RL_CALL_VERBOSE(rl_push, RL_OK, db, key, keylen, 1, 1, 1, &value1, &valuelen, NULL);
		RL_BALANCED();
	}

	RL_CALL_VERBOSE(rl_lrem, RL_OK, db, key, keylen, 1, 2, value2, valuelen, &deleted);
	RL_BALANCED();

	EXPECT_LONG(deleted, 2);

#define TEST_VALUE(index, value)\
	{\
		unsigned char *testvalue;\
		long testvaluelen;\
		RL_CALL_VERBOSE(rl_lindex, RL_OK, db, key, keylen, index, &testvalue, &testvaluelen);\
		if (testvaluelen != (long)strlen((char *)value) || memcmp(testvalue, value, testvaluelen) != 0) {\
			FAIL();\
		}\
		rl_free(testvalue);\
	}

	TEST_VALUE(0, value1);
	TEST_VALUE(1, value1);
	TEST_VALUE(2, value1);
	TEST_VALUE(3, value2);
	TEST_VALUE(4, value1);

	RL_CALL_VERBOSE(rl_lrem, RL_OK, db, key, keylen, -1, 200, value1, valuelen, &deleted);
	RL_BALANCED();

	EXPECT_LONG(deleted, 100);

	RL_CALL_VERBOSE(rl_lrange, RL_OK, db, key, keylen, 0, -1, &size, &values, &valueslen);
	for (i = 0; i < size; i++) {
		EXPECT_STR("BB", values[i], valueslen[i]);
		rl_free(values[i]);
	}
	rl_free(values);
	rl_free(valueslen);

	RL_CALL_VERBOSE(rl_lrem, RL_DELETED, db, key, keylen, 1, 0, value2, valuelen, &deleted);
	EXPECT_LONG(deleted, 98);
	RL_BALANCED();

	RL_CALL_VERBOSE(rl_lrange, RL_NOT_FOUND, db, key, keylen, 0, -1, &size, &values, &valueslen);

	rl_close(db);
	PASS();
}
Exemple #5
0
int test_main(int, char **)
{
	typedef ion::playlists < ion::flat_playlist > playlists_t;
	typedef ion::filter_playlist < playlists_t > filter_playlist_t;

	ion::flat_playlist::unique_ids_t unique_ids_;

	ion::flat_playlist *playlist1 = new ion::flat_playlist(unique_ids_);
	playlist1->add_entry(ion::flat_playlist::entry_t(ion::uri("foo://bar11"), *ion::parse_metadata("{ \"title\" : \"hello 441\" }"), false), false);
	playlist1->add_entry(ion::flat_playlist::entry_t(ion::uri("foo://bar12"), *ion::parse_metadata("{ \"title\" : \"abc def\" }"), false), false);
	playlist1->add_entry(ion::flat_playlist::entry_t(ion::uri("foo://bar13"), *ion::parse_metadata("{ \"title\" : \"lorem ipsum\" }"), false), false);
	playlist1->add_entry(ion::flat_playlist::entry_t(ion::uri("foo://bar14"), *ion::parse_metadata("{ \"title\" : \"max mustermann\" }"), false), false);

	ion::flat_playlist *playlist2 = new ion::flat_playlist(unique_ids_);
	playlist2->add_entry(ion::flat_playlist::entry_t(ion::uri("foo://bar21"), *ion::parse_metadata("{ \"title\" : \"ugauga\" }"), false), false);
	playlist2->add_entry(ion::flat_playlist::entry_t(ion::uri("foo://bar22"), *ion::parse_metadata("{ \"title\" : \"john smith\" }"), false), false);
	playlist2->add_entry(ion::flat_playlist::entry_t(ion::uri("foo://bar23"), *ion::parse_metadata("{ \"title\" : \"test c55\" }"), false), false);
	playlist2->add_entry(ion::flat_playlist::entry_t(ion::uri("foo://bar24"), *ion::parse_metadata("{ \"title\" : \"xxycz\" }"), false), false);

	playlists_t playlists;
	playlists.add_playlist(playlists_t::playlist_ptr_t(playlist1));
	playlists.add_playlist(playlists_t::playlist_ptr_t(playlist2));

	filter_playlist_t filter_playlist(playlists, boost::phoenix::bind(&match, boost::phoenix::arg_names::arg1));


	TEST_VALUE(ion::get_num_entries(filter_playlist), 3);
	TEST_VALUE(boost::fusion::at_c < 0 > (*ion::get_entry(filter_playlist, 0)).get_path(), "bar12");
	TEST_VALUE(boost::fusion::at_c < 0 > (*ion::get_entry(filter_playlist, 1)).get_path(), "bar23");
	TEST_VALUE(boost::fusion::at_c < 0 > (*ion::get_entry(filter_playlist, 2)).get_path(), "bar24");

	{
		// testing uri-based retrieval and incompatibility marking
		// since the playlist adds an id option to the URI, it is retrieved from one of the entries instead of created manually
		ion::uri test_uri = boost::fusion::at_c < 0 > (*ion::get_entry(filter_playlist, 1));
		TEST_ASSERT(ion::get_metadata_for(filter_playlist, test_uri), "");

		ion::mark_backend_resource_incompatibility(filter_playlist, test_uri, "test_backend");
		TEST_VALUE(boost::fusion::at_c < 2 > (*ion::get_entry(filter_playlist, 1)), true);
	}

	// The following code tests the signal relay in filter_playlist
	// Internally, if one of the playlists that have URIs in the filter playlist proxy entry list get altered,
	// the filter playlist is notified, and changes its proxy entry list accordingly.

	playlist1->add_entry(ion::flat_playlist::entry_t(ion::uri("foo://extra"), *ion::parse_metadata("{ \"title\" : \"ccccc\" }"), false), true);
	TEST_VALUE(ion::get_num_entries(filter_playlist), 4);
	TEST_VALUE(boost::fusion::at_c < 0 > (*ion::get_entry(filter_playlist, 0)).get_path(), "bar12");
	TEST_VALUE(boost::fusion::at_c < 0 > (*ion::get_entry(filter_playlist, 1)).get_path(), "extra");
	TEST_VALUE(boost::fusion::at_c < 0 > (*ion::get_entry(filter_playlist, 2)).get_path(), "bar23");
	TEST_VALUE(boost::fusion::at_c < 0 > (*ion::get_entry(filter_playlist, 3)).get_path(), "bar24");

	playlist2->remove_entry(*ion::get_entry(filter_playlist, 2), true);
	//print_playlist(filter_playlist);
	TEST_VALUE(ion::get_num_entries(filter_playlist), 3);
	TEST_VALUE(boost::fusion::at_c < 0 > (*ion::get_entry(filter_playlist, 0)).get_path(), "bar12");
	TEST_VALUE(boost::fusion::at_c < 0 > (*ion::get_entry(filter_playlist, 1)).get_path(), "extra");
	TEST_VALUE(boost::fusion::at_c < 0 > (*ion::get_entry(filter_playlist, 2)).get_path(), "bar24");

	playlists.remove_playlist(*playlist1);
	TEST_VALUE(ion::get_num_entries(filter_playlist), 1);
	TEST_VALUE(boost::fusion::at_c < 0 > (*ion::get_entry(filter_playlist, 0)).get_path(), "bar24");


	{
		// The following code tests correct signal disconnection

		playlists_t playlists_;

		ion::flat_playlist *playlist1 = new ion::flat_playlist(unique_ids_);
		filter_playlist_t *filter_playlist_ = new filter_playlist_t(playlists_, boost::phoenix::bind(&match, boost::phoenix::arg_names::arg1));
		playlists_.add_playlist(playlists_t::playlist_ptr_t(playlist1));
		delete filter_playlist_;
		playlist1->add_entry(ion::flat_playlist::entry_t(ion::uri("foo://abc"), *ion::parse_metadata("{ \"title\" : \"ccccc\" }"), false), true);
	}


	return 0;
}
Exemple #6
0
/* It's hard to explain "the rules" for bucket_merge, in large part because
 * any automatic conflict-resolution scheme is going to be incorrect for
 * some endcases of *some* app.  The scheme here is pretty conservative,
 * and should be OK for most apps.  It's easier to explain what the code
 * allows than what it forbids:
 *
 * Leaving things alone:  it's OK if both s2 and s3 leave a piece of s1
 * alone (don't delete the key, and don't change the value).
 *
 * Key deletion:  a transaction (s2 or s3) can delete a key (from s1), but
 * only if the other transaction (of s2 and s3) doesn't delete the same key.
 * However, it's not OK for s2 and s3 to, between them, end up deleting all
 * the keys.  This is a higher-level constraint, due to that the caller of
 * bucket_merge() doesn't have enough info to unlink the resulting empty
 * bucket from its BTree correctly.  It's also not OK if s2 or s3 are empty,
 * because the transaction that emptied the bucket unlinked the bucket from
 * the tree, and nothing we do here can get it linked back in again.
 *
 * Key insertion:  s2 or s3 can add a new key, provided the other transaction
 * doesn't insert the same key.  It's not OK even if they insert the same
 * <key, value> pair.
 *
 * Mapping value modification:  s2 or s3 can modify the value associated
 * with a key in s1, provided the other transaction doesn't make a
 * modification of the same key to a different value.  It's OK if s2 and s3
 * both give the same new value to the key while it's hard to be precise about
 * why, this doesn't seem consistent with that it's *not* OK for both to add
 * a new key mapping to the same value).
 */
static PyObject *
bucket_merge(Bucket *s1, Bucket *s2, Bucket *s3)
{
  Bucket *r=0;
  PyObject *s;
  SetIteration i1 = {0,0,0}, i2 = {0,0,0}, i3 = {0,0,0};
  int cmp12, cmp13, cmp23, mapping, set;

  /* If either "after" bucket is empty, punt. */
  if (s2->len == 0 || s3->len == 0)
    {
      merge_error(-1, -1, -1, 12);
      goto err;
    }

  if (initSetIteration(&i1, OBJECT(s1), 1) < 0)
      goto err;
  if (initSetIteration(&i2, OBJECT(s2), 1) < 0)
      goto err;
  if (initSetIteration(&i3, OBJECT(s3), 1) < 0)
      goto err;

  mapping = i1.usesValue | i2.usesValue | i3.usesValue;
  set = !mapping;

  if (mapping)
      r = (Bucket *)PyObject_CallObject((PyObject *)&BucketType, NULL);
  else
      r = (Bucket *)PyObject_CallObject((PyObject *)&SetType, NULL);
  if (r == NULL)
      goto err;

  if (i1.next(&i1) < 0)
      goto err;
  if (i2.next(&i2) < 0)
      goto err;
  if (i3.next(&i3) < 0)
      goto err;

  /* Consult zodb/btrees/interfaces.py for the meaning of the last
   * argument passed to merge_error().
   */
  /* TODO:  This isn't passing on errors raised by value comparisons. */
  while (i1.position >= 0 && i2.position >= 0 && i3.position >= 0)
    {
      TEST_KEY_SET_OR(cmp12, i1.key, i2.key) goto err;
      TEST_KEY_SET_OR(cmp13, i1.key, i3.key) goto err;
      if (cmp12==0)
        {
          if (cmp13==0)
            {
              if (set || (TEST_VALUE(i1.value, i2.value) == 0))
                {               /* change in i3 value or all same */
                  if (merge_output(r, &i3, mapping) < 0) goto err;
                }
              else if (set || (TEST_VALUE(i1.value, i3.value) == 0))
                {               /* change in i2 value */
                  if (merge_output(r, &i2, mapping) < 0) goto err;
                }
              else
                {               /* conflicting value changes in i2 and i3 */
                  merge_error(i1.position, i2.position, i3.position, 1);
                  goto err;
                }
              if (i1.next(&i1) < 0) goto err;
              if (i2.next(&i2) < 0) goto err;
              if (i3.next(&i3) < 0) goto err;
            }
          else if (cmp13 > 0)
            {                   /* insert i3 */
              if (merge_output(r, &i3, mapping) < 0) goto err;
              if (i3.next(&i3) < 0) goto err;
            }
          else if (set || (TEST_VALUE(i1.value, i2.value) == 0))
            {                   /* deleted in i3 */
              if (i3.position == 1)
                {
                  /* Deleted the first item.  This will modify the
                     parent node, so we don't know if merging will be
                     safe
                  */
                  merge_error(i1.position, i2.position, i3.position, 13);
                  goto err;
                }
              if (i1.next(&i1) < 0) goto err;
              if (i2.next(&i2) < 0) goto err;
            }
          else
            {                   /* conflicting del in i3 and change in i2 */
              merge_error(i1.position, i2.position, i3.position, 2);
              goto err;
            }
        }
      else if (cmp13 == 0)
        {
          if (cmp12 > 0)
            {                   /* insert i2 */
              if (merge_output(r, &i2, mapping) < 0) goto err;
              if (i2.next(&i2) < 0) goto err;
            }
          else if (set || (TEST_VALUE(i1.value, i3.value) == 0))
            {                   /* deleted in i2 */
              if (i2.position == 1)
                {
                  /* Deleted the first item.  This will modify the
                     parent node, so we don't know if merging will be
                     safe
                  */
                  merge_error(i1.position, i2.position, i3.position, 13);
                  goto err;
                }
              if (i1.next(&i1) < 0) goto err;
              if (i3.next(&i3) < 0) goto err;
            }
          else
            {                   /* conflicting del in i2 and change in i3 */
              merge_error(i1.position, i2.position, i3.position, 3);
              goto err;
            }
        }
      else
        {                       /* Both keys changed */
          TEST_KEY_SET_OR(cmp23, i2.key, i3.key) goto err;
          if (cmp23==0)
            {                   /* dueling inserts or deletes */
              merge_error(i1.position, i2.position, i3.position, 4);
              goto err;
            }
          if (cmp12 > 0)
            {                   /* insert i2 */
              if (cmp23 > 0)
                {               /* insert i3 first */
                  if (merge_output(r, &i3, mapping) < 0) goto err;
                  if (i3.next(&i3) < 0) goto err;
                }
              else
                {               /* insert i2 first */
                  if (merge_output(r, &i2, mapping) < 0) goto err;
                  if (i2.next(&i2) < 0) goto err;
                }
            }
          else if (cmp13 > 0)
            {                   /* Insert i3 */
              if (merge_output(r, &i3, mapping) < 0) goto err;
              if (i3.next(&i3) < 0) goto err;
            }
          else
            {                   /* 1<2 and 1<3:  both deleted 1.key */
	      merge_error(i1.position, i2.position, i3.position, 5);
              goto err;
            }
        }
    }

  while (i2.position >= 0 && i3.position >= 0)
    {                           /* New inserts */
      TEST_KEY_SET_OR(cmp23, i2.key, i3.key) goto err;
      if (cmp23==0)
        {                       /* dueling inserts */
          merge_error(i1.position, i2.position, i3.position, 6);
          goto err;
        }
      if (cmp23 > 0)
        {                       /* insert i3 */
          if (merge_output(r, &i3, mapping) < 0) goto err;
          if (i3.next(&i3) < 0) goto err;
        }
      else
        {                       /* insert i2 */
          if (merge_output(r, &i2, mapping) < 0) goto err;
          if (i2.next(&i2) < 0) goto err;
        }
    }

  while (i1.position >= 0 && i2.position >= 0)
    {                           /* remainder of i1 deleted in i3 */
      TEST_KEY_SET_OR(cmp12, i1.key, i2.key) goto err;
      if (cmp12 > 0)
        {                       /* insert i2 */
          if (merge_output(r, &i2, mapping) < 0) goto err;
          if (i2.next(&i2) < 0) goto err;
        }
      else if (cmp12==0 && (set || (TEST_VALUE(i1.value, i2.value) == 0)))
        {                       /* delete i3 */
          if (i1.next(&i1) < 0) goto err;
          if (i2.next(&i2) < 0) goto err;
        }
      else
        {                       /* Dueling deletes or delete and change */
          merge_error(i1.position, i2.position, i3.position, 7);
          goto err;
        }
    }

  while (i1.position >= 0 && i3.position >= 0)
    {                           /* remainder of i1 deleted in i2 */
      TEST_KEY_SET_OR(cmp13, i1.key, i3.key) goto err;
      if (cmp13 > 0)
        {                       /* insert i3 */
          if (merge_output(r, &i3, mapping) < 0) goto err;
          if (i3.next(&i3) < 0) goto err;
        }
      else if (cmp13==0 && (set || (TEST_VALUE(i1.value, i3.value) == 0)))
        {                       /* delete i2 */
          if (i1.next(&i1) < 0) goto err;
          if (i3.next(&i3) < 0) goto err;
        }
      else
        {                       /* Dueling deletes or delete and change */
          merge_error(i1.position, i2.position, i3.position, 8);
          goto err;
        }
    }

  if (i1.position >= 0)
    {                           /* Dueling deletes */
      merge_error(i1.position, i2.position, i3.position, 9);
      goto err;
    }

  while (i2.position >= 0)
    {                           /* Inserting i2 at end */
      if (merge_output(r, &i2, mapping) < 0) goto err;
      if (i2.next(&i2) < 0) goto err;
    }

  while (i3.position >= 0)
    {                           /* Inserting i3 at end */
      if (merge_output(r, &i3, mapping) < 0) goto err;
      if (i3.next(&i3) < 0) goto err;
    }

  /* If the output bucket is empty, conflict resolution doesn't have
   * enough info to unlink it from its containing BTree correctly.
   */
  if (r->len == 0)
    {
      merge_error(-1, -1, -1, 10);
      goto err;
    }

  finiSetIteration(&i1);
  finiSetIteration(&i2);
  finiSetIteration(&i3);

  if (s1->next)
    {
      Py_INCREF(s1->next);
      r->next = s1->next;
    }
  s = bucket_getstate(r);
  Py_DECREF(r);

  return s;

 err:
  finiSetIteration(&i1);
  finiSetIteration(&i2);
  finiSetIteration(&i3);
  Py_XDECREF(r);
  return NULL;
}