void tst_QLlcpSocket::tst_invalidServiceUri()
{
    QLatin1String invalidServiceUri("invalid");

    QLlcpSocket *socket = new QLlcpSocket;

    QSignalSpy stateSpy(socket, SIGNAL(stateChanged(QLlcpSocket::SocketState)));
    QSignalSpy errorSpy(socket, SIGNAL(error(QLlcpSocket::SocketError)));

    socket->connectToService(0, invalidServiceUri);

    QCOMPARE(stateSpy.count(), 1);
    QCOMPARE(stateSpy.takeFirst().at(0).value<QLlcpSocket::SocketState>(),
             QLlcpSocket::ConnectingState);
    QCOMPARE(socket->state(), QLlcpSocket::ConnectingState);

    QTRY_VERIFY(!errorSpy.isEmpty());

    QCOMPARE(stateSpy.count(), 1);
    QCOMPARE(stateSpy.takeFirst().at(0).value<QLlcpSocket::SocketState>(),
             QLlcpSocket::UnconnectedState);
    QCOMPARE(socket->state(), QLlcpSocket::UnconnectedState);

    QCOMPARE(errorSpy.takeFirst().at(0).value<QLlcpSocket::SocketError>(),
             QLlcpSocket::SocketAccessError);
    QCOMPARE(socket->error(), QLlcpSocket::SocketAccessError);
    QVERIFY(!socket->errorString().isEmpty());

    delete socket;
}
void tst_QBluetoothDeviceDiscoveryAgent::tst_deviceDiscovery()
{
    {
        QFETCH(QBluetoothDeviceDiscoveryAgent::InquiryType, inquiryType);

        QBluetoothDeviceDiscoveryAgent discoveryAgent;
        QVERIFY(discoveryAgent.error() == discoveryAgent.NoError);
        QVERIFY(discoveryAgent.errorString().isEmpty());
        QVERIFY(!discoveryAgent.isActive());

        QVERIFY(discoveryAgent.discoveredDevices().isEmpty());

        QSignalSpy finishedSpy(&discoveryAgent, SIGNAL(finished()));
        QSignalSpy errorSpy(&discoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)));
        QSignalSpy discoveredSpy(&discoveryAgent, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo&)));
//        connect(&discoveryAgent, SIGNAL(finished()), this, SLOT(finished()));
//        connect(&discoveryAgent, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo&)),
//                this, SLOT(deviceDiscoveryDebug(const QBluetoothDeviceInfo&)));

        discoveryAgent.setInquiryType(inquiryType);
        discoveryAgent.start();

        QVERIFY(discoveryAgent.isActive());

        // Wait for up to MaxScanTime for the scan to finish
        int scanTime = MaxScanTime;
        while (finishedSpy.count() == 0 && scanTime > 0) {
            QTest::qWait(15000);
            scanTime -= 15000;
        }
        qDebug() << scanTime << MaxScanTime;
        // verify that we are finished
        QVERIFY(!discoveryAgent.isActive());
        // stop
        discoveryAgent.stop();
        QVERIFY(!discoveryAgent.isActive());
        qDebug() << "Scan time left:" << scanTime;
        // Expect finished signal with no error
        QVERIFY(finishedSpy.count() == 1);
        QVERIFY(errorSpy.isEmpty());
        QVERIFY(discoveryAgent.error() == discoveryAgent.NoError);
        QVERIFY(discoveryAgent.errorString().isEmpty());

        // verify that the list is as big as the signals received.
        QVERIFY(discoveredSpy.count() == discoveryAgent.discoveredDevices().length());
        // verify that there really was some devices in the array
        QVERIFY(discoveredSpy.count() > 0);

        // All returned QBluetoothDeviceInfo should be valid.
        while (!discoveredSpy.isEmpty()) {
            const QBluetoothDeviceInfo info =
                qvariant_cast<QBluetoothDeviceInfo>(discoveredSpy.takeFirst().at(0));
            QVERIFY(info.isValid());
        }
    }
}
void tst_QBluetoothDeviceDiscoveryAgent::tst_startStopDeviceDiscoveries()
{
    {
        QBluetoothDeviceDiscoveryAgent::InquiryType inquiryType = QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry;
        QBluetoothDeviceDiscoveryAgent discoveryAgent;

        QVERIFY(discoveryAgent.error() == discoveryAgent.NoError);
        QVERIFY(discoveryAgent.errorString().isEmpty());
        QVERIFY(!discoveryAgent.isActive());
        QVERIFY(discoveryAgent.discoveredDevices().isEmpty());

        QSignalSpy finishedSpy(&discoveryAgent, SIGNAL(finished()));
        QSignalSpy cancelSpy(&discoveryAgent, SIGNAL(canceled()));
        QSignalSpy errorSpy(&discoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)));
        QSignalSpy discoveredSpy(&discoveryAgent, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo&)));

        // Starting case 1: start-stop, expecting cancel signal
        discoveryAgent.setInquiryType(inquiryType);
        // we should have no errors at this point.
        QVERIFY(errorSpy.isEmpty());

        discoveryAgent.start();
        QVERIFY(discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        // cancel current request.
        discoveryAgent.stop();

        // Wait for up to MaxWaitTime for the cancel to finish
        int waitTime = MaxWaitTime;
        while (cancelSpy.count() == 0 && waitTime > 0) {
            QTest::qWait(100);
            waitTime-=100;
        }

        // we should not be active anymore
        QVERIFY(!discoveryAgent.isActive());        
        QVERIFY(errorSpy.isEmpty());
        QVERIFY(cancelSpy.count() == 1);
        cancelSpy.clear();
        // Starting case 2: start-start-stop, expecting cancel signal
        discoveryAgent.start();
        // we should be active now
        QVERIFY(discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        // start again. should this be error?
        discoveryAgent.start();
        QVERIFY(discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        // stop
        discoveryAgent.stop();               

        // Wait for up to MaxWaitTime for the cancel to finish
        waitTime = MaxWaitTime;
        while (cancelSpy.count() == 0 && waitTime > 0) {
            QTest::qWait(100);
            waitTime-=100;
        }

        // we should not be active anymore
        QVERIFY(!discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        QVERIFY(cancelSpy.count() == 1);
        cancelSpy.clear();

        //  Starting case 3: stop
        discoveryAgent.stop();
        QVERIFY(!discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());

        // Expect finished signal with no error
        QVERIFY(finishedSpy.count() == 0);
        QVERIFY(discoveryAgent.error() == discoveryAgent.NoError);
        QVERIFY(discoveryAgent.errorString().isEmpty());


        // Starting case 4: start-stop-start-stop, expecting only 1 cancel signal
        discoveryAgent.start();
        QVERIFY(discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        // cancel current request.
        discoveryAgent.stop();
        // start a new one
        discoveryAgent.start();
        // we should be active now
        QVERIFY(discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        // stop
        discoveryAgent.stop();

        // Wait for up to MaxWaitTime for the cancel to finish
        waitTime = MaxWaitTime;
        while (waitTime > 0) {
            QTest::qWait(100);
            waitTime-=100;
        }

        // we should not be active anymore
        QVERIFY(!discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        // should only have 1 cancel
        QVERIFY(cancelSpy.count() == 1);
        cancelSpy.clear();

        // Starting case 5: start-stop-start: expecting finished signal & no cancel
        discoveryAgent.start();
        QVERIFY(discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        // cancel current request.
        discoveryAgent.stop();
        // start a new one
        discoveryAgent.start();
        // we should be active now
        QVERIFY(discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());

        // Wait for up to MaxScanTime for the cancel to finish
        waitTime = MaxScanTime;
        while (finishedSpy.count() == 0 && waitTime > 0) {
            QTest::qWait(1000);
            waitTime-=1000;
        }

        // we should not be active anymore
        QVERIFY(!discoveryAgent.isActive());
        QVERIFY(errorSpy.isEmpty());
        // should only have 1 cancel
        QVERIFY(finishedSpy.count() == 1);
        QVERIFY(cancelSpy.isEmpty());
    }
}
void tst_QAudioDecoderBackend::fileTest()
{
    QAudioDecoder d;
    QAudioBuffer buffer;
    quint64 duration = 0;
    int byteCount = 0;
    int sampleCount = 0;

    QVERIFY(d.state() == QAudioDecoder::StoppedState);
    QVERIFY(d.bufferAvailable() == false);
    QCOMPARE(d.sourceFilename(), QString(""));
    QVERIFY(d.audioFormat() == QAudioFormat());

    // Test local file
    QFileInfo fileInfo(QFINDTESTDATA(TEST_FILE_NAME));
    d.setSourceFilename(fileInfo.absoluteFilePath());
    QVERIFY(d.state() == QAudioDecoder::StoppedState);
    QVERIFY(!d.bufferAvailable());
    QCOMPARE(d.sourceFilename(), fileInfo.absoluteFilePath());

    QSignalSpy readySpy(&d, SIGNAL(bufferReady()));
    QSignalSpy bufferChangedSpy(&d, SIGNAL(bufferAvailableChanged(bool)));
    QSignalSpy errorSpy(&d, SIGNAL(error(QAudioDecoder::Error)));
    QSignalSpy stateSpy(&d, SIGNAL(stateChanged(QAudioDecoder::State)));
    QSignalSpy durationSpy(&d, SIGNAL(durationChanged(qint64)));
    QSignalSpy finishedSpy(&d, SIGNAL(finished()));
    QSignalSpy positionSpy(&d, SIGNAL(positionChanged(qint64)));

    d.start();
    QTRY_VERIFY(d.state() == QAudioDecoder::DecodingState);
    QTRY_VERIFY(!stateSpy.isEmpty());
    QTRY_VERIFY(!readySpy.isEmpty());
    QTRY_VERIFY(!bufferChangedSpy.isEmpty());
    QVERIFY(d.bufferAvailable());
    QTRY_VERIFY(!durationSpy.isEmpty());
    QVERIFY(qAbs(d.duration() - 1000) < 20);

    buffer = d.read();
    QVERIFY(buffer.isValid());

    // Test file is 44.1K 16bit mono, 44094 samples
    QCOMPARE(buffer.format().channelCount(), 1);
    QCOMPARE(buffer.format().sampleRate(), 44100);
    QCOMPARE(buffer.format().sampleSize(), 16);
    QCOMPARE(buffer.format().sampleType(), QAudioFormat::SignedInt);
    QCOMPARE(buffer.format().codec(), QString("audio/pcm"));
    QCOMPARE(buffer.byteCount(), buffer.sampleCount() * 2); // 16bit mono

    // The decoder should still have no format set
    QVERIFY(d.audioFormat() == QAudioFormat());

    QVERIFY(errorSpy.isEmpty());

    duration += buffer.duration();
    sampleCount += buffer.sampleCount();
    byteCount += buffer.byteCount();

    // Now drain the decoder
    if (sampleCount < 44094) {
        QTRY_COMPARE(d.bufferAvailable(), true);
    }

    while (d.bufferAvailable()) {
        buffer = d.read();
        QVERIFY(buffer.isValid());
        QTRY_VERIFY(!positionSpy.isEmpty());
        QVERIFY(positionSpy.takeLast().at(0).toLongLong() == qint64(duration / 1000));

        duration += buffer.duration();
        sampleCount += buffer.sampleCount();
        byteCount += buffer.byteCount();

        if (sampleCount < 44094) {
            QTRY_COMPARE(d.bufferAvailable(), true);
        }
    }

    // Make sure the duration is roughly correct (+/- 20ms)
    QCOMPARE(sampleCount, 44094);
    QCOMPARE(byteCount, 44094 * 2);
    QVERIFY(qAbs(qint64(duration) - 1000000) < 20000);
    QVERIFY(qAbs((d.position() + (buffer.duration() / 1000)) - 1000) < 20);
    QTRY_COMPARE(finishedSpy.count(), 1);
    QVERIFY(!d.bufferAvailable());
    QTRY_COMPARE(d.state(), QAudioDecoder::StoppedState);

    d.stop();
    QTRY_COMPARE(d.state(), QAudioDecoder::StoppedState);
    QTRY_COMPARE(durationSpy.count(), 2);
    QCOMPARE(d.duration(), qint64(-1));
    QVERIFY(!d.bufferAvailable());
    readySpy.clear();
    bufferChangedSpy.clear();
    stateSpy.clear();
    durationSpy.clear();
    finishedSpy.clear();
    positionSpy.clear();

    // change output audio format
    QAudioFormat format;
    format.setChannelCount(2);
    format.setSampleSize(8);
    format.setSampleRate(11050);
    format.setCodec("audio/pcm");
    format.setSampleType(QAudioFormat::SignedInt);

    d.setAudioFormat(format);

    // We expect 1 second still, at 11050 * 2 samples == 22k samples.
    // (at 1 byte/sample -> 22kb)

    // Make sure it stuck
    QVERIFY(d.audioFormat() == format);

    duration = 0;
    sampleCount = 0;
    byteCount = 0;

    d.start();
    QTRY_VERIFY(d.state() == QAudioDecoder::DecodingState);
    QTRY_VERIFY(!stateSpy.isEmpty());
    QTRY_VERIFY(!readySpy.isEmpty());
    QTRY_VERIFY(!bufferChangedSpy.isEmpty());
    QVERIFY(d.bufferAvailable());
    QTRY_VERIFY(!durationSpy.isEmpty());
    QVERIFY(qAbs(d.duration() - 1000) < 20);

    buffer = d.read();
    QVERIFY(buffer.isValid());
    // See if we got the right format
    QVERIFY(buffer.format() == format);

    // The decoder should still have the same format
    QVERIFY(d.audioFormat() == format);

    QVERIFY(errorSpy.isEmpty());

    duration += buffer.duration();
    sampleCount += buffer.sampleCount();
    byteCount += buffer.byteCount();

    // Now drain the decoder
    if (duration < 998000) {
        QTRY_COMPARE(d.bufferAvailable(), true);
    }

    while (d.bufferAvailable()) {
        buffer = d.read();
        QVERIFY(buffer.isValid());
        QTRY_VERIFY(!positionSpy.isEmpty());
        QVERIFY(positionSpy.takeLast().at(0).toLongLong() == qint64(duration / 1000));
        QVERIFY(d.position() - (duration / 1000) < 20);

        duration += buffer.duration();
        sampleCount += buffer.sampleCount();
        byteCount += buffer.byteCount();

        if (duration < 998000) {
            QTRY_COMPARE(d.bufferAvailable(), true);
        }
    }

    // Resampling might end up with fewer or more samples
    // so be a bit sloppy
    QVERIFY(qAbs(sampleCount - 22047) < 100);
    QVERIFY(qAbs(byteCount - 22047) < 100);
    QVERIFY(qAbs(qint64(duration) - 1000000) < 20000);
    QVERIFY(qAbs((d.position() + (buffer.duration() / 1000)) - 1000) < 20);
    QTRY_COMPARE(finishedSpy.count(), 1);
    QVERIFY(!d.bufferAvailable());
    QTRY_COMPARE(d.state(), QAudioDecoder::StoppedState);

    d.stop();
    QTRY_COMPARE(d.state(), QAudioDecoder::StoppedState);
    QTRY_COMPARE(durationSpy.count(), 2);
    QCOMPARE(d.duration(), qint64(-1));
    QVERIFY(!d.bufferAvailable());
}
void tst_QAudioDecoderBackend::deviceTest()
{
    QAudioDecoder d;
    QAudioBuffer buffer;
    quint64 duration = 0;
    int sampleCount = 0;

    QSignalSpy readySpy(&d, SIGNAL(bufferReady()));
    QSignalSpy bufferChangedSpy(&d, SIGNAL(bufferAvailableChanged(bool)));
    QSignalSpy errorSpy(&d, SIGNAL(error(QAudioDecoder::Error)));
    QSignalSpy stateSpy(&d, SIGNAL(stateChanged(QAudioDecoder::State)));
    QSignalSpy durationSpy(&d, SIGNAL(durationChanged(qint64)));
    QSignalSpy finishedSpy(&d, SIGNAL(finished()));
    QSignalSpy positionSpy(&d, SIGNAL(positionChanged(qint64)));

    QVERIFY(d.state() == QAudioDecoder::StoppedState);
    QVERIFY(d.bufferAvailable() == false);
    QCOMPARE(d.sourceFilename(), QString(""));
    QVERIFY(d.audioFormat() == QAudioFormat());

    QFileInfo fileInfo(QFINDTESTDATA(TEST_FILE_NAME));
    QFile file(fileInfo.absoluteFilePath());
    QVERIFY(file.open(QIODevice::ReadOnly));
    d.setSourceDevice(&file);

    QVERIFY(d.sourceDevice() == &file);
    QVERIFY(d.sourceFilename().isEmpty());

    // We haven't set the format yet
    QVERIFY(d.audioFormat() == QAudioFormat());

    d.start();
    QTRY_VERIFY(d.state() == QAudioDecoder::DecodingState);
    QTRY_VERIFY(!stateSpy.isEmpty());
    QTRY_VERIFY(!readySpy.isEmpty());
    QTRY_VERIFY(!bufferChangedSpy.isEmpty());
    QVERIFY(d.bufferAvailable());
    QTRY_VERIFY(!durationSpy.isEmpty());
    QVERIFY(qAbs(d.duration() - 1000) < 20);

    buffer = d.read();
    QVERIFY(buffer.isValid());

    // Test file is 44.1K 16bit mono
    QCOMPARE(buffer.format().channelCount(), 1);
    QCOMPARE(buffer.format().sampleRate(), 44100);
    QCOMPARE(buffer.format().sampleSize(), 16);
    QCOMPARE(buffer.format().sampleType(), QAudioFormat::SignedInt);
    QCOMPARE(buffer.format().codec(), QString("audio/pcm"));

    QVERIFY(errorSpy.isEmpty());

    duration += buffer.duration();
    sampleCount += buffer.sampleCount();

    // Now drain the decoder
    if (sampleCount < 44094) {
        QTRY_COMPARE(d.bufferAvailable(), true);
    }

    while (d.bufferAvailable()) {
        buffer = d.read();
        QVERIFY(buffer.isValid());
        QTRY_VERIFY(!positionSpy.isEmpty());
        QVERIFY(positionSpy.takeLast().at(0).toLongLong() == qint64(duration / 1000));
        QVERIFY(d.position() - (duration / 1000) < 20);

        duration += buffer.duration();
        sampleCount += buffer.sampleCount();
        if (sampleCount < 44094) {
            QTRY_COMPARE(d.bufferAvailable(), true);
        }
    }

    // Make sure the duration is roughly correct (+/- 20ms)
    QCOMPARE(sampleCount, 44094);
    QVERIFY(qAbs(qint64(duration) - 1000000) < 20000);
    QVERIFY(qAbs((d.position() + (buffer.duration() / 1000)) - 1000) < 20);
    QTRY_COMPARE(finishedSpy.count(), 1);
    QVERIFY(!d.bufferAvailable());
    QTRY_COMPARE(d.state(), QAudioDecoder::StoppedState);

    d.stop();
    QTRY_COMPARE(d.state(), QAudioDecoder::StoppedState);
    QVERIFY(!d.bufferAvailable());
    QTRY_COMPARE(durationSpy.count(), 2);
    QCOMPARE(d.duration(), qint64(-1));
    readySpy.clear();
    bufferChangedSpy.clear();
    stateSpy.clear();
    durationSpy.clear();
    finishedSpy.clear();
    positionSpy.clear();

    // Now try changing formats
    QAudioFormat format;
    format.setChannelCount(2);
    format.setSampleSize(8);
    format.setSampleRate(8000);
    format.setCodec("audio/pcm");
    format.setSampleType(QAudioFormat::SignedInt);

    d.setAudioFormat(format);

    // Make sure it stuck
    QVERIFY(d.audioFormat() == format);

    d.start();
    QTRY_VERIFY(d.state() == QAudioDecoder::DecodingState);
    QTRY_VERIFY(!stateSpy.isEmpty());
    QTRY_VERIFY(!readySpy.isEmpty());
    QTRY_VERIFY(!bufferChangedSpy.isEmpty());
    QVERIFY(d.bufferAvailable());
    QTRY_VERIFY(!durationSpy.isEmpty());
    QVERIFY(qAbs(d.duration() - 1000) < 20);

    buffer = d.read();
    QVERIFY(buffer.isValid());
    // See if we got the right format
    QVERIFY(buffer.format() == format);

    // The decoder should still have the same format
    QVERIFY(d.audioFormat() == format);

    QVERIFY(errorSpy.isEmpty());

    d.stop();
    QTRY_COMPARE(d.state(), QAudioDecoder::StoppedState);
    QVERIFY(!d.bufferAvailable());
    QTRY_COMPARE(durationSpy.count(), 2);
    QCOMPARE(d.duration(), qint64(-1));
}
/*
 The corrupted file is generated by copying a few random numbers
 from /dev/random on a linux machine.
*/
void tst_QAudioDecoderBackend::corruptedFileTest()
{
    QAudioDecoder d;
    QAudioBuffer buffer;

    QVERIFY(d.state() == QAudioDecoder::StoppedState);
    QVERIFY(d.bufferAvailable() == false);
    QCOMPARE(d.sourceFilename(), QString(""));
    QVERIFY(d.audioFormat() == QAudioFormat());

    // Test local file
    QFileInfo fileInfo(QFINDTESTDATA(TEST_CORRUPTED_FILE_NAME));
    d.setSourceFilename(fileInfo.absoluteFilePath());
    QVERIFY(d.state() == QAudioDecoder::StoppedState);
    QVERIFY(!d.bufferAvailable());
    QCOMPARE(d.sourceFilename(), fileInfo.absoluteFilePath());

    QSignalSpy readySpy(&d, SIGNAL(bufferReady()));
    QSignalSpy bufferChangedSpy(&d, SIGNAL(bufferAvailableChanged(bool)));
    QSignalSpy errorSpy(&d, SIGNAL(error(QAudioDecoder::Error)));
    QSignalSpy stateSpy(&d, SIGNAL(stateChanged(QAudioDecoder::State)));
    QSignalSpy durationSpy(&d, SIGNAL(durationChanged(qint64)));
    QSignalSpy finishedSpy(&d, SIGNAL(finished()));
    QSignalSpy positionSpy(&d, SIGNAL(positionChanged(qint64)));

    d.start();
    QTRY_VERIFY(d.state() == QAudioDecoder::StoppedState);
    QVERIFY(!d.bufferAvailable());
    QCOMPARE(d.audioFormat(), QAudioFormat());
    QCOMPARE(d.duration(), qint64(-1));
    QCOMPARE(d.position(), qint64(-1));

    // Check the error code.
    QTRY_VERIFY(!errorSpy.isEmpty());

    // Have to use qvariant_cast, toInt will return 0 because unrecognized type;
    QAudioDecoder::Error errorCode = qvariant_cast<QAudioDecoder::Error>(errorSpy.takeLast().at(0));
    QCOMPARE(errorCode, QAudioDecoder::FormatError);
    QCOMPARE(d.error(), QAudioDecoder::FormatError);

    // Check all other spies.
    QVERIFY(readySpy.isEmpty());
    QVERIFY(bufferChangedSpy.isEmpty());
    QVERIFY(stateSpy.isEmpty());
    QVERIFY(finishedSpy.isEmpty());
    QVERIFY(positionSpy.isEmpty());
    QVERIFY(durationSpy.isEmpty());

    errorSpy.clear();

    // Try read even if the file is corrupted to test the robustness.
    buffer = d.read();
    QTRY_VERIFY(d.state() == QAudioDecoder::StoppedState);
    QVERIFY(!buffer.isValid());
    QVERIFY(!d.bufferAvailable());
    QCOMPARE(d.position(), qint64(-1));

    QVERIFY(errorSpy.isEmpty());
    QVERIFY(readySpy.isEmpty());
    QVERIFY(bufferChangedSpy.isEmpty());
    QVERIFY(stateSpy.isEmpty());
    QVERIFY(finishedSpy.isEmpty());
    QVERIFY(positionSpy.isEmpty());
    QVERIFY(durationSpy.isEmpty());


    d.stop();
    QTRY_COMPARE(d.state(), QAudioDecoder::StoppedState);
    QCOMPARE(d.duration(), qint64(-1));
    QVERIFY(!d.bufferAvailable());
}
Example #7
0
// --------------------------------------------------------------------------
int qMidasAPITest(int argc, char* argv[])
{
  QCoreApplication app(argc, argv);

  bool ok = false;
  QList<QVariantMap> result;

  // --------------------------------------------------------------------------
  // Check that query associated with local file release file handle
  // --------------------------------------------------------------------------
  QDir tmp = QDir::temp();
  QString temporaryDirName =
        QString("qMidasAPITest1-queryFile.%1").arg(QTime::currentTime().toString("hhmmsszzz"));
  tmp.mkdir(temporaryDirName);
  tmp.cd(temporaryDirName);
  tmp.mkdir("api");
  tmp.cd("api");

  QFile fileReply(tmp.filePath("json"));
  if (!fileReply.open(QFile::WriteOnly))
    {
    std::cerr << "Line " << __LINE__ << " - Failed to create temporary file." 
              << qPrintable(tmp.filePath("json")) << std::endl;
    return EXIT_FAILURE;
    }

  fileReply.write(
    QString("{\"stat\":\"ok\",\"code\":\"0\",\"message\":\"\",\"data\":{"
            "\"quote\":\"If a day goes past and you do not learn anything, it is a waste of a day.\","
            "\"author\" : \"Mike Horn\"}}").toLatin1());
            
  fileReply.close();

  ok = false;
  result = qMidasAPI::synchronousQuery(ok,
    QUrl::fromLocalFile(QDir::temp().filePath(temporaryDirName)).toString(), "midas.quote.of.the.day");
  std::cout << "result: " <<
    qPrintable(qMidasAPI::qVariantMapListToString(result)) << std::endl;
  if (!ok || result.size() == 0)
    {
    std::cout << "Failed to query 'midas.quote.of.the.day'." << std::endl;
    return EXIT_FAILURE;
    }

  // Attempt to delete 'queryFile'
  if (!QFile::remove(tmp.filePath("json")))
    {
    std::cout << "Failed to remove queryFile. [" << qPrintable(tmp.filePath("json")) << "]" << std::endl;
    return EXIT_FAILURE;
    }

  // --------------------------------------------------------------------------
  QString midasUrl("http://slicer.kitware.com/midas3");
  qMidasAPI midasAPI;
  midasAPI.setMidasUrl(midasUrl);

  if (midasAPI.midasUrl() != midasUrl)
    {
    std::cout << "Failed to set Midas Url" << std::endl;
    return EXIT_FAILURE;
    }

  // --------------------------------------------------------------------------
  // Successfull query: midas.version
  // --------------------------------------------------------------------------
  QSignalSpy errorSpy(&midasAPI, SIGNAL(errorReceived(QUuid,QString)));
  QSignalSpy receivedSpy(&midasAPI, SIGNAL(resultReceived(QUuid,QList<QVariantMap>)));
  QUuid queryUuid = midasAPI.get("midas.version");

  // Give 5 seconds for the server to answer
  wait(5000);

  if (queryUuid.isNull() ||
      errorSpy.count() > 0||
      receivedSpy.count() != 1)
    {
    std::cerr << "Failed to query 'midas.version': "
              << errorSpy.count() << " errors,"
              << receivedSpy.count() << " results." << std::endl;
    return EXIT_FAILURE;
    }
  errorSpy.clear();
  receivedSpy.clear();

  // --------------------------------------------------------------------------
  // Fail query: midas.notafunction
  // --------------------------------------------------------------------------
  queryUuid = midasAPI.get("midas.notafunction");

  // Give 5 seconds for the server to answer
  wait(5000);

  /// Even if errors are received, an empty result is sent
  if (queryUuid.isNull() ||
      errorSpy.count() == 0 ||
      receivedSpy.count() != 1)
    {
    std::cerr << "Failed to query 'midas.notafunction': "
              << errorSpy.count() << " errors,"
              << receivedSpy.count() << " results." << std::endl;
    return EXIT_FAILURE;
    }

  // --------------------------------------------------------------------------
  // Synchronous query: midas.info
  // --------------------------------------------------------------------------
  ok = false;
  result  = qMidasAPI::synchronousQuery(ok, midasUrl, "midas.info");
  std::cout << "result: " <<
    qPrintable(qMidasAPI::qVariantMapListToString(result))<< std::endl;
  if (!ok || result.size() == 0)
    {
    std::cout << "Failed to query 'midas.info'."
              << std::endl;
    return EXIT_FAILURE;
    }

  // --------------------------------------------------------------------------
  // Synchronous fail query: midas.notafunction
  // --------------------------------------------------------------------------
  result= qMidasAPI::synchronousQuery(ok, midasUrl,"midas.notafunction");
  std::cout << "result: " <<
    qPrintable(qMidasAPI::qVariantMapListToString(result))<< std::endl;
  if (ok ||
      result.size() != 1 ||
      result.at(0)["queryError"].isNull())
    {
    std::cout << "Failed to query 'midas.info'."
              << result.size() << " results."
              << std::endl;
    return EXIT_FAILURE;
    }

  // --------------------------------------------------------------------------
  // Synchronous fail query: midas.login (wrong credentials)
  // --------------------------------------------------------------------------
  qMidasAPI::ParametersType wrongParameters;
  wrongParameters["appname"] = "qMidasAPITest";
  wrongParameters["email"] = "*****@*****.**";
  wrongParameters["apikey"] = "123456789";
  result= qMidasAPI::synchronousQuery(ok, midasUrl,"midas.login", wrongParameters);
  std::cout << "result: " <<
    qPrintable(qMidasAPI::qVariantMapListToString(result))<< std::endl;
  if (ok ||
      result.size() != 1 ||
      result.at(0)["queryError"].isNull())
    {
    std::cout << "Failed to query 'midas.login'."
              << result.size() << " results."
              << std::endl;
    return EXIT_FAILURE;
    }
    
  // --------------------------------------------------------------------------
  // Synchronous query: midas.community.list (return array of data)
  // --------------------------------------------------------------------------
  result= qMidasAPI::synchronousQuery(ok, midasUrl,"midas.community.list");
  std::cout << "result: " <<
    qPrintable(qMidasAPI::qVariantMapListToString(result))<< std::endl;
  if (!ok || result.size() == 0)
    {
    std::cout << "Failed to query 'midas.community.list'." << std::endl;
    return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}
Example #8
0
/*!
 Description: Add a llcp2 server which will always
 run( actually run twice ), then a client in a device connect,
 after the case finish, another device connect the
 server again.

 CounterPart: tst_qllcpsockettype2 echo:"0"
 run this case twice to test multiConnection()
*/
void tst_QLlcpServer::multiConnection()
{
    QString uri = TestUri;
    QString hint ="multiConnection test";

    QLlcpServer server;
    qDebug() << "Create QLlcpServer completed";
    qDebug() << "Start listening...";
    QSignalSpy connectionSpy(&server, SIGNAL(newConnection()));

    bool ret = server.listen(uri);
    QVERIFY(ret);
    qDebug() << "Listen() return ok";
    const int KLoopCount = 2;
    int loopCount = 0;
    while(loopCount < KLoopCount)
    {
        qDebug() << "#########Loop count = " << loopCount <<" #########";
        QNfcTestUtil::ShowAutoMsg(hint, &connectionSpy, 1);

        QTRY_VERIFY(!connectionSpy.isEmpty());
        qDebug() << "try to call nextPendingConnection()";
        QLlcpSocket *socket = server.nextPendingConnection();
        QVERIFY(socket != NULL);
        QSignalSpy readyReadSpy(socket, SIGNAL(readyRead()));
        QSignalSpy errorSpy(socket, SIGNAL(error(QLlcpSocket::SocketError)));

        //Get data from client
        QTRY_VERIFY(!readyReadSpy.isEmpty());

        qDebug() << "Bytes available = " << socket->bytesAvailable();
        quint16 blockSize = 0;
        QDataStream in(socket);
        in.setVersion(QDataStream::Qt_4_6);
        while (socket->bytesAvailable() < (int)sizeof(quint16)) {
            QSignalSpy readyRead(socket, SIGNAL(readyRead()));
            QTRY_VERIFY(!readyRead.isEmpty());
        }
        in >> blockSize;
        qDebug()<<"Read blockSize from client: " << blockSize;
        while (socket ->bytesAvailable() < blockSize) {
            QSignalSpy readyRead(socket, SIGNAL(readyRead()));
            QTRY_VERIFY(!readyRead.isEmpty());
        }
        QString echo;
        in >> echo;
        qDebug() << "Read data from client:" << echo;
        //Send data to client
        QSignalSpy bytesWrittenSpy(socket, SIGNAL(bytesWritten(qint64)));
        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_4_6);
        out << (quint16)0;
        out << echo;
        qDebug()<<"Write echoed data back to client";
        out.device()->seek(0);
        out << (quint16)(block.size() - sizeof(quint16));
        qint64 val = socket->write(block);
        qDebug("Write() return value = %d", val);
        QVERIFY(val == 0);

        QTRY_VERIFY(!bytesWrittenSpy.isEmpty());
        qint64 written = countBytesWritten(bytesWrittenSpy);
        qDebug()<<"Server::bytesWritten signal return value = " << written;
        while (written < block.size())
        {
            QSignalSpy bytesWrittenSpy(socket, SIGNAL(bytesWritten(qint64)));
            QTRY_VERIFY(!bytesWrittenSpy.isEmpty());
            written += countBytesWritten(bytesWrittenSpy);
        }
        QVERIFY(written == block.size());
        //Now data has been sent,check the if existing error
        QVERIFY(errorSpy.isEmpty());

        connectionSpy.removeFirst();
        loopCount++;
    }
    QTest::qWait(1500);//give some time to client to finish
    server.close();
}
Example #9
0
/*!
 Description: Unit test for NFC LLCP server sync(waitXXX) functions

 TestScenario: 1. Server will listen to a pre-defined URI
               2. Wait client to connect.
               3. Read message from client.
               4. Echo the same message back to client
               5. Wait client disconnect event.

 TestExpectedResults:
               1. The listen successfully set up.
               2. The message has be received from client.
               3. The echoed message has been sent to client.
               4. Connection disconnected and NO error signals emitted.
*/
void tst_QLlcpServer::newConnection_wait()
{
    QFETCH(QString, uri);
    QFETCH(QString, hint);

    QLlcpServer server;
    qDebug() << "Create QLlcpServer completed";
    qDebug() << "Start listening...";
    bool ret = server.listen(uri);
    QVERIFY(ret);
    qDebug() << "Listen() return ok";
    QSignalSpy connectionSpy(&server, SIGNAL(newConnection()));

    QNfcTestUtil::ShowAutoMsg(hint, &connectionSpy, 1);

    QTRY_VERIFY(!connectionSpy.isEmpty());
    qDebug() << "try to call nextPendingConnection()";
    QLlcpSocket *socket = server.nextPendingConnection();
    QVERIFY(socket != NULL);

    QSignalSpy errorSpy(socket, SIGNAL(error(QLlcpSocket::SocketError)));
    //Get data from client
    const int Timeout = 10 * 1000;

    quint16 blockSize = 0;
    QDataStream in(socket);
    in.setVersion(QDataStream::Qt_4_6);
    while (socket->bytesAvailable() < (int)sizeof(quint16)) {
        bool ret = socket->waitForReadyRead(Timeout);
        QVERIFY(ret);
    }

    in >> blockSize;
    qDebug()<<"Read blockSize from client: " << blockSize;
    while (socket ->bytesAvailable() < blockSize) {
        bool ret = socket->waitForReadyRead(Timeout);
        QVERIFY(ret);
    }
    QString echo;
    in >> echo;
    qDebug() << "Read data from client:" << echo;
    //Send data to client
    QSignalSpy bytesWrittenSpy(socket, SIGNAL(bytesWritten(qint64)));

    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_6);
    out << (quint16)0;
    out << echo;
    qDebug()<<"Write echoed data back to client";
    out.device()->seek(0);
    out << (quint16)(block.size() - sizeof(quint16));

    qint64 val = socket->write(block);
    qDebug("Write() return value = %d", val);
    QVERIFY(val == 0);

    ret = socket->waitForBytesWritten(Timeout);
    QVERIFY(ret);

    QTRY_VERIFY(!bytesWrittenSpy.isEmpty());
    qint64 written = countBytesWritten(bytesWrittenSpy);

    while (written < block.size())
    {
        QSignalSpy bytesWrittenSpy(socket, SIGNAL(bytesWritten(qint64)));
        bool ret = socket->waitForBytesWritten(Timeout);
        QVERIFY(ret);
        QTRY_VERIFY(!bytesWrittenSpy.isEmpty());
        written += countBytesWritten(bytesWrittenSpy);
    }
    QVERIFY(written == block.size());
    //Now data has been sent,check the if existing error
    if (!errorSpy.isEmpty())
    {
        QLlcpSocket::SocketError error = errorSpy.first().at(0).value<QLlcpSocket::SocketError>();
        qDebug("QLlcpSocket::SocketError =%d", error);
    }
    QVERIFY(errorSpy.isEmpty());
    QTest::qWait(1500);//give some time to client to finish
    server.close();
}
void tst_QLlcpSocket::tst_clientConnection()
{
    QFETCH(ClientConnectionShutdown, shutdown);
    QFETCH(bool, stream);

    QString service = QLatin1String("urn:nfc:sn:com.nokia.qtmobility.commandserver") +
                      (stream ? QLatin1String(".stream") : QLatin1String(".datagram"));

    /* Construction */
    QLlcpSocket *socket = new QLlcpSocket;

    QSignalSpy stateSpy(socket, SIGNAL(stateChanged(QLlcpSocket::SocketState)));

    QCOMPARE(socket->state(), QLlcpSocket::UnconnectedState);

    /* Connection */
    QSignalSpy connectedSpy(socket, SIGNAL(connected()));
    QSignalSpy errorSpy(socket, SIGNAL(error(QLlcpSocket::SocketError)));

    socket->connectToService(0, service);

    QCOMPARE(stateSpy.count(), 1);
    QCOMPARE(stateSpy.takeFirst().at(0).value<QLlcpSocket::SocketState>(),
             QLlcpSocket::ConnectingState);
    QCOMPARE(socket->state(), QLlcpSocket::ConnectingState);

    stateSpy.clear();

    QTRY_VERIFY_TIMEOUT(30000, !connectedSpy.isEmpty() || !errorSpy.isEmpty());

    if (errorSpy.count() != 0) {
        qDebug() << errorSpy.takeFirst().at(0).toInt();
        QSKIP("Connection error", SkipSingle);
    }

    QCOMPARE(connectedSpy.count(), 1);
    QCOMPARE(stateSpy.count(), 1);
    QCOMPARE(stateSpy.takeFirst().at(0).value<QLlcpSocket::SocketState>(),
             QLlcpSocket::ConnectedState);
    QCOMPARE(socket->state(), QLlcpSocket::ConnectedState);

    stateSpy.clear();

    QSignalSpy bytesWrittenSpy(socket, SIGNAL(bytesWritten(qint64)));
    QSignalSpy readyReadSpy(socket, SIGNAL(readyRead()));

    /* Verify connected to correct service */
    if (stream) {
        socket->write("URI\n");

        QCOMPARE(bytesWrittenSpy.count(), 1);
        QCOMPARE(bytesWrittenSpy.takeFirst().at(0).value<qint64>(), qint64(4));

        QTRY_VERIFY(!readyReadSpy.isEmpty() && socket->canReadLine());

        const QByteArray line = socket->readLine().trimmed();

        QCOMPARE(line, service.toLatin1());
    } else {
        socket->writeDatagram("URI");

        QCOMPARE(bytesWrittenSpy.count(), 1);
        QCOMPARE(bytesWrittenSpy.takeFirst().at(0).value<qint64>(), qint64(3));

        QTRY_VERIFY(!readyReadSpy.isEmpty() && socket->hasPendingDatagrams());

        QByteArray datagram;
        datagram.resize(socket->pendingDatagramSize());

        socket->readDatagram(datagram.data(), datagram.size());

        QCOMPARE(datagram, service.toLatin1());
    }

    bytesWrittenSpy.clear();
    readyReadSpy.clear();

    /* Read / Write */
    if (stream) {
        QByteArray data("ECHO Test data\n");
        socket->write(data);

        QCOMPARE(bytesWrittenSpy.count(), 1);
        QCOMPARE(bytesWrittenSpy.takeFirst().at(0).value<qint64>(), qint64(data.size()));

        QTRY_VERIFY(!readyReadSpy.isEmpty());

        const QByteArray line = socket->readLine().trimmed();

        QCOMPARE(line.constData(), "Test data");
    } else {
        socket->writeDatagram("ECHO Test data");

        QCOMPARE(bytesWrittenSpy.count(), 1);
        QCOMPARE(bytesWrittenSpy.takeFirst().at(0).value<qint64>(), qint64(14));

        QTRY_VERIFY(!readyReadSpy.isEmpty());

        QByteArray datagram;
        datagram.resize(socket->pendingDatagramSize());

        socket->readDatagram(datagram.data(), datagram.size());

        QCOMPARE(datagram.constData(), "Test data");
    }

    bytesWrittenSpy.clear();
    readyReadSpy.clear();

    QSignalSpy disconnectedSpy(socket, SIGNAL(disconnected()));
    errorSpy.clear();

    /* Shutdown */
    switch (shutdown) {
    case ServerDisconnect:
        if (stream)
            socket->write("DISCONNECT\n");
        else
            socket->writeDatagram("DISCONNECT");
        break;
    case ServerClose:
        if (stream)
            socket->write("CLOSE\n");
        else
            socket->writeDatagram("CLOSE");
        break;
    case ClientDisconnect:
        socket->disconnectFromService();
        break;
    case ClientClose:
        socket->close();
        break;
    }

    QTRY_VERIFY(!disconnectedSpy.isEmpty());

    QCOMPARE(disconnectedSpy.count(), 1);
    QCOMPARE(stateSpy.count(), 2);
    QCOMPARE(stateSpy.takeFirst().at(0).value<QLlcpSocket::SocketState>(),
             QLlcpSocket::ClosingState);
    QCOMPARE(stateSpy.takeFirst().at(0).value<QLlcpSocket::SocketState>(),
             QLlcpSocket::UnconnectedState);
    QVERIFY(!socket->isOpen());

    if (shutdown == ServerDisconnect || shutdown == ServerClose) {
        QTRY_VERIFY(!errorSpy.isEmpty());

        QCOMPARE(errorSpy.count(), 1);
        QCOMPARE(errorSpy.takeFirst().at(0).value<QLlcpSocket::SocketError>(),
                 QLlcpSocket::RemoteHostClosedError);
        QCOMPARE(socket->error(), QLlcpSocket::RemoteHostClosedError);
    }

    delete socket;
}