int TrackerUnitTest()

in layer0/Tracker.cpp [935:1505]


int TrackerUnitTest(PyMOLGlobals * G)
{
  int result = true;
  int cand_id[N_ID], list_id[N_ID], iter_id[N_ID], iter_start[N_ID];
  int a;
  int tmp_int;

  OVRandom *ov_rand = OVRandom_NewBySeed(G->Context->heap, 12345678);
  CTracker *I = TrackerNew(G);

  for(a = 0; a < N_ID; a++) {
    iter_id[a] = 0;
  }
  /* first test simple new/del */

  for(a = 0; a < N_ID; a++) {
    cand_id[a] = TrackerNewCand(I, NULL);
    if(!cand_id[a])
      fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d==0\n", __LINE__,
              cand_id[a]);
  }

  for(a = 0; a < N_ID; a++) {
    list_id[a] = TrackerNewList(I, NULL);
    if(!list_id[a])
      fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d==0\n", __LINE__,
              list_id[a]);
  }

  for(a = 0; a < N_ID; a++) {
    if(cand_id[a]) {
      if(TrackerDelCand(I, cand_id[a]))
        cand_id[a] = 0;
      else
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d\n", __LINE__);
    }
    if(list_id[a]) {
      if(TrackerDelList(I, list_id[a]))
        list_id[a] = 0;
      else
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d\n", __LINE__);
    }
  }

  if((tmp_int = TrackerGetNList(I))) {
    fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d!=0\n", __LINE__, tmp_int);
  }

  if((tmp_int = TrackerGetNCand(I))) {
    fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d!=0\n", __LINE__, tmp_int);
  }

  for(a = 0; a < N_ID; a++) {
    cand_id[a] = TrackerNewCand(I, NULL);
    list_id[a] = TrackerNewList(I, NULL);
  }

  /* test simple serial linking and unlinking */

  {

    for(a = 0; a < N_ID; a++) {
      if(!TrackerLink(I, cand_id[a], list_id[a], 1)) {
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; a=%d \n", __LINE__, a);
      }
      if(!TrackerUnlink(I, cand_id[a], list_id[a])) {
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; a=%d\n", __LINE__, a);
      }
    }

    for(a = 0; a < N_ID; a++) {
      if(!TrackerLink(I, cand_id[a], list_id[a], 1)) {
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; a=%d\n", __LINE__, a);
      }
    }

    if(N_ID != TrackerGetNLink(I)) {
      fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d!=%d\n", __LINE__, N_ID,
              TrackerGetNLink(I));
    }

    for(a = 0; a < N_ID; a++) {
      if(!TrackerUnlink(I, cand_id[a], list_id[a])) {
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; a=%d\n", __LINE__, a);
      }
    }
  }

  /* next test random linking and unlinking, followed by systematic unlinking */

  {
    int n_link = 0;
    int list_idx, cand_idx;
    int b;

    for(a = 0; a < (N_ID * N_ID); a++) {
      cand_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));
      list_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));

      if(TrackerLink(I, cand_id[cand_idx], list_id[list_idx], 0))
        n_link++;
    }

    if(n_link != TrackerGetNLink(I)) {
      fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d!=%d\n", __LINE__, n_link,
              TrackerGetNLink(I));
    }

    for(a = 0; a < (N_ID * N_ID); a++) {
      cand_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));
      list_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));

      if(TrackerUnlink(I, cand_id[cand_idx], list_id[list_idx]))
        n_link--;
    }

    if(n_link != TrackerGetNLink(I)) {
      fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d!=%d\n", __LINE__, n_link,
              TrackerGetNLink(I));
    }

    for(a = 0; a < N_ID; a++) {
      for(b = 0; b < N_ID; b++) {
        if(TrackerUnlink(I, cand_id[a], list_id[b]))
          n_link--;
      }
    }
    if(n_link != TrackerGetNLink(I)) {
      fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d!=%d\n", __LINE__, n_link,
              TrackerGetNLink(I));
    }
    if(n_link != 0) {
      fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; 0!=%d\n", __LINE__, n_link);
    }
  }

  /* next test random linking and list deletion */

  {
    int n_link = 0;
    int list_idx, cand_idx;

    for(a = 0; a < (N_ID * N_ID); a++) {
      cand_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));
      list_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));

      if(TrackerLink(I, cand_id[cand_idx], list_id[list_idx], 0))
        n_link++;
    }

    if(n_link != TrackerGetNLink(I)) {
      fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d!=%d\n", __LINE__, n_link,
              TrackerGetNLink(I));
    }
  }

  for(a = 0; a < N_ID; a++) {
    if(cand_id[a]) {
      if(TrackerDelCand(I, cand_id[a]))
        cand_id[a] = 0;
      else
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d\n\n", __LINE__);
    }

    if(list_id[a]) {
      if(TrackerDelList(I, list_id[a]))
        list_id[a] = 0;
      else
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d\n\n", __LINE__);
    }
  }

  if(TrackerGetNLink(I)) {
    fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; 0!=%d\n", __LINE__,
            TrackerGetNLink(I));
  }

  /* make sure everyone was deleted */

  for(a = 0; a < N_ID; a++) {
    if(cand_id[a])
      fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d;  %d!=0\n", __LINE__,
              cand_id[a]);
    if(list_id[a])
      fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d;  %d!=0\n", __LINE__,
              list_id[a]);
  }

  /* next test random linking and unlinking and list deletion */

  {
    int n_link = 0;
    int list_idx, cand_idx;
    int b;

    for(a = 0; a < N_ID; a++) {

      for(b = 0; b < N_ID; b++) {
        cand_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));
        list_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));

        if(!cand_id[cand_idx]) {
          cand_id[cand_idx] = TrackerNewCand(I, NULL);
        }
        if(!list_id[list_idx]) {
          list_id[list_idx] = TrackerNewList(I, NULL);
        }

        if(cand_id[cand_idx] && list_id[list_idx]) {
          if(TrackerLink(I, cand_id[cand_idx], list_id[list_idx], 0))
            n_link++;
        }
      }

      cand_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));
      list_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));

      if(cand_id[cand_idx] && list_id[list_idx]) {
        if(TrackerUnlink(I, cand_id[cand_idx], list_id[list_idx]))
          n_link--;
      }

      cand_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));
      list_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));

      if(cand_id[cand_idx]) {
        int len = TrackerGetNListForCand(I, cand_id[cand_idx]);
        if(len >= 0) {
          if(TrackerDelCand(I, cand_id[cand_idx])) {
            cand_id[cand_idx] = 0;
            n_link -= len;
          } else
            fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d\n\n", __LINE__);
        }
      }

      if(list_id[list_idx]) {
        int len = TrackerGetNCandForList(I, list_id[list_idx]);
        if(len >= 0) {
          if(TrackerDelList(I, list_id[list_idx])) {
            list_id[list_idx] = 0;
            n_link -= len;
          } else
            fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d\n\n", __LINE__);
        }
      }

    }

    if(n_link != TrackerGetNLink(I)) {
      fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d!=%d\n", __LINE__, n_link,
              TrackerGetNLink(I));
    }
  }

  for(a = 0; a < N_ID; a++) {
    if(cand_id[a]) {
      if(TrackerDelCand(I, cand_id[a]))
        cand_id[a] = 0;
      else
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d\n\n", __LINE__);
    }
    if(list_id[a]) {
      if(TrackerDelList(I, list_id[a]))
        list_id[a] = 0;
      else
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d\n\n", __LINE__);
    }
  }

  if(TrackerGetNLink(I)) {
    fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; 0!=%d\n", __LINE__,
            TrackerGetNLink(I));
  }

  /* make sure everyone was deleted */

  for(a = 0; a < N_ID; a++) {
    if(cand_id[a])
      fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d;  %d!=0\n", __LINE__,
              cand_id[a]);
    if(list_id[a])
      fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d;  %d!=0\n", __LINE__,
              list_id[a]);
  }

  /* okay, now let's mix in some iterators... */

  for(a = 0; a < N_ID; a++) {
    cand_id[a] = TrackerNewCand(I, NULL);
    list_id[a] = TrackerNewList(I, NULL);
  }

  if(TrackerGetNCand(I) != N_ID) {
    fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d!=%d\n", __LINE__, N_ID,
            TrackerGetNCand(I));
  }

  if(TrackerGetNList(I) != N_ID) {
    fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d!=%d\n", __LINE__, N_ID,
            TrackerGetNList(I));
  }

  {
    int n_link = 0;
    int list_idx, cand_idx;

    for(a = 0; a < (N_ID * N_ID); a++) {
      cand_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));
      list_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));

      if(TrackerLink(I, cand_id[cand_idx], list_id[list_idx], 0))
        n_link++;
    }

    if(n_link != TrackerGetNLink(I)) {
      fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d!=%d\n", __LINE__, n_link,
              TrackerGetNLink(I));
    }
  }

  /* do iters iterate over the expected number of members? */

  {
    int len;
    int list_idx, cand_idx;

    for(a = 0; a < N_ID; a++) {
      cand_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));
      if(!(iter_id[a] = TrackerNewIter(I, cand_id[cand_idx], 0))) {
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; 0==%d\n",
                __LINE__, iter_id[a]);
      }

      len = 0;
      while(TrackerIterNextListInCand(I, iter_id[a], NULL))
        len++;

      if(len != TrackerGetNListForCand(I, cand_id[cand_idx]))
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d!=%d\n",
                __LINE__, len, TrackerGetNListForCand(I, cand_id[cand_idx]));

      if(TrackerDelIter(I, iter_id[a])) {
        iter_id[a] = 0;
      } else {
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; \n", __LINE__);
      }
    }

    for(a = 0; a < N_ID; a++) {
      list_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));
      if(!(iter_id[a] = TrackerNewIter(I, list_id[list_idx], 0))) {
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; 0==%d\n",
                __LINE__, iter_id[a]);
      }

      len = 0;
      while(TrackerIterNextCandInList(I, iter_id[a], NULL))
        len++;

      if(len != TrackerGetNCandForList(I, list_id[list_idx]))
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d!=%d\n",
                __LINE__, len, TrackerGetNCandForList(I, list_id[list_idx]));

      if(TrackerDelIter(I, iter_id[a])) {
        iter_id[a] = 0;
      } else {
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; \n", __LINE__);
      }
    }
  }
  /* are iterators robust to member deletion? */

  {
    int list_idx, cand_idx;
    int b;

    for(a = 0; a < N_ID; a++) {
      cand_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));
      if(!(iter_id[a] = TrackerNewIter(I, cand_id[cand_idx], 0))) {
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; 0==%d\n",
                __LINE__, iter_id[a]);
      }
    }

    {
      int cnt = 0;
      const int expected_cnt = 5341;    /* THIS TEST IS FRAGILE -- result depends on 
                                           N_ID, random seem, tests that have been run above and
                                           of course, the iterator recovery behavior */

      for(a = 0; a < N_ID; a++) {
        cand_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));
        list_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));

        if(cand_id[cand_idx]) {
          if(TrackerDelCand(I, cand_id[cand_idx]))
            cand_id[cand_idx] = 0;
          else
            fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d\n\n", __LINE__);
        }

        if(list_id[list_idx]) {
          if(TrackerDelList(I, list_id[list_idx]))
            list_id[list_idx] = 0;
          else
            fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d\n\n", __LINE__);
        }

        for(b = 0; b < N_ID; b++) {
          if(TrackerIterNextListInCand(I, iter_id[b], NULL))
            cnt++;
        }
      }

      if(cnt != expected_cnt) {
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d!=%d\n",
                __LINE__, expected_cnt, cnt);
      }
    }
  }

  if(TrackerGetNIter(I) != N_ID) {
    fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d!=%d\n", __LINE__, N_ID,
            TrackerGetNIter(I));
  }

  /* delete iters */

  for(a = 0; a < N_ID; a++) {
    if(iter_id[a]) {
      if(TrackerDelIter(I, iter_id[a])) {
        iter_id[a] = 0;
      } else {
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; \n", __LINE__);
      }
    }
  }

  /* recreate cand, lists, links */

  for(a = 0; a < N_ID; a++) {
    if(!cand_id[a])
      cand_id[a] = TrackerNewCand(I, NULL);
    if(!list_id[a])
      list_id[a] = TrackerNewList(I, NULL);
  }

  {
    int n_link = 0;
    int list_idx, cand_idx;

    for(a = 0; a < (N_ID * N_ID); a++) {
      cand_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));
      list_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));

      if(TrackerLink(I, cand_id[cand_idx], list_id[list_idx], 0))
        n_link++;
    }

  }

  /* do iters iterate over the expected number of members? */

  {
    int len;
    int list_idx, cand_idx;
    int diff;

    for(a = 0; a < N_ID; a++) {
      cand_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));
      iter_start[a] = cand_id[cand_idx];
      if(!(iter_id[a] = TrackerNewIter(I, cand_id[cand_idx], 0))) {
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; 0==%d\n",
                __LINE__, iter_id[a]);
      }
      TrackerIterNextListInCand(I, iter_id[a], NULL);
    }

    for(a = 0; a < N_ID; a++) {
      list_idx = (int) (N_ID * OVRandom_Get_float64_exc1(ov_rand));
      if(list_id[list_idx]) {
        if(TrackerDelList(I, list_id[list_idx]))
          list_id[list_idx] = 0;
      }
    }

    for(a = 0; a < N_ID; a++) {
      len = 1;
      while(TrackerIterNextListInCand(I, iter_id[a], NULL))
        len++;

      diff = abs(len - TrackerGetNListForCand(I, iter_start[a]));
      /* shouldn't vary by more than 1 */

      if(diff > 1) {
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; %d>1\n", __LINE__, diff);
      }

      if(TrackerDelIter(I, iter_id[a])) {
        iter_id[a] = 0;
      } else {
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; \n", __LINE__);
      }
    }
  }

  /* delete everyone */

  for(a = 0; a < N_ID; a++) {
    if(cand_id[a]) {
      if(TrackerDelCand(I, cand_id[a]))
        cand_id[a] = 0;
      else
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d\n\n", __LINE__);
    }
    if(list_id[a]) {
      if(TrackerDelList(I, list_id[a]))
        list_id[a] = 0;
      else
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d\n\n", __LINE__);
    }
    if(iter_id[a]) {
      if(TrackerDelIter(I, iter_id[a])) {
        iter_id[a] = 0;
      } else {
        fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; \n", __LINE__);
      }
    }
  }

  if(TrackerGetNLink(I)) {
    fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; 0!=%d\n", __LINE__,
            TrackerGetNLink(I));
  }

  if(TrackerGetNCand(I)) {
    fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; 0!=%d\n", __LINE__,
            TrackerGetNLink(I));
  }

  if(TrackerGetNList(I)) {
    fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; 0!=%d\n", __LINE__,
            TrackerGetNList(I));
  }

  if(TrackerGetNIter(I)) {
    fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d; 0!=%d\n", __LINE__,
            TrackerGetNIter(I));
  }

  /* make sure everyone was deleted */

  for(a = 0; a < N_ID; a++) {
    if(cand_id[a])
      fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d;  %d!=0\n", __LINE__,
              cand_id[a]);
    if(list_id[a])
      fprintf(stderr, "TRACKER_UNIT_TEST FAILED AT LINE %d;  %d!=0\n", __LINE__,
              list_id[a]);
  }

  OVRandom_Del(ov_rand);
  TrackerFree(I);

  if(!result) {
    fprintf(stderr, "TRACKER_UNIT_TEST FAILED -- EXITING\n");
    exit(0);
  }
  return result;
}