[ros-diffs] [cfinck] 41734: - Simplify ERROR_* return values, don't make a difference between "Shutdown for some reason" and "Failed somehow". This should also fix a bug about the entire testing process being canceled when Kdbg is hit. As a consequence, the crash counter was renamed to a "retry counter" and the value for "maxretries" was increased, since the shutdowns in 1st and 2nd stage count as retries now. - Detect whether the same line appears over and over again and reboot the VM in this case to continue with the next test. This is done using a line cache and a configurable value of 50 allowed cache hits before we cancel the process. - Simplify some code by leaving out a block for the STDIN_FILENO fd. - Fix return values in case of early failures in ProcessDebugData. - Use "unsigned int" instead of "int" where appropriate. - Add missing license header after talking with Christoph.

cfinck at svn.reactos.org cfinck at svn.reactos.org
Thu Jul 2 01:30:16 CEST 2009


Author: cfinck
Date: Thu Jul  2 03:30:15 2009
New Revision: 41734

URL: http://svn.reactos.org/svn/reactos?rev=41734&view=rev
Log:
- Simplify ERROR_* return values, don't make a difference between "Shutdown for some reason" and "Failed somehow".
  This should also fix a bug about the entire testing process being canceled when Kdbg is hit.
  As a consequence, the crash counter was renamed to a "retry counter" and the value for "maxretries" was increased, since the shutdowns in 1st and 2nd stage count as retries now.
- Detect whether the same line appears over and over again and reboot the VM in this case to continue with the next test.
  This is done using a line cache and a configurable value of 50 allowed cache hits before we cancel the process.
- Simplify some code by leaving out a block for the STDIN_FILENO fd.
- Fix return values in case of early failures in ProcessDebugData.
- Use "unsigned int" instead of "int" where appropriate.
- Add missing license header after talking with Christoph.

Modified:
    trunk/tools/sysreg2/console.c
    trunk/tools/sysreg2/options.c
    trunk/tools/sysreg2/raddr2line.c
    trunk/tools/sysreg2/sysreg.h
    trunk/tools/sysreg2/sysreg.xml
    trunk/tools/sysreg2/utils.c
    trunk/tools/sysreg2/virt.c

Modified: trunk/tools/sysreg2/console.c
URL: http://svn.reactos.org/svn/reactos/trunk/tools/sysreg2/console.c?rev=41734&r1=41733&r2=41734&view=diff
==============================================================================
--- trunk/tools/sysreg2/console.c [iso-8859-1] (original)
+++ trunk/tools/sysreg2/console.c [iso-8859-1] Thu Jul  2 03:30:15 2009
@@ -1,28 +1,43 @@
+/*
+ * PROJECT:     ReactOS System Regression Testing Utility
+ * LICENSE:     GNU GPLv2 or any later version as published by the Free Software Foundation
+ * PURPOSE:     Processing the incoming debugging data
+ * COPYRIGHT:   Copyright 2008-2009 Christoph von Wittich <christoph_vw at reactos.org>
+ *              Copyright 2009 Colin Finck <colin at reactos.org>
+ */
+
 #include "sysreg.h"
+#define BUFFER_SIZE         512
 
 int ProcessDebugData(const char* tty, int timeout, int stage )
 {
-    char buf[512];
-    char rbuf[512];
+    char Buffer[BUFFER_SIZE];
+    char CacheBuffer[BUFFER_SIZE];
+    char Raddr2LineBuffer[BUFFER_SIZE];
     char* bp;
     int got;
-    int ttyfd, i;
+    int Ret = EXIT_DONT_CONTINUE;
+    int ttyfd;
     struct termios ttyattr, rawattr;
-    int Ret = EXIT_NONCONTINUABLE_ERROR;
-    int KdbgHit = 0;
+    unsigned int CacheHits = 0;
+    unsigned int i;
+    unsigned int KdbgHit = 0;
+
+    /* Initialize CacheBuffer with an empty string */
+    *CacheBuffer = 0;
 
     /* ttyfd is the file descriptor of the virtual COM port */
     if ((ttyfd = open(tty, O_NOCTTY | O_RDWR)) < 0)
     {
         SysregPrintf("error opening tty\n");
-        return false;
+        return Ret;
     }
 
     /* We also monitor STDIN_FILENO, so a user can cancel the process with ESC */
     if (tcgetattr(STDIN_FILENO, &ttyattr) < 0)
     {
         SysregPrintf("tcgetattr failed with error %d\n", errno);
-        return false;
+        return Ret;
     }
 
     rawattr = ttyattr;
@@ -36,10 +51,10 @@
     if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &rawattr) < 0)
     {
         SysregPrintf("tcsetattr failed with error %d\n", errno);
-        return false;
-    }
-
-    while (1)
+        return Ret;
+    }
+
+    for(;;)
     { 
         struct pollfd fds[] = {
             { STDIN_FILENO, POLLIN, 0 },
@@ -60,7 +75,7 @@
         {
             /* timeout */
             SysregPrintf("timeout\n");
-            Ret = EXIT_ERROR;
+            Ret = EXIT_CONTINUE;
             goto cleanup;
         }
 
@@ -70,10 +85,10 @@
             if (!(fds[i].revents & POLLIN))
                 continue;
 
-            bp = buf;
+            bp = Buffer;
 
             /* Read one line or a maximum of 511 bytes into a buffer (leave space for the null character) */
-            while (bp - buf < sizeof(buf) - 1)
+            while (bp - Buffer < (BUFFER_SIZE - 1))
             {
                 got = read(fds[i].fd, bp, 1);
 
@@ -87,10 +102,6 @@
                     /* No more data */
                     break;
                 }
-
-                /* Also break on newlines */
-                if(*bp == '\n')
-                    break;
 
                 if (fds[i].fd == STDIN_FILENO)
                 {
@@ -100,67 +111,94 @@
                 }
                 else
                 {
+                    /* Also break on newlines */
+                    if(*bp == '\n')
+                        break;
+
                     /* KDBG doesn't send a newline */
-                    if ((strstr(buf, "kdb:>")) || 
-                        (strstr(buf, "--- Press q")))
+                    if ((strstr(Buffer, "kdb:>")) || 
+                        (strstr(Buffer, "--- Press q")))
                         break;
                 }
                 
                 ++bp;
             }
 
-            if (bp == buf)
-            {
-                /* This usually means the machine shut down (like in 1st or 2nd stage) */
-                Ret = EXIT_SHUTDOWN;
+            /* The rest of this logic is just about processing the serial output */
+            if(fds[i].fd == STDIN_FILENO)
+                continue;
+
+            /* Check whether the message is of zero length */
+            if (bp == Buffer)
+            {
+                /* This can happen when the machine shut down (like after 1st or 2nd stage)
+                   or after we got a Kdbg backtrace. */
+                Ret = EXIT_CONTINUE;
                 goto cleanup;
             }
 
+            /* Null-terminate the line */
             *(++bp) = 0;
 
-            /* Now check the output */
-            if (fds[i].fd != STDIN_FILENO)
-            {
-                /* Check for "magic" sequences */
-                if (strstr(buf, "kdb:>"))
-                {
-                    ++KdbgHit;
-
-                    if (KdbgHit == 1)
-                    {
-                        /* We hit Kdbg for the first time, get a backtrace for the log */
-                        safewrite(ttyfd, "bt\r", 3);
-                        continue;
-                    }
-                    else
-                    {
-                        /* We hit it yet another time, give up here */
-                        Ret = EXIT_ERROR;
-                        goto cleanup;
-                    }
-                }
-                else if (strstr(buf, "--- Press q"))
-                {
-                    /* Send Return to get more data from Kdbg */
-                    safewrite(ttyfd, "\r", 1);
+            /* Detect whether the same line appears over and over again.
+               If that is the case, cancel this test after a specified number of repetitions. */
+            if(!strcmp(Buffer, CacheBuffer))
+            {
+                ++CacheHits;
+
+                if(CacheHits > AppSettings.MaxCacheHits)
+                {
+                    SysregPrintf("Test seems to be stuck in an endless loop, canceled!\n");
+                    Ret = EXIT_CONTINUE;
+                    goto cleanup;
+                }
+            }
+            else
+            {
+                CacheHits = 0;
+                memcpy(CacheBuffer, Buffer, bp - Buffer);
+            }
+
+            /* Output the line, raddr2line the included addresses if necessary */
+            if (ResolveAddressFromFile(Raddr2LineBuffer, BUFFER_SIZE, Buffer))
+                printf("%s", Raddr2LineBuffer);
+            else
+                printf("%s", Buffer);
+
+            /* Check for "magic" sequences */
+            if (strstr(Buffer, "kdb:>"))
+            {
+                ++KdbgHit;
+
+                if (KdbgHit == 1)
+                {
+                    /* We hit Kdbg for the first time, get a backtrace for the log */
+                    safewrite(ttyfd, "bt\r", 3);
                     continue;
                 }
-                else if (strstr(buf, "SYSREG_ROSAUTOTEST_FAILURE"))
-                {
-                    /* rosautotest itself has problems, so there's no reason to continue */
+                else
+                {
+                    /* We hit it yet another time, give up here */
+                    Ret = EXIT_CONTINUE;
                     goto cleanup;
                 }
-                else if (*AppSettings.Stage[stage].Checkpoint && strstr(buf, AppSettings.Stage[stage].Checkpoint))
-                {
-                    /* We reached a checkpoint, so return success */
-                    Ret = EXIT_CHECKPOINT_REACHED;
-                    goto cleanup;
-                }
-
-                if (ResolveAddressFromFile(rbuf, sizeof(rbuf), buf))
-                    printf("%s", rbuf);
-                else
-                    printf("%s", buf);
+            }
+            else if (strstr(Buffer, "--- Press q"))
+            {
+                /* Send Return to get more data from Kdbg */
+                safewrite(ttyfd, "\r", 1);
+                continue;
+            }
+            else if (strstr(Buffer, "SYSREG_ROSAUTOTEST_FAILURE"))
+            {
+                /* rosautotest itself has problems, so there's no reason to continue */
+                goto cleanup;
+            }
+            else if (*AppSettings.Stage[stage].Checkpoint && strstr(Buffer, AppSettings.Stage[stage].Checkpoint))
+            {
+                /* We reached a checkpoint, so return success */
+                Ret = EXIT_CHECKPOINT_REACHED;
+                goto cleanup;
             }
         }
     }
@@ -172,4 +210,3 @@
 
     return Ret;
 }
-

Modified: trunk/tools/sysreg2/options.c
URL: http://svn.reactos.org/svn/reactos/trunk/tools/sysreg2/options.c?rev=41734&r1=41733&r2=41734&view=diff
==============================================================================
--- trunk/tools/sysreg2/options.c [iso-8859-1] (original)
+++ trunk/tools/sysreg2/options.c [iso-8859-1] Thu Jul  2 03:30:15 2009
@@ -1,3 +1,11 @@
+/*
+ * PROJECT:     ReactOS System Regression Testing Utility
+ * LICENSE:     GNU GPLv2 or any later version as published by the Free Software Foundation
+ * PURPOSE:     Loading the utility settings
+ * COPYRIGHT:   Copyright 2008-2009 Christoph von Wittich <christoph_vw at reactos.org>
+ *              Copyright 2009 Colin Finck <colin at reactos.org>
+ */
+
 #include "sysreg.h"
 
 bool LoadSettings(const char* XmlConfig)
@@ -51,10 +59,18 @@
     if (obj)
         xmlXPathFreeObject(obj);
 
-    obj = xmlXPathEval(BAD_CAST"number(/settings/general/maxcrashes/@value)",ctxt);
+    obj = xmlXPathEval(BAD_CAST"number(/settings/general/maxcachehits/@value)",ctxt);
     if ((obj != NULL) && (obj->type == XPATH_NUMBER))
     {
-        AppSettings.MaxCrashes = (int)obj->floatval;
+        AppSettings.MaxCacheHits = (unsigned int)obj->floatval;
+    }
+    if (obj)
+        xmlXPathFreeObject(obj);
+
+    obj = xmlXPathEval(BAD_CAST"number(/settings/general/maxretries/@value)",ctxt);
+    if ((obj != NULL) && (obj->type == XPATH_NUMBER))
+    {
+        AppSettings.MaxRetries = (unsigned int)obj->floatval;
     }
     if (obj)
         xmlXPathFreeObject(obj);

Modified: trunk/tools/sysreg2/raddr2line.c
URL: http://svn.reactos.org/svn/reactos/trunk/tools/sysreg2/raddr2line.c?rev=41734&r1=41733&r2=41734&view=diff
==============================================================================
--- trunk/tools/sysreg2/raddr2line.c [iso-8859-1] (original)
+++ trunk/tools/sysreg2/raddr2line.c [iso-8859-1] Thu Jul  2 03:30:15 2009
@@ -1,3 +1,11 @@
+/*
+ * PROJECT:     ReactOS System Regression Testing Utility
+ * LICENSE:     GNU GPLv2 or any later version as published by the Free Software Foundation
+ * PURPOSE:     Integrated raddr2line tool for getting source references from addresses
+ * COPYRIGHT:   Copyright 2008-2009 Christoph von Wittich <christoph_vw at reactos.org>
+ *              Copyright 2009 Colin Finck <colin at reactos.org>
+ */
+
 #include "sysreg.h"
 
 bool GetPackagePath(char* Buffer, int BuffSize, char* Module)

Modified: trunk/tools/sysreg2/sysreg.h
URL: http://svn.reactos.org/svn/reactos/trunk/tools/sysreg2/sysreg.h?rev=41734&r1=41733&r2=41734&view=diff
==============================================================================
--- trunk/tools/sysreg2/sysreg.h [iso-8859-1] (original)
+++ trunk/tools/sysreg2/sysreg.h [iso-8859-1] Thu Jul  2 03:30:15 2009
@@ -1,3 +1,11 @@
+/*
+ * PROJECT:     ReactOS System Regression Testing Utility
+ * LICENSE:     GNU GPLv2 or any later version as published by the Free Software Foundation
+ * PURPOSE:     Shared header
+ * COPYRIGHT:   Copyright 2008-2009 Christoph von Wittich <christoph_vw at reactos.org>
+ *              Copyright 2009 Colin Finck <colin at reactos.org>
+ */
+
 #include <fcntl.h>
 #include <libvirt.h>
 #include <poll.h>
@@ -16,9 +24,8 @@
 #include <sys/sysinfo.h>
 
 #define EXIT_CHECKPOINT_REACHED     0
-#define EXIT_SHUTDOWN               1
-#define EXIT_ERROR                  2
-#define EXIT_NONCONTINUABLE_ERROR   3
+#define EXIT_CONTINUE               1
+#define EXIT_DONT_CONTINUE          2
 #define NUM_STAGES                  3
 
 typedef struct {
@@ -27,13 +34,14 @@
 } stage;
 
 typedef struct {
-    int MaxCrashes;
     int Timeout;
     char Filename[255];
     char Name[80];
     char HardDiskImage[255];
     int ImageSize;
     stage Stage[3];
+    unsigned int MaxCacheHits;
+    unsigned int MaxRetries;
 } Settings;
 
 Settings AppSettings;

Modified: trunk/tools/sysreg2/sysreg.xml
URL: http://svn.reactos.org/svn/reactos/trunk/tools/sysreg2/sysreg.xml?rev=41734&r1=41733&r2=41734&view=diff
==============================================================================
--- trunk/tools/sysreg2/sysreg.xml [iso-8859-1] (original)
+++ trunk/tools/sysreg2/sysreg.xml [iso-8859-1] Thu Jul  2 03:30:15 2009
@@ -6,8 +6,13 @@
 		<!-- size of the hdd image in MB -->
 		<hdd size="512"/>
 
-		<!-- Maximum number of crashes allowed before we kill the VM -->
-		<maxcrashes value="10" />
+		<!-- Maximum number of line cache hits allowed before we cancel this test and proceed with the next one.
+		     See "console.c" code for more details. -->
+		<maxcachehits value="50" />
+
+		<!-- Maximum number of retries allowed before we cancel the entire testing process.
+		     Note that this value needs to be at least 2, since the shutdowns after 1st and 2nd stage count as retries. -->
+		<maxretries value="15" />
 	</general>
 	<firststage bootdevice="cdrom">
 	</firststage>

Modified: trunk/tools/sysreg2/utils.c
URL: http://svn.reactos.org/svn/reactos/trunk/tools/sysreg2/utils.c?rev=41734&r1=41733&r2=41734&view=diff
==============================================================================
--- trunk/tools/sysreg2/utils.c [iso-8859-1] (original)
+++ trunk/tools/sysreg2/utils.c [iso-8859-1] Thu Jul  2 03:30:15 2009
@@ -1,3 +1,11 @@
+/*
+ * PROJECT:     ReactOS System Regression Testing Utility
+ * LICENSE:     GNU GPLv2 or any later version as published by the Free Software Foundation
+ * PURPOSE:     Various auxiliary functions
+ * COPYRIGHT:   Copyright 2008-2009 Christoph von Wittich <christoph_vw at reactos.org>
+ *              Copyright 2009 Colin Finck <colin at reactos.org>
+ */
+
 #include "sysreg.h"
 
 ssize_t safewrite(int fd, const void *buf, size_t count)

Modified: trunk/tools/sysreg2/virt.c
URL: http://svn.reactos.org/svn/reactos/trunk/tools/sysreg2/virt.c?rev=41734&r1=41733&r2=41734&view=diff
==============================================================================
--- trunk/tools/sysreg2/virt.c [iso-8859-1] (original)
+++ trunk/tools/sysreg2/virt.c [iso-8859-1] Thu Jul  2 03:30:15 2009
@@ -1,3 +1,11 @@
+/*
+ * PROJECT:     ReactOS System Regression Testing Utility
+ * LICENSE:     GNU GPLv2 or any later version as published by the Free Software Foundation
+ * PURPOSE:     Main entry point and controlling the virtual machine
+ * COPYRIGHT:   Copyright 2008-2009 Christoph von Wittich <christoph_vw at reactos.org>
+ *              Copyright 2009 Colin Finck <colin at reactos.org>
+ */
+
 #include "sysreg.h"
 
 bool GetConsole(virDomainPtr vDomPtr, char* console)
@@ -145,13 +153,13 @@
     virConnectPtr vConn = NULL;
     virDomainPtr vDom;
     virDomainInfo info;
-    int Crashes;
-    int Stage;
     char qemu_img_cmdline[300];
     FILE* file;
     char config[255];
-    int Ret = EXIT_NONCONTINUABLE_ERROR;
+    int Ret = EXIT_DONT_CONTINUE;
     char console[50];
+    unsigned int Retries;
+    unsigned int Stage;
 
     if (argc == 2)
         strcpy(config, argv[1]);
@@ -193,7 +201,7 @@
 
     for(Stage = 0; Stage < NUM_STAGES; Stage++)
     {
-        for(Crashes = 0; Crashes < AppSettings.MaxCrashes; Crashes++)
+        for(Retries = 0; Retries < AppSettings.MaxRetries; Retries++)
         {
             vDom = LaunchVirtualMachine(vConn, AppSettings.Filename,
                     AppSettings.Stage[Stage].BootDevice);
@@ -223,19 +231,19 @@
             /* If we have a checkpoint to reach for success, assume that
                the application used for running the tests (probably "rosautotest")
                continues with the next test after a VM restart. */
-            if (Ret == EXIT_ERROR && *AppSettings.Stage[Stage].Checkpoint)
-                SysregPrintf("Crash %d encountered, resuming the testing process\n", Crashes);
+            if (Ret == EXIT_CONTINUE && *AppSettings.Stage[Stage].Checkpoint)
+                SysregPrintf("Rebooting VM (retry %d)\n", Retries + 1);
             else
                 break;
         }
 
-        if (Crashes == AppSettings.MaxCrashes)
-        {
-            SysregPrintf("Maximum number of allowed crashes exceeded, aborting!\n");
-            break;
-        }
-
-        if (Ret == EXIT_ERROR || Ret == EXIT_NONCONTINUABLE_ERROR)
+        if (Retries == AppSettings.MaxRetries)
+        {
+            SysregPrintf("Maximum number of allowed retries exceeded, aborting!\n");
+            break;
+        }
+
+        if (Ret == EXIT_CONTINUE || Ret == EXIT_DONT_CONTINUE)
             break;
     }
 
@@ -250,15 +258,11 @@
             SysregPrintf("Status: Reached the checkpoint!\n");
             break;
 
-        case EXIT_SHUTDOWN:
-            SysregPrintf("Status: Machine shut down, but did not reach the checkpoint!\n");
-            break;
-
-        case EXIT_ERROR:
+        case EXIT_CONTINUE:
             SysregPrintf("Status: Failed to reach the checkpoint!\n");
             break;
 
-        case EXIT_NONCONTINUABLE_ERROR:
+        case EXIT_DONT_CONTINUE:
             SysregPrintf("Status: Testing process aborted!\n");
             break;
     }



More information about the Ros-diffs mailing list