Exemple #1
0
int main(int argc, char *argv[])
{
    int n;
    static const char dots[] = "......................";
    
    /* get basename(argv[0]) */
    test_suite = strrchr(argv[0], '/');
    if (test_suite == NULL) {
	test_suite = argv[0];
    } else {
	test_suite++;
    }

#ifdef HAVE_SETLOCALE
    setlocale(LC_MESSAGES, "");
#endif

    ne_i18n_init(NULL);

#if defined(HAVE_ISATTY) && defined(STDOUT_FILENO)
    if (isatty(STDOUT_FILENO)) {
	use_colour = 1;
    }
#endif

    test_argc = argc;
    test_argv = argv;

    debug = fopen("debug.log", "a");
    if (debug == NULL) {
	fprintf(stderr, "%s: Could not open debug.log: %s\n", test_suite,
		strerror(errno));
	return -1;
    }
    child_debug = fopen("child.log", "a");
    if (child_debug == NULL) {
	fprintf(stderr, "%s: Could not open child.log: %s\n", test_suite,
		strerror(errno));
	fclose(debug);
	return -1;
    }

    if (tests[0].fn == NULL) {
	printf("-> no tests found in `%s'\n", test_suite);
	return -1;
    }

    /* install special SEGV handler. */
    signal(SIGSEGV, parent_segv);
    signal(SIGABRT, parent_segv);

    /* test the "no-debugging" mode of ne_debug. */
    ne_debug_init(NULL, 0);
    NE_DEBUG(TEST_DEBUG, "This message should go to /dev/null");

    /* enable debugging for real. */
    ne_debug_init(debug, TEST_DEBUG);
    NE_DEBUG(TEST_DEBUG | NE_DBG_FLUSH, "Version string: %s\n", 
             ne_version_string());
    
    /* another silly test. */
    NE_DEBUG(0, "This message should also go to /dev/null");

    if (ne_sock_init()) {
	COL("43;01"); printf("WARNING:"); NOCOL;
	printf(" Socket library initalization failed.\n");
    }

    printf("-> running `%s':\n", test_suite);
    
    for (n = 0; !aborted && tests[n].fn != NULL; n++) {
	int result, is_xfail = 0;
#ifdef NEON_MEMLEAK
        size_t allocated = ne_alloc_used;
        int is_xleaky = 0;
#endif

	test_name = tests[n].name;
	printf("%2d. %s%.*s ", n, test_name, 
	       (int) (strlen(dots) - strlen(test_name)), dots);
	have_context = 0;
	test_num = n;
	warned = 0;
	fflush(stdout);
	NE_DEBUG(TEST_DEBUG, "******* Running test %d: %s ********\n", 
		 n, test_name);

	/* run the test. */
	result = tests[n].fn();

#ifdef NEON_MEMLEAK
        /* issue warnings for memory leaks, if requested */
        if ((tests[n].flags & T_CHECK_LEAKS) && result == OK &&
            ne_alloc_used > allocated) {
            t_context("memory leak of %" NE_FMT_SIZE_T " bytes",
                      ne_alloc_used - allocated);
            fprintf(debug, "Blocks leaked: ");
            ne_alloc_dump(debug);
            result = FAIL;
        } else if (tests[n].flags & T_EXPECT_LEAKS && result == OK &&
                   ne_alloc_used == allocated) {
            t_context("expected memory leak not detected");
            result = FAIL;
        } else if (tests[n].flags & T_EXPECT_LEAKS && result == OK) {
            fprintf(debug, "Blocks leaked (expected): ");
            ne_alloc_dump(debug);
            is_xleaky = 1;
        } 
#endif

        if (tests[n].flags & T_EXPECT_FAIL) {
            if (result == OK) {
                t_context("test passed but expected failure");
                result = FAIL;
            } else if (result == FAIL) {
                result = OK;
                is_xfail = 1;
            }
        }

	/* align the result column if we've had warnings. */
	if (warned) {
	    printf("    %s ", dots);
	}

	switch (result) {
	case OK:
            if (is_xfail) {
                COL("32;07"); 
                printf("xfail");
            } else {
                COL("32"); 
                printf("pass"); 
            }
            NOCOL;
	    if (warned) {
		printf(" (with %d warning%s)", warned, (warned > 1)?"s":"");
	    }
#ifdef NEON_MEMLEAK
            if (is_xleaky) {
                printf(" (with expected leak, %" NE_FMT_SIZE_T " bytes)",
                       ne_alloc_used - allocated);
            }
#endif
	    putchar('\n');
	    passes++;
	    break;
	case FAILHARD:
	    aborted = 1;
	    /* fall-through */
	case FAIL:
	    COL("41;37;01"); printf("FAIL"); NOCOL;
	    if (have_context) {
		printf(" (%s)", test_context);
	    }
	    putchar('\n');
	    fails++;
	    break;
	case SKIPREST:
	    aborted = 1;
	    /* fall-through */
	case SKIP:
	    COL("44;37;01"); printf("SKIPPED"); NOCOL;
	    if (have_context) {
		printf(" (%s)", test_context);
	    }
	    putchar('\n');
	    skipped++;
	    break;
	default:
	    COL("41;37;01"); printf("OOPS"); NOCOL;
	    printf(" unexpected test result `%d'\n", result);
	    break;
	}

	reap_server();
    }

    /* discount skipped tests */
    if (skipped) {
	printf("-> %d %s.\n", skipped,
	       skipped==1?"test was skipped":"tests were skipped");
	n -= skipped;
	if (passes + fails != n) {
	    printf("-> ARGH! Number of test results does not match "
		   "number of tests.\n"
		   "-> ARGH! Test Results are INRELIABLE.\n");
	}
    }
    /* print the summary. */
    if (skipped && n == 0) {
	printf("<- all tests skipped for `%s'.\n", test_suite);
    } else {
	printf("<- summary for `%s': "
	       "of %d tests run: %d passed, %d failed. %.1f%%\n",
	       test_suite, n, passes, fails, 100*(float)passes/n);
	if (warnings) {
	    printf("-> %d warning%s issued.\n", warnings, 
		   warnings==1?" was":"s were");
	}
    }

    if (fclose(debug)) {
	fprintf(stderr, "Error closing debug.log: %s\n", strerror(errno));
	fails = 1;
    }
       
    if (fclose(child_debug)) {
	fprintf(stderr, "Error closing child.log: %s\n", strerror(errno));
	fails = 1;
    }

    ne_sock_exit();
    
    return fails;
}
Exemple #2
0
void SyncEngine::startSync()
{
    if (_journal->exists()) {
        QVector< SyncJournalDb::PollInfo > pollInfos = _journal->getPollInfos();
        if (!pollInfos.isEmpty()) {
            qDebug() << "Finish Poll jobs before starting a sync";
            CleanupPollsJob *job = new CleanupPollsJob(pollInfos, AccountManager::instance()->account(),
                                                       _journal, _localPath, this);
            connect(job, SIGNAL(finished()), this, SLOT(startSync()));
            connect(job, SIGNAL(aborted(QString)), this, SLOT(slotCleanPollsJobAborted(QString)));
            job->start();
            return;
        }
    }

    Q_ASSERT(!_syncRunning);
    _syncRunning = true;

    Q_ASSERT(_csync_ctx);

    if (!QDir(_localPath).exists()) {
        // No _tr, it should only occur in non-mirall
        emit csyncError("Unable to find local sync directory.");
        finalize();
        return;
    }

    _syncedItems.clear();
    _syncItemMap.clear();
    _needsUpdate = false;

    csync_resume(_csync_ctx);

    int fileRecordCount = -1;
    if (!_journal->exists()) {
        qDebug() << "=====sync looks new (no DB exists)";
    } else {
        qDebug() << "=====sync with existing DB";
    }

    qDebug() <<  "=====Using Qt" << qVersion();
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
    qDebug() <<  "=====Using SSL library version"
             <<  QSslSocket::sslLibraryVersionString().toUtf8().data();
#endif
    // Note that this seems to output the OpenSSL build version not runtime version:
    qDebug() <<  "=====Using" << ne_version_string();

    fileRecordCount = _journal->getFileRecordCount(); // this creates the DB if it does not exist yet
    bool isUpdateFrom_1_5 = _journal->isUpdateFrom_1_5();

    if( fileRecordCount == -1 ) {
        qDebug() << "No way to create a sync journal!";
        emit csyncError(tr("Unable to initialize a sync journal."));
        finalize();
        return;
        // database creation error!
    }

    if (fileRecordCount >= 1 && isUpdateFrom_1_5) {
        qDebug() << "detected update from 1.5" << fileRecordCount << isUpdateFrom_1_5;
        // Disable the read from DB to be sure to re-read all the fileid and etags.
        csync_set_read_from_db(_csync_ctx, false);
    } else {
        csync_set_read_from_db(_csync_ctx, true);
    }

    bool usingSelectiveSync = (!_selectiveSyncBlackList.isEmpty());
    qDebug() << (usingSelectiveSync ? "====Using Selective Sync" : "====NOT Using Selective Sync");
    if (fileRecordCount >= 0 && fileRecordCount < 50 && !usingSelectiveSync) {
        qDebug() << "===== Activating recursive PROPFIND (currently" << fileRecordCount << "file records)";
        bool no_recursive_propfind = false;
        csync_set_module_property(_csync_ctx, "no_recursive_propfind", &no_recursive_propfind);
    } else {
        bool no_recursive_propfind = true;
        csync_set_module_property(_csync_ctx, "no_recursive_propfind", &no_recursive_propfind);
    }

    csync_set_userdata(_csync_ctx, this);
    // TODO: This should be a part of this method, but we don't have
    // any way to get "session_key" module property from csync. Had we
    // have it, then we could keep this code and remove it from
    // AbstractCredentials implementations.
    if (Account *account = AccountManager::instance()->account()) {
        account->credentials()->syncContextPreStart(_csync_ctx);
    } else {
        qDebug() << Q_FUNC_INFO << "No default Account object, huh?";
    }
    // if (_lastAuthCookies.length() > 0) {
    //     // Stuff cookies inside csync, then we can avoid the intermediate HTTP 401 reply
    //     // when https://github.com/owncloud/core/pull/4042 is merged.
    //     QString cookiesAsString;
    //     foreach(QNetworkCookie c, _lastAuthCookies) {
    //         cookiesAsString += c.name();
    //         cookiesAsString += '=';
    //         cookiesAsString += c.value();
    //         cookiesAsString += "; ";
    //     }
    //     csync_set_module_property(_csync_ctx, "session_key", cookiesAsString.to
    // }

    // csync_set_auth_callback( _csync_ctx, getauth );
    //csync_set_log_level( 11 ); don't set the loglevel here, it shall be done by folder.cpp or owncloudcmd.cpp
    int timeout = OwncloudPropagator::httpTimeout();
    csync_set_module_property(_csync_ctx, "timeout", &timeout);


    _stopWatch.start();

    qDebug() << "#### Discovery start #################################################### >>";

    DiscoveryJob *job = new DiscoveryJob(_csync_ctx);
    job->_selectiveSyncBlackList = _selectiveSyncBlackList;
    job->moveToThread(&_thread);
    connect(job, SIGNAL(finished(int)), this, SLOT(slotDiscoveryJobFinished(int)));
    connect(job, SIGNAL(folderDiscovered(bool,QString)),
            this, SIGNAL(folderDiscovered(bool,QString)));
    QMetaObject::invokeMethod(job, "start", Qt::QueuedConnection);
}