WIP: pg_regress updates for vc++ bulid - Mailing list pgsql-patches

From Magnus Hagander
Subject WIP: pg_regress updates for vc++ bulid
Date
Msg-id 459582E5.2060705@hagander.net
Whole thread Raw
Responses Re: pg_regress updates for vc++ bulid  (Magnus Hagander <magnus@hagander.net>)
List pgsql-patches
Hello!

Per some previous discussion that I can't really recall if it was on or
off list, here is a WIP patch to make pg_regress run completely outside
of msys on win32.

The change needed is that the processing of files from input/ and
output/ into sql/ and expected/ is moved from the Makefile and into
pg_regress itself.

I have tested on Win32 non-MSVC and on Linux (non-VPATH), and it appears
to work there.

Still to be done is the "make install" part on MSVC build, currently
#ifdef:ed out. While working on that, I'd appreciate some comments on
the patch in general - if there are more things I need to fix before it
can be considered. Particularly I'm concerned around the VPATH stuff,
since I've never used that myself.

//Magnus
Index: src/include/port.h
===================================================================
RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/include/port.h,v
retrieving revision 1.106
diff -c -r1.106 port.h
*** src/include/port.h    28 Nov 2006 01:12:33 -0000    1.106
--- src/include/port.h    29 Dec 2006 18:31:27 -0000
***************
*** 46,51 ****
--- 46,56 ----
  extern bool get_home_path(char *ret_path);
  extern void get_parent_directory(char *path);

+
+ /* port/dirmod.c */
+ extern char **pgfnames(char *path);
+ extern void pgfnames_cleanup(char **filenames);
+
  /*
   *    is_absolute_path
   *
Index: src/port/dirmod.c
===================================================================
RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/port/dirmod.c,v
retrieving revision 1.45
diff -c -r1.45 dirmod.c
*** src/port/dirmod.c    4 Dec 2006 22:23:40 -0000    1.45
--- src/port/dirmod.c    29 Dec 2006 18:32:36 -0000
***************
*** 287,298 ****


  /*
!  * fnames
   *
   * return a list of the names of objects in the argument directory
   */
! static char **
! fnames(char *path)
  {
      DIR           *dir;
      struct dirent *file;
--- 287,298 ----


  /*
!  * pgfnames
   *
   * return a list of the names of objects in the argument directory
   */
! char **
! pgfnames(char *path)
  {
      DIR           *dir;
      struct dirent *file;
***************
*** 357,368 ****


  /*
!  *    fnames_cleanup
   *
   *    deallocate memory used for filenames
   */
! static void
! fnames_cleanup(char **filenames)
  {
      char      **fn;

--- 357,368 ----


  /*
!  *    pgfnames_cleanup
   *
   *    deallocate memory used for filenames
   */
! void
! pgfnames_cleanup(char **filenames)
  {
      char      **fn;

***************
*** 394,400 ****
       * we copy all the names out of the directory before we start modifying
       * it.
       */
!     filenames = fnames(path);

      if (filenames == NULL)
          return false;
--- 394,400 ----
       * we copy all the names out of the directory before we start modifying
       * it.
       */
!     filenames = pgfnames(path);

      if (filenames == NULL)
          return false;
***************
*** 415,421 ****
              if (!rmtree(filepath, true))
              {
                  /* we already reported the error */
!                 fnames_cleanup(filenames);
                  return false;
              }
          }
--- 415,421 ----
              if (!rmtree(filepath, true))
              {
                  /* we already reported the error */
!                 pgfnames_cleanup(filenames);
                  return false;
              }
          }
***************
*** 433,439 ****
              goto report_and_fail;
      }

!     fnames_cleanup(filenames);
      return true;

  report_and_fail:
--- 433,439 ----
              goto report_and_fail;
      }

!     pgfnames_cleanup(filenames);
      return true;

  report_and_fail:
***************
*** 444,449 ****
      fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"),
              filepath, strerror(errno));
  #endif
!     fnames_cleanup(filenames);
      return false;
  }
--- 444,449 ----
      fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"),
              filepath, strerror(errno));
  #endif
!     pgfnames_cleanup(filenames);
      return false;
  }
Index: src/test/regress/GNUmakefile
===================================================================
RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/GNUmakefile,v
retrieving revision 1.62
diff -c -r1.62 GNUmakefile
*** src/test/regress/GNUmakefile    21 Jul 2006 00:24:04 -0000    1.62
--- src/test/regress/GNUmakefile    29 Dec 2006 20:44:54 -0000
***************
*** 40,46 ****
  # stuff to pass into build of pg_regress
  EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \
      '-DMAKEPROG="$(MAKE)"' \
!     '-DSHELLPROG="$(SHELL)"'

  ##
  ## Prepare for tests
--- 40,47 ----
  # stuff to pass into build of pg_regress
  EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \
      '-DMAKEPROG="$(MAKE)"' \
!     '-DSHELLPROG="$(SHELL)"' \
!     '-DDLSUFFIX="$(DLSUFFIX)"'

  ##
  ## Prepare for tests
***************
*** 83,96 ****
      rm -f $(NAME)$(DLSUFFIX)
      $(LN_S) $(shlib) $(NAME)$(DLSUFFIX)

- # Build test input and expected files
-
- file_list := copy create_function_1 create_function_2 misc constraints tablespace
- input_files  := $(foreach file, $(file_list), sql/$(file).sql)
- output_files := $(foreach file, $(file_list), expected/$(file).out)
-
- all: $(input_files) $(output_files)
-
  ifneq ($(PORTNAME),win32)
  abs_srcdir := $(shell cd $(srcdir) && pwd)
  abs_builddir := $(shell pwd)
--- 84,89 ----
***************
*** 99,120 ****
  abs_builddir := $(shell pwd -W)
  endif

- testtablespace := $(abs_builddir)/testtablespace
-
-
- define sed-command
- sed -e 's,@abs_srcdir@,$(abs_srcdir),g' \
-     -e 's,@abs_builddir@,$(abs_builddir),g' \
-     -e 's,@testtablespace@,$(testtablespace),g' \
-     -e 's/@DLSUFFIX@/$(DLSUFFIX)/g' $< >$@
- endef
-
- $(input_files): sql/%.sql: input/%.source
-     $(sed-command)
-
- $(output_files): expected/%.out: output/%.source
-     $(sed-command)
-
  # When doing a VPATH build, copy over the remaining .sql and .out
  # files so that the driver script can find them.  We have to use an
  # absolute path for the targets, because otherwise make will try to
--- 92,97 ----
***************
*** 148,154 ****
  check: all
      -rm -rf ./testtablespace
      mkdir ./testtablespace
!     ./pg_regress --temp-install=./tmp_check --top-builddir=$(top_builddir) --temp-port=$(TEMP_PORT)
--schedule=$(srcdir)/parallel_schedule--multibyte=$(MULTIBYTE) --load-language=plpgsql $(MAXCONNOPT) $(NOLOCALE) 

  installcheck: all
      -rm -rf ./testtablespace
--- 125,131 ----
  check: all
      -rm -rf ./testtablespace
      mkdir ./testtablespace
!     ./pg_regress --temp-install=./tmp_check --top-builddir=$(top_builddir) --srcdir=$(abs_srcdir)
--temp-port=$(TEMP_PORT)--schedule=$(srcdir)/parallel_schedule --multibyte=$(MULTIBYTE) --load-language=plpgsql
$(MAXCONNOPT)$(NOLOCALE) 

  installcheck: all
      -rm -rf ./testtablespace
Index: src/test/regress/pg_regress.c
===================================================================
RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/pg_regress.c,v
retrieving revision 1.23
diff -c -r1.23 pg_regress.c
*** src/test/regress/pg_regress.c    4 Oct 2006 00:30:14 -0000    1.23
--- src/test/regress/pg_regress.c    29 Dec 2006 20:48:04 -0000
***************
*** 62,68 ****
--- 62,70 ----
  static char *libdir = LIBDIR;
  static char *datadir = PGSHAREDIR;
  static char *host_platform = HOST_TUPLE;
+ #ifndef WIN32_ONLY_COMPILER
  static char *makeprog = MAKEPROG;
+ #endif

  #ifndef WIN32                    /* not used in WIN32 case */
  static char *shellprog = SHELLPROG;
***************
*** 90,95 ****
--- 92,98 ----
  static char *hostname = NULL;
  static int    port = -1;
  static char *user = NULL;
+ static char *srcdir = NULL;

  /* internal variables */
  static const char *progname;
***************
*** 106,111 ****
--- 109,119 ----
  static int    fail_count = 0;
  static int    fail_ignore_count = 0;

+ static bool
+ directory_exists(const char *dir);
+ static void
+ make_directory(const char *dir);
+
  static void
  header(const char *fmt,...)
  /* This extension allows gcc to check the format string for consistency with
***************
*** 302,307 ****
--- 310,436 ----
  }

  /*
+  * Replace all occurances of a string in a string with a different stirng.
+  * NOTE: Assumes there is enough room in the target buffer!
+  */
+ static void
+ replace_string(char *string, char *replace, char *replacement)
+ {
+     char *ptr;
+
+     while ((ptr = strstr(string, replace)) != NULL)
+     {
+         char *dup = strdup(string);
+
+         strncpy(string, dup, ptr-string);
+         string[ptr-string]=0;
+         strcat(string, replacement);
+         strcat(string, dup+(ptr-string)+strlen(replace));
+         free(dup);
+     }
+ }
+
+ /*
+  * Convert *.source in input/ and output/ into actual files used by the
+  * regression tests in sql/ and expected/.
+  */
+ static void
+ convert_sourcefiles_in(char *source, char *dest, char *suffix)
+ {
+     char abs_srcdir[MAXPGPATH];
+     char abs_builddir[MAXPGPATH];
+     char testtablespace[MAXPGPATH];
+     char **name;
+     char **names = pgfnames(source);
+ #ifdef WIN32
+     char *c;
+ #endif
+
+     if (!names)
+         /* Error logged in pgfnames */
+         exit_nicely(2);
+
+     if (!getcwd(abs_builddir, sizeof(abs_builddir)))
+     {
+         fprintf(stderr, _("%s: could not get current directory: %s\n"),
+             progname, strerror(errno));
+         exit_nicely(2);
+     }
+     if (srcdir)
+         strcpy(abs_srcdir, srcdir);
+     else
+         strcpy(abs_srcdir, abs_builddir);
+ #ifdef WIN32
+     for (c = abs_builddir; *c; c++)
+         if (*c == '\\')
+             *c = '/';
+     for (c = abs_srcdir; *c; c++)
+         if (*c == '\\')
+             *c = '/';
+ #endif
+
+
+     snprintf(testtablespace, sizeof(testtablespace), "%s/testtablespace", abs_builddir);
+     if (directory_exists(testtablespace))
+         rmtree(testtablespace, true);
+     make_directory(testtablespace);
+
+     for (name = names; *name; name++)
+     {
+         char srcfile[MAXPGPATH];
+         char destfile[MAXPGPATH];
+         FILE *infile, *outfile;
+         char line[1024];
+
+         if (strlen(*name) < 8)
+             continue;
+         if (strcmp(*name+strlen(*name)-7,".source"))
+             continue;
+
+         strcpy(srcfile,source);
+         strcat(srcfile, *name);
+         strcpy(destfile,dest);
+         strncat(destfile, *name, strlen(*name)-6);
+         strcat(destfile,suffix);
+
+         infile = fopen(srcfile,"r");
+         if (!infile)
+         {
+             fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
+                     progname, srcfile, strerror(errno));
+             exit_nicely(2);
+         }
+         outfile = fopen(destfile,"w");
+         if (!outfile)
+         {
+             fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"),
+                 progname, destfile, strerror(errno));
+             exit_nicely(2);
+         }
+         while (fgets(line, sizeof(line), infile))
+         {
+             replace_string(line,"@abs_srcdir@", abs_srcdir);
+             replace_string(line,"@abs_builddir@", abs_builddir);
+             replace_string(line,"@testtablespace@", testtablespace);
+             replace_string(line,"@DLSUFFIX@", DLSUFFIX);
+             fputs(line, outfile);
+         }
+         fclose(infile);
+         fclose(outfile);
+     }
+
+     pgfnames_cleanup(names);
+ }
+
+ static void
+ convert_sourcefiles(void)
+ {
+     convert_sourcefiles_in("input/","sql/","sql");
+     convert_sourcefiles_in("output/","expected/","out");
+ }
+
+ /*
   * Scan resultmap file to find which platform-specific expected files to use.
   *
   * The format of each line of the file is
***************
*** 564,569 ****
--- 693,699 ----
              printf(_("(using postmaster on Unix socket, default port)\n"));
      }

+     convert_sourcefiles();
      load_resultmap();
  }

***************
*** 1293,1298 ****
--- 1423,1429 ----
      printf(_("  --outputdir=DIR           place output files in DIR (default \".\")\n"));
      printf(_("  --schedule=FILE           use test ordering schedule from FILE\n"));
      printf(_("                            (may be used multiple times to concatenate)\n"));
+     printf(_("  --srcdir=DIR              absolute path to source directory (for VPATH builds)\n"));
      printf(_("  --temp-install=DIR        create a temporary installation in DIR\n"));
      printf(_("  --no-locale               use C locale\n"));
      printf(_("\n"));
***************
*** 1340,1345 ****
--- 1471,1477 ----
          {"port", required_argument, NULL, 14},
          {"user", required_argument, NULL, 15},
          {"psqldir", required_argument, NULL, 16},
+         {"srcdir", required_argument, NULL, 17},
          {NULL, 0, NULL, 0}
      };

***************
*** 1432,1437 ****
--- 1564,1572 ----
                  if (strlen(optarg))
                      psqldir = strdup(optarg);
                  break;
+             case 17:
+                 srcdir = strdup(optarg);
+                 break;
              default:
                  /* getopt_long already emitted a complaint */
                  fprintf(stderr, _("\nTry \"%s -h\" for more information.\n"),
***************
*** 1487,1492 ****
--- 1622,1628 ----
              make_directory(buf);

          /* "make install" */
+ #ifndef WIN32_ONLY_COMPILER
          snprintf(buf, sizeof(buf),
                   SYSTEMQUOTE "\"%s\" -C \"%s\" DESTDIR=\"%s/install\" install with_perl=no with_python=no >
\"%s/log/install.log\"2>&1" SYSTEMQUOTE, 
                   makeprog, top_builddir, temp_install, outputdir);
***************
*** 1495,1500 ****
--- 1631,1639 ----
              fprintf(stderr, _("\n%s: installation failed\nExamine %s/log/install.log for the reason.\nCommand was:
%s\n"),progname, outputdir, buf); 
              exit_nicely(2);
          }
+ #else
+         fprintf(stderr,"FIXME: can't install yet");
+ #endif

          /* initdb */
          header(_("initializing database system"));
Index: src/test/regress/resultmap
===================================================================
RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/test/regress/resultmap,v
retrieving revision 1.83
diff -c -r1.83 resultmap
*** src/test/regress/resultmap    3 Aug 2006 17:04:00 -0000    1.83
--- src/test/regress/resultmap    29 Dec 2006 19:51:45 -0000
***************
*** 1,8 ****
--- 1,11 ----
  float4/i.86-pc-mingw32=float4-exp-three-digits
+ float4/i.86-pc-win32vc=float4-exp-three-digits
  float8/i.86-.*-freebsd=float8-small-is-zero
  float8/i.86-.*-openbsd=float8-small-is-zero
  float8/i.86-.*-netbsd=float8-small-is-zero
  float8/m68k-.*-netbsd=float8-small-is-zero
  float8/i.86-pc-mingw32=float8-exp-three-digits-win32
+ float8/i.86-pc-win32vc=float8-exp-three-digits-win32
  float8/i.86-pc-cygwin=float8-small-is-zero
  int8/i.86-pc-mingw32=int8-exp-three-digits
+ int8/i.86-pc-win32vc=int8-exp-three-digits
Index: src/tools/msvc/mkvcbuild.pl
===================================================================
RCS file: c:/prog/cvsrepo/pgsql/pgsql/src/tools/msvc/mkvcbuild.pl,v
retrieving revision 1.8
diff -c -r1.8 mkvcbuild.pl
*** src/tools/msvc/mkvcbuild.pl    21 Nov 2006 17:54:26 -0000    1.8
--- src/tools/msvc/mkvcbuild.pl    29 Dec 2006 19:50:59 -0000
***************
*** 255,264 ****
  }


! # Regression DLLs
  my $regress = $solution->AddProject('regress','dll','misc');
  $regress->AddFile('src\test\regress\regress.c');
  $regress->AddReference($postgres);

  $solution->Save();

--- 255,271 ----
  }


! # Regression DLL and EXE
  my $regress = $solution->AddProject('regress','dll','misc');
  $regress->AddFile('src\test\regress\regress.c');
  $regress->AddReference($postgres);
+
+ my $pgregress = $solution->AddProject('pg_regress','exe','misc');
+ $pgregress->AddFile('src\test\regress\pg_regress.c');
+ $pgregress->AddIncludeDir('src\port');
+ $pgregress->AddDefine('HOST_TUPLE="i686-pc-win32vc"');
+ $pgregress->AddDefine('FRONTEND');
+ $pgregress->AddReference($libpgport);

  $solution->Save();


pgsql-patches by date:

Previous
From: Magnus Hagander
Date:
Subject: Small vcbuild patch
Next
From: Andrew Dunstan
Date:
Subject: Re: [HACKERS] Recent SIGSEGV failures in buildfarm HEAD