cURL / Mailing Lists / curl-library / Single Mail

curl-library

[PATCH] Script to convert --libcurl test

From: Colin Hogben <curl_at_pythontech.co.uk>
Date: Tue, 27 Dec 2011 18:37:57 +0000

This script reads a test definition which exercises curl's --libcurl
option and generates either compilable source code for a new test
tool, or a new test definition which runs the tool and expects the
same output.

---
 tests/convsrctest.pl |  250 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 250 insertions(+), 0 deletions(-)
 create mode 100755 tests/convsrctest.pl
diff --git a/tests/convsrctest.pl b/tests/convsrctest.pl
new file mode 100755
index 0000000..56a4f85
--- /dev/null
+++ b/tests/convsrctest.pl
@@ -0,0 +1,250 @@
+#!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel_at_haxx.se>, et al.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution. The terms
+# are also available at http://curl.haxx.se/docs/copyright.html.
+#
+# You may opt to use, copy, modify, merge, publish, distribute and/or sell
+# copies of the Software, and permit persons to whom the Software is
+# furnished to do so, under the terms of the COPYING file.
+#
+# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+# KIND, either express or implied.
+#
+#***************************************************************************
+
+#=======================================================================
+# Read a test definition which exercises curl's --libcurl option.
+# Generate either compilable source code for a new test tool,
+# or a new test definition which runs the tool and expects the
+# same output.
+# This should verify that the --libcurl code really does perform
+# the same actions as the original curl invocation.
+#=======================================================================
+use strict;
+require "getpart.pm";
+
+# Boilerplate code for test tool
+my $head =
+'#include "test.h"
+#include "memdebug.h"
+
+int test(char *URL)
+{
+  CURLcode res;
+  CURL *curl;
+';
+# Other declarations from --libcurl come here
+# e.g. curl_slist
+my $init =
+'
+  if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+    fprintf(stderr, "curl_global_init() failed\n");
+    return TEST_ERR_MAJOR_BAD;
+  }
+
+  if ((curl = curl_easy_init()) == NULL) {
+    fprintf(stderr, "curl_easy_init() failed\n");
+    curl_global_cleanup();
+    return TEST_ERR_MAJOR_BAD;
+  }
+';
+# Option setting comes here
+my $doit =
+'
+  res = curl_easy_perform(curl);
+
+test_cleanup:
+';
+# Other cleanup code comes here
+my $exit =
+'  curl_easy_cleanup(curl);
+  curl_global_cleanup();
+
+  return (int)res;
+}
+';
+
+my $myname = leaf($0);
+sub usage {die "Usage: $myname -c|-test=num testfile\n";}
+
+sub main {
+    @ARGV == 2
+        or usage;
+    my($opt,$testfile) = @ARGV;
+
+    if(loadtest($testfile)) {
+        die "$myname: $testfile doesn't look like a test case\n";
+    }
+
+    my $comment = sprintf("DO NOT EDIT - generated from %s by %s",
+                          leaf($testfile), $myname);
+    if($opt eq '-c') {
+        generate_c($comment);
+    }
+    elsif(my($num) = $opt =~ /^-test=(\d+)$/) {
+        generate_test($comment, $num);
+    }
+    else {
+        usage;
+    }
+}
+
+sub generate_c {
+    my($comment) = @_;
+    # Fetch the generated code, which is the output file checked by
+    # the old test.
+    my @libcurl = getpart("verify", "file")
+        or die "$myname: no <verify><file> section found\n";
+
+    # Mangle the code into a suitable form for a test tool.
+    # We want to extract the important parts (declarations,
+    # URL, setopt calls, cleanup code) from the --libcurl
+    # boilerplate and insert them into a new boilerplate.
+    my(@decl,@setopt,@clean);
+    my($seen_main,$seen_setopt,$seen_perform,$seen_return);
+    foreach (@libcurl) {
+        # Check state changes first (even though it
+        # duplicates some matches) so that the other tests
+        # are in a logical order).
+        if(/^int main/) {
+            $seen_main = 1;
+        }
+        if($seen_main and /curl_easy_setopt/) {
+            # Don't match 'curl_easy_setop' in comment!
+            $seen_setopt = 1;
+        }
+        if(/curl_easy_perform/) {
+            $seen_perform = 1;
+        }
+        if(/^\s*return/) {
+            $seen_return = 1;
+        }
+
+        # Now filter the code according to purpose
+        if(! $seen_main) {
+            next;
+        }
+        elsif(! $seen_setopt) {
+            if(/^\s*(int main|\{|CURLcode |CURL )/) {
+                next;
+            }
+            else {
+                push @decl, $_;
+            }
+        }
+        elsif(! $seen_perform) {
+            if (/CURLOPT_URL/) {
+                # URL will be passed in as argument
+                s/\"[^\"]*\"/URL/;
+            }
+            # Convert to macro wrapper
+            s/curl_easy_setopt\(\w+/test_setopt\(curl/;
+            push @setopt, $_;
+        }
+        elsif(! $seen_return) {
+            if(/curl_easy_(perform|cleanup)/) {
+                next;
+            }
+            else {
+                push @clean, $_;
+            }
+        }
+    }
+
+    print ("/* $comment */\n",
+           $head,
+           @decl,
+           $init,
+           @setopt,
+           $doit,
+           @clean,
+           $exit);
+}
+
+sub generate_test {
+    my($comment,$newnumber) = @_;
+    my @libcurl = getpart("verify", "file")
+        or die "$myname: no <verify><file> section found\n";
+    my $url;
+    foreach (@libcurl) {
+        if(my($u) = /CURLOPT_URL, \"([^\"]*)\"/) {
+            $url = $u;
+        }
+    }
+    die "$myname: CURLOPT_URL not found\n"
+        unless defined $url;
+
+    # The new test is identical to the old except:
+    # - no <verify><file> section (was --libcurl output)
+    # - <client><tool> set to our new C program
+    # - <client><command> is the URL from CURLOPT_URL
+    my @new;
+    my(@path,$path,$skip);
+    foreach (getall()) {
+        if(my($end) = /\s*<(\/?)testcase>/) {
+            push @new, $_;
+            push @new, "# $comment\n"
+                unless $end;
+        }
+        elsif(my($tag) = /^\s*<(\w+)/) {
+            push @path, $tag;
+            $path = join '/', @path;
+            if($path eq 'verify/file') {
+                $skip = 1;
+            }
+            push @new, $_
+                unless $skip;
+            if($path eq 'client') {
+                push @new, ("<tool>\n",
+                            "lib$newnumber\n",
+                            "</tool>\n");
+            }
+            elsif($path eq 'client/command') {
+                push @new, sh_quote($url)."\n";
+            }
+        }
+        elsif(my($etag) = /^\s*<\/(\w+)/) {
+            my $tag = pop @path;
+            die "$myname: mismatched </$etag>\n"
+                unless $tag eq $etag;
+            push @new, $_
+                unless $skip;
+            $skip --
+                if $path eq 'verify/file';
+            $path = join '/', @path;
+        }
+        else {
+            if($path eq 'client/command') {
+                # Replaced above
+            }
+            else {
+                push @new, $_
+                    unless $skip;
+            }
+        }
+    }
+    print @new;
+}
+
+sub leaf {
+    # Works for POSIX filenames
+    (my $path = shift) =~ s!.*/!!;
+    return $path;
+}
+
+sub sh_quote {
+    my $word = shift;
+    $word =~ s/[\$\"\'\\]/\\$&/g;
+    return '"' . $word . '"';
+}
+
+main;
-- 
1.6.5.6
--------------040709030700070807000602
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html
--------------040709030700070807000602--
Received on 2001-09-17