You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@lucy.apache.org by Marvin Humphrey <ma...@rectangular.com> on 2011/05/13 02:02:08 UTC

[lucy-dev] STATUS file / TODO list

Greets,

I was hobnobbing with Joe Schaefer on IRC while he perused the Lucy code base
and he suggested that we adopt a convention used by the Apache HTTPD project:
keep a to-do list in a "STATUS" file at the top level of trunk, alongside
README and such.

  https://svn.apache.org/repos/asf/httpd/httpd/trunk/STATUS

Two other alternatives are to use JIRA milestones, or a wiki page.  My
preference, though, would be for the STATUS file, as I think it will be
easiest to manage and will yield the most the most coherent and easily
consumed presentation over time.

The HTTPD folks use CTR (commit-then-review) for adding to their STATUS file
on trunk, so any committer can add a TODO item.  It's RTC (review-then-commit)
for adding to STATUS on stable branches.  That makes sense to me as a policy.

I think we should expect a certain degree of courtesy from each other with
regards to the addition of potentially controversial action items.  My sense
is that we've been doing pretty well at building consensus via the dev list
before investing time working up patches; we don't to find ourselves working
out differences of opinion about project direction or priorities over multiple
commits to the STATUS file.  In that spirit, here's a seed list of items I
suspect no one will object to:

  * Port the Clownfish compiler to C.
  * Replace dependency on Parse::RecDescent within Clownfish::Parser with
    the Lemon parser generator.
  * Add Ruby and Python bindings.
  * Refactor away C89 idioms, since we have chosen the intersection of C99
    and C++ as our C dialect.
  * Port most test files within trunk/perl/t/ to C.
  * Replace dependency on JSON::XS with ??? (LUCY-133).

I should probably go open JIRA issues for those that don't have them to
explain at greater length and to track progress.

If this sounds like a good plan to people, I can go build an initial STATUS
file for Lucy using the HTTPD example as a template.

Marvin Humphrey


Re: [lucy-dev] C TAP test harnesses

Posted by Marvin Humphrey <ma...@rectangular.com>.
On Fri, May 13, 2011 at 11:17:44AM -0700, Marvin Humphrey wrote:
> On Thu, May 12, 2011 at 09:59:47PM -0700, Joe Schaefer wrote:
> > FWIW the features in the apreq stuff that are nice for me are
> > 
> > 1) macros provide access to __FILE__ and __LINE__ in the test source file,
> 
> It's definitely nice having access to __FILE__ and __LINE__.  The Charmonizer
> tests don't include them because we prioritized taking variadic arguments for
> the test label.  We couldn't keep that feature and include __FILE__ and
> __LINE__ implicitly without requiring variadic macro support from the
> compiler.
> 
> >From what I can tell, you made the opposite choice in the apreq harness -- you
> support __FILE__ and __LINE__, but you only accept simple string test labels. 
> 
> If we were to change the Lucy test harness to use __FILE__ and __LINE__
> implicitly, we would also have to modify some number of tests by creating
> pre-formatted test labels locally to pass into the TEST_XXXXX() routines.  
> A starter patch incorporating the necessary changes to TEST_TRUE() is below my
> sig.  (It does not include fixes for the 22 incompatible variadic invocations
> of TEST_TRUE().)

Another possibility is to integrate __FILE__ and __LINE__ while still
accepting variadic arguments to our test macros.  This is a less invasive
approach, since none of the client code has to change.  A diff illustrating
the necessary mods to TEST_TRUE is below my sig. 

We would need fallback code for when the compiler does not provide proper
support for variadic macros, akin to what we have for THROW in Lucy::Object::Err.

Joe, would you be interested in hacking on Test.cfh/Test.c until all the
functions look something like the example below?  If we get a patch from you
for that, I'll build on it with a patch supplying the fallback code.

Marvin Humphrey


diff --git a/core/Lucy/Test.c b/core/Lucy/Test.c
index 0457683..bab29da 100644
--- a/core/Lucy/Test.c
+++ b/core/Lucy/Test.c
@@ -56,11 +56,12 @@ TestBatch_plan(TestBatch *self) {
 }
 
 bool_t
-TestBatch_test_true(void *vself, bool_t condition, const char *pattern, ...) {
+TestBatch_test_true(void *vself, bool_t condition, const char *file, 
+                    int line, const char *pattern, ...) {
     va_list args;
     va_start(args, pattern);
-    bool_t result = TestBatch_VTest_True((TestBatch*)vself, condition,
-                                         pattern, args);
+    bool_t result = TestBatch_VTest_True((TestBatch*)vself, condition, file,
+                                         line, pattern, args);
     va_end(args);
     return result;
 }
@@ -135,8 +136,8 @@ TestBatch_skip(void *vself, const char *pattern, ...) {
 }
 
 bool_t
-TestBatch_vtest_true(TestBatch *self, bool_t condition, const char *pattern,
-                     va_list args) {
+TestBatch_vtest_true(TestBatch *self, bool_t condition, const char *file,
+                     int line, const char *pattern, va_list args) {
     // Increment test number.
     self->test_num++;
 
@@ -152,7 +153,7 @@ TestBatch_vtest_true(TestBatch *self, bool_t condition, const char *pattern,
         self->num_failed++;
         printf("not ok %" I64P " - ", self->test_num);
         vprintf(pattern, args);
-        printf("\n");
+        printf(" # (%s:%d)\n", file, line);
         return false;
     }
 }
diff --git a/core/Lucy/Test.cfh b/core/Lucy/Test.cfh
index 1b14224..5fc7df5 100644
--- a/core/Lucy/Test.cfh
+++ b/core/Lucy/Test.cfh
@@ -37,7 +37,8 @@ class Lucy::Test::TestBatch inherits Lucy::Object::Obj {
     Plan(TestBatch *self);
 
     inert bool_t
-    test_true(void *vself, bool_t condition, const char *pattern, ...);
+    test_true(void *vself, bool_t condition, const char *file, int line,
+              const char *pattern, ...);
 
     inert bool_t
     test_false(void *vself, bool_t condition, const char *pattern, ...);
@@ -64,8 +65,8 @@ class Lucy::Test::TestBatch inherits Lucy::Object::Obj {
     skip(void *vself, const char *pattern, ...);
 
     bool_t
-    VTest_True(TestBatch *self, bool_t condition, const char *pattern,
-               va_list args);
+    VTest_True(TestBatch *self, bool_t condition, const char *file,
+               int line, const char *pattern, va_list args);
 
     bool_t
     VTest_False(TestBatch *self, bool_t condition, const char *pattern,
@@ -94,8 +95,13 @@ class Lucy::Test::TestBatch inherits Lucy::Object::Obj {
 }
 
 __C__
+
+#define LUCY_TESTBATCH_TEST_TRUE(_batch, _condition, ...) \
+    lucy_TestBatch_test_true(_batch, _condition, __FILE__, __LINE__, \
+                             __VA_ARGS__) 
+
 #ifdef LUCY_USE_SHORT_NAMES
-  #define TEST_TRUE                    lucy_TestBatch_test_true
+  #define TEST_TRUE                    LUCY_TESTBATCH_TEST_TRUE
   #define TEST_FALSE                   lucy_TestBatch_test_false
   #define TEST_INT_EQ                  lucy_TestBatch_test_int_equals
   #define TEST_FLOAT_EQ                lucy_TestBatch_test_float_equals



Re: [lucy-dev] C TAP test harnesses

Posted by Joe Schaefer <jo...@yahoo.com>.
Oh it was just my way of being cute.  Projects don't live
or die based on their dependency choices, they just need
to be interesting enough for outside devs to not belabor
too much about the decisions made.  I'm fine with the
no apr dependency for lucy at this point, especially not
for something as silly as a test apparatus.


I'm planning to throw the at.[ch] files on github and 
see where we wind up in a week or so from now.



----- Original Message ----
> From: Nathan Kurz <na...@verse.com>
> To: lucy-dev@incubator.apache.org
> Sent: Tue, May 17, 2011 4:19:37 PM
> Subject: Re: [lucy-dev] C TAP test harnesses
> 
> On Tue, May 17, 2011 at 11:42 AM, Joe Schaefer <jo...@yahoo.com>  
wrote:
> > As an apreq dev, I have no interest in creating an independent  Apache 
>project
> > geared toward a TAP apparatus.  However I might be  willing to throw 
together
> > something on github (or google code etc) that  is more consumable by a 
>project
> > like lucy which has an irrational fear  of apr dependencies.
> 
> Joe ---
> 
> Do you say "irrational fear" in a  whimsical way, or does it impact
> your interest in this project?  Could  you expand on this?
> 
> I don't have a strong preference on dependencies, but  I'm eager to
> figure out how to make Lucy appealing for future  developers.
> 
> Thanks!
> 
> --nate
> 

Re: [lucy-dev] C TAP test harnesses

Posted by Nathan Kurz <na...@verse.com>.
On Tue, May 17, 2011 at 11:42 AM, Joe Schaefer <jo...@yahoo.com> wrote:
> As an apreq dev, I have no interest in creating an independent Apache project
> geared toward a TAP apparatus.  However I might be willing to throw together
> something on github (or google code etc) that is more consumable by a project
> like lucy which has an irrational fear of apr dependencies.

Joe ---

Do you say "irrational fear" in a whimsical way, or does it impact
your interest in this project?  Could you expand on this?

I don't have a strong preference on dependencies, but I'm eager to
figure out how to make Lucy appealing for future developers.

Thanks!

--nate

Re: [lucy-dev] C TAP test harnesses

Posted by Joe Schaefer <jo...@yahoo.com>.
----- Original Message ----

> From: Marvin Humphrey <ma...@rectangular.com>
> To: lucy-dev@incubator.apache.org
> Sent: Tue, May 17, 2011 1:34:22 AM
> Subject: Re: [lucy-dev] C TAP test harnesses
> 
> On Fri, May 13, 2011 at 11:33:55AM -0700, Joe Schaefer wrote:
> > > Whoa,  if the apreq harness can  work without APR that would be sweet.   I
> > > looked at at.c and I see that  it makes heavy use of  apr_snprintf().  Can
> > > you fall back to sprintf()   safely?
> > 
> > Haven't looked closely, but I don't see a priori why  the stdlib's 
formatting
> > functions can't be used effectively  here.
>   
> > > > It could be dropped without much effort, or  these features  added to 
the
> > > > existing Lucy C test  apparatus.
> > > 
> > > Would apreq accept  patches removing  the APR dependency?  And is at.h a 
>public
> > > API?   Ideally,  we would want to bundle those files and use them  
>verbatim.
> > >  Maintaining our own fork for the sake of Charmonizer's tests is   less
> > > desirable, unless we decide we want to go all out and publish  a  supported 
>C
> > > TAP library ourselves.
> > 
> > Yes, of  course that would be accepted/encouraged in apreq.  (The at.[ch]  
>stuff
> > is also designed to work within an httpd server C module (tho we  don't make 
>use
> > of it in apreq) where the TAP output is sent out over  HTTP.)  Getting rid 
of
> > the apr dependency would be a welcome  change, so long as we're careful to
> > avoid leaks.
> 
> I put in a few  hours on this over the weekend.  I made some "progress", but I
> don't  think any of that "progress" so far improves on the existing apreq 
>code.  
>
> 
> Joe warned me in IRC that the hard part of this refactoring job was  likely to
> be the excision of the APR memory pool code -- and he was  right.  Memory
> allocation under a pool system has a distinct usage  pattern, and since the
> standard library doesn't provide pools, it doesn't  support that usage 
pattern.
> With the stdlib.h heap allocation functions,  ordinarily you have to pair each
> malloc() with a free().  With a memory  pool, you don't have to do that -- you
> can overwrite allocated pointers, and  you can mix and match pointers to
> static/data-segment memory with pointers to  pool memory:
> 
>     /* Start off by allocating some memory from  the apr_pool_t. */
>     thing->ptr = (char*)apr_palloc(pool,  1);
> 
>     /* Later, we might overwrite that pool pointer with  another pool pointer.
>      * Note that we don't free() the existing  pointer first. */
>     if (foo != NULL) {
>          thing->ptr = apr_pstrdup(pool, foo);
>     }
> 
>      /* Later, we might overwrite that pointer to pool memory with a pointer  
>to
>      * some static data. */
>     static char bar[] =  "bar";
>     thing->ptr = &bar;
> 
>     /* When  the cleanup finally happens, it doesn't matter what's in
>      *  thing->ptr, because the *pool* keeps track of what memory needs to  be
>      * freed.  We never call free() on individual  pointers.  */
>     apr_pool_clear(pool);
> 
> Additionally,  the apreq harness takes advantage of the fact that you can
> register  pseudo-destructors that are triggered by apr_pool_clear() and get 
run
> just  before the pool memory gets deallocated.
> 
>          apr_pool_cleanup_register(p, q, report_local_cleanup,
>                                           report_local_cleanup);
> 
> The  localizer functionality in the apreq test harness depends on  these
> pseudo-destructors. (And unusually, it's the user's responsibility to  invoke
> apr_pool_clear() directly and cause the subtest cleanup as a side  effect, as
> opposed to invoking something like "AT_subtest_done()" which  cleans up memory
> as an implementation detail.)

That's because AT_localize localizes AT to a given *pool*.  Just like local
in Perl localizes a variable to a given scope duration. It makes as much sense
to have AT_delocalize as it does to have a delocalize fcn in Perl.

> During this destructor,  certain information gets
> transfered from the child test harness object to the  parent in a way which is
> hard to track under a malloc/free memory  model.  It all works fine when 
you're
> playing by the loose rules of the  APR pool system, but things get complicated
> when you try to apply the  constraints imposed by malloc/free.
> 
> I don't see how we can make the  localizer feature work once APR is removed
> without substantial  rearchitecting.  And there's a bunch of other stuff that
> has to happen  too before the harness is Lucy-ready, all of it churn for zero
> positive  impact or mildly negative impact from the apreq perspective, such  
as
> replacing apr_snprintf with a fixed up version of _snprintf under MSVC  or
> eliminating APR status codes.
> 
> It doesn't seem to me like it's in  Lucy's interest to proceed further down
> this path, nor in apreq's.  I  don't like the idea of going to apreq-dev and
> saying, "Here a series of  patches that make your code crappier.  It's a
> significant rearchitecting  with a lot of churn, so it almost certainly
> introduces new bugs that you're  going to have to deal with.  And I'm doing
> this because I want to take a  private implementation detail of your project
> and turn it into a public API  that you have to support.  We'll be counting on
> you!"
> 
> If the  apreq community were to decide spontaneously to remove APR as a
> dependency  from at.c/at.h and start publishing it as a public API with full
> backwards  compatibility promises, that would be great.  But it doesn't make
> sense  for apreq to accept these changes, and it doesn't make sense for Lucy  
>to
> depend on apreq code when it isn't in apreq's interest to tailor it to  Lucy's
> needs.  
> 
> If we're going to put in this much effort making  a test harness work for us,
> we should either fork it and own the code, or we  should be contributing to a
> common project with an official public API. 

Well my whole original thought was for lucy to just take at.ch and modify it
to taste.  Getting C programmers to standardize on a test suite is generally
IMO a wasted effort given the relative size of the problem and the various
options a given C community might be interested in.  99% of the time they
will hack up their own custom solution (eg what APR did after dropping 
a test lib they picked up on the net).

As an apreq dev, I have no interest in creating an independent Apache project
geared toward a TAP apparatus.  However I might be willing to throw together
something on github (or google code etc) that is more consumable by a project
like lucy which has an irrational fear of apr dependencies.

Re: [lucy-dev] C TAP test harnesses

Posted by Joe Schaefer <jo...@yahoo.com>.
----- Original Message ----

> From: Marvin Humphrey <ma...@rectangular.com>
> To: lucy-dev@incubator.apache.org
> Sent: Wed, May 18, 2011 1:05:49 AM
> Subject: Re: [lucy-dev] C TAP test harnesses
> 
> On Tue, May 17, 2011 at 08:52:59PM -0700, Joe Schaefer wrote:
> > Two hours  of hacking on your pull request and I've gotten at.[ch] to the 
>point
> >  where the apr dependence is gone and the apreq tests (tweaked by about 10  
>LOC)
> > all pass.  
> 
> Nice! :)
> 
> To bring everyone up to  speed, Joe forked at.[ch] on Github, extracting those
> files from the apreq  source tree.
> 
>     https://github.com/joesuf4/at
> 
> I then forked that,  applied the changes I'd been working on locally, and
> issued a pull  request.
> 
>     https://github.com/creamygoodness/at
> 
> Joe pulled my  changes in, and then did the final hard hacking on the memory
> pool stuff to  close out the purge of the APR dependency.
> 
> > There are some warnings  issued under maintainer mode, but I probably
> > will just ignore those and  change apreq to use this de-apr'd code instead.
> 
> Those warnings happen  because of the way at_vsnprintf forwards all its args 
to
> vsnprintf, including  the format string.  Under maximally strict warnings, GCC
> wants to see  that argument tagged with an __attribute__ indicating that it's 
a
> format  variable so that validation can be performed at the sites where the
> function  is invoked.
> 
> FWIW, now that we aren't using the APR IO stuff, I think we  might be able to
> adapt the test harness to print to a FILE* stream using  fprintf, instead of
> printing to a buffer using  _vsnprintf/vsnprintf.

That would undo the point of the whole report infrastructure.  The point of the
report stuff is that it allows you to direct the TAP output anywhere, to a file,
to a socket, to a bucket brigade, etc.  I want to keep that flexibility to allow
at.[ch] to be used in a client-server environment where Test::Harness drives the
client but at.[ch] runs in the server which dishes out TAP to the client.

It's easier and cheaper to use snprintf than it is to provide a stream 
abstraction with
a custom formatter.  Yeah there is a cutoff involved, but it shouldn't hamper 
the
output in practice.

> > > If the  apreq community were to  decide spontaneously to remove APR as a
> > > dependency  from  at.c/at.h and start publishing it as a public API with 
>full
> > >  backwards  compatibility promises, that would be great.  But it  doesn't 
>make
> > > sense  for apreq to accept these changes, and it  doesn't make sense for 
>Lucy  
>
> > >to
> > > depend on apreq  code when it isn't in apreq's interest to tailor it to  
>Lucy's
> > >  needs.  
> > > 
> > > If we're going to put in this much  effort making  a test harness work for 
>us,
> > > we should either  fork it and own the code, or we  should be contributing 
>to a
> > >  common project with an official public API. 
> > 
> > If we can get lucy  using the code at http://github.com/joesuf4/at then that 
>can
> > be the  upstream location for both projects.
> > 
> > WDYT?
> 
> +1 to switch  Charmonizer's test files over to this test harness, with an eye
> towards  deleting trunk/charmonizer/src/Charmonizer/Test.[ch].
> 
> I have some IP  concerns, though.  If the project stays on Github, things are
> going to  get complicated from a code provenance standpoint.  Our Github
> commits  have not been granted to the ASF, so the ALv2 header in those files 
is
> no  longer accurate.  We'll need to change the copyright to use your name,  
per
> the guidelines in the ALv2's appendix.  We'll also need to add  LICENSE and
> NOTICE files to the Github repo, and when we pull them in to  Lucy, we'll need
> to add a clause to Lucy's NOTICE.
> 
> I'm willing to do  the legal busywork to help ensure that all our i's are
> dotted and t's  crossed, but it might be less troublesome to have these files
> live at the ASF  somewhere.  I'm OK with your original plan to fork within
> Lucy.  I  guess I'm OK with apreq as upstream, too, if apreq really is OK with
> these  changes -- if Lucy decides that we have to fork at some future point, 
we
> can  just fork then.
> 
> Also, if we want to start committing this stuff to Lucy  soon, we should start
> a topic branch in svn, since this shouldn't go into  0.1.0.

I can wait for the release.  No rush.

Re: [lucy-dev] C TAP test harnesses

Posted by Marvin Humphrey <ma...@rectangular.com>.
On Tue, May 17, 2011 at 08:52:59PM -0700, Joe Schaefer wrote:
> Two hours of hacking on your pull request and I've gotten at.[ch] to the point
> where the apr dependence is gone and the apreq tests (tweaked by about 10 LOC)
> all pass.  

Nice! :)

To bring everyone up to speed, Joe forked at.[ch] on Github, extracting those
files from the apreq source tree.

    https://github.com/joesuf4/at

I then forked that, applied the changes I'd been working on locally, and
issued a pull request.

    https://github.com/creamygoodness/at

Joe pulled my changes in, and then did the final hard hacking on the memory
pool stuff to close out the purge of the APR dependency.

> There are some warnings issued under maintainer mode, but I probably
> will just ignore those and change apreq to use this de-apr'd code instead.

Those warnings happen because of the way at_vsnprintf forwards all its args to
vsnprintf, including the format string.  Under maximally strict warnings, GCC
wants to see that argument tagged with an __attribute__ indicating that it's a
format variable so that validation can be performed at the sites where the
function is invoked.

FWIW, now that we aren't using the APR IO stuff, I think we might be able to
adapt the test harness to print to a FILE* stream using fprintf, instead of
printing to a buffer using _vsnprintf/vsnprintf.

> > If the  apreq community were to decide spontaneously to remove APR as a
> > dependency  from at.c/at.h and start publishing it as a public API with full
> > backwards  compatibility promises, that would be great.  But it doesn't make
> > sense  for apreq to accept these changes, and it doesn't make sense for Lucy  
> >to
> > depend on apreq code when it isn't in apreq's interest to tailor it to  Lucy's
> > needs.  
> > 
> > If we're going to put in this much effort making  a test harness work for us,
> > we should either fork it and own the code, or we  should be contributing to a
> > common project with an official public API. 
> 
> If we can get lucy using the code at http://github.com/joesuf4/at then that can
> be the upstream location for both projects.
> 
> WDYT?

+1 to switch Charmonizer's test files over to this test harness, with an eye
towards deleting trunk/charmonizer/src/Charmonizer/Test.[ch].

I have some IP concerns, though.  If the project stays on Github, things are
going to get complicated from a code provenance standpoint.  Our Github
commits have not been granted to the ASF, so the ALv2 header in those files is
no longer accurate.  We'll need to change the copyright to use your name, per
the guidelines in the ALv2's appendix.  We'll also need to add LICENSE and
NOTICE files to the Github repo, and when we pull them in to Lucy, we'll need
to add a clause to Lucy's NOTICE.

I'm willing to do the legal busywork to help ensure that all our i's are
dotted and t's crossed, but it might be less troublesome to have these files
live at the ASF somewhere.  I'm OK with your original plan to fork within
Lucy.  I guess I'm OK with apreq as upstream, too, if apreq really is OK with
these changes -- if Lucy decides that we have to fork at some future point, we
can just fork then.

Also, if we want to start committing this stuff to Lucy soon, we should start
a topic branch in svn, since this shouldn't go into 0.1.0.

Marvin Humphrey


Re: [lucy-dev] C TAP test harnesses

Posted by Joe Schaefer <jo...@yahoo.com>.
----- Original Message ----

> From: Marvin Humphrey <ma...@rectangular.com>
> To: lucy-dev@incubator.apache.org
> Sent: Tue, May 17, 2011 1:34:22 AM
> Subject: Re: [lucy-dev] C TAP test harnesses
> 
> On Fri, May 13, 2011 at 11:33:55AM -0700, Joe Schaefer wrote:
> > > Whoa,  if the apreq harness can  work without APR that would be sweet.   I
> > > looked at at.c and I see that  it makes heavy use of  apr_snprintf().  Can
> > > you fall back to sprintf()   safely?
> > 
> > Haven't looked closely, but I don't see a priori why  the stdlib's 
formatting
> > functions can't be used effectively  here.
>   
> > > > It could be dropped without much effort, or  these features  added to 
the
> > > > existing Lucy C test  apparatus.
> > > 
> > > Would apreq accept  patches removing  the APR dependency?  And is at.h a 
>public
> > > API?   Ideally,  we would want to bundle those files and use them  
>verbatim.
> > >  Maintaining our own fork for the sake of Charmonizer's tests is   less
> > > desirable, unless we decide we want to go all out and publish  a  supported 
>C
> > > TAP library ourselves.
> > 
> > Yes, of  course that would be accepted/encouraged in apreq.  (The at.[ch]  
>stuff
> > is also designed to work within an httpd server C module (tho we  don't make 
>use
> > of it in apreq) where the TAP output is sent out over  HTTP.)  Getting rid 
of
> > the apr dependency would be a welcome  change, so long as we're careful to
> > avoid leaks.
> 
> I put in a few  hours on this over the weekend.  I made some "progress", but I
> don't  think any of that "progress" so far improves on the existing apreq 
>code.  
>
> 
> Joe warned me in IRC that the hard part of this refactoring job was  likely to
> be the excision of the APR memory pool code -- and he was  right.  Memory
> allocation under a pool system has a distinct usage  pattern, and since the
> standard library doesn't provide pools, it doesn't  support that usage 
pattern.
> With the stdlib.h heap allocation functions,  ordinarily you have to pair each
> malloc() with a free().  With a memory  pool, you don't have to do that -- you
> can overwrite allocated pointers, and  you can mix and match pointers to
> static/data-segment memory with pointers to  pool memory:
> 
>     /* Start off by allocating some memory from  the apr_pool_t. */
>     thing->ptr = (char*)apr_palloc(pool,  1);
> 
>     /* Later, we might overwrite that pool pointer with  another pool pointer.
>      * Note that we don't free() the existing  pointer first. */
>     if (foo != NULL) {
>          thing->ptr = apr_pstrdup(pool, foo);
>     }
> 
>      /* Later, we might overwrite that pointer to pool memory with a pointer  
>to
>      * some static data. */
>     static char bar[] =  "bar";
>     thing->ptr = &bar;
> 
>     /* When  the cleanup finally happens, it doesn't matter what's in
>      *  thing->ptr, because the *pool* keeps track of what memory needs to  be
>      * freed.  We never call free() on individual  pointers.  */
>     apr_pool_clear(pool);
> 
> Additionally,  the apreq harness takes advantage of the fact that you can
> register  pseudo-destructors that are triggered by apr_pool_clear() and get 
run
> just  before the pool memory gets deallocated.
> 
>          apr_pool_cleanup_register(p, q, report_local_cleanup,
>                                           report_local_cleanup);
> 
> The  localizer functionality in the apreq test harness depends on  these
> pseudo-destructors. (And unusually, it's the user's responsibility to  invoke
> apr_pool_clear() directly and cause the subtest cleanup as a side  effect, as
> opposed to invoking something like "AT_subtest_done()" which  cleans up memory
> as an implementation detail.) During this destructor,  certain information 
gets
> transfered from the child test harness object to the  parent in a way which is
> hard to track under a malloc/free memory  model.  It all works fine when 
you're
> playing by the loose rules of the  APR pool system, but things get complicated
> when you try to apply the  constraints imposed by malloc/free.
> 
> I don't see how we can make the  localizer feature work once APR is removed
> without substantial  rearchitecting.  And there's a bunch of other stuff that
> has to happen  too before the harness is Lucy-ready, all of it churn for zero
> positive  impact or mildly negative impact from the apreq perspective, such  
as
> replacing apr_snprintf with a fixed up version of _snprintf under MSVC  or
> eliminating APR status codes.
> 
> It doesn't seem to me like it's in  Lucy's interest to proceed further down
> this path, nor in apreq's.  I  don't like the idea of going to apreq-dev and
> saying, "Here a series of  patches that make your code crappier.  It's a
> significant rearchitecting  with a lot of churn, so it almost certainly
> introduces new bugs that you're  going to have to deal with.  And I'm doing
> this because I want to take a  private implementation detail of your project
> and turn it into a public API  that you have to support.  We'll be counting on
> you!"

Two hours of hacking on your pull request and I've gotten at.[ch] to the point
where the apr dependence is gone and the apreq tests (tweaked by about 10 LOC)
all pass.  There are some warnings issued under maintainer mode, but I probably
will just ignore those and change apreq to use this de-apr'd code instead.

> If the  apreq community were to decide spontaneously to remove APR as a
> dependency  from at.c/at.h and start publishing it as a public API with full
> backwards  compatibility promises, that would be great.  But it doesn't make
> sense  for apreq to accept these changes, and it doesn't make sense for Lucy  
>to
> depend on apreq code when it isn't in apreq's interest to tailor it to  Lucy's
> needs.  
> 
> If we're going to put in this much effort making  a test harness work for us,
> we should either fork it and own the code, or we  should be contributing to a
> common project with an official public API. 

If we can get lucy using the code at http://github.com/joesuf4/at then that can
be the upstream location for both projects.

WDYT?

Re: [lucy-dev] C TAP test harnesses

Posted by Marvin Humphrey <ma...@rectangular.com>.
On Fri, May 13, 2011 at 11:33:55AM -0700, Joe Schaefer wrote:
> > Whoa, if the apreq harness can  work without APR that would be sweet.  I
> > looked at at.c and I see that  it makes heavy use of apr_snprintf().  Can
> > you fall back to sprintf()  safely?
> 
> Haven't looked closely, but I don't see a priori why the stdlib's formatting
> functions can't be used effectively here.
  
> > > It could be dropped without much effort, or these features  added to the
> > > existing Lucy C test apparatus.
> > 
> > Would apreq accept  patches removing the APR dependency?  And is at.h a public
> > API?   Ideally, we would want to bundle those files and use them  verbatim.
> > Maintaining our own fork for the sake of Charmonizer's tests is  less
> > desirable, unless we decide we want to go all out and publish a  supported C
> > TAP library ourselves.
> 
> Yes, of course that would be accepted/encouraged in apreq.  (The at.[ch] stuff
> is also designed to work within an httpd server C module (tho we don't make use
> of it in apreq) where the TAP output is sent out over HTTP.)  Getting rid of
> the apr dependency would be a welcome change, so long as we're careful to
> avoid leaks.

I put in a few hours on this over the weekend.  I made some "progress", but I
don't think any of that "progress" so far improves on the existing apreq code.  

Joe warned me in IRC that the hard part of this refactoring job was likely to
be the excision of the APR memory pool code -- and he was right.  Memory
allocation under a pool system has a distinct usage pattern, and since the
standard library doesn't provide pools, it doesn't support that usage pattern.
With the stdlib.h heap allocation functions, ordinarily you have to pair each
malloc() with a free().  With a memory pool, you don't have to do that -- you
can overwrite allocated pointers, and you can mix and match pointers to
static/data-segment memory with pointers to pool memory:

    /* Start off by allocating some memory from the apr_pool_t. */
    thing->ptr = (char*)apr_palloc(pool, 1);

    /* Later, we might overwrite that pool pointer with another pool pointer.
     * Note that we don't free() the existing pointer first. */
    if (foo != NULL) {
        thing->ptr = apr_pstrdup(pool, foo);
    }

    /* Later, we might overwrite that pointer to pool memory with a pointer to
     * some static data. */
    static char bar[] = "bar";
    thing->ptr = &bar;

    /* When the cleanup finally happens, it doesn't matter what's in
     * thing->ptr, because the *pool* keeps track of what memory needs to be
     * freed.  We never call free() on individual pointers.  */
    apr_pool_clear(pool);

Additionally, the apreq harness takes advantage of the fact that you can
register pseudo-destructors that are triggered by apr_pool_clear() and get run
just before the pool memory gets deallocated.

        apr_pool_cleanup_register(p, q, report_local_cleanup,
                                        report_local_cleanup);

The localizer functionality in the apreq test harness depends on these
pseudo-destructors. (And unusually, it's the user's responsibility to invoke
apr_pool_clear() directly and cause the subtest cleanup as a side effect, as
opposed to invoking something like "AT_subtest_done()" which cleans up memory
as an implementation detail.) During this destructor, certain information gets
transfered from the child test harness object to the parent in a way which is
hard to track under a malloc/free memory model.  It all works fine when you're
playing by the loose rules of the APR pool system, but things get complicated
when you try to apply the constraints imposed by malloc/free.

I don't see how we can make the localizer feature work once APR is removed
without substantial rearchitecting.  And there's a bunch of other stuff that
has to happen too before the harness is Lucy-ready, all of it churn for zero
positive impact or mildly negative impact from the apreq perspective, such as
replacing apr_snprintf with a fixed up version of _snprintf under MSVC or
eliminating APR status codes.

It doesn't seem to me like it's in Lucy's interest to proceed further down
this path, nor in apreq's.  I don't like the idea of going to apreq-dev and
saying, "Here a series of patches that make your code crappier.  It's a
significant rearchitecting with a lot of churn, so it almost certainly
introduces new bugs that you're going to have to deal with.  And I'm doing
this because I want to take a private implementation detail of your project
and turn it into a public API that you have to support.  We'll be counting on
you!"

If the apreq community were to decide spontaneously to remove APR as a
dependency from at.c/at.h and start publishing it as a public API with full
backwards compatibility promises, that would be great.  But it doesn't make
sense for apreq to accept these changes, and it doesn't make sense for Lucy to
depend on apreq code when it isn't in apreq's interest to tailor it to Lucy's
needs.  

If we're going to put in this much effort making a test harness work for us,
we should either fork it and own the code, or we should be contributing to a
common project with an official public API. 

Marvin Humphrey


Re: [lucy-dev] C TAP test harnesses

Posted by Joe Schaefer <jo...@yahoo.com>.
----- Original Message ----

> From: Marvin Humphrey <ma...@rectangular.com>
> To: lucy-dev@incubator.apache.org
> Sent: Fri, May 13, 2011 2:17:44 PM
> Subject: Re: [lucy-dev] C TAP test harnesses
> 
> On Thu, May 12, 2011 at 09:59:47PM -0700, Joe Schaefer wrote:
> > FWIW the  features in the apreq stuff that are nice for me are
> > 
> > 1) macros  provide access to __FILE__ and __LINE__ in the test source file,
> 
> It's  definitely nice having access to __FILE__ and __LINE__.  The  
Charmonizer
> tests don't include them because we prioritized taking variadic  arguments for
> the test label.  We couldn't keep that feature and include  __FILE__ and
> __LINE__ implicitly without requiring variadic macro support  from the
> compiler.
> 
> From what I can tell, you made the opposite choice  in the apreq harness -- 
you
> support __FILE__ and __LINE__, but you only  accept simple string test labels. 

> 
> If we were to change the Lucy test  harness to use __FILE__ and __LINE__
> implicitly, we would also have to modify  some number of tests by creating
> pre-formatted test labels locally to pass  into the TEST_XXXXX() routines.  
> A starter patch incorporating the  necessary changes to TEST_TRUE() is below 
my
> sig.  (It does not include  fixes for the 22 incompatible variadic invocations
> of  TEST_TRUE().)
> 
> > 2) skip lists, todo lists, and fatals are  supported.
> > 
> > 3) there is a localizer which allows you to next  test frameworks.  it 
>basically
> > supplies its own harness and treats  all subtest errors as fatal- handy if
> > you're running a tight loop of  tests and really aren't interested in 
feeding
> > all that data directly to  stdout.
> 
> These are great, too.   Our existing test harnesses have  only a crude
> mechanism for skipping tests, and no support for TODO tests or  subtests.
> 
> > The apr dependency is just because apreq has a core  dependency on apr, so 
>why 
>
> > not.
> 
> Whoa, if the apreq harness can  work without APR that would be sweet.  I 
looked
> at at.c and I see that  it makes heavy use of apr_snprintf().  Can you fall
> back to sprintf()  safely?

Haven't looked closely, but I don't see a priori why the stdlib's formatting 
functions
can't be used effectively here.
 
> > It could be dropped without much effort, or these features  added to the
> > existing Lucy C test apparatus.
> 
> Would apreq accept  patches removing the APR dependency?  And is at.h a public
> API?   Ideally, we would want to bundle those files and use them  verbatim.
> Maintaining our own fork for the sake of Charmonizer's tests is  less
> desirable, unless we decide we want to go all out and publish a  supported C
> TAP library ourselves.

Yes, of course that would be accepted/encouraged in apreq.  (The at.[ch] stuff
is also designed to work within an httpd server C module (tho we don't make use
of it in apreq) where the TAP output is sent out over HTTP.)  Getting rid of
the apr dependency would be a welcome change, so long as we're careful to
avoid leaks.

Re: [lucy-dev] C TAP test harnesses

Posted by Marvin Humphrey <ma...@rectangular.com>.
On Thu, May 12, 2011 at 09:59:47PM -0700, Joe Schaefer wrote:
> FWIW the features in the apreq stuff that are nice for me are
> 
> 1) macros provide access to __FILE__ and __LINE__ in the test source file,

It's definitely nice having access to __FILE__ and __LINE__.  The Charmonizer
tests don't include them because we prioritized taking variadic arguments for
the test label.  We couldn't keep that feature and include __FILE__ and
__LINE__ implicitly without requiring variadic macro support from the
compiler.

>From what I can tell, you made the opposite choice in the apreq harness -- you
support __FILE__ and __LINE__, but you only accept simple string test labels. 

If we were to change the Lucy test harness to use __FILE__ and __LINE__
implicitly, we would also have to modify some number of tests by creating
pre-formatted test labels locally to pass into the TEST_XXXXX() routines.  
A starter patch incorporating the necessary changes to TEST_TRUE() is below my
sig.  (It does not include fixes for the 22 incompatible variadic invocations
of TEST_TRUE().)

> 2) skip lists, todo lists, and fatals are supported.
> 
> 3) there is a localizer which allows you to next test frameworks.  it basically
> supplies its own harness and treats all subtest errors as fatal- handy if
> you're running a tight loop of tests and really aren't interested in feeding
> all that data directly to stdout.

These are great, too.   Our existing test harnesses have only a crude
mechanism for skipping tests, and no support for TODO tests or subtests.
 
> The apr dependency is just because apreq has a core dependency on apr, so why 
> not.

Whoa, if the apreq harness can work without APR that would be sweet.  I looked
at at.c and I see that it makes heavy use of apr_snprintf().  Can you fall
back to sprintf() safely?

> It could be dropped without much effort, or these features added to the
> existing Lucy C test apparatus.

Would apreq accept patches removing the APR dependency?  And is at.h a public
API?  Ideally, we would want to bundle those files and use them verbatim.
Maintaining our own fork for the sake of Charmonizer's tests is less
desirable, unless we decide we want to go all out and publish a supported C
TAP library ourselves.

Marvin Humphrey


diff --git a/core/Lucy/Test.c b/core/Lucy/Test.c
index 0457683..b0a69c2 100644
--- a/core/Lucy/Test.c
+++ b/core/Lucy/Test.c
@@ -56,13 +56,23 @@ TestBatch_plan(TestBatch *self) {
 }
 
 bool_t
-TestBatch_test_true(void *vself, bool_t condition, const char *pattern, ...) {
-    va_list args;
-    va_start(args, pattern);
-    bool_t result = TestBatch_VTest_True((TestBatch*)vself, condition,
-                                         pattern, args);
-    va_end(args);
-    return result;
+TestBatch_test_true(TestBatch *self, bool_t condition, const char *label,
+                    const char *file, int line) {
+    // Increment test number.
+    self->test_num++;
+
+    // Test condition and pass or fail.
+    if (condition) {
+        self->num_passed++;
+        printf("ok %" I64P " - %s\n", self->test_num, label);
+        return true;
+    }
+    else {
+        self->num_failed++;
+        printf("not ok %" I64P " - %s # (%s:%d)\n", self->test_num, label, 
+               file, line);
+        return false;
+    }
 }
 
 bool_t
@@ -135,29 +145,6 @@ TestBatch_skip(void *vself, const char *pattern, ...) {
 }
 
 bool_t
-TestBatch_vtest_true(TestBatch *self, bool_t condition, const char *pattern,
-                     va_list args) {
-    // Increment test number.
-    self->test_num++;
-
-    // Test condition and pass or fail.
-    if (condition) {
-        self->num_passed++;
-        printf("ok %" I64P " - ", self->test_num);
-        vprintf(pattern, args);
-        printf("\n");
-        return true;
-    }
-    else {
-        self->num_failed++;
-        printf("not ok %" I64P " - ", self->test_num);
-        vprintf(pattern, args);
-        printf("\n");
-        return false;
-    }
-}
-
-bool_t
 TestBatch_vtest_false(TestBatch *self, bool_t condition,
                       const char *pattern, va_list args) {
     // Increment test number.
diff --git a/core/Lucy/Test.cfh b/core/Lucy/Test.cfh
index 1b14224..91bec02 100644
--- a/core/Lucy/Test.cfh
+++ b/core/Lucy/Test.cfh
@@ -36,8 +36,9 @@ class Lucy::Test::TestBatch inherits Lucy::Object::Obj {
     void
     Plan(TestBatch *self);
 
-    inert bool_t
-    test_true(void *vself, bool_t condition, const char *pattern, ...);
+    bool_t
+    Test_True(TestBatch *self, bool_t condition, const char *label,
+              const char *file, int line);
 
     inert bool_t
     test_false(void *vself, bool_t condition, const char *pattern, ...);
@@ -64,10 +65,6 @@ class Lucy::Test::TestBatch inherits Lucy::Object::Obj {
     skip(void *vself, const char *pattern, ...);
 
     bool_t
-    VTest_True(TestBatch *self, bool_t condition, const char *pattern,
-               va_list args);
-
-    bool_t
     VTest_False(TestBatch *self, bool_t condition, const char *pattern,
                 va_list args);
 
@@ -94,8 +91,12 @@ class Lucy::Test::TestBatch inherits Lucy::Object::Obj {
 }
 
 __C__
+
+#define LUCY_TESTBATCH_TEST_TRUE(_batch, _condition, _label) \
+    lucy_TestBatch_test_true(_batch, _condition, _label, __FILE__, __LINE__)
+   
 #ifdef LUCY_USE_SHORT_NAMES
-  #define TEST_TRUE                    lucy_TestBatch_test_true
+  #define TEST_TRUE                    LUCY_TESTBATCH_TEST_TRUE
   #define TEST_FALSE                   lucy_TestBatch_test_false
   #define TEST_INT_EQ                  lucy_TestBatch_test_int_equals
   #define TEST_FLOAT_EQ                lucy_TestBatch_test_float_equals


Re: [lucy-dev] C TAP test harnesses

Posted by Joe Schaefer <jo...@yahoo.com>.
----- Original Message ----

> From: Marvin Humphrey <ma...@rectangular.com>
> To: lucy-dev@incubator.apache.org
> Sent: Fri, May 13, 2011 12:33:06 AM
> Subject: [lucy-dev] C TAP test harnesses
> 
> On Thu, May 12, 2011 at 05:24:14PM -0700, Joe Schaefer wrote:
> > >    * Port most test files  within trunk/perl/t/ to C.
> > 
> > If  we're in need of a test framework for C I wrote a small TAP-compliant
> >  test framework for apreq here:
> > 
> >  http://svn.apache.org/repos/asf/httpd/apreq/trunk/library/t/
> 
> Great minds  think alike.  We have two of those. :)
> 
>      http://svn.apache.org/repos/asf/incubator/lucy/trunk/core/Lucy/Test.cfh
>       http://svn.apache.org/repos/asf/incubator/lucy/trunk/core/Lucy/Test.c
> 
>       
>http://svn.apache.org/repos/asf/incubator/lucy/trunk/charmonizer/src/Charmonizer/Test.h
>
>       
>http://svn.apache.org/repos/asf/incubator/lucy/trunk/charmonizer/src/Charmonizer/Test.c
>
> 
> (And  another Lucy community member, David Wheeler, authored a JavaScript port
> of  Test.Simple a few years ago.)
> 
> An additional related project of note is  APR's test harness, which isn't TAP.
> 
>      http://svn.apache.org/repos/asf/apr/apr/trunk/test/abts.h
>      http://svn.apache.org/repos/asf/apr/apr/trunk/test/abts.c
> 
> Aside from  TAP/no-TAP, these test harness libraries are distinguished by  
>their
> dependencies.
> 
>      ==================================================================
>      | Test harness   |  TAP  |  Dependencies                           |
>      ------------------------------------------------------------------
>      | APR            |  no   |  none                                   |
>     | apreq           |  yes  | APR                                     |
>     | Charmonizer    |  yes  |  none                                   |
>     | Lucy/Clownfish  |  yes  | C99/C++, Charmonizer, Clownfish        |
>      ==================================================================
> 
> The  Lucy/Clownfish test harness is a fork of the one written  for
> Charmonizer[1].  We have a lot of tests for Lucy, and we're going  to
> accumulate a lot more over time.  It makes sense to have a  C99,
> Clownfish-friendly test harness we can customize at will -- so this one,  IMO,
> we ought to keep.
> 
> In contrast, now that Lucy no longer uses the  Charmonizer test harness, it's
> become less important to us and it would be  kind of nice to consolidate it
> away.  The apreq harness isn't a good  replacement candidate in its present
> form, though, because it requires  APR.  That leaves the APR test harness.
> It's not TAP, though.  I  like TAP.  I'm not motivated to do a bunch of work
> refactoring something  that's TAP and working already.

FWIW the features in the apreq stuff that are nice for me are

1) macros provide access to __FILE__ and __LINE__ in the test source file,
which an emacs compile buffer will understand when written appropriately to 
stdout.

2) skip lists, todo lists, and fatals are supported.

3) there is a localizer which allows you to next test frameworks.  it basically
supplies its own harness and treats all subtest errors as fatal- handy if you're
running a tight loop of tests and really aren't interested in feeding all that 
data
directly to stdout.

The apr dependency is just because apreq has a core dependency on apr, so why 
not.
It could be dropped without much effort, or these features added to the
existing Lucy C test apparatus.

 
> For the record, there are also all of  these out there in the world:
> 
>      http://testanything.org/wiki/index.php/TAP_Producers#C_.2F_C.2B.2B
> 
> It  seems like the ASF could use a decent standalone C TAP library with  an
> official public API, C89, cross-platform-compatible and with no  dependencies.
> 
> Marvin Humphrey
> 
> [1] Charmonizer is a C configuration  prober, like Autoconf and Metaconfig, 
but
>     written in C and  Windows-compatible.  See Lucy::Docs::DevGuide for an
>      overview of Lucy's layers:
>     
>https://svn.apache.org/repos/asf/incubator/lucy/trunk/core/Lucy/Docs/DevGuide.cfh
>
> 
> 

[lucy-dev] Dependencies

Posted by Marvin Humphrey <ma...@rectangular.com>.
On Sun, May 15, 2011 at 10:47:24PM -0700, Nathan Kurz wrote:
> On Thu, May 12, 2011 at 9:33 PM, Marvin Humphrey <ma...@rectangular.com> wrote:
> > The apreq harness isn't a good replacement candidate in its present
> > form, though, because it requires APR.
> 
> I tend to like the approach of having everything self-contained, but
> if there were candidates I would think the the APR would be high on
> the list.

There are two TAP-producing test frameworks within Lucy right now: one
belonging to Charmonizer, and one belonging to Lucy/Clownfish.  That passage
you've quoted refers to replacing the Charmonizer test framework, not the
Lucy/Clownfish test framework.

Like Clownfish, Charmonizer has been designed as a distinct layer within the
Lucy project, mainly for separation of concerns.  It might potentially
become usable outside of Lucy at some point[1].  If that day ever comes, it
would be absurd for a C configuration prober to require APR as a 
prerequisite.  :)

So, I stand by my statement above that the apreq harness is not a good
replacement candidate for Charmonizer's test framework as long as it requires
APR.

However, I realize that you're speaking of adding APR as a dependency for Lucy
at large.  OK, but what concrete advantages would that give us?  APR is big
and complicated.  It took me 10 minutes to build APR and run its test suite
just now on my MacBook Pro.  It failed.

APR is more of a base platform for development rather than something you add
to get specific targeted features.  The ill-fated Lucene4C project was built
on top of it.  Lucy isn't.

It would take an awful lot to persuade me that taking on APR as a dependency
at this point was worthwhile.  

> Also, I would guess that a developer only test-suite wouldn't be much of a
> hindrance to adoption.

Run our tests only during development?  I disagree strongly with that
proposition, even if it's only Charmonizer's tests.   Our users need to know
when Lucy won't work effectively on their platform.  We need to know, too.

Developer-only tests can be useful and important -- Lucy's "test_valgrind"
build target is a good example.  But easy tests ought to be run everywhere we
can run them.

> Is there a formal policy on avoiding outside dependencies, or is this
> just a general preference?

I'm pretty sure that there is no formal ASF policy, though from what I've seen
most ASF projects bundle their dependencies unless licensing restrictions make
that impossible.  For Lucy, the policy is whatever we decide on as a community
and vote for as a PPMC. 

Here's my personal perspective:

Lucy is a low-level library.  Our goal should be to make it so rock solid and
portable that other projects will not hesitate to add it as a dependency.

Lucy should be easy to install.  Historically, KinoSearch has been easy to
install via the CPAN client (modulo its own bugs) because all our dependencies
were extremely reliable and portable and CPAN did a good job of resolving
them.  Since we are preparing to expand outside the purview of Perl/CPAN we
should bundle all the dependencies we add from here on out.

Lucy (and Clownfish) are designed to live within the context of a host
language and its library directories, rather than within the context of an
operating system and its shared library directories (e.g. /usr/local/lib).
There can be multiple installs of Lucy on a system if you have multiple
installs of Perl (and eventually Ruby, Python, etc).  Any dependency we add
has to be able to live harmoniously within this environment.

> Are you planning to stay the course of independence, or is there a point
> you'd consider utilizing outside libraries?

We're bundling the Snowball stemming libraries already.  We'll be bundling the
Lemon parser generator soon.

These two dependencies share a few common traits:

 * They're bare .c/.h files.
 * They are extremely reliable and trouble free[2].
 * Their authors aren't narrow-minded GCC/Linux parochialists (or Windows
   parochialists, for that matter).  Both libraries are standard C and work
   fine across multiple compilers and operating systems.

I'm not opposed to dependencies per se, but they must meet high standards for
portability, reliability and ease-of-integration.

Marvin Humphrey


[1] Charmonizer is actually somewhat closer to being spun off from Lucy than
    Clownfish.

[2] I don't know for certain that Lemon itself is trouble free, but SQLite's
    parser, which is built with Lemon, surely qualifies.


Re: [lucy-dev] C TAP test harnesses

Posted by Nathan Kurz <na...@verse.com>.
On Thu, May 12, 2011 at 9:33 PM, Marvin Humphrey <ma...@rectangular.com> wrote:
> The apreq harness isn't a good replacement candidate in its present
> form, though, because it requires APR.

I tend to like the approach of having everything self-contained, but
if there were candidates I would think the the APR would be high on
the list.  Also, I would guess that a developer only test-suite
wouldn't be much of a hindrance to adoption.

Is there a formal policy on avoiding outside dependencies, or is this
just a general preference?   Are you planning to stay the course of
independence, or is there a point you'd consider utilizing outside
libraries?

--nate

[lucy-dev] C TAP test harnesses

Posted by Marvin Humphrey <ma...@rectangular.com>.
On Thu, May 12, 2011 at 05:24:14PM -0700, Joe Schaefer wrote:
> >   * Port most test files  within trunk/perl/t/ to C.
> 
> If we're in need of a test framework for C I wrote a small TAP-compliant
> test framework for apreq here:
> 
> http://svn.apache.org/repos/asf/httpd/apreq/trunk/library/t/

Great minds think alike.  We have two of those. :)

    http://svn.apache.org/repos/asf/incubator/lucy/trunk/core/Lucy/Test.cfh
    http://svn.apache.org/repos/asf/incubator/lucy/trunk/core/Lucy/Test.c

    http://svn.apache.org/repos/asf/incubator/lucy/trunk/charmonizer/src/Charmonizer/Test.h
    http://svn.apache.org/repos/asf/incubator/lucy/trunk/charmonizer/src/Charmonizer/Test.c

(And another Lucy community member, David Wheeler, authored a JavaScript port
of Test.Simple a few years ago.)

An additional related project of note is APR's test harness, which isn't TAP.

    http://svn.apache.org/repos/asf/apr/apr/trunk/test/abts.h
    http://svn.apache.org/repos/asf/apr/apr/trunk/test/abts.c

Aside from TAP/no-TAP, these test harness libraries are distinguished by their
dependencies.

    ==================================================================
    | Test harness   |  TAP  |  Dependencies                         |
    ------------------------------------------------------------------
    | APR            |  no   | none                                  |
    | apreq          |  yes  | APR                                   |
    | Charmonizer    |  yes  | none                                  |
    | Lucy/Clownfish |  yes  | C99/C++, Charmonizer, Clownfish       |
    ==================================================================

The Lucy/Clownfish test harness is a fork of the one written for
Charmonizer[1].  We have a lot of tests for Lucy, and we're going to
accumulate a lot more over time.  It makes sense to have a C99,
Clownfish-friendly test harness we can customize at will -- so this one, IMO,
we ought to keep.

In contrast, now that Lucy no longer uses the Charmonizer test harness, it's
become less important to us and it would be kind of nice to consolidate it
away.  The apreq harness isn't a good replacement candidate in its present
form, though, because it requires APR.  That leaves the APR test harness.
It's not TAP, though.  I like TAP.  I'm not motivated to do a bunch of work
refactoring something that's TAP and working already.

For the record, there are also all of these out there in the world:

    http://testanything.org/wiki/index.php/TAP_Producers#C_.2F_C.2B.2B

It seems like the ASF could use a decent standalone C TAP library with an
official public API, C89, cross-platform-compatible and with no dependencies.

Marvin Humphrey

[1] Charmonizer is a C configuration prober, like Autoconf and Metaconfig, but
    written in C and Windows-compatible.  See Lucy::Docs::DevGuide for an
    overview of Lucy's layers:
    https://svn.apache.org/repos/asf/incubator/lucy/trunk/core/Lucy/Docs/DevGuide.cfh


Re: [lucy-dev] STATUS file / TODO list

Posted by Marvin Humphrey <ma...@rectangular.com>.
On Thu, May 12, 2011 at 05:24:14PM -0700, Joe Schaefer wrote:
> > I should probably go open JIRA issues for those that don't  have them to
> > explain at greater length and to track progress.
> > 
> > If this  sounds like a good plan to people, I can go build an initial STATUS
> > file for  Lucy using the HTTPD example as a template.
> 
> +1 obviously.
 
I've opened an issue and uploaded a provisional STATUS file:

    https://issues.apache.org/jira/browse/LUCY-150

In addition, I opened a bunch of new issues today explaining TODO tasks.
Here's the list from the STATUS file:

  * Port the Clownfish compiler to C.
    <https://issues.apache.org/jira/browse/LUCY-142>

  * Replace dependency on Parse::RecDescent within Clownfish::Parser with
    the Lemon parser generator. 
    <https://issues.apache.org/jira/browse/LUCY-143>
    <https://issues.apache.org/jira/browse/LUCY-134>

  * Replace dependency on JSON::XS with ???
    <https://issues.apache.org/jira/browse/LUCY-133>

  * Refactor away C89 idioms, since we have chosen the intersection of C99 
    and C++ as our C dialect.
    <https://issues.apache.org/jira/browse/LUCY-144>

  * Port most test files within trunk/perl/t/ to C.
    <https://issues.apache.org/jira/browse/LUCY-149>

I'm not planning to commit STATUS right away since trunk is sort of in code
freeze until 0.1.0 gets cut.

Marvin Humphrey


Re: [lucy-dev] STATUS file / TODO list

Posted by Joe Schaefer <jo...@yahoo.com>.
----- Original Message ----

> From: Marvin Humphrey <ma...@rectangular.com>
> To: lucy-dev@incubator.apache.org
> Sent: Thu, May 12, 2011 8:02:08 PM
> Subject: [lucy-dev] STATUS file / TODO list
>   * Port most test files  within trunk/perl/t/ to C.

If we're in need of a test framework for C I wrote a small TAP-compliant
test framework for apreq here:

http://svn.apache.org/repos/asf/httpd/apreq/trunk/library/t/

(relevant files are at.[ch])

>   * Replace dependency on JSON::XS with ???  (LUCY-133).
> 
> I should probably go open JIRA issues for those that don't  have them to
> explain at greater length and to track progress.
> 
> If this  sounds like a good plan to people, I can go build an initial STATUS
> file for  Lucy using the HTTPD example as a template.

+1 obviously.