Ejemplo n.º 1
0
void
RLFEAddLog(
    CDirectory *pDir,
    RLFE_STATUS status,
    const char *testName,
    const char *subTestName,
    const char *logText
)
{
    int pathLen, logLen, num;
    BYTE buf[4];
    char pathBuf[BUFFER_SIZE], *path;

    ASSERTNR(testName || subTestName);
    ASSERTNR(logText);

    path = pathBuf;
    if (testName)
        path += sprintf_s(path, REMAININGARRAYLEN(pathBuf, path), "%c%s", PIPE_SEP_CHAR, testName);
    if (subTestName)
        path += sprintf_s(path, REMAININGARRAYLEN(pathBuf, path), "%c%s", PIPE_SEP_CHAR, subTestName);

    // String has a leading PIPE_SEP_CHAR, so chop that off.

    path = pathBuf + 1;
    pathLen = (int)strlen(path);
    ASSERTNR(pathLen < BUFFER_SIZE - 1);

    logLen = (int)strlen(logText);

    num = pDir->GetDirectoryNumber();
    ASSERTNR((SHORT)num == num);

    *(SHORT *)buf = (SHORT)num;
    buf[2] = (BYTE)pDir->stat;
    buf[3] = (BYTE)status;

#ifdef TRACE
    printf("RLFEAddLog: %d, %d, %s, %s\n", pDir->stat, num, path, logText);
#endif

    if (RLFEEnterCritSec()) {
        SendCommand(RLFE_ADD_LOG, 2 + pathLen + 4 + logLen);
        SendDataWithLen((BYTE *)path, pathLen);
        SendData(buf, 4);
        SendData((BYTE *)logText, logLen);
        RLFELeaveCritSec();
    }
}
Ejemplo n.º 2
0
// null terminated string of null terminated strings
// name=data from testinfo and all of parent process env, arg for CreateProcess()
void * GetEnvFlags
    (
    TestVariant * pTestVariant
    )
{
    char temp[BUFFER_SIZE];
    size_t len = 0, totalEnvLen = 0;
    char * envFlags = NULL;
    Xml::Node *env = (Xml::Node *)pTestVariant->testInfo.data[TIK_ENV];
    if (env != NULL) {
        // use a fixed global array for memory
        memset(EnvFlags, '\0', MAX_ENV_LEN);
        *temp = '\0';
        for ( Xml::Node * child = env->ChildList; child != NULL; child = child->Next) {
            sprintf_s(temp, "%s=%s", child->Name, child->Data);
            if (envFlags == NULL) {
                sprintf_s(EnvFlags, "%s", temp);
                envFlags = EnvFlags;
            } else {
                strcat_s(envFlags, REMAININGARRAYLEN(EnvFlags, envFlags), temp);
            }
            len = strlen(envFlags);
            envFlags += len+1;
        }
        LPTSTR lpszParentEnv = GetEnvironmentStrings();
        totalEnvLen = len;
        ASSERT(totalEnvLen < BUFFER_SIZE);
        len = 0;
        while(!((lpszParentEnv[len] == '\0') && (lpszParentEnv[len+1] == '\0'))) {
            len++;
        }
        ASSERT(totalEnvLen+len+2 < MAX_ENV_LEN);
        memcpy(envFlags, lpszParentEnv, len+2);
        FreeEnvironmentStrings(lpszParentEnv);
        envFlags = EnvFlags;
    }
    return (void*)envFlags;
}
Ejemplo n.º 3
0
// This function takes care of creating the pipe between RL and RLFE and
// starts RLFE.
BOOL
RLFEConnect(
    const char *prefix
)
{
    char pipeName[32];
    char options[512], *pOpt, *s;
    char pipeID[9], *pID;
    DWORD id = 0;

    pOpt = options;
    pID = NULL;

    // Parse RLFE options.

    while (RLFEOpts && *RLFEOpts) {
        s = strchr(RLFEOpts, ',');
        if (s)
            *s++ = '\0';

        if (!_stricmp(RLFEOpts, "min"))
            pOpt += sprintf_s(pOpt, REMAININGARRAYLEN(options, pOpt), " -min");
        else if (!_strnicmp(RLFEOpts, "pipe", 4))
            pID = RLFEOpts + 4;

        RLFEOpts = s;
    }

    if (pID == NULL) {
        id = GetCurrentProcessId();
        sprintf_s(pipeID, "%08x", id);
        pID = pipeID;
    }

    sprintf_s(pipeName, "%s%s", PIPE_NAME, pID);
    if (strlen(pipeName) > 31) {
        printf("RLFE pipename buffer too small\n");
        return FALSE;
    }

    pOpt += sprintf_s(pOpt, REMAININGARRAYLEN(options, pOpt), " -pipe %s", pID);
    if (prefix)
        pOpt += sprintf_s(pOpt, REMAININGARRAYLEN(options, pOpt), " -prefix \"%s\"", prefix);

    HPipe = CreateNamedPipe(
        pipeName,
        PIPE_ACCESS_OUTBOUND | FILE_FLAG_WRITE_THROUGH,
        PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
        1,
        2048,
        2048,
        5 * 1000,
        NULL);
    if (HPipe == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "RLFE pipe creation failed\n");
        return FALSE;
    }

    if (id) {
        if (strlen(options) > 511) {
            printf("RLFE options buffer too small\n");
            return FALSE;
        }
        if (SpawnRLFE(options)) {
            CloseHandle(HPipe);
            return FALSE;
        }
    }
    else {
        printf("Please launch RLFE manually with -pipe %s\n", pID);
    }

    if (!ConnectNamedPipe(HPipe, NULL)) {
        CloseHandle(HPipe);
        fprintf(stderr, "RLFE failed to connected\n");
        return FALSE;
    }

    FConnected = TRUE;

    return TRUE;
}
Ejemplo n.º 4
0
BOOL
    DoOneSimpleTest(
    CDirectory *pDir,
    Test * pTest,
    TestVariant * pTestVariant,
    const char *optFlags,
    const char *inCCFlags,
    const char *inLinkFlags,
    BOOL fSyncVariationWhenFinished,
    BOOL fCleanAfter,
    BOOL fLinkOnly,    // relink only
    BOOL fSuppressNoGPF,
    DWORD millisecTimeout
    )
{
    int rc;
    char *p = NULL;
    char cmdbuf[BUFFER_SIZE*2];
    char ccFlags[BUFFER_SIZE];
    char linkFlags[BUFFER_SIZE];
    char nogpfFlags[BUFFER_SIZE];
    char optReportBuf[BUFFER_SIZE];
    char full[MAX_PATH];
    char exebuf[BUFFER_SIZE];
    char fullexebuf[BUFFER_SIZE];
    char buf[BUFFER_SIZE];
    char failDir[BUFFER_SIZE];
    char copyName[BUFFER_SIZE];
    char tmp_file1[MAX_PATH];
    char tmp_file2[MAX_PATH];
    time_t start_variation;
    UINT elapsed_variation;
    BOOL fFailed;
    void *envFlags = GetEnvFlags(pTestVariant);

    // Avoid conditionals by copying/creating ccFlags appropriately.

    if (inCCFlags)
        sprintf_s(ccFlags, " %s", inCCFlags);
    else
        ccFlags[0] = '\0';

    switch (TargetMachine) {
    case TM_WVM:
    case TM_WVMX86:
    case TM_WVM64:
        strcat_s(ccFlags, " /BC ");
        break;
    }

    if (inLinkFlags)
        strcpy_s(linkFlags, inLinkFlags);
    else
        linkFlags[0] = '\0';

    sprintf_s(optReportBuf, "%s%s%s", optFlags, *linkFlags ? ";" : "", linkFlags);

    // Figure out the exe name and path

    strcpy_s(exebuf, pTest->name);
    p = strrchr(exebuf, '.');
    if (p != NULL)
    {
        strcpy_s(p + 1, REMAININGARRAYLEN(exebuf, p + 1), "exe");
    }
    else
    {
        strcat_s(exebuf, ".exe");
    }

    sprintf_s(fullexebuf, "%s\\%s", pDir->GetDirectoryPath(), exebuf);

    start_variation = time(NULL);

    // Build up the compile command string.

    sprintf_s(cmdbuf, "%s %s%s %s", REGR_CL,
        optFlags, ccFlags, EXTRA_CC_FLAGS);

    for (StringList * pFile = pTest->files; pFile != NULL; pFile = pFile->next)
    {
        strcat_s(cmdbuf, " ");
        strcat_s(cmdbuf, pFile->string);

        // If we're only relinking, hammer the extension to .obj

        if (fLinkOnly)
        {
            p = strrchr(cmdbuf, '.');
            sprintf_s(p, REMAININGARRAYLEN(cmdbuf, p), ".obj");
        }
    }

    // Build the link option string.

    if (LINKFLAGS && LINKFLAGS[0] != '\0') {
        strcat_s(linkFlags, " ");
        strcat_s(linkFlags, LINKFLAGS);
    }

    FillNoGPFFlags(nogpfFlags, fSuppressNoGPF);
    strcat_s(linkFlags, nogpfFlags);

    switch (TargetMachine) {
    case TM_X86:
    case TM_IA64:
    case TM_AMD64:
    case TM_AMD64SYS:
    case TM_AM33:
    case TM_ARM:
    case TM_ARM64:
    case TM_THUMB:
    case TM_M32R:
    case TM_MIPS:
    case TM_SH3:
    case TM_SH4:
    case TM_SH5M:
    case TM_SH5C:
    case TM_WVMX86:
        if (*linkFlags) {
            strcat_s(cmdbuf, " /link ");
            strcat_s(cmdbuf, linkFlags);
        }
        break;
    case TM_WVM:
        strcat_s(cmdbuf, " /c ");
        break;
    case TM_PPCWCE:
        if (*linkFlags) {
            strcat_s(cmdbuf, " ");
            strcat_s(cmdbuf, linkFlags);
        }
        break;
    }

    sprintf_s(buf, "%s (%s)", pTest->name, optReportBuf);
    ThreadInfo[ThreadId].SetCurrentTest(pDir->GetDirectoryName(), buf, pDir->IsBaseline());
    UpdateTitleStatus();

    // Remove exe if it's already there. We have to keep trying to delete it
    // until it's gone, or else the link will fail (if it is somehow still in
    // use).

    DeleteFileRetryMsg(fullexebuf);

    if (FTest)
    {
        Message("%s", cmdbuf);
        if (pTestVariant->testInfo.data[TIK_BASELINE]) {
            Message("   (baseline %s)", pTestVariant->testInfo.data[TIK_BASELINE]);
        }
        return 0;
    }

    // Do the compile.

    Message("Compiling:");
    Message("    %s", cmdbuf);

    rc = ExecuteCommand(pDir->GetDirectoryPath(), cmdbuf);

    // Some machines require separate linking of the
    // compiler and/or assembler output.

    if (rc == 0)
    {
        switch (TargetMachine)
        {
        case TM_WVM:
            // Build up the linker command string.

            strcpy_s(cmdbuf, LINKER);

            for (StringList * pFile = pTest->files;
                pFile != NULL;
                pFile = pFile->next)
            {
                strcat_s(cmdbuf, " ");
                strcat_s(cmdbuf, pFile->string);
                p = strrchr(cmdbuf, '.');
                strcpy_s(p + 1, REMAININGARRAYLEN(cmdbuf, p + 1), "obj");
            }

            if (linkFlags) {
                strcat_s(cmdbuf, " ");
                strcat_s(cmdbuf, linkFlags);
            }

            // Do the link.

            Message("Linking:");
            Message("    %s", cmdbuf);
            ExecuteCommand(pDir->GetDirectoryPath(), cmdbuf);
            break;

        default:
            break;
        }
    }

    // See if the compile succeeded by checking for the existence
    // of the executable.

    if ((rc != 0) || GetFileAttributes(fullexebuf) == INVALID_FILE_ATTRIBUTES) {
        LogOut("ERROR: Test failed to compile or link (%s):", optReportBuf);
        LogOut("    %s", cmdbuf);
        fFailed = TRUE;
        goto logFailure;
    }

    // Run the resulting exe.

    if (TargetVM) {
        strcpy_s(buf, TargetVM);
        strcat_s(buf, " ");
        strcat_s(buf, exebuf);

        // Copy the VM command to cmdbuf, so we get a useful error message
        // in the log file if test fails.

        strcpy_s(cmdbuf, buf);
    }
    else {
        strcpy_s(buf, exebuf);
    }

    // We need some temporary files.
    // Note: these are full pathnames, not relative pathnames. Also, note that
    // mytmpnam creates the file to be used. To avoid losing that file, and
    // risking another program using it, don't delete the file before use.
    // We currently delete the file before running the test, so we can see if
    // the test ever creates it. We should probably create the temp files in
    // the same directory as the test, since we guarantee that no other copies
    // of RL are running in the same directory.

    if (mytmpnam(pDir->GetDirectoryPath(), TMP_PREFIX, tmp_file1) == NULL ||
        mytmpnam(pDir->GetDirectoryPath(), TMP_PREFIX, tmp_file2) == NULL) {
            Fatal("Unable to create temporary files");
    }

    ThreadInfo[ThreadId].AddToTmpFileList(tmp_file1);
    ThreadInfo[ThreadId].AddToTmpFileList(tmp_file2);

    if (FVerbose)
        Message("INFO: tmp file 1 = %s, tmp file 2 = %s", tmp_file1, tmp_file2);

    Message("Running the test (%s)", buf);
    strcat_s(buf, " > ");
    strcat_s(buf, tmp_file1);

    // Make sure the output file isn't there.

    DeleteFileIfFound(tmp_file1);

    fFailed = FALSE;

    // Check for timeout.
    {
        int retval = ExecuteCommand(pDir->GetDirectoryPath(), buf, millisecTimeout, envFlags);
        if (retval == WAIT_TIMEOUT) {
            ASSERT(millisecTimeout != INFINITE);
            LogOut("ERROR: Test timed out after %ul seconds", millisecTimeout / 1000);
            fFailed = TRUE;
            goto logFailure;
        }
    }

    // Check the output.

    if (pTestVariant->testInfo.data[TIK_BASELINE]) {
        int spiff_ret;

        // Check to see if the exe ran at all.

        if (GetFileAttributes(tmp_file1) == INVALID_FILE_ATTRIBUTES) {
            LogOut("ERROR: Test failed to run. Couldn't find file '%s' (%s):", tmp_file1, optReportBuf);
            LogOut("    %s", cmdbuf);
            fFailed = TRUE;
        }
        else {
            sprintf_s(full, "%s\\%s", pDir->GetFullPathFromSourceOrDirectory(),
                pTestVariant->testInfo.data[TIK_BASELINE]);
            if (DoCompare(tmp_file1, full, pTestVariant->testInfo.hasData[TIK_EOL_NORMALIZATION])) {

                // Output differs, run spiff to see if it's just minor
                // floating point anomalies.

                DeleteFileIfFound(tmp_file2);
                sprintf_s(buf, "spiff -m -n -s \"command spiff\" %s %s > %s",
                    tmp_file1, full, tmp_file2);
                spiff_ret = ExecuteCommand(pDir->GetDirectoryPath(), buf);
                if (GetFileAttributes(tmp_file2) == INVALID_FILE_ATTRIBUTES) {
                    LogError("ERROR: spiff failed to run");
                    fFailed = TRUE;
                }
                else if (spiff_ret) {
                    LogOut("ERROR: Test failed to run correctly. spiff returned %d (%s):", spiff_ret, optReportBuf);
                    LogOut("    %s", cmdbuf);
                    fFailed = TRUE;
                }
            }
        }
    }
    else {
        if (!CheckForPass(tmp_file1, optReportBuf, cmdbuf)) {
            fFailed = TRUE;
        }
    }

logFailure:

    if (fFailed) {
        if (FCopyOnFail) {
            if (FVerbose)
                Message("INFO: Copying '%s' failure", optReportBuf);

            sprintf_s(failDir, "%s\\fail.%s",
                pDir->GetDirectoryPath(), optReportBuf);

            if ((GetFileAttributes(failDir) == INVALID_FILE_ATTRIBUTES) &&
                !CreateDirectory(failDir, NULL)) {
                    Message("ERROR: Couldn't create directory '%s'", failDir);
            }
            else
            {
                for (StringList * pFile = pTest->files;
                    pFile != NULL;
                    pFile = pFile->next)
                {
                    sprintf_s(copyName, "%s\\%s", failDir, pFile->string);
                    p = strrchr(copyName, '.') + 1;
                    strcpy_s(p, REMAININGARRAYLEN(copyName, p + 1), "obj");
                    sprintf_s(buf, "%s\\%s", pDir->GetDirectoryPath(),
                        pFile->string);
                    p = strrchr(buf, '.') + 1;
                    strcpy_s(p, REMAININGARRAYLEN(buf, p + 1), "obj");

                    if (!CopyFile(buf, copyName, FALSE)) {
                        Message("ERROR: Couldn't copy '%s' to '%s'",
                            buf, copyName);
                    }
                }

                sprintf_s(copyName, "%s\\%s", failDir, exebuf);
                if (!CopyFile(fullexebuf, copyName, FALSE)) {
                    Message("ERROR: Couldn't copy '%s' to '%s'",
                        fullexebuf, copyName);
                }
            }
        }
    }

    if (FRLFE) {
        RLFETestStatus(pDir);
    }

    if (FVerbose)
        Message("INFO: cleaning up test run");

    // Remove the exe.

    if (!FNoDelete) {
        DeleteFileRetryMsg(fullexebuf);
    }

    // Don't trash fullexebuf!

    strcpy_s(buf, fullexebuf);

    p = strrchr(buf, '.') + 1;

    // Remove the pdb(s) (if it exists).

    strcpy_s(p, REMAININGARRAYLEN(buf, p), "pdb");
    DeleteFileIfFound(buf);
    DeleteMultipleFiles(pDir, "*.pdb");

    // Remove the ilk (if it exists).

    strcpy_s(p, REMAININGARRAYLEN(buf, p), "ilk");
    DeleteFileIfFound(buf);

    // Remove the objs.

    if (!FNoDelete)
    {
        for (StringList * pFile = pTest->files;
            pFile != NULL;
            pFile = pFile->next)
        {
            sprintf_s(buf, "%s\\%s", pDir->GetDirectoryPath(), pFile->string);
            p = strrchr(buf, '.') + 1;

            if (fCleanAfter)
            {
                strcpy_s(p, REMAININGARRAYLEN(buf, p), "obj");
                DeleteFileRetryMsg(buf);
            }

            if (REGR_ASM) {
                strcpy_s(p, REMAININGARRAYLEN(buf, p), "asm");
                DeleteFileRetryMsg(buf);
            }
        }
    }

    elapsed_variation = (int)(time(NULL) - start_variation);
    if (Timing & TIME_VARIATION) {
        Message("RL: Variation elapsed time (%s, %s, %s): %02d:%02d",
            pDir->GetDirectoryName(), pTest->name, optReportBuf,
            elapsed_variation / 60, elapsed_variation % 60);
    }

    if (FSyncVariation) {
        if (FRLFE && fFailed)
            RLFEAddLog(pDir, RLFES_FAILED, pTest->name, optReportBuf, ThreadOut->GetText());

        if (fSyncVariationWhenFinished)
            FlushOutput();
    }

    ThreadInfo[ThreadId].DeleteTmpFileList();

    return fFailed ? -1 : 0;
}