Skip to content

Commit

Permalink
String test refresh (dotnet#25948)
Browse files Browse the repository at this point in the history
* Rewrite all LP*STR/BSTR/AnsiBSTR parameter/return type tests.

* Add string-field-in-struct tests.

* Add tests for UnmanagedType.ByValTStr.

* Fix casing in name.

* PR Feedback.

* Fix AnsiBStr test.

* Remove redundant cast.

* 2-phase lookup compliance. SysFreeString -> CoreClrBStrFree.

* Remove extra using

* Remove extra space

* Calling conventions....
  • Loading branch information
jkoritzinsky committed Aug 8, 2019
1 parent df32fb8 commit ef1b0f7
Show file tree
Hide file tree
Showing 32 changed files with 655 additions and 1,877 deletions.
50 changes: 50 additions & 0 deletions LPTStrTestNative.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#include "../Native/StringMarshalingNative.h"

using StringType = LPWSTR;
using Tests = StringMarshalingTests<StringType, TP_slen>;

#define FUNCTION_NAME __FUNCTIONW__

#include "../Native/StringTestEntrypoints.inl"

// Verify that we append extra null terminators to our StringBuilder native buffers.
// Although this is a hidden implementation detail, it would be breaking behavior to stop doing this
// so we have a test for it. In particular, this detail prevents us from optimizing marshalling StringBuilders by pinning.
extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE Verify_NullTerminators_PastEnd(LPCWSTR buffer, int length)
{
return buffer[length+1] == W('\0');
}

struct ByValStringInStructAnsi
{
char str[20];
};

struct ByValStringInStructUnicode
{
WCHAR str[20];
};

extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE MatchFuncNameAnsi(ByValStringInStructAnsi str)
{
return StringMarshalingTests<char*, strlen>::Compare(__func__, str.str);
}

extern "C" DLL_EXPORT BOOL STDMETHODCALLTYPE MatchFuncNameUni(ByValStringInStructUnicode str)
{
return StringMarshalingTests<LPWSTR, TP_slen>::Compare(__FUNCTIONW__, str.str);
}

extern "C" DLL_EXPORT void STDMETHODCALLTYPE ReverseByValStringAnsi(ByValStringInStructAnsi* str)
{
StringMarshalingTests<char*, strlen>::ReverseInplace(str->str);
}

extern "C" DLL_EXPORT void STDMETHODCALLTYPE ReverseByValStringUni(ByValStringInStructUnicode* str)
{
StringMarshalingTests<LPWSTR, TP_slen>::ReverseInplace(str->str);
}
2 changes: 1 addition & 1 deletion tests/src/Common/Platform/platformdefines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ size_t TP_SysStringByteLen(BSTR bstr)
#endif
}

DWORD TP_SysStringLen(BSTR bstr)
size_t TP_SysStringLen(BSTR bstr)
{
#ifdef WINDOWS
return SysStringLen(bstr);
Expand Down
3 changes: 2 additions & 1 deletion tests/src/Common/Platform/platformdefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ LPWSTR HackyConvertToWSTR(const char* pszInput);
#define L(t) HackyConvertToWSTR(t)
#define W(str) u##str
#define MAX_PATH 260
#define __FUNCTIONW__ HackyConvertToWSTR(__func__)

typedef pthread_t THREAD_ID;
typedef void* (*MacWorker)(void*);
Expand Down Expand Up @@ -210,7 +211,7 @@ inline void CoreClrBStrFree(void* p)

size_t TP_SysStringByteLen(BSTR bstr);
BSTR TP_SysAllocString(LPCWSTR psz);
DWORD TP_SysStringLen(BSTR bstr);
size_t TP_SysStringLen(BSTR bstr);


inline void *CoreClrAlloc(size_t cb)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ HRESULT ReverseBSTR(BSTR str, BSTR *res)
if (resLocal == nullptr)
return E_INVALIDARG;

UINT len = TP_SysStringLen(str);
size_t len = TP_SysStringLen(str);
*res = ReverseInplace(len, resLocal);

return S_OK;
Expand Down
101 changes: 8 additions & 93 deletions tests/src/Interop/StringMarshalling/AnsiBSTR/AnsiBStrTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,106 +6,21 @@
using System;
using System.Reflection;
using System.Text;
using NativeDefs;
using System.Diagnostics;
using TestLibrary;

class Test
class AnsiBStrTest
{

#region "Report Failure"
static int fails = 0; //record the fail numbers
// Overload methods for reportfailure
static int ReportFailure(string s)
{
Console.WriteLine(" === Fail:" + s);
return (++fails);
}
static int ReportFailure(string expect, string actual)
{
Console.WriteLine(" === Fail: Expected:" + expect + "\n Actual:" + actual);
return (++fails);
}
static int ReportFailure(string describe, string expect, string actual)
public static int Main()
{
Console.WriteLine(" === Fail: " + describe + "\n\tExpected:" + expect + "\n\tActual:" + actual);
return (++fails);
}
#endregion

#region "Helper"
// ************************************************************
// Returns the appropriate exit code
// *************************************************************
static int ExitTest()
{
if (fails == 0)
try
{
Console.WriteLine("PASS");
return 100;
CommonStringTests.RunTests(runStringBuilderTests: false, runStructTests: false);
}
else
catch (System.Exception ex)
{
Console.WriteLine("FAIL - " + fails + " failure(s) occurred");
Console.WriteLine(ex.ToString());
return 101;
}
}
#endregion

public static int Main(string[] args)
{
string strManaged = " \0Managed\0String\0 ";
string strRet = "a";
string strNative = "Native String";

//since the out attributes doesnt work for string, so i dont check the out value.
string strPara2 = strManaged;
string strRet2 = AnsiBStrTestNative.Marshal_InOut(strPara2);
if (!strRet2.Equals(strRet))
{
ReportFailure("Method AnsiBStrTestNative.Marshal_InOut[Managed Side],The Return string is wrong", strRet, strRet2);
}
if (!strPara2.Equals(strManaged))
{
ReportFailure("Method AnsiBStrTestNative.Marshal_InOut[Managed Side],The Parameter string is Changed", strManaged, strPara2);
}

//TestMethod3
string strPara3 = strManaged;
string strRet3 = AnsiBStrTestNative.Marshal_Out(strPara3);
if (!strRet.Equals(strRet3))
{
ReportFailure("Method AnsiBStrTestNative.Marshal_Out[Managed Side],The Return string is wrong", strRet, strRet3);
}
if (!strPara3.Equals(strManaged))
{
ReportFailure("Method AnsiBStrTestNative.Marshal_Out[Managed Side],The Parameter string is not Changed", strManaged, strPara3);
}

//TestMethod5
string strPara5 = strManaged;
string strRet5 = AnsiBStrTestNative.MarshalPointer_InOut(ref strPara5);

if (!strRet5.Equals(strRet))
{
ReportFailure("Method AnsiBStrTestNative.MarshalPointer_InOut[Managed Side],The Return string is wrong", strRet, strRet5);
}
if (!strPara5.Equals(strNative))
{
ReportFailure("Method AnsiBStrTestNative.MarshalPointer_InOut[Managed Side],The Passed string is wrong", strNative, strPara5);
}

//TestMethod6
string strPara6 = strManaged;
string strRet6 = AnsiBStrTestNative.MarshalPointer_Out(out strPara6);
if (!strRet6.Equals(strRet))
{
ReportFailure("Method AnsiBStrTestNative.MarshalPointer_Out[Managed Side],The Return string is wrong", strRet, strRet6);
}
if (!strPara6.Equals(strNative))
{
ReportFailure("Method AnsiBStrTestNative.MarshalPointer_Out[Managed Side],The Passed string is wrong", strNative, strPara6);
}

return ExitTest();
return 100;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineConstants>$(DefineConstants);STATIC</DefineConstants>
<DefineConstants>$(DefineConstants);STATIC;ANSIBSTR</DefineConstants>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
Expand All @@ -25,6 +25,8 @@
</ItemGroup>
<ItemGroup>
<Compile Include="*.cs" />
<Compile Include="../Common/*.cs" />
<Compile Include="../Native/StringMarshalingTestNative.cs" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
Expand Down
141 changes: 6 additions & 135 deletions tests/src/Interop/StringMarshalling/AnsiBSTR/AnsiBStrTestNative.cpp
Original file line number Diff line number Diff line change
@@ -1,142 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include <xplatform.h>
#include "platformdefines.h"

const char strManaged[] = " \0Managed\0String\0 ";
size_t lenstrManaged = ARRAYSIZE(strManaged) - 1; // the length of strManaged

const char strReturn[] = "a";
size_t lenstrReturn = ARRAYSIZE(strReturn) - 1; //the length of strReturn

const char strNative[] = "Native String";
size_t lenstrNative = ARRAYSIZE(strNative) - 1; //the len of strNative

//Test Method1
extern "C" DLL_EXPORT BSTR STDMETHODCALLTYPE Marshal_In(/*[in]*/ BSTR s)
{
//Check the input
size_t len = TP_SysStringByteLen(s);
if ((len != lenstrManaged) || (memcmp(s, strManaged, len) != 0))
{
printf("Error in Function Marshal_In(Native Client)\n");

//Expected
printf("Expected:");
for (size_t i = 0; i < lenstrManaged; ++i)
putchar(*(((char *)strManaged) + i));
printf("\tThe length of Expected:%zd\n", lenstrManaged);

//Actual
printf("Actual:");
for (size_t j = 0; j < len; ++j)
putchar(*(((char *)s) + j));
printf("\tThe length of Actual:%zd\n", len);
}

return CoreClrBStrAlloc(strReturn, lenstrReturn);
}

//Test Method2
extern "C" DLL_EXPORT BSTR STDMETHODCALLTYPE Marshal_InOut(/*[In,Out]*/ BSTR s)
{

//Check the Input
size_t len = TP_SysStringByteLen(s);
if ((len != lenstrManaged) || (memcmp(s, strManaged, len) != 0))
{
printf("Error in Function Marshal_InOut(Native Client)\n");

//Expected
printf("Expected:");
for (size_t i = 0; i < lenstrManaged; ++i)
putchar(*(((char *)strManaged) + i));
printf("\tThe length of Expected:%zd\n", lenstrManaged);

//Actual
printf("Actual:");
for (size_t j = 0; j < len; ++j)
putchar(*(((char *)s) + j));
printf("\tThe length of Actual:%zd\n", len);
}

//In-Place Change
memcpy((char *)s, strNative, lenstrNative);
*((UINT *)s - 1) = (UINT) TP_SysStringByteLen(s);

//Return
return CoreClrBStrAlloc(strReturn, lenstrReturn);
}
extern "C" DLL_EXPORT BSTR STDMETHODCALLTYPE Marshal_Out(/*[Out]*/ BSTR s)
{
s = CoreClrBStrAlloc(strNative, lenstrNative);

//In-Place Change
memcpy((char *)s, strNative, lenstrNative);
*((UINT *)s - 1) = (UINT) TP_SysStringByteLen(s);

//Return
return CoreClrBStrAlloc(strReturn, lenstrReturn);
}

extern "C" DLL_EXPORT BSTR STDMETHODCALLTYPE MarshalPointer_In(/*[in]*/ BSTR *s)
{
//CheckInput
size_t len = TP_SysStringByteLen(*s);
if ((len != lenstrManaged) || (memcmp(*s, strManaged, len) != 0))
{
printf("Error in Function MarshalPointer_In\n");

//Expected
printf("Expected:");
for (size_t i = 0; i < lenstrManaged; ++i)
putchar(*(((char *)strManaged) + i));
printf("\tThe length of Expected:%zd\n", lenstrManaged);

//Actual
printf("Actual:");
for (size_t j = 0; j < len; ++j)
putchar(*(((char *)*s) + j));
printf("\tThe length of Actual:%zd\n", len);
}

return CoreClrBStrAlloc(strReturn, lenstrReturn);
}

extern "C" DLL_EXPORT BSTR STDMETHODCALLTYPE MarshalPointer_InOut(/*[in,out]*/ BSTR *s)
{
//Check the Input
size_t len = TP_SysStringByteLen(*s);
if ((len != lenstrManaged) || (memcmp(*s, strManaged, len) != 0))
{
printf("Error in Function MarshalPointer_InOut\n");

//Expected
printf("Expected:");
for (size_t i = 0; i < lenstrManaged; ++i)
putchar(*(((char *)strManaged) + i));

printf("\tThe length of Expected:%zd\n", lenstrManaged);

//Actual
printf("Actual:");
for (size_t j = 0; j < len; ++j)
putchar(*(((char *)*s) + j));

printf("\tThe length of Actual:%zd\n", len);
}
#include "platformdefines.h"
#include "../Native/StringMarshalingNative.h"

//Allocate New
CoreClrBStrFree(*s);
*s = CoreClrBStrAlloc(strNative, lenstrNative);
using StringType = BSTR;
using Tests = BStrMarshalingTests<TP_SysStringByteLen, char, CoreClrBStrAlloc>;

//Return
return CoreClrBStrAlloc(strReturn, lenstrReturn);
}
#define FUNCTION_NAME CoreClrBStrAlloc(__func__, ARRAYSIZE(__func__) - 1)

extern "C" DLL_EXPORT BSTR STDMETHODCALLTYPE MarshalPointer_Out(/*[out]*/ BSTR *s)
{
*s = CoreClrBStrAlloc(strNative, lenstrNative);
return CoreClrBStrAlloc(strReturn, lenstrReturn);
}
#include "../Native/StringTestEntrypoints.inl"
Loading

0 comments on commit ef1b0f7

Please sign in to comment.