Esempio n. 1
0
void FileTests::TestReadFileBasicEmpty()
{
    HANDLE const hIn = GetStdInputHandle();
    VERIFY_IS_NOT_NULL(hIn, L"Verify we have the standard input handle.");

    DWORD dwMode = 0;
    VERIFY_WIN32_BOOL_SUCCEEDED(SetConsoleMode(hIn, dwMode), L"Set input mode for test.");

    VERIFY_WIN32_BOOL_SUCCEEDED(FlushConsoleInputBuffer(hIn), L"Flush input buffer in preparation for test.");

    char ch = '\0';
    Log::Comment(L"Queue background blocking read file operation.");
    auto BackgroundRead = std::async([&] {
        DWORD dwRead = 0;
        VERIFY_WIN32_BOOL_SUCCEEDED(ReadFile(hIn, &ch, 1, &dwRead, nullptr), L"Read file was successful.");
        VERIFY_ARE_EQUAL(0u, dwRead, L"We should have read nothing back. It should just return from Ctrl+Z");
    });

    char const chExpected = '\x1a'; // ctrl+z character
    Log::Comment(L"Send a key into the console.");
    SendFullKeyStrokeHelper(hIn, chExpected);

    Log::Comment(L"Wait for background to unblock.");
    BackgroundRead.wait();
    VERIFY_ARE_EQUAL('\0', ch);
}
Esempio n. 2
0
TEST_FIXTURE(e2e_raw_client, update_entity_with_patch)
{
	auto model = client.get_model().get();

	//check the old value
	auto query_result = client.get_data_from_server(U("Accounts(101)")).get();
	auto old_entity = std::dynamic_pointer_cast<odata_entity_value>(query_result[0]);
	std::shared_ptr<odata_value> old_value;
	old_entity->get_property_value(U("Country"), old_value);
	auto old_country = std::dynamic_pointer_cast<odata_primitive_value>(old_value);
	VERIFY_ARE_EQUAL(U("US"), old_country->as<::utility::string_t>());

	//update the entity with patch
	old_entity->set_value(U("Country"), U("GB"));

	auto response_code = client.patch_entity(U("Accounts"), old_entity).get();
	VERIFY_ARE_EQUAL(204, response_code);

	//query the updated entity
	auto check_query = client.get_data_from_server(U("Accounts(101)")).get();

	auto new_entity = std::dynamic_pointer_cast<odata_entity_value>(check_query[0]);
	std::shared_ptr<odata_value> property_value;
	VERIFY_IS_TRUE(new_entity->get_property_value(U("Country"), property_value));
	auto primitive_value = std::dynamic_pointer_cast<odata_primitive_value>(property_value);
	::utility::string_t new_country = primitive_value->as<::utility::string_t>();
	VERIFY_ARE_EQUAL(U("GB"), new_country);
}
Esempio n. 3
0
TEST_FIXTURE(e2e_raw_client, create_entity)
{
	auto model = client.get_model().get();

	::utility::string_t entity_set_name = U("Accounts");
	std::shared_ptr<odata_entity_value> entity = std::make_shared<odata_entity_value>(model->find_entity_set_type(entity_set_name));

	entity->set_value(U("AccountID"), 130);
	entity->set_value(U("Country"), U("CN"));

	auto accountinfo_type = model->find_complex_type(U("AccountInfo"));
	auto account_info = std::make_shared<odata_complex_value>(accountinfo_type);
	::utility::string_t account_firstname = U("cpp");
	::utility::string_t account_lastname = U("client");
	account_info->set_value(U("FirstName"), account_firstname);
	account_info->set_value(U("LastName"), account_lastname);

	entity->set_value(U("AccountInfo"), account_info);

	auto response_code = client.create_entity(entity_set_name, entity).get();
	VERIFY_ARE_EQUAL(201, response_code);

	//query the newly created entity
	auto query_result = client.get_data_from_server(U("Accounts(130)")).get();
	VERIFY_ARE_EQUAL(query_result.size(), 1);

	auto new_entity = std::dynamic_pointer_cast<odata_entity_value>(query_result[0]);
	std::shared_ptr<odata_value> property_value;
	VERIFY_IS_TRUE(entity->get_property_value(U("AccountID"), property_value));
	auto primitive_value = std::dynamic_pointer_cast<odata_primitive_value>(property_value);
	int32_t new_id = primitive_value->as<int32_t>();
	VERIFY_ARE_EQUAL(130, new_id);
}
Esempio n. 4
0
void FontTests::TestGetFontSizeLargeIndexInvalid()
{
    SetLastError(0);
    COORD coordFontSize = OneCoreDelay::GetConsoleFontSize(GetStdOutputHandle(), 0xFFFFFFFF);
    VERIFY_ARE_EQUAL(coordFontSize, c_coordZero, L"Ensure (0,0) coord returned to indicate failure");
    VERIFY_ARE_EQUAL(GetLastError(), (DWORD)ERROR_INVALID_PARAMETER, L"Ensure last error was set appropriately");
}
Esempio n. 5
0
void FileTests::TestWriteFileDisableNewlineAutoReturn()
{
    bool fDisableAutoReturn;
    VERIFY_SUCCEEDED(TestData::TryGetValue(L"fDisableAutoReturn", fDisableAutoReturn));

    bool fProcessedOn;
    VERIFY_SUCCEEDED(TestData::TryGetValue(L"fProcessedOn", fProcessedOn));

    HANDLE const hOut = GetStdOutputHandle();
    VERIFY_IS_NOT_NULL(hOut, L"Verify we have the standard output handle.");

    CONSOLE_SCREEN_BUFFER_INFOEX csbiexOriginal = { 0 };
    csbiexOriginal.cbSize = sizeof(csbiexOriginal);
    VERIFY_WIN32_BOOL_SUCCEEDED(GetConsoleScreenBufferInfoEx(hOut, &csbiexOriginal), L"Retrieve screen buffer properties at beginning of test.");

    DWORD dwMode = 0;
    WI_SetFlagIf(dwMode, DISABLE_NEWLINE_AUTO_RETURN, fDisableAutoReturn);
    WI_SetFlagIf(dwMode, ENABLE_PROCESSED_OUTPUT, fProcessedOn);
    VERIFY_WIN32_BOOL_SUCCEEDED(SetConsoleMode(hOut, dwMode), L"Set console mode for test.");

    COORD const coordZero = { 0 };
    VERIFY_ARE_EQUAL(coordZero, csbiexOriginal.dwCursorPosition, L"Cursor should be at 0,0 in fresh buffer.");

    CONSOLE_SCREEN_BUFFER_INFOEX csbiexBefore = { 0 };
    csbiexBefore.cbSize = sizeof(csbiexBefore);
    CONSOLE_SCREEN_BUFFER_INFOEX csbiexAfter = { 0 };
    csbiexAfter.cbSize = sizeof(csbiexAfter);
    COORD coordExpected = { 0 };

    WriteFileHelper(hOut, csbiexBefore, csbiexAfter, "abc", 3);
    coordExpected = csbiexBefore.dwCursorPosition;
    coordExpected.X += 3;
    VERIFY_ARE_EQUAL(coordExpected, csbiexAfter.dwCursorPosition, L"Cursor should have moved right to the end of the text written.");

    WriteFileHelper(hOut, csbiexBefore, csbiexAfter, "\n", 1);

    if (fProcessedOn)
    {
        if (fDisableAutoReturn)
        {
            coordExpected = csbiexBefore.dwCursorPosition;
            coordExpected.Y += 1;
        }
        else
        {
            coordExpected = csbiexBefore.dwCursorPosition;
            coordExpected.Y += 1;
            coordExpected.X = 0;
        }
    }
    else
    {
        coordExpected = csbiexBefore.dwCursorPosition;
        coordExpected.X += 1;
    }

    VERIFY_ARE_EQUAL(coordExpected, csbiexAfter.dwCursorPosition, L"Cursor should move to expected position.");
}
Esempio n. 6
0
void FileTests::TestWriteFileVTProcessing()
{
    bool fVtOn;
    VERIFY_SUCCEEDED(TestData::TryGetValue(L"fVtOn", fVtOn));

    bool fProcessedOn;
    VERIFY_SUCCEEDED(TestData::TryGetValue(L"fProcessedOn", fProcessedOn));

    HANDLE const hOut = GetStdOutputHandle();
    VERIFY_IS_NOT_NULL(hOut, L"Verify we have the standard output handle.");

    CONSOLE_SCREEN_BUFFER_INFOEX csbiexOriginal = { 0 };
    csbiexOriginal.cbSize = sizeof(csbiexOriginal);
    VERIFY_WIN32_BOOL_SUCCEEDED(GetConsoleScreenBufferInfoEx(hOut, &csbiexOriginal), L"Retrieve screen buffer properties at beginning of test.");

    DWORD dwFlags = 0;
    WI_SetFlagIf(dwFlags, ENABLE_VIRTUAL_TERMINAL_PROCESSING, fVtOn);
    WI_SetFlagIf(dwFlags, ENABLE_PROCESSED_OUTPUT, fProcessedOn);
    VERIFY_WIN32_BOOL_SUCCEEDED(SetConsoleMode(hOut, dwFlags), L"Turn on relevant flags for test.");

    COORD const coordZero = { 0 };
    VERIFY_ARE_EQUAL(coordZero, csbiexOriginal.dwCursorPosition, L"Cursor should be at 0,0 in fresh buffer.");

    PCSTR pszTestString = "\x1b" "[14m";
    DWORD const cchTest = (DWORD)strlen(pszTestString);

    CONSOLE_SCREEN_BUFFER_INFOEX csbiexBefore = { 0 };
    csbiexBefore.cbSize = sizeof(csbiexBefore);
    CONSOLE_SCREEN_BUFFER_INFOEX csbiexAfter = { 0 };
    csbiexAfter.cbSize = sizeof(csbiexAfter);

    WriteFileHelper(hOut, csbiexBefore, csbiexAfter, pszTestString, cchTest);

    // We only expect characters to be processed and not printed if both processed mode and VT mode are on.
    bool const fProcessedNotPrinted = fProcessedOn && fVtOn;

    if (fProcessedNotPrinted)
    {
        PCSTR pszReadBackExpected = "      ";
        DWORD const cchReadBackExpected = (DWORD)strlen(pszReadBackExpected);

        VERIFY_ARE_EQUAL(csbiexBefore.dwCursorPosition, csbiexAfter.dwCursorPosition, L"Verify cursor didn't move because the VT sequence was processed instead of printed.");

        wistd::unique_ptr<char[]> pszReadBack;
        ReadBackHelper(hOut, coordZero, cchReadBackExpected, pszReadBack);
        VERIFY_ARE_EQUAL(String(pszReadBackExpected), String(pszReadBack.get()), L"Verify that nothing was printed into the buffer.");
    }
    else
    {
        COORD coordExpected = csbiexBefore.dwCursorPosition;
        coordExpected.X += (SHORT)cchTest;
        VERIFY_ARE_EQUAL(coordExpected, csbiexAfter.dwCursorPosition, L"Verify cursor moved as characters should have been emitted, not consumed.");

        wistd::unique_ptr<char[]> pszReadBack;
        ReadBackHelper(hOut, coordZero, cchTest, pszReadBack);
        VERIFY_ARE_EQUAL(String(pszTestString), String(pszReadBack.get()), L"Verify that original test string was printed into the buffer.");
    }
}
Esempio n. 7
0
void TestSetConsoleCursorPositionImpl(WORD wCursorX, WORD wCursorY, BOOL bExpectedResult)
{
    COORD coordCursor;
    coordCursor.X = wCursorX;
    coordCursor.Y = wCursorY;

    // Get initial position data
    CONSOLE_SCREEN_BUFFER_INFOEX sbiInitial = { 0 };
    sbiInitial.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
    BOOL bResult = GetConsoleScreenBufferInfoEx(Common::_hConsole, &sbiInitial);
    VERIFY_WIN32_BOOL_SUCCEEDED(bResult, L"Get the initial buffer data.");

    // Attempt to set cursor into valid area
    bResult = SetConsoleCursorPosition(Common::_hConsole, coordCursor);
    VERIFY_ARE_EQUAL(bResult, bExpectedResult, L"Ensure that return from SET matches success/failure state we were expecting.");

    CONSOLE_SCREEN_BUFFER_INFOEX sbiTest = { 0 };
    sbiTest.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
    bResult = GetConsoleScreenBufferInfoEx(Common::_hConsole, &sbiTest);
    VERIFY_WIN32_BOOL_SUCCEEDED(bResult, L"GET the values back to ensure they were set properly.");

    // Cursor is where it was set to if we were supposed to be successful
    if (bExpectedResult)
    {
        VERIFY_ARE_EQUAL(coordCursor, sbiTest.dwCursorPosition, L"If SET was TRUE, we expect the cursor to be where we SET it.");
    }
    else
    {
        // otherwise, it's at where it was before
        VERIFY_ARE_EQUAL(sbiInitial.dwCursorPosition, sbiTest.dwCursorPosition, L"If SET was FALSE, we expect the cursor to not have moved.");
    }

    // Verify the viewport.
    bool fViewportMoveExpected = false;

    // If we expected the cursor to be set successfully, the viewport might have moved.
    if (bExpectedResult)
    {
        // If the position we set was outside the initial rectangle, then the viewport should have moved.
        if (coordCursor.X > sbiInitial.srWindow.Right ||
            coordCursor.X < sbiInitial.srWindow.Left ||
            coordCursor.Y > sbiInitial.srWindow.Bottom ||
            coordCursor.Y < sbiInitial.srWindow.Top)
        {
            fViewportMoveExpected = true;
        }
    }

    if (fViewportMoveExpected)
    {
        // Something had to have changed in the viewport
        VERIFY_ARE_NOT_EQUAL(sbiInitial.srWindow, sbiTest.srWindow, L"The viewports must have changed if we set the cursor outside the current area.");
    }
    else
    {
        VERIFY_ARE_EQUAL(sbiInitial.srWindow, sbiTest.srWindow, L"The viewports must remain the same if the cursor was set inside the existing one.");
    }
}
Esempio n. 8
0
TEST_FIXTURE(e2e_raw_client, query_collection_property)
{
	auto query_result = client.get_data_from_server(U("People(4)/Numbers")).get();
	VERIFY_ARE_EQUAL(query_result.size(), 3);
	VERIFY_ARE_EQUAL(edm_type_kind_t::Primitive, query_result[0]->get_value_type()->get_type_kind());

	auto primitive_value = std::dynamic_pointer_cast<odata_primitive_value>(query_result[1]);
	::utility::string_t number = primitive_value->as<::utility::string_t>();
	VERIFY_ARE_EQUAL(U("555-555-5555"), number);
}
Esempio n. 9
0
void FileTests::TestWriteFileWrapEOL()
{
    bool fFlagOn;
    VERIFY_SUCCEEDED(TestData::TryGetValue(L"fFlagOn", fFlagOn));

    HANDLE const hOut = GetStdOutputHandle();
    VERIFY_IS_NOT_NULL(hOut, L"Verify we have the standard output handle.");

    CONSOLE_SCREEN_BUFFER_INFOEX csbiexOriginal = { 0 };
    csbiexOriginal.cbSize = sizeof(csbiexOriginal);
    VERIFY_WIN32_BOOL_SUCCEEDED(GetConsoleScreenBufferInfoEx(hOut, &csbiexOriginal), L"Retrieve screen buffer properties at beginning of test.");

    if (fFlagOn)
    {
        VERIFY_WIN32_BOOL_SUCCEEDED(SetConsoleMode(hOut, ENABLE_WRAP_AT_EOL_OUTPUT), L"Set wrap at EOL.");
    }
    else
    {
        VERIFY_WIN32_BOOL_SUCCEEDED(SetConsoleMode(hOut, 0), L"Make sure wrap at EOL is off.");
    }

    COORD const coordZero = { 0 };
    VERIFY_ARE_EQUAL(coordZero, csbiexOriginal.dwCursorPosition, L"Cursor should be at 0,0 in fresh buffer.");

    // Fill first row of the buffer with Z characters until 1 away from the end.
    for (SHORT i = 0; i < csbiexOriginal.dwSize.X - 1; i++)
    {
        WriteFile(hOut, "Z", 1, nullptr, nullptr);
    }

    CONSOLE_SCREEN_BUFFER_INFOEX csbiexBefore = { 0 };
    csbiexBefore.cbSize = sizeof(csbiexBefore);
    CONSOLE_SCREEN_BUFFER_INFOEX csbiexAfter = { 0 };
    csbiexAfter.cbSize = sizeof(csbiexAfter);
    COORD coordExpected = { 0 };

    VERIFY_WIN32_BOOL_SUCCEEDED(GetConsoleScreenBufferInfoEx(hOut, &csbiexBefore), L"Get cursor position information before attempting to wrap at end of line.");
    VERIFY_WIN32_BOOL_SUCCEEDED(WriteFile(hOut, "Y", 1, nullptr, nullptr), L"Write of final character in line succeeded.");
    VERIFY_WIN32_BOOL_SUCCEEDED(GetConsoleScreenBufferInfoEx(hOut, &csbiexAfter), L"Get cursor position information after attempting to wrap at end of line.");

    if (fFlagOn)
    {
        Log::Comment(L"Cursor should go down a row if we tried to print at end of line.");
        coordExpected = csbiexBefore.dwCursorPosition;
        coordExpected.Y++;
        coordExpected.X = 0;
    }
    else
    {
        Log::Comment(L"Cursor shouldn't move when printing at end of line.");
        coordExpected = csbiexBefore.dwCursorPosition;
    }

    VERIFY_ARE_EQUAL(coordExpected, csbiexAfter.dwCursorPosition, L"Verify cursor moved as expected based on flag state.");
}
Esempio n. 10
0
void FontTests::TestGetFontSizeInvalid()
{
    DWORD dwConsoleOutput;
    VERIFY_SUCCEEDED(TestData::TryGetValue(L"dwConsoleOutput", dwConsoleOutput), L"Get input handle value");

    // Need to make sure that last error is cleared so that we can verify that lasterror was set by GetConsoleFontSize
    SetLastError(0);

    COORD coordFontSize = OneCoreDelay::GetConsoleFontSize((HANDLE)dwConsoleOutput, 0);
    VERIFY_ARE_EQUAL(coordFontSize, c_coordZero, L"Ensure (0,0) coord returned to indicate failure");
    VERIFY_ARE_EQUAL(GetLastError(), (DWORD)ERROR_INVALID_HANDLE, L"Ensure last error was set appropriately");
}
Esempio n. 11
0
void FileTests::TestUtf8WriteFileInvalid()
{
    Log::Comment(L"Backup original console codepage.");
    UINT const uiOriginalCP = GetConsoleOutputCP();
    auto restoreOriginalCP = wil::scope_exit([&] {
        Log::Comment(L"Restore original console codepage.");
        SetConsoleOutputCP(uiOriginalCP);
    });

    HANDLE const hOut = GetStdOutputHandle();
    VERIFY_IS_NOT_NULL(hOut, L"Verify we have the standard output handle.");

    VERIFY_WIN32_BOOL_SUCCEEDED(SetConsoleOutputCP(CP_UTF8), L"Set output codepage to UTF8");

    DWORD dwWritten;
    DWORD dwExpectedWritten;
    char* str;
    DWORD cbStr;

    // \x80 is an invalid UTF-8 continuation
    // \x40 is the @ symbol which is valid.
    str = "\x80\x40";
    cbStr = (DWORD)strlen(str);
    dwWritten = 0;
    dwExpectedWritten = cbStr;

    VERIFY_WIN32_BOOL_SUCCEEDED(WriteFile(hOut, str, cbStr, &dwWritten, nullptr));
    VERIFY_ARE_EQUAL(dwExpectedWritten, dwWritten);

    // \x80 is an invalid UTF-8 continuation
    // \x40 is the @ symbol which is valid.
    str = "\x80\x40\x40";
    cbStr = (DWORD)strlen(str);
    dwWritten = 0;
    dwExpectedWritten = cbStr;

    VERIFY_WIN32_BOOL_SUCCEEDED(WriteFile(hOut, str, cbStr, &dwWritten, nullptr));
    VERIFY_ARE_EQUAL(dwExpectedWritten, dwWritten);

    // \x80 is an invalid UTF-8 continuation
    // \x40 is the @ symbol which is valid.
    str = "\x80\x80\x80\x40";
    cbStr = (DWORD)strlen(str);
    dwWritten = 0;
    dwExpectedWritten = cbStr;

    VERIFY_WIN32_BOOL_SUCCEEDED(WriteFile(hOut, str, cbStr, &dwWritten, nullptr));
    VERIFY_ARE_EQUAL(dwExpectedWritten, dwWritten);
}
Esempio n. 12
0
void FontTests::TestLongFontNameScenario()
{
    wistd::unique_ptr<wchar_t[]> expandedLongFontPath;
    VERIFY_SUCCEEDED(ExpandPathToMutable(pwszLongFontPath, expandedLongFontPath));
    if (!CheckIfFileExists(expandedLongFontPath.get()))
    {
        Log::Comment(L"Lucida Sans Typewriter doesn't exist; skipping long font test.");
        Log::Result(WEX::Logging::TestResults::Result::Skipped);
        return;
    }

    const HANDLE hConsoleOutput = GetStdOutputHandle();

    CONSOLE_FONT_INFOEX cfieSetLong = { 0 };
    cfieSetLong.cbSize = sizeof(cfieSetLong);
    cfieSetLong.FontFamily = 54;
    cfieSetLong.dwFontSize.Y = 12;
    VERIFY_SUCCEEDED(StringCchCopy(cfieSetLong.FaceName, ARRAYSIZE(cfieSetLong.FaceName), L"Lucida Sans Typewriter"));

    VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::SetCurrentConsoleFontEx(hConsoleOutput, FALSE, &cfieSetLong));

    CONSOLE_FONT_INFOEX cfiePostLong = { 0 };
    cfiePostLong.cbSize = sizeof(cfiePostLong);
    VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::GetCurrentConsoleFontEx(hConsoleOutput, FALSE, &cfiePostLong));

    Log::Comment(NoThrowString().Format(L"%ls %ls", cfieSetLong.FaceName, cfiePostLong.FaceName));

    VERIFY_ARE_EQUAL(0, NoThrowString(cfieSetLong.FaceName).CompareNoCase(cfiePostLong.FaceName));
}
Esempio n. 13
0
void FileTests::TestWriteFileSuspended()
{
    HANDLE const hOut = GetStdOutputHandle();
    VERIFY_IS_NOT_NULL(hOut, L"Verify we have the standard output handle.");

    HANDLE const hIn = GetStdInputHandle();
    VERIFY_IS_NOT_NULL(hIn, L"Verify we have the standard input handle.");

    CONSOLE_SCREEN_BUFFER_INFOEX csbiexOriginal = { 0 };
    csbiexOriginal.cbSize = sizeof(csbiexOriginal);
    VERIFY_WIN32_BOOL_SUCCEEDED(GetConsoleScreenBufferInfoEx(hOut, &csbiexOriginal), L"Retrieve screen buffer properties at beginning of test.");

    DWORD dwMode = 0;
    VERIFY_WIN32_BOOL_SUCCEEDED(SetConsoleMode(hOut, dwMode), L"Set console mode for test.");

    COORD const coordZero = { 0 };
    VERIFY_ARE_EQUAL(coordZero, csbiexOriginal.dwCursorPosition, L"Cursor should be at 0,0 in fresh buffer.");

    VERIFY_WIN32_BOOL_SUCCEEDED(WriteFile(hOut, "abc", 3, nullptr, nullptr), L"Test first write success.");
    PauseHelper(hIn);

    auto BlockedWrite = std::async([&] {
        Log::Comment(L"Background WriteFile scheduled.");
        VERIFY_WIN32_BOOL_SUCCEEDED(WriteFile(hOut, "def", 3, nullptr, nullptr), L"Test second write success.");
    });

    UnpauseHelper(hIn);

    BlockedWrite.wait();
}
Esempio n. 14
0
void FileTests::TestWriteFileRaw()
{
    // \x7 is bell
    // \x8 is backspace
    // \x9 is tab
    // \xa is linefeed
    // \xd is carriage return
    // All should be ignored/printed in raw mode.
    PCSTR strTest = "z\x7y\x8z\x9y\xaz\xdy";
    DWORD const cchTest = (DWORD)strlen(strTest);
    String strReadBackExpected(strTest);

    HANDLE const hOut = GetStdOutputHandle();
    VERIFY_IS_NOT_NULL(hOut, L"Verify we have the standard output handle.");

    CONSOLE_SCREEN_BUFFER_INFOEX csbiexBefore = { 0 };
    csbiexBefore.cbSize = sizeof(csbiexBefore);
    VERIFY_WIN32_BOOL_SUCCEEDED(GetConsoleScreenBufferInfoEx(hOut, &csbiexBefore), L"Retrieve screen buffer properties before writing.");

    VERIFY_WIN32_BOOL_SUCCEEDED(SetConsoleMode(hOut, 0), L"Set raw write mode.");

    COORD const coordZero = { 0 };
    VERIFY_ARE_EQUAL(coordZero, csbiexBefore.dwCursorPosition, L"Cursor should be at 0,0 in fresh buffer.");

    DWORD dwWritten = 0;
    VERIFY_WIN32_BOOL_SUCCEEDED(WriteFile(hOut, strTest, cchTest, &dwWritten, nullptr), L"Write text into buffer using WriteFile");
    VERIFY_ARE_EQUAL(cchTest, dwWritten);

    CONSOLE_SCREEN_BUFFER_INFOEX csbiexAfter = { 0 };
    csbiexAfter.cbSize = sizeof(csbiexAfter);
    VERIFY_WIN32_BOOL_SUCCEEDED(GetConsoleScreenBufferInfoEx(hOut, &csbiexAfter), L"Retrieve screen buffer properties after writing.");

    csbiexBefore.dwCursorPosition.X += (SHORT)cchTest;
    VERIFY_ARE_EQUAL(csbiexBefore.dwCursorPosition, csbiexAfter.dwCursorPosition, L"Verify cursor moved expected number of squares for the write length.");

    DWORD const cbReadBackBuffer = cchTest + 2; // +1 so we can read back a "space" that should be after what we wrote. +1 more so this can be null terminated for String class comparison.
    wistd::unique_ptr<char[]> strReadBack = wil::make_unique_failfast<char[]>(cbReadBackBuffer);
    ZeroMemory(strReadBack.get(), cbReadBackBuffer * sizeof(char));

    DWORD dwRead = 0;
    VERIFY_WIN32_BOOL_SUCCEEDED(ReadConsoleOutputCharacterA(hOut, strReadBack.get(), cchTest + 1, coordZero, &dwRead), L"Read back the data in the buffer.");
    // +1 to read back the space that should be after the text we wrote

    strReadBackExpected += " "; // add in the space that should appear after the written text (buffer should be space filled when empty)

    VERIFY_ARE_EQUAL(strReadBackExpected, String(strReadBack.get()), L"Ensure that the buffer contents match what we expected based on what we wrote.");
}
    // BackupMetadataFile ReadAsync function with cancellation token canceled test
    // 1. Set up the expected values.
    // 2. ReadAsync call with cancellation token got canceled 
    // 3. Verify it throws and the exception is as expected
    Awaitable<void> BackupMetadataFileTests::Test_BackupMetadataFile_ReadAsync_WithCanceledToken_Throws(
        __in KString const & fileName)
    {
        NTSTATUS status = STATUS_UNSUCCESSFUL;

        KAllocator & allocator = underlyingSystem_->PagedAllocator();
        KWString filePath(allocator, fileName);

        BackupMetadataFile::SPtr backupMetadataFileSPtr = nullptr;
        status = BackupMetadataFile::Create(
            *prId_,
            filePath,
            allocator,
            backupMetadataFileSPtr);
        VERIFY_IS_TRUE(NT_SUCCESS(status));

        // Expected 
        const FABRIC_BACKUP_OPTION expectedBackupOption = FABRIC_BACKUP_OPTION_FULL;
        KGuid expectedParentBackupId;
        expectedParentBackupId.CreateNew();
        KGuid expectedBackupId;
        expectedBackupId.CreateNew();
        KGuid expectedPartitionId;
        expectedPartitionId.CreateNew();
        const FABRIC_REPLICA_ID expectedReplicaId = 16;
        const LONG64 expectedDataLossNumber = 32;
        const LONG64 expectedConfigurationNumber = 64;
        TxnReplicator::Epoch expectedStartingEpoch = TxnReplicator::Epoch(expectedDataLossNumber, expectedConfigurationNumber);
        FABRIC_SEQUENCE_NUMBER expectedStartingLSN = 8;
        TxnReplicator::Epoch expectedBackupEpoch = TxnReplicator::Epoch(expectedDataLossNumber, expectedConfigurationNumber);
        FABRIC_SEQUENCE_NUMBER expectedBackupLSN = 128;

        status = co_await backupMetadataFileSPtr->WriteAsync(
            expectedBackupOption,
            expectedParentBackupId,
            expectedBackupId,
            expectedPartitionId,
            expectedReplicaId,
            expectedStartingEpoch,
            expectedStartingLSN,
            expectedBackupEpoch,
            expectedBackupLSN,
            CancellationToken::None);
        CODING_ERROR_ASSERT(NT_SUCCESS(status));

        KGuid readId;
        readId.CreateNew();

        CancellationTokenSource::SPtr cts;
        status = CancellationTokenSource::Create(allocator, BACKUPMETADATAFILETEST_TAG, cts);
        CODING_ERROR_ASSERT(NT_SUCCESS(status));
        cts->Cancel();

        status = co_await backupMetadataFileSPtr->ReadAsync(readId, cts->Token);
        VERIFY_ARE_EQUAL(STATUS_CANCELLED, status);

        Common::File::Delete(static_cast<LPCWSTR>(fileName), true);
    }
Esempio n. 16
0
void CursorTests::TestGetSetConsoleCursorInfo()
{
    DWORD dwSize;
    bool bVisible;

    VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"dwSize", dwSize), L"Get size parameter");
    VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"bVisible", bVisible), L"Get visibility parameter");

    // Get initial state of the cursor
    CONSOLE_CURSOR_INFO cciInitial = { 0 };
    BOOL bResult = GetConsoleCursorInfo(Common::_hConsole, &cciInitial);
    VERIFY_WIN32_BOOL_SUCCEEDED(bResult, L"Retrieve initial cursor state.");

    // Fill a structure with the value under test
    CONSOLE_CURSOR_INFO cciTest = { 0 };
    cciTest.bVisible = bVisible;
    cciTest.dwSize = dwSize;

    // If the cursor size is out of range, we expect a failure on set
    BOOL fExpectedResult = TRUE;
    if (cciTest.dwSize < 1 || cciTest.dwSize > 100)
    {
        fExpectedResult = FALSE;
    }

    // Attempt to set and verify that we get the expected result
    bResult = SetConsoleCursorInfo(Common::_hConsole, &cciTest);
    VERIFY_ARE_EQUAL(bResult, fExpectedResult, L"Ensure that return matches success/failure state we were expecting.");

    // Get the state of the cursor again
    CONSOLE_CURSOR_INFO cciReturned = { 0 };
    bResult = GetConsoleCursorInfo(Common::_hConsole, &cciReturned);
    VERIFY_WIN32_BOOL_SUCCEEDED(bResult, L"GET back the cursor information we just set.");

    if (fExpectedResult)
    {
        // If we expected the set to be successful, the returned structure should match the test one
        VERIFY_ARE_EQUAL(cciReturned, cciTest, L"If we expected SET success, the values we set should match what we retrieved.");
    }
    else
    {
        // If we expected the set to fail, the returned structure should match the initial one
        VERIFY_ARE_EQUAL(cciReturned, cciInitial, L"If we expected SET failure, the initial values before the SET should match what we retrieved.");
    }
}
Esempio n. 17
0
// Helper function send a simple request to test the connection.
// Take in the path to request and what path should be received in the server.
void test_connection(test_http_server *p_server, http_client *p_client, const utility::string_t &request_path, const utility::string_t &expected_path)
{
    p_server->next_request().then([expected_path](test_request *p_request)
    {
        http_asserts::assert_test_request_equals(p_request, methods::GET, expected_path);
        VERIFY_ARE_EQUAL(0u, p_request->reply(200));
    });
    http_asserts::assert_response_equals(p_client->request(methods::GET, request_path).get(), status_codes::OK);
}
Esempio n. 18
0
TEST_FIXTURE(e2e_raw_client, query_basic_properties_in_entity)
{
	auto query_result = client.get_data_from_server(U("People(4)")).get();
	VERIFY_ARE_EQUAL(query_result.size(), 1);
	VERIFY_ARE_EQUAL(edm_type_kind_t::Entity, query_result[0]->get_value_type()->get_type_kind());

	std::shared_ptr<odata_entity_value> entity = std::dynamic_pointer_cast<odata_entity_value>(query_result[0]);

	//collection property
	std::shared_ptr<odata_value> collection_property;
	VERIFY_IS_TRUE(entity->get_property_value(U("Numbers"), collection_property));
	VERIFY_ARE_EQUAL(edm_type_kind_t::Collection, collection_property->get_value_type()->get_type_kind());

	auto collection_value = std::dynamic_pointer_cast<odata_collection_value>(collection_property);
	auto collection_vector = collection_value->get_collection_values();
	VERIFY_ARE_EQUAL(3, collection_vector.size());

	auto collectin_member = std::dynamic_pointer_cast<odata_primitive_value>(collection_vector[1]);
	VERIFY_ARE_EQUAL(U("555-555-5555"), collectin_member->as<::utility::string_t>());

	//TODO-tiano: check the other property types 
}
Esempio n. 19
0
void FileTests::TestReadFileBasicSync()
{
    HANDLE const hIn = GetStdInputHandle();
    VERIFY_IS_NOT_NULL(hIn, L"Verify we have the standard input handle.");

    DWORD dwMode = 0;
    VERIFY_WIN32_BOOL_SUCCEEDED(SetConsoleMode(hIn, dwMode), L"Set input mode for test.");

    VERIFY_WIN32_BOOL_SUCCEEDED(FlushConsoleInputBuffer(hIn), L"Flush input buffer in preparation for test.");

    char const chExpected = 'a';
    Log::Comment(L"Send a key into the console.");
    SendFullKeyStrokeHelper(hIn, chExpected);

    char ch = '\0';
    Log::Comment(L"Read with synchronous blocking read.");
    DWORD dwRead = 0;
    VERIFY_WIN32_BOOL_SUCCEEDED(ReadFile(hIn, &ch, 1, &dwRead, nullptr), L"Read file was successful.");
    VERIFY_ARE_EQUAL(1u, dwRead, L"Verify we read 1 character.");

    VERIFY_ARE_EQUAL(chExpected, ch);
}
Esempio n. 20
0
void test_server_utilities::verify_request(
        ::http::client::http_client *p_client,
        const utility::string_t &method,
        const utility::string_t &path,
        test_http_server *p_server,
        unsigned short code)
{
    p_server->next_request().then([&](test_request *p_request)
    {
        http_asserts::assert_test_request_equals(p_request, method, path);
        VERIFY_ARE_EQUAL(0, p_request->reply(code));
    });
    http_asserts::assert_response_equals(p_client->request(method, path).get(), code);
}
Esempio n. 21
0
void FileTests::TestReadFileLineSync()
{
    HANDLE const hIn = GetStdInputHandle();
    VERIFY_IS_NOT_NULL(hIn, L"Verify we have the standard input handle.");

    DWORD dwMode = ENABLE_LINE_INPUT;
    VERIFY_WIN32_BOOL_SUCCEEDED(SetConsoleMode(hIn, dwMode), L"Set input mode for test.");

    VERIFY_WIN32_BOOL_SUCCEEDED(FlushConsoleInputBuffer(hIn), L"Flush input buffer in preparation for test.");

    char const chExpected = 'a';
    Log::Comment(L"Send a key into the console followed by a carriage return.");
    SendFullKeyStrokeHelper(hIn, chExpected);
    SendFullKeyStrokeHelper(hIn, '\r');

    char ch = '\0';
    Log::Comment(L"Read back the input with a synchronous blocking read.");
    DWORD dwRead = 0;
    VERIFY_WIN32_BOOL_SUCCEEDED(ReadFile(hIn, &ch, 1, nullptr, nullptr), L"Read file was successful.");
    VERIFY_ARE_EQUAL(0u, dwRead, L"Verify we read 0 characters.");

    VERIFY_ARE_EQUAL(chExpected, ch);
}
Esempio n. 22
0
void ReadBackHelper(HANDLE hOut,
                    COORD coordReadBackPos,
                    DWORD dwReadBackLength,
                    wistd::unique_ptr<char[]>& pszReadBack)
{
    // Add one so it can be zero terminated.
    DWORD cbBuffer = dwReadBackLength + 1;
    wistd::unique_ptr<char[]> pszRead = wil::make_unique_failfast<char[]>(cbBuffer);
    ZeroMemory(pszRead.get(), cbBuffer * sizeof(char));

    DWORD dwRead = 0;
    VERIFY_WIN32_BOOL_SUCCEEDED(ReadConsoleOutputCharacterA(hOut, pszRead.get(), dwReadBackLength, coordReadBackPos, &dwRead), L"Read back data in the buffer.");
    VERIFY_ARE_EQUAL(dwReadBackLength, dwRead, L"Verify API reports we read back the number of characters we asked for.");

    pszReadBack.swap(pszRead);
}
Esempio n. 23
0
void WriteFileHelper(HANDLE hOut,
                     CONSOLE_SCREEN_BUFFER_INFOEX& csbiexBefore,
                     CONSOLE_SCREEN_BUFFER_INFOEX& csbiexAfter,
                     PCSTR psTest,
                     DWORD cchTest)
{
    csbiexBefore.cbSize = sizeof(csbiexBefore);
    VERIFY_WIN32_BOOL_SUCCEEDED(GetConsoleScreenBufferInfoEx(hOut, &csbiexBefore), L"Retrieve screen buffer properties before writing.");

    DWORD dwWritten = 0;
    VERIFY_WIN32_BOOL_SUCCEEDED(WriteFile(hOut, psTest, cchTest, &dwWritten, nullptr), L"Write text into buffer using WriteFile");
    VERIFY_ARE_EQUAL(cchTest, dwWritten, L"Verify all characters were written.");

    csbiexAfter.cbSize = sizeof(csbiexAfter);
    VERIFY_WIN32_BOOL_SUCCEEDED(GetConsoleScreenBufferInfoEx(hOut, &csbiexAfter), L"Retrieve screen buffer properties after writing.");
}
Esempio n. 24
0
void SendFullKeyStrokeHelper(HANDLE hIn, char ch)
{
    INPUT_RECORD ir[2];
    ZeroMemory(ir, ARRAYSIZE(ir) * sizeof(INPUT_RECORD));
    ir[0].EventType = KEY_EVENT;
    ir[0].Event.KeyEvent.bKeyDown = TRUE;
    ir[0].Event.KeyEvent.dwControlKeyState = ch < 0x20 ? LEFT_CTRL_PRESSED : 0; // set left_ctrl_pressed for control keys.
    ir[0].Event.KeyEvent.uChar.AsciiChar = ch;
    ir[0].Event.KeyEvent.wVirtualKeyCode = VkKeyScanA(ir[0].Event.KeyEvent.uChar.AsciiChar);
    ir[0].Event.KeyEvent.wVirtualScanCode = (WORD)MapVirtualKeyA(ir[0].Event.KeyEvent.wVirtualKeyCode, MAPVK_VK_TO_VSC);
    ir[0].Event.KeyEvent.wRepeatCount = 1;
    ir[1] = ir[0];
    ir[1].Event.KeyEvent.bKeyDown = FALSE;

    DWORD dwWritten = 0;
    VERIFY_WIN32_BOOL_SUCCEEDED(WriteConsoleInputA(hIn, ir, (DWORD)ARRAYSIZE(ir), &dwWritten), L"Writing key stroke.");
    VERIFY_ARE_EQUAL((DWORD)ARRAYSIZE(ir), dwWritten, L"Written matches expected.");
}
    shared_ptr<FailoverManagerStore> FailoverManagerStoreTest::InitializeStore(
        wstring ownerId,
        bool shouldPass,
        bool existingStore,
        Common::Guid const & partitionId,
        ::FABRIC_REPLICA_ID replicaId,
        Common::ComponentRoot const & root,
        const wstring storeType)
    {
        UNREFERENCED_PARAMETER(ownerId);
        UNREFERENCED_PARAMETER(shouldPass);


        if (storeType == L"ESENT")
        {
            auto replicatedStore = Store::KeyValueStoreReplica::CreateForUnitTests(
                partitionId,
                replicaId,
                Store::EseLocalStoreSettings(GetEseFilename(), GetEseDirectory()),
                root);
            ErrorCode error = replicatedStore->InitializeLocalStoreForUnittests(existingStore);

            shared_ptr<FailoverManagerStore> store = make_shared<FailoverManagerStore>(move(replicatedStore));

            if (shouldPass)
            {
                VERIFY_ARE_EQUAL(ErrorCodeValue::Success, error.ReadValue(), L"store.Open did not return success");
                return store;
            }
            else
            {
                VERIFY_ARE_NOT_EQUAL(ErrorCodeValue::Success, error.ReadValue(), L"store.Open returned success");
                return nullptr;
            }
        }

        Common::Assert::CodingError("StoreType not found in properties");
    }
Esempio n. 26
0
void FileTests::TestReadFileLine()
{
    HANDLE const hIn = GetStdInputHandle();
    VERIFY_IS_NOT_NULL(hIn, L"Verify we have the standard input handle.");

    DWORD dwMode = ENABLE_LINE_INPUT;
    VERIFY_WIN32_BOOL_SUCCEEDED(SetConsoleMode(hIn, dwMode), L"Set input mode for test.");

    VERIFY_WIN32_BOOL_SUCCEEDED(FlushConsoleInputBuffer(hIn), L"Flush input buffer in preparation for test.");

    char ch = '\0';
    Log::Comment(L"Queue background blocking read file operation.");
    auto BackgroundRead = std::async([&] {
        DWORD dwRead = 0;
        VERIFY_WIN32_BOOL_SUCCEEDED(ReadFile(hIn, &ch, 1, &dwRead, nullptr), L"Read file was successful.");
        VERIFY_ARE_EQUAL(1u, dwRead, L"Verify we read 1 character.");
    });

    char const chExpected = 'a';
    Log::Comment(L"Send a key into the console.");
    SendFullKeyStrokeHelper(hIn, chExpected);

    auto status = BackgroundRead.wait_for(std::chrono::milliseconds(250));
    VERIFY_ARE_EQUAL(std::future_status::timeout, status, L"We should still be waiting for a result.");
    VERIFY_ARE_EQUAL('\0', ch, L"Character shouldn't be filled by background read yet.");

    Log::Comment(L"Send a line feed character, we should stay blocked.");
    SendFullKeyStrokeHelper(hIn, '\n');
    status = BackgroundRead.wait_for(std::chrono::milliseconds(250));
    VERIFY_ARE_EQUAL(std::future_status::timeout, status, L"We should still be waiting for a result.");
    VERIFY_ARE_EQUAL('\0', ch, L"Character shouldn't be filled by background read yet.");

    Log::Comment(L"Now send a carriage return into the console to signify the end of the input line.");
    SendFullKeyStrokeHelper(hIn, '\r');

    Log::Comment(L"Wait for background thread to unblock.");
    BackgroundRead.wait();
    VERIFY_ARE_EQUAL(chExpected, ch);
}
        Awaitable<void> ReplicatorPerfTest::Run(
            __in wstring const & testFolder,
            __in int concurrentTransactions,
            __in int totalTransactions,
            __in Data::Log::LogManager & logManager)
        {
#ifndef PERF_TEST
            UNREFERENCED_PARAMETER(testFolder);
            UNREFERENCED_PARAMETER(concurrentTransactions);
            UNREFERENCED_PARAMETER(totalTransactions);
            UNREFERENCED_PARAMETER(logManager);
#else
            Replica::SPtr replica = Replica::Create(
                pId_,
                rId_,
                testFolder,
                logManager,
                underlyingSystem_->PagedAllocator());

            co_await replica->OpenAsync();

            FABRIC_EPOCH epoch1; epoch1.DataLossNumber = 1; epoch1.ConfigurationNumber = 1; epoch1.Reserved = nullptr;
            co_await replica->ChangeRoleAsync(epoch1, FABRIC_REPLICA_ROLE_PRIMARY);

            replica->SetReadStatus(FABRIC_SERVICE_PARTITION_ACCESS_STATUS_GRANTED);
            replica->SetWriteStatus(FABRIC_SERVICE_PARTITION_ACCESS_STATUS_GRANTED);

            KUri::CSPtr stateProviderName = GetStateProviderName(0);
            {
                Transaction::SPtr txn;
                replica->TxnReplicator->CreateTransaction(txn);
                KFinally([&] {txn->Dispose(); });

                NTSTATUS status = co_await replica->TxnReplicator->AddAsync(*txn, *stateProviderName, L"ReplicatorPerfTest");
                VERIFY_IS_TRUE(NT_SUCCESS(status));
                co_await txn->CommitAsync();
            }

            {
                IStateProvider2::SPtr stateProvider2;
                NTSTATUS status = replica->TxnReplicator->Get(*stateProviderName, stateProvider2);
                VERIFY_IS_TRUE(NT_SUCCESS(status));
                VERIFY_IS_NOT_NULL(stateProvider2);
                VERIFY_ARE_EQUAL(*stateProviderName, stateProvider2->GetName());

                IStore<int, int>::SPtr store = dynamic_cast<IStore<int, int>*>(stateProvider2.RawPtr());

                Stopwatch s;
                s.Start();

                KArray<Awaitable<void>> tasks(underlyingSystem_->PagedAllocator(), concurrentTransactions, 0);

                for (int i = 0; i < concurrentTransactions; i++)
                {
                    status = tasks.Append(DoWorkOnKey(store, replica, totalTransactions / concurrentTransactions, i));
                    KInvariant(NT_SUCCESS(status));
                }

                co_await TaskUtilities<Awaitable<void>>::WhenAll(tasks);

                s.Stop();

                int64 txPerSec = ((totalTransactions * 1000) / s.ElapsedMilliseconds);

                Trace.WriteInfo(
                    TraceComponent,
                    "{0}: Tx/Sec is {1}",
                    prId_->TraceId,
                    txPerSec);
            }

            replica->SetReadStatus(FABRIC_SERVICE_PARTITION_ACCESS_STATUS_NOT_PRIMARY);
            replica->SetWriteStatus(FABRIC_SERVICE_PARTITION_ACCESS_STATUS_NOT_PRIMARY);

            co_await replica->CloseAsync();
#endif
            co_return;
        }
Esempio n. 28
0
void FileTests::TestWriteFileProcessed()
{
    // \x7 is bell
    // \x8 is backspace
    // \x9 is tab
    // \xa is linefeed
    // \xd is carriage return
    // All should cause activity in processed mode.

    HANDLE const hOut = GetStdOutputHandle();
    VERIFY_IS_NOT_NULL(hOut, L"Verify we have the standard output handle.");

    CONSOLE_SCREEN_BUFFER_INFOEX csbiexOriginal = { 0 };
    csbiexOriginal.cbSize = sizeof(csbiexOriginal);
    VERIFY_WIN32_BOOL_SUCCEEDED(GetConsoleScreenBufferInfoEx(hOut, &csbiexOriginal), L"Retrieve screen buffer properties at beginning of test.");

    VERIFY_WIN32_BOOL_SUCCEEDED(SetConsoleMode(hOut, ENABLE_PROCESSED_OUTPUT), L"Set processed write mode.");

    COORD const coordZero = { 0 };
    VERIFY_ARE_EQUAL(coordZero, csbiexOriginal.dwCursorPosition, L"Cursor should be at 0,0 in fresh buffer.");

    // Declare variables needed for each character test.
    CONSOLE_SCREEN_BUFFER_INFOEX csbiexBefore = { 0 };
    CONSOLE_SCREEN_BUFFER_INFOEX csbiexAfter = { 0 };
    COORD coordExpected = { 0 };
    PCSTR pszTest;
    DWORD cchTest;
    PCSTR pszReadBackExpected;
    DWORD cchReadBack;
    wistd::unique_ptr<char[]> pszReadBack;

    // 1. Test bell (\x7)
    {
        pszTest = "z\x7";
        cchTest = (DWORD)strlen(pszTest);
        pszReadBackExpected = "z ";
        cchReadBack = (DWORD)strlen(pszReadBackExpected);

        // Write z and a bell. Cursor should move once as bell should have made audible noise (can't really test) and not moved or printed anything.
        WriteFileHelper(hOut, csbiexBefore, csbiexAfter, pszTest, cchTest);
        coordExpected = csbiexBefore.dwCursorPosition;
        coordExpected.X += 1;
        VERIFY_ARE_EQUAL(coordExpected, csbiexAfter.dwCursorPosition, L"Verify cursor moved once for printable character and not for bell.");

        // Read back written data.
        ReadBackHelper(hOut, csbiexBefore.dwCursorPosition, cchReadBack, pszReadBack);
        VERIFY_ARE_EQUAL(String(pszReadBackExpected), String(pszReadBack.get()), L"Verify text matches what we expected to be written into the buffer.");
    }


    // 2. Test backspace (\x8)
    {
        pszTest = "yx\x8";
        cchTest = (DWORD)strlen(pszTest);
        pszReadBackExpected = "yx ";
        cchReadBack = (DWORD)strlen(pszReadBackExpected);

        // Write two characters and a backspace. Cursor should move only one forward as the backspace should have moved the cursor back one after printing the second character.
        // The backspace character itself is typically non-destructive so it should only affect the cursor, not the buffer contents.
        WriteFileHelper(hOut, csbiexBefore, csbiexAfter, pszTest, cchTest);
        coordExpected = csbiexBefore.dwCursorPosition;
        coordExpected.X += 1;
        VERIFY_ARE_EQUAL(coordExpected, csbiexAfter.dwCursorPosition, L"Verify cursor moved twice forward for printable characters and once backward for backspace.");

        // Read back written data.
        ReadBackHelper(hOut, csbiexBefore.dwCursorPosition, cchReadBack, pszReadBack);
        VERIFY_ARE_EQUAL(String(pszReadBackExpected), String(pszReadBack.get()), L"Verify text matches what we expected to be written into the buffer.");
    }

    // 3. Test tab (\x9)
    {
        // The tab character will space pad out the buffer to the next multiple-of-8 boundary.
        // NOTE: This is dependent on the previous tests running first.
        pszTest = "\x9";
        cchTest = (DWORD)strlen(pszTest);
        pszReadBackExpected = "     ";
        cchReadBack = (DWORD)strlen(pszReadBackExpected);

        // Write tab character. Cursor should move out to the next multiple-of-8 and leave space characters in its wake.
        WriteFileHelper(hOut, csbiexBefore, csbiexAfter, pszTest, cchTest);
        coordExpected = csbiexBefore.dwCursorPosition;
        coordExpected.X = 8;
        VERIFY_ARE_EQUAL(coordExpected, csbiexAfter.dwCursorPosition, L"Verify cursor moved forward to position 8 for tab.");

        // Read back written data.
        ReadBackHelper(hOut, csbiexBefore.dwCursorPosition, cchReadBack, pszReadBack);
        VERIFY_ARE_EQUAL(String(pszReadBackExpected), String(pszReadBack.get()), L"Verify text matches what we expected to be written into the buffer.");
    }

    // 4. Test linefeed (\xa)
    {
        // The line feed character should move us down to the next line.
        pszTest = "\xaQ";
        cchTest = (DWORD)strlen(pszTest);
        pszReadBackExpected = "Q ";
        cchReadBack = (DWORD)strlen(pszReadBackExpected);

        // Write line feed character. Cursor should move down a line and then the Q from our string should be printed.
        WriteFileHelper(hOut, csbiexBefore, csbiexAfter, pszTest, cchTest);
        coordExpected.X = 1;
        coordExpected.Y = 1;
        VERIFY_ARE_EQUAL(coordExpected, csbiexAfter.dwCursorPosition, L"Verify cursor moved down a line and then one character over for linefeed + Q.");

        // Read back written data from the 2nd line.
        COORD coordRead;
        coordRead.Y = 1;
        coordRead.X = 0;
        ReadBackHelper(hOut, coordRead, cchReadBack, pszReadBack);
        VERIFY_ARE_EQUAL(String(pszReadBackExpected), String(pszReadBack.get()), L"Verify text matches what we expected to be written into the buffer.");
    }

    // 5. Test carriage return (\xd)
    {
        // The carriage return character should move us to the front of the line.
        pszTest = "J\xd";
        cchTest = (DWORD)strlen(pszTest);
        pszReadBackExpected = "QJ "; // J written, then move to beginning of line.
        cchReadBack = (DWORD)strlen(pszReadBackExpected);

        // Write text and carriage return character. Cursor should end up at the beginning of this line. The J should have been printed in the line before we moved.
        WriteFileHelper(hOut, csbiexBefore, csbiexAfter, pszTest, cchTest);
        coordExpected = csbiexBefore.dwCursorPosition;
        coordExpected.X = 0;
        VERIFY_ARE_EQUAL(coordExpected, csbiexAfter.dwCursorPosition, L"Verify cursor moved to beginning of line for carriage return character.");

        // Read back text written from the 2nd line.
        ReadBackHelper(hOut, csbiexAfter.dwCursorPosition, cchReadBack, pszReadBack);
        VERIFY_ARE_EQUAL(String(pszReadBackExpected), String(pszReadBack.get()), L"Verify text matches what we expected to be written into the buffer.");
    }

    // 6. Print a character over the top of the existing
    {
        // After the carriage return, try typing on top of the Q with a K
        pszTest = "K";
        cchTest = (DWORD)strlen(pszTest);
        pszReadBackExpected = "KJ "; // NOTE: This is based on the previous test(s).
        cchReadBack = (DWORD)strlen(pszReadBackExpected);

        // Write text. Cursor should end up on top of the J.
        WriteFileHelper(hOut, csbiexBefore, csbiexAfter, pszTest, cchTest);
        coordExpected = csbiexBefore.dwCursorPosition;
        coordExpected.X += 1;
        VERIFY_ARE_EQUAL(coordExpected, csbiexAfter.dwCursorPosition, L"Verify cursor moved over one for printing character.");

        // Read back text written from the 2nd line.
        ReadBackHelper(hOut, csbiexBefore.dwCursorPosition, cchReadBack, pszReadBack);
        VERIFY_ARE_EQUAL(String(pszReadBackExpected), String(pszReadBack.get()), L"Verify text matches what we expected to be written into the buffer.");
    }
}
Esempio n. 29
0
void FontTests::TestFontScenario()
{
    const HANDLE hConsoleOutput = GetStdOutputHandle();

    Log::Comment(L"1. Ensure that the various GET APIs for font information align with each other.");
    CONSOLE_FONT_INFOEX cfie = {0};
    cfie.cbSize = sizeof(cfie);
    VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::GetCurrentConsoleFontEx(hConsoleOutput, FALSE, &cfie));

    CONSOLE_FONT_INFO cfi = {0};
    VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::GetCurrentConsoleFont(hConsoleOutput, FALSE, &cfi));

    VERIFY_ARE_EQUAL(cfi.nFont, cfie.nFont, L"Ensure regular and Ex APIs return same nFont");
    VERIFY_ARE_NOT_EQUAL(cfi.dwFontSize, c_coordZero, L"Ensure non-zero font size");
    VERIFY_ARE_EQUAL(cfi.dwFontSize, cfie.dwFontSize, L"Ensure regular and Ex APIs return same dwFontSize");

    const COORD coordCurrentFontSize = OneCoreDelay::GetConsoleFontSize(hConsoleOutput, cfi.nFont);
    VERIFY_ARE_EQUAL(coordCurrentFontSize, cfi.dwFontSize, L"Ensure GetConsoleFontSize output matches GetCurrentConsoleFont");

    // ---------------------

    Log::Comment(L"2. Ensure that our font settings round-trip appropriately through the Ex APIs");
    CONSOLE_FONT_INFOEX cfieSet = {0};
    cfieSet.cbSize = sizeof(cfieSet);
    cfieSet.dwFontSize.Y = 12;
    VERIFY_SUCCEEDED(StringCchCopy(cfieSet.FaceName, ARRAYSIZE(cfieSet.FaceName), L"Lucida Console"));

    VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::SetCurrentConsoleFontEx(hConsoleOutput, FALSE, &cfieSet));

    CONSOLE_FONT_INFOEX cfiePost = {0};
    cfiePost.cbSize = sizeof(cfiePost);
    VERIFY_WIN32_BOOL_SUCCEEDED(OneCoreDelay::GetCurrentConsoleFontEx(hConsoleOutput, FALSE, &cfiePost));

    // Ensure that the two values we attempted to set did accurately round-trip through the API.
    // The other unspecified values may have been adjusted/updated by GDI.
    if (0 != NoThrowString(cfieSet.FaceName).CompareNoCase(cfiePost.FaceName))
    {
        Log::Comment(L"We cannot test changing fonts on systems that do not have alternatives available. Skipping test.");
        Log::Result(WEX::Logging::TestResults::Result::Skipped);
        return;
    }
    VERIFY_ARE_EQUAL(cfieSet.dwFontSize.Y, cfiePost.dwFontSize.Y);

    // Ensure that the entire structure we received matches what we expect to usually get for this Lucida Console Size 12 ask.
    CONSOLE_FONT_INFOEX cfieFullExpected = { 0 };
    cfieFullExpected.cbSize = sizeof(cfieFullExpected);
    wcscpy_s(cfieFullExpected.FaceName, L"Lucida Console");

    if (!OneCoreDelay::IsIsWindowPresent())
    {
        // On OneCore Windows without GDI, this is what we expect to get.
        cfieFullExpected.dwFontSize.X = 8;
        cfieFullExpected.dwFontSize.Y = 12;
        cfieFullExpected.FontFamily = 4;
        cfieFullExpected.FontWeight = 0;
    }
    else
    {
        // On client Windows with GDI, this is what we expect to get.
        cfieFullExpected.dwFontSize.X = 7;
        cfieFullExpected.dwFontSize.Y = 12;
        cfieFullExpected.FontFamily = 54;
        cfieFullExpected.FontWeight = 400;
    }

    VERIFY_ARE_EQUAL(cfieFullExpected, cfiePost);
}
void TestGetConsoleAliasHelper(TCH* ptszSourceGiven,
                               TCH* ptszExpectedTargetGiven,
                               TCH* ptszExeNameGiven,
                               DWORD& dwSource,
                               DWORD& dwTarget,
                               DWORD& dwExeName,
                               bool& /*bUnicode*/,
                               bool& bSetFirst)
{
    TCH* ptszSource = nullptr;
    TCH* ptszExeName = nullptr;
    TCH* ptszExpectedTarget = ptszExpectedTargetGiven;
    TCH* ptchTargetBuffer = nullptr;
    DWORD cbTargetBuffer = 0;

    switch (dwSource)
    {
    case 0:
        ptszSource = nullptr;
        Log::Comment(L"Using null source arg.");
        break;
    case 1:
        ptszSource = ptszSourceGiven;
        Log::Comment(String().Format(L"Using source arg: '" TSTRFORMAT "'", ptszSource));
        break;
    default:
        VERIFY_FAIL(L"Unknown type.");
    }

    switch (dwExeName)
    {
    case 0:
        ptszExeName = nullptr;
        Log::Comment(L"Using null exe name.");
        break;
    case 1:
        ptszExeName = ptszExeNameGiven;
        Log::Comment(String().Format(L"Using exe name arg: '" TSTRFORMAT "'", ptszExeName));
        break;
    default:
        VERIFY_FAIL(L"Unknown type.");
    }

    DWORD const cbExpectedTargetString = (DWORD)TLEN(ptszExpectedTargetGiven) * sizeof(TCH);

    switch (dwTarget)
    {
    case 0:
        cbTargetBuffer = 0;
        break;
    case 1:
        cbTargetBuffer = sizeof(TCH);
        break;
    case 2:
        cbTargetBuffer = cbExpectedTargetString - sizeof(TCH);
        break;
    case 3:
        cbTargetBuffer = cbExpectedTargetString;
        break;
    case 4:
        cbTargetBuffer = cbExpectedTargetString + sizeof(TCH);
        break;
    case 5:
        cbTargetBuffer = cbExpectedTargetString + sizeof(TCH) + sizeof(TCH);
        break;
    case 6:
        cbTargetBuffer = MAX_PATH * sizeof(TCH);
        break;
    default:
        VERIFY_FAIL(L"Unknown type.");
    }

    if (cbTargetBuffer == 0)
    {
        ptchTargetBuffer = nullptr;
    }
    else
    {
        ptchTargetBuffer = new TCH[cbTargetBuffer / sizeof(TCH)];
        ZeroMemory(ptchTargetBuffer, cbTargetBuffer);
    }

    auto freeTargetBuffer = wil::scope_exit([&]()
    {
        if (ptchTargetBuffer != nullptr)
        {
            delete[] ptchTargetBuffer;
        }
    });

    Log::Comment(String().Format(L"Using target buffer size: '%d'", cbTargetBuffer));

    // Set the alias if we're supposed to and prepare for cleanup later.
    if (bSetFirst)
    {
        AddConsoleAliasT(ptszSource, ptszExpectedTarget, ptszExeName);
    }
    // This is strange because it's a scope exit so we need to declare in the parent scope, then let it go if we didn't actually need it.
    // I just prefer keeping the exit next to the allocation so it doesn't get lost.
    auto removeAliasOnExit = wil::scope_exit([&] {
        AddConsoleAliasT(ptszSource, NULL, ptszExeName);
    });
    if (!bSetFirst)
    {
        removeAliasOnExit.release();
    }

    // Determine what the result codes should be
    // See console client side in conlibk...
    // a->TargetLength on the server side will become the return value
    // The returned status will be put into SetLastError
    // If there is an error and it's not STATUS_BUFFER_TOO_SMALL, then a->TargetLength (and the return) will be zeroed.
    // Some sample errors:
    // - 87 = 0x57 = ERROR_INVALID_PARAMETER
    // - 122 = 0x7a = ERROR_INSUFFICIENT_BUFFER

    DWORD dwExpectedResult;
    DWORD dwExpectedLastError;

    // NOTE: This order is important. Don't rearrange IF statements.
    if (nullptr == ptszSource ||
        nullptr == ptszExeName)
    {
        // If the source or exe name aren't valid, invalid parameter.
        dwExpectedResult = 0;
        dwExpectedLastError = ERROR_INVALID_PARAMETER;
    }
    else if (!bSetFirst)
    {
        // If we didn't set an alias, generic failure.
        dwExpectedResult = 0;
        dwExpectedLastError = ERROR_GEN_FAILURE;
    }
    else if (ptchTargetBuffer == nullptr ||
             cbTargetBuffer < (cbExpectedTargetString + sizeof(TCH))) // expected target plus a null terminator.
    {
        // If the target isn't enough space, insufficient buffer.
        dwExpectedResult = cbTargetBuffer;

        // For some reason, the console API *ALWAYS* says it needs enough space as if we were copying Unicode,
        // even if the final result will be ANSI.
        // Therefore, if we're mathing based on a char size buffer, multiple the expected result by 2.
        #pragma warning(suppress:4127) // This is a constant, but conditionally compiled twice so we need the check.
        if (1 == sizeof(TCH))
        {
            dwExpectedResult *= sizeof(wchar_t);
        }

        dwExpectedLastError = ERROR_INSUFFICIENT_BUFFER;
    }
    else
    {
        // Otherwise, success. API should always null terminate string.
        dwExpectedResult = cbExpectedTargetString + sizeof(TCH); // expected target plus a null terminator.
        dwExpectedLastError = 0;
    }

    TCH* ptchExpectedTarget;
    auto freeExpectedTarget = wil::scope_exit([&] {
        if (ptchExpectedTarget != nullptr)
        {
            delete[] ptchExpectedTarget;
            ptchExpectedTarget = nullptr;
        }
    });

    if (0 == cbTargetBuffer)
    {
        // If no buffer, we should expect null back out.
        ptchExpectedTarget = nullptr;
    }
    else
    {
        // If there is buffer space, allocate it.
        ptchExpectedTarget = new TCH[cbTargetBuffer / sizeof(TCH)];
        ZeroMemory(ptchExpectedTarget, cbTargetBuffer);
    }

    if (0 == dwExpectedLastError)
    {
        // If it was successful, it should have been filled. Otherwise it will be zeroed as when it started.
        StringCbCopyT(ptchExpectedTarget, cbTargetBuffer, ptszExpectedTargetGiven);
    }

    // Perform the test
    SetLastError(S_OK);
    DWORD const dwActualResult = GetConsoleAliasT(ptszSource, ptchTargetBuffer, cbTargetBuffer, ptszExeName);
    DWORD const dwActualLastError = GetLastError();

    VERIFY_ARE_EQUAL(dwExpectedResult, dwActualResult, L"Ensure result code/return value matches expected.");
    VERIFY_ARE_EQUAL(dwExpectedLastError, dwActualLastError, L"Ensure last error code matches expected.");

    Log::Comment(L"Compare target buffer character by character...");
    for (size_t i = 0; i < (cbTargetBuffer / sizeof(TCH)); i++)
    {
        if (ptchExpectedTarget[i] != ptchTargetBuffer[i])
        {
            VERIFY_FAIL(String().Format(L"Target mismatch at %d. Expected: '" TCHFORMAT "'  Actual: '" TCHFORMAT "'", i, ptchExpectedTarget[i], ptchTargetBuffer[i]));
        }
    }
}