Logo Search packages:      
Sourcecode: pan version File versions  Download package

test-thread.c

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <glib.h>

#include <pan/base/article.h>
#include <pan/base/article-thread.h>
#include <pan/base/base-prefs.h>
#include <pan/base/gnksa.h>
#include <pan/base/pan-glib-extensions.h>


static void
init_pan (void)
{
      base_prefs_init (g_get_tmp_dir(), 100, FALSE, FALSE);
}

extern int server_saving_enabled;

static int
pan_g_ptr_array_find (GPtrArray * a, gpointer data)
{
      int i;
      int retval = -1;

      for (i=0; retval==-1 && i<a->len; ++i)
            if (g_ptr_array_index (a, i) == data)
                  retval = i;

      return retval;
}

static void
add_articles_to_ptr_array (Article ** articles, guint article_qty, gpointer ptr_array)
{
      pan_g_ptr_array_append ((GPtrArray*)ptr_array, (gpointer*)articles, article_qty);
}


#define check(A) \
      ++test; \
      if (A) \
            g_message ("PASS: article_thread test %d", test); \
      else { \
            g_message ("FAIL: article_thread test %d, file %s, line %d", test, __FILE__, __LINE__); \
            return test;  \
      }

static int
test_thread (Server * server, Group * group)
{
      int i;
      int test = 0;
      int qty = 0;
      char * pch;
      static gulong number = 0;
      Article * a;
      Article * articles[128];
      GPtrArray * articles_ptr_array = NULL;
      PString pstr;

      /**
      ***  A simple multipart
      **/

      a = articles[qty++] = article_new (group);
      a->number = ++number;
      a->part = 1;
      a->parts = 4;
      pstr = pstring_shallow ("<pan.2001.01.01.12.59.59@sea.org>", -1);
      article_set_message_id (a, &pstr);
      pstr = pstring_shallow ("Some multipart part 0123.par (01/04)", -1);
      article_set_subject (a, &pstr);
      pstr = pstring_shallow ("Meg White <meg@whitestripes.com>", -1);
      article_set_author (a, &pstr);

      a = articles[qty++] = article_new (group);
      a->part = 2;
      a->parts = 4;
      a->number = ++number;
      pstr = pstring_shallow ("<pan.2001.01.01.13.00.01@sea.org>", -1);
      article_set_message_id (a, &pstr);
      pstr = pstring_shallow ("Some multipart part 0123.par (02/04)", -1);
      article_set_subject (a, &pstr);
      pstr = pstring_shallow ("Meg White <meg@whitestripes.com>", -1);
      article_set_author (a, &pstr);

      a = articles[qty++] = article_new (group);
      a->part = 3;
      a->parts = 4;
      a->number = ++number;
      pstr = pstring_shallow ("<pan.2001.01.01.13.00.02@sea.org>", -1);
      article_set_message_id (a, &pstr);
      pstr = pstring_shallow ("Some multipart part 0123.par (03/04)", -1);
      article_set_subject (a, &pstr);
      pstr = pstring_shallow ("Meg White <meg@whitestripes.com>", -1);
      article_set_author (a, &pstr);

      a = articles[qty++] = article_new (group);
      a->part = 4;
      a->parts = 4;
      a->number = ++number;
      pstr = pstring_shallow ("<pan.2001.01.01.13.00.03@sea.org>", -1);
      article_set_message_id (a, &pstr);
      pstr = pstring_shallow ("Some multipart part 0123.par (04/04)", -1);
      article_set_subject (a, &pstr);
      pstr = pstring_shallow ("Meg White <meg@whitestripes.com>", -1);
      article_set_author (a, &pstr);

      thread_articles (articles, qty);

      /* check the multipart threading */
      check (articles[0]->parent == NULL)
      check (g_slist_length (articles[0]->threads) == 3)
      check (g_slist_index (articles[0]->threads, articles[1]) == 0)
      check (g_slist_index (articles[0]->threads, articles[2]) == 1)
      check (g_slist_index (articles[0]->threads, articles[3]) == 2)
      check (articles[1]->parent == articles[0])
      check (articles[1]->threads == NULL)
      check (articles[2]->parent == articles[0])
      check (articles[2]->threads == NULL)
      check (articles[3]->parent == articles[0])
      check (articles[3]->threads == NULL)
      check (article_get_multipart_state (articles[0]) == MULTIPART_STATE_ALL)
      check (article_get_multipart_state (articles[1]) == MULTIPART_STATE_ALL)
      check (article_get_multipart_state (articles[2]) == MULTIPART_STATE_ALL)
      check (article_get_multipart_state (articles[3]) == MULTIPART_STATE_ALL)

      /**
      ***  Now, what if someone posts something similar but in
      ***  larger chunks, so the part totals are different?
      **/

      a = articles[0];
      a->part = 1;
      a->parts = 512;
      pstr = pstring_shallow ("<pan.2001.01.01.12.59.59@sea.org>", -1);
      article_set_message_id (a, &pstr);
      pstr = pstring_shallow ("Some multipart part 0123.par (01/512)", -1);
      article_set_subject (a, &pstr);
      pstr = pstring_shallow ("Meg White <meg@whitestripes.com>", -1);
      article_set_author (a, &pstr);

      thread_articles (articles, qty);

      /* check the multipart threading */
      check (articles[0]->parent == NULL)
      check (articles[0]->threads == NULL)
      check (articles[1]->parent == NULL)
      check (g_slist_length (articles[1]->threads) == 2)
      check (g_slist_index (articles[1]->threads, articles[2]) == 0)
      check (g_slist_index (articles[1]->threads, articles[3]) == 1)
      check (articles[2]->parent == articles[1])
      check (articles[2]->threads == NULL)
      check (articles[3]->parent == articles[1])
      check (articles[3]->threads == NULL)
      check (article_get_multipart_state (articles[0]) == MULTIPART_STATE_SOME)
      check (article_get_multipart_state (articles[1]) == MULTIPART_STATE_SOME)
      check (article_get_multipart_state (articles[2]) == MULTIPART_STATE_SOME)
      check (article_get_multipart_state (articles[3]) == MULTIPART_STATE_SOME)

      /**
      ***  Thread by reference
      **/

      qty = 0;

      a = articles[qty++] = article_new (group);
      a->number = ++number;
      a->date = 100;
      pstr = pstring_shallow ("Hello", -1);
      article_set_subject (a, &pstr);
      pstr = pstring_shallow ("<pan.2001.01.01.12.59.59@sea.org>", -1);
      article_set_message_id (a, &pstr);
      pstr = pstring_shallow ("Meg White <meg@whitestripes.com>", -1);
      article_set_author (a, &pstr);

      a = articles[qty++] = article_new (group);
      a->number = ++number;
      a->date = 200;
      pstr = pstring_shallow ("Re: Hello", -1);
      article_set_subject (a, &pstr);
      pstr = pstring_shallow ("<pan.2001.01.01.13.00.01@sea.org>", -1);
      article_set_message_id (a, &pstr);
      pstr = pstring_shallow ("<pan.2001.01.01.12.59.59@sea.org>", -1);
      article_set_references (a, &pstr);
      pstr = pstring_shallow ("Bob White <bob@whitestripes.com>", -1);
      article_set_author (a, &pstr);

      a = articles[qty++] = article_new (group);
      a->number = ++number;
      a->date = 300;
      pstr = pstring_shallow ("Re: Hello", -1);
      article_set_subject (a, &pstr);
      pstr = pstring_shallow ("<pan.2001.01.01.13.00.02@sea.org>", -1);
      article_set_message_id (a, &pstr);
      pstr = pstring_shallow ("<pan.2001.01.01.12.59.59@sea.org> <pan.2001.01.01.13.00.01@sea.org>", -1);
      article_set_references (a, &pstr);
      pstr = pstring_shallow ("Meg White <meg@whitestripes.com>", -1);
      article_set_author (a, &pstr);

      a = articles[qty++] = article_new (group);
      a->number = ++number;
      a->date = 310;
      pstr = pstring_shallow ("Re: Hello", -1);
      article_set_subject (a, &pstr);
      pstr = pstring_shallow ("<pan.2001.01.01.13.00.03@sea.org>", -1);
      article_set_message_id (a, &pstr);
      pstr = pstring_shallow ("<pan.2001.01.01.12.59.59@sea.org> <pan.2001.01.01.13.00.01@sea.org>", -1);
      article_set_references (a, &pstr);
      pstr = pstring_shallow ("Al White <al@whitestripes.com>", -1);
      article_set_author (a, &pstr);

      thread_articles (articles, qty);

      /* check references threading */
      check (articles[0]->parent == NULL)
      check (g_slist_length (articles[0]->threads) == 1)
      check (g_slist_index (articles[0]->threads, articles[1]) == 0)
      check (articles[1]->parent == articles[0])
      check (g_slist_length (articles[1]->threads) == 2)
      check (g_slist_index (articles[1]->threads, articles[2]) == 0)
      check (g_slist_index (articles[1]->threads, articles[3]) == 1)
      check (articles[2]->parent == articles[1])
      check (articles[2]->threads == NULL)
      check (articles[3]->parent == articles[1])
      check (articles[3]->threads == NULL)
      check (article_get_multipart_state (articles[0]) == MULTIPART_STATE_NONE)
      check (article_get_multipart_state (articles[1]) == MULTIPART_STATE_NONE)
      check (article_get_multipart_state (articles[2]) == MULTIPART_STATE_NONE)
      check (article_get_multipart_state (articles[3]) == MULTIPART_STATE_NONE)

      /* now, what if the fourth article were posted before the third? */
      {
            const time_t swap = articles[3]->date;
            articles[3]->date = articles[2]->date;
            articles[2]->date = swap;
      }

      thread_articles (articles, qty);

      /* check references threading */
      check (articles[0]->parent == NULL)
      check (g_slist_length (articles[0]->threads) == 1)
      check (g_slist_index (articles[0]->threads, articles[1]) == 0)
      check (articles[1]->parent == articles[0])
      check (g_slist_length (articles[1]->threads) == 2)
      check (g_slist_index (articles[1]->threads, articles[2]) == 1) /* changed the order */
      check (g_slist_index (articles[1]->threads, articles[3]) == 0)
      check (articles[2]->parent == articles[1])
      check (articles[2]->threads == NULL)
      check (articles[3]->parent == articles[1])
      check (articles[3]->threads == NULL)

      /**
      ***  article_get_root
      ***  article_forall_in_thread
      ***  article_forall_in_subthread
      ***  article_forall_in_references
      **/

      check (article_get_root(articles[0]) == articles[0])
      check (article_get_root(articles[1]) == articles[0])
      check (article_get_root(articles[2]) == articles[0])
      check (article_get_root(articles[3]) == articles[0])
      check (article_get_root(NULL) == NULL)

      article_forall_in_thread (NULL, add_articles_to_ptr_array, NULL);

      articles_ptr_array = g_ptr_array_new ();

      for (i=0; i<4; ++i) {
            g_ptr_array_set_size (articles_ptr_array, 0);
            article_forall_in_thread (articles[0], add_articles_to_ptr_array, articles_ptr_array);
            check (articles_ptr_array->len == 4)
            check (pan_g_ptr_array_find (articles_ptr_array, articles[0]) != -1)
            check (pan_g_ptr_array_find (articles_ptr_array, articles[1]) != -1)
            check (pan_g_ptr_array_find (articles_ptr_array, articles[2]) != -1)
            check (pan_g_ptr_array_find (articles_ptr_array, articles[3]) != -1)
      }

      g_ptr_array_set_size (articles_ptr_array, 0);
      article_forall_in_subthread (articles[1], add_articles_to_ptr_array, articles_ptr_array);
      check (articles_ptr_array->len == 3)
      check (pan_g_ptr_array_find (articles_ptr_array, articles[1]) != -1)
      check (pan_g_ptr_array_find (articles_ptr_array, articles[2]) != -1)
      check (pan_g_ptr_array_find (articles_ptr_array, articles[3]) != -1)

      g_ptr_array_set_size (articles_ptr_array, 0);
      article_forall_in_references (articles[2], add_articles_to_ptr_array, articles_ptr_array);
      check (articles_ptr_array->len == 3)
      check (pan_g_ptr_array_find (articles_ptr_array, articles[0]) != -1)
      check (pan_g_ptr_array_find (articles_ptr_array, articles[1]) != -1)
      check (pan_g_ptr_array_find (articles_ptr_array, articles[2]) != -1)

      g_ptr_array_set_size (articles_ptr_array, 0);
      article_forall_in_references (articles[3], add_articles_to_ptr_array, articles_ptr_array);
      check (articles_ptr_array->len == 3)
      check (pan_g_ptr_array_find (articles_ptr_array, articles[0]) != -1)
      check (pan_g_ptr_array_find (articles_ptr_array, articles[1]) != -1)
      check (pan_g_ptr_array_find (articles_ptr_array, articles[3]) != -1)

      g_ptr_array_set_size (articles_ptr_array, 0);
      article_forall_in_references (articles[1], add_articles_to_ptr_array, articles_ptr_array);
      check (articles_ptr_array->len == 2)
      check (pan_g_ptr_array_find (articles_ptr_array, articles[0]) != -1)
      check (pan_g_ptr_array_find (articles_ptr_array, articles[1]) != -1)

      g_ptr_array_set_size (articles_ptr_array, 0);
      article_forall_in_references (articles[0], add_articles_to_ptr_array, articles_ptr_array);
      check (articles_ptr_array->len == 1)
      check (pan_g_ptr_array_find (articles_ptr_array, articles[0]) != -1)

      g_ptr_array_set_size (articles_ptr_array, 0);
      article_forall_in_references (NULL, add_articles_to_ptr_array, articles_ptr_array);
      article_forall_in_references (NULL, NULL, NULL);
      check (articles_ptr_array->len == 0)


      /* now, what if one of the middle articles has expired? */
      --qty;
      g_memmove (articles+1, articles+2, sizeof(Article*)*2);
      thread_articles (articles, qty);

      /* check references threading */
      check (articles[0]->parent == NULL)
      check (g_slist_length (articles[0]->threads) == 2)
      check (g_slist_index (articles[0]->threads, articles[1]) == 1) /* remember, we swapped the time_t fields */
      check (g_slist_index (articles[0]->threads, articles[2]) == 0)
      check (articles[1]->parent == articles[0])
      check (articles[1]->threads == NULL)
      check (articles[2]->parent == articles[0])
      check (articles[3]->threads == NULL)
      check (article_get_multipart_state (articles[0]) == MULTIPART_STATE_NONE)
      check (article_get_multipart_state (articles[1]) == MULTIPART_STATE_NONE)
      check (article_get_multipart_state (articles[2]) == MULTIPART_STATE_NONE)

      /**
      ***  Regression test for bugzilla #82751:
      ***
      ***  This one is best described by example. After downloading from
      ***  alt.binaries.movies.shadowrealm the article pane shows eg
      ***  
      ***  [green bitmap] |-some text (1of2).part01.P01 (1/45)              222361
      ***  [red bitmap  ] |-some text (2of2).part01.P01 (1/45)                5002
      ***  
      ***  That's wrong, because all 90 articles are available on the server, as I
      ***  found out with another reader. As a hint : 0.11.92 displayed the same group
      ***  on the same server as
      ***  
      ***  [green bitmap] |-some text (1of2).part01.P01 (1/45) (89)         222361
      ***  [red bitmap  ] |-some text (2of2).part01.P01 (1/45)                5002
      **/

      qty = 0;

      pch = gnksa_generate_message_id ("rebelbase.com");
      a = articles[qty++] = article_new (group);
      a->part = 1;
      a->parts = 3;
      a->number = ++number;
      pstr = pstring_shallow ("some text (1of2).part01.P01 (1/3)", -1);
      article_set_subject (a, &pstr);
      pstr = pstring_shallow (pch, -1);
      article_set_message_id (a, &pstr);
      pstr = pstring_shallow ("Meg White <meg@whitestripes.com>", -1);
      article_set_author (a, &pstr);
      g_free (pch);

      pch = gnksa_generate_message_id ("rebelbase.com");
      a = articles[qty++] = article_new (group);
      a->part = 2;
      a->parts = 3;
      a->number = ++number;
      pstr = pstring_shallow ("some text (1of2).part01.P01 (2/3)", -1);
      article_set_subject (a, &pstr);
      pstr = pstring_shallow (pch, -1);
      article_set_message_id (a, &pstr);
      pstr = pstring_shallow ("Bob White <bob@whitestripes.com>", -1);
      article_set_author (a, &pstr);
      g_free (pch);

      pch = gnksa_generate_message_id ("rebelbase.com");
      a = articles[qty++] = article_new (group);
      a->part = 3;
      a->parts = 3;
      a->number = ++number;
      pstr = pstring_shallow ("some text (1of2).part01.P01 (3/3)", -1);
      article_set_subject (a, &pstr);
      pstr = pstring_shallow (pch, -1);
      article_set_message_id (a, &pstr);
      pstr = pstring_shallow ("Meg White <meg@whitestripes.com>", -1);
      article_set_author (a, &pstr);
      g_free (pch);

      pch = gnksa_generate_message_id ("rebelbase.com");
      a = articles[qty++] = article_new (group);
      a->part = 1;
      a->parts = 3;
      a->number = ++number;
      pstr = pstring_shallow ("some text (2of2).part01.P01 (1/3)", -1);
      article_set_subject (a, &pstr);
      pstr = pstring_shallow (pch, -1);
      article_set_message_id (a, &pstr);
      pstr = pstring_shallow ("Meg White <meg@whitestripes.com>", -1);
      article_set_author (a, &pstr);
      g_free (pch);

      pch = gnksa_generate_message_id ("rebelbase.com");
      a = articles[qty++] = article_new (group);
      a->part = 2;
      a->parts = 3;
      a->number = ++number;
      pstr = pstring_shallow ("some text (2of2).part01.P01 (2/3)", -1);
      article_set_subject (a, &pstr);
      pstr = pstring_shallow (pch, -1);
      article_set_message_id (a, &pstr);
      pstr = pstring_shallow ("Bob White <bob@whitestripes.com>", -1);
      article_set_author (a, &pstr);
      g_free (pch);

      pch = gnksa_generate_message_id ("rebelbase.com");
      a = articles[qty++] = article_new (group);
      a->part = 3;
      a->parts = 3;
      a->number = ++number;
      pstr = pstring_shallow ("some text (2of2).part01.P01 (3/3)", -1);
      article_set_subject (a, &pstr);
      pstr = pstring_shallow (pch, -1);
      article_set_message_id (a, &pstr);
      pstr = pstring_shallow ("Meg White <meg@whitestripes.com>", -1);
      article_set_author (a, &pstr);
      g_free (pch);

      thread_articles (articles, qty);

      check (articles[0]->parent == NULL)
      check (g_slist_length(articles[0]->threads) == 2);
      check (g_slist_index(articles[0]->threads, articles[1]) == 0);
      check (g_slist_index(articles[0]->threads, articles[2]) == 1);
      check (articles[1]->parent == articles[0])
      check (articles[1]->threads == NULL)
      check (articles[2]->parent == articles[0])
      check (articles[2]->threads == NULL)

      check (articles[3]->parent == NULL)
      check (g_slist_length(articles[3]->threads) == 2);
      check (g_slist_index(articles[3]->threads, articles[4]) == 0);
      check (g_slist_index(articles[3]->threads, articles[5]) == 1);
      check (articles[4]->parent == articles[3])
      check (articles[4]->threads == NULL)
      check (articles[5]->parent == articles[3])
      check (articles[5]->threads == NULL)

      check (article_get_multipart_state (articles[0]) == MULTIPART_STATE_ALL)
      check (article_get_multipart_state (articles[1]) == MULTIPART_STATE_ALL)
      check (article_get_multipart_state (articles[3]) == MULTIPART_STATE_ALL)
      check (article_get_multipart_state (articles[4]) == MULTIPART_STATE_ALL)
      check (article_get_multipart_state (articles[5]) == MULTIPART_STATE_ALL)

      return 0;
}


int
main (void)
{
      int val;
      Server * server;
      Group * group;

      /* setup Pan base */
      g_thread_init (NULL);
      init_pan ();
      server_saving_enabled = FALSE;

      /* setup server & groups */
      server = server_new ();
      pstring_set (&server->name, "dummy_server", -1);
      group = group_new (server, "dummy_group");
      group_set_is_folder (group, TRUE);

      /* run the tests */
      if ((val = test_thread (server, group)))
            return val;

      g_message ("All thread tests passed");
      return 0;
}

Generated by  Doxygen 1.6.0   Back to index