Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
MIGraphX
Commits
691fa499
"src/targets/vscode:/vscode.git/clone" did not exist on "d46c72240962d7727821840df3d995221ea1827d"
Commit
691fa499
authored
Dec 05, 2023
by
Tijana Vukovic
Browse files
Added windows process test for string and binary input
parent
48b2c661
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
245 additions
and
66 deletions
+245
-66
test/child.cpp
test/child.cpp
+18
-10
test/parent_process.cpp
test/parent_process.cpp
+227
-56
No files found.
test/child.cpp
View file @
691fa499
#include <iostream>
#include <array>
#include <string>
#include <vector>
#include <Windows.h>
#include <migraphx/ranges.hpp>
#include <migraphx/errors.hpp>
#include <migraphx/file_buffer.hpp>
#include <migraphx/msgpack.hpp>
int
ma
in
()
void
read_std
in
()
{
std
::
vector
<
char
>
result
;
constexpr
std
::
size_t
BUFFER_SIZE
=
1024
;
DWORD
bytes_read
;
TCHAR
buffer
[
BUFFER_SIZE
];
HANDLE
std_in
=
GetStdHandle
(
STD_INPUT_HANDLE
);
HANDLE
std_out
=
GetStdHandle
(
STD_OUTPUT_HANDLE
);
if
(
std_in
==
INVALID_HANDLE_VALUE
)
MIGRAPHX_THROW
(
"STDIN invalid handle ("
+
std
::
to_string
(
GetLastError
())
+
")"
);
constexpr
std
::
size_t
BUFFER_SIZE
=
1024
;
DWORD
bytes_read
;
TCHAR
buffer
[
BUFFER_SIZE
];
if
(
std_out
==
INVALID_HANDLE_VALUE
)
MIGRAPHX_THROW
(
"STDOUT invalid handle ("
+
std
::
to_string
(
GetLastError
())
+
")"
)
;
for
(;;)
{
BOOL
status
=
ReadFile
(
std_in
,
buffer
,
BUFFER_SIZE
,
&
bytes_read
,
nullptr
);
...
...
@@ -25,8 +32,9 @@ int main()
DWORD
written
;
if
(
WriteFile
(
std_out
,
buffer
,
bytes_read
,
&
written
,
nullptr
)
==
FALSE
)
break
;
// result.insert(result.end(), buffer, buffer + bytes_read);
}
// std::cout << result.data();
return
0
;
}
int
main
(
int
argc
,
char
const
*
argv
[])
{
read_stdin
();
}
test/parent_process.cpp
View file @
691fa499
#include <Windows.h>
#include <tchar.h>
#include <iostream>
#include <string>
#include <
c
string>
#include "test.hpp"
#include <migraphx/errors.hpp>
#include <migraphx/file_buffer.hpp>
#include <migraphx/filesystem.hpp>
#include <migraphx/msgpack.hpp>
#include <migraphx/process.hpp>
#include <migraphx/filesystem.hpp>
#include <migraphx/errors.hpp>
#include <tchar.h>
#define BUFSIZE MAX_PATH
constexpr
std
::
size_t
BUFFER_SIZE
=
4096
;
STARTUPINFO
info
;
PROCESS_INFORMATION
process_info
;
enum
class
direction
{
input
,
output
};
template
<
direction
dir
>
class
pipe
{
public:
explicit
pipe
()
{
SECURITY_ATTRIBUTES
attrs
;
attrs
.
nLength
=
sizeof
(
SECURITY_ATTRIBUTES
);
attrs
.
bInheritHandle
=
TRUE
;
attrs
.
lpSecurityDescriptor
=
nullptr
;
if
(
CreatePipe
(
&
m_read
,
&
m_write
,
&
attrs
,
0
)
==
FALSE
)
throw
GetLastError
();
if
(
dir
==
direction
::
output
)
{
// Do not inherit the read handle for the output pipe
if
(
SetHandleInformation
(
m_read
,
HANDLE_FLAG_INHERIT
,
0
)
==
0
)
throw
GetLastError
();
}
else
{
// Do not inherit the write handle for the input pipe
if
(
SetHandleInformation
(
m_write
,
HANDLE_FLAG_INHERIT
,
0
)
==
0
)
throw
GetLastError
();
}
}
pipe
(
const
pipe
&
)
=
delete
;
pipe
&
operator
=
(
const
pipe
&
)
=
delete
;
pipe
(
pipe
&&
)
=
default
;
~
pipe
()
{
if
(
m_write
!=
nullptr
)
{
CloseHandle
(
m_write
);
}
if
(
m_read
!=
nullptr
)
{
CloseHandle
(
m_read
);
}
}
bool
close_write_handle
()
{
auto
result
=
true
;
if
(
m_write
!=
nullptr
)
{
result
=
CloseHandle
(
m_write
)
==
TRUE
;
m_write
=
nullptr
;
}
return
result
;
}
bool
close_read_handle
()
{
auto
result
=
true
;
if
(
m_read
!=
nullptr
)
{
result
=
CloseHandle
(
m_read
)
==
TRUE
;
m_read
=
nullptr
;
}
return
result
;
}
std
::
pair
<
bool
,
DWORD
>
read
(
LPVOID
buffer
,
DWORD
length
)
const
{
DWORD
bytes_read
;
if
(
ReadFile
(
m_read
,
buffer
,
length
,
&
bytes_read
,
nullptr
)
==
FALSE
and
GetLastError
()
==
ERROR_MORE_DATA
)
{
return
{
true
,
bytes_read
};
}
return
{
false
,
bytes_read
};
}
HANDLE
get_read_handle
()
const
{
return
m_read
;
}
bool
write
(
LPCVOID
buffer
,
DWORD
length
)
const
{
DWORD
bytes_written
;
return
WriteFile
(
m_write
,
buffer
,
length
,
&
bytes_written
,
nullptr
)
==
TRUE
;
}
HANDLE
get_write_handle
()
const
{
return
m_write
;
}
HANDLE
m_write
=
nullptr
,
m_read
=
nullptr
;
};
std
::
string
get_cwd
()
{
...
...
@@ -21,69 +123,138 @@ std::string get_cwd()
return
std
::
string
(
Buffer
);
}
void
CreateProcess
(
pipe
<
direction
::
input
>&
input
,
pipe
<
direction
::
output
>&
output
,
const
std
::
string
&
child_process_name
,
const
std
::
string
&
cwd
)
{
ZeroMemory
(
&
info
,
sizeof
(
STARTUPINFO
));
info
.
cb
=
sizeof
(
STARTUPINFO
);
info
.
hStdError
=
output
.
get_write_handle
();
info
.
hStdOutput
=
output
.
get_write_handle
();
info
.
hStdInput
=
input
.
get_read_handle
();
info
.
dwFlags
|=
STARTF_USESTDHANDLES
;
TCHAR
cmdline
[
MAX_PATH
];
std
::
strncpy
(
cmdline
,
child_process_name
.
c_str
(),
MAX_PATH
);
ZeroMemory
(
&
process_info
,
sizeof
(
process_info
));
if
(
CreateProcess
(
nullptr
,
cmdline
,
nullptr
,
nullptr
,
TRUE
,
0
,
nullptr
,
cwd
.
empty
()
?
nullptr
:
static_cast
<
LPCSTR
>
(
cwd
.
c_str
()),
&
info
,
&
process_info
)
==
FALSE
)
{
MIGRAPHX_THROW
(
"Error creating process ("
+
std
::
to_string
(
GetLastError
())
+
")"
);
}
if
(
not
output
.
close_write_handle
())
MIGRAPHX_THROW
(
"Error closing STDOUT handle for writing ("
+
std
::
to_string
(
GetLastError
())
+
")"
);
if
(
not
input
.
close_read_handle
())
MIGRAPHX_THROW
(
"Error closing STDIN handle for reading ("
+
std
::
to_string
(
GetLastError
())
+
")"
);
}
void
write_to_child
(
LPCVOID
buffer
,
std
::
size_t
n
,
pipe
<
direction
::
input
>&
input
)
{
DWORD
bytes_written
;
if
(
WriteFile
(
input
.
m_write
,
buffer
,
n
,
&
bytes_written
,
nullptr
)
==
FALSE
)
{
MIGRAPHX_THROW
(
"Error writing to child STDIN ("
+
std
::
to_string
(
GetLastError
())
+
")"
);
}
if
(
not
input
.
close_write_handle
())
MIGRAPHX_THROW
(
"Error closing STDIN handle for writing ("
+
std
::
to_string
(
GetLastError
())
+
")"
);
}
std
::
vector
<
char
>
read_from_child
(
pipe
<
direction
::
output
>&
output
)
{
std
::
vector
<
char
>
result
;
DWORD
bytes_read
;
TCHAR
buffer
[
BUFFER_SIZE
];
for
(;;)
{
BOOL
status
=
ReadFile
(
output
.
m_read
,
buffer
,
BUFFER_SIZE
,
&
bytes_read
,
nullptr
);
if
(
status
==
FALSE
or
bytes_read
==
0
)
break
;
result
.
insert
(
result
.
end
(),
buffer
,
buffer
+
bytes_read
);
}
return
result
;
}
TEST_CASE
(
string_data
)
{
std
::
string
cwd
=
get_cwd
();
auto
child_path
=
migraphx
::
fs
::
path
{
cwd
};
std
::
string
string_data
=
"Parent string"
;
// write string data to child process
migraphx
::
process
{
"test_child.exe"
}.
cwd
(
child_path
).
write
([
&
](
auto
writer
)
{
migraphx
::
to_msgpack
(
string_data
,
writer
);
});
//// parent process read from child stdout
// std::vector<char> result;
// HANDLE std_in = GetStdHandle(STD_INPUT_HANDLE);
// if(std_in == INVALID_HANDLE_VALUE)
// MIGRAPHX_THROW("STDIN invalid handle (" + std::to_string(GetLastError()) + ")");
// constexpr std::size_t BUFFER_SIZE = 4096;
// DWORD bytes_read;
// TCHAR buffer[BUFFER_SIZE];
// for(;;)
// {
// BOOL status = ReadFile(std_in, buffer, BUFFER_SIZE, &bytes_read, nullptr);
// if(status == FALSE or bytes_read == 0)
// break;
// result.insert(result.end(), buffer, buffer + bytes_read);
// }
// EXPECT(result.data() == string_data);
std
::
string
child_process_name
=
"test_child.exe"
;
pipe
<
direction
::
input
>
input
{};
pipe
<
direction
::
output
>
output
{};
CreateProcess
(
input
,
output
,
child_process_name
,
cwd
);
// write to child process
TCHAR
buffer
[
BUFFER_SIZE
];
std
::
strncpy
(
buffer
,
string_data
.
c_str
(),
BUFFER_SIZE
);
write_to_child
(
buffer
,
BUFFER_SIZE
,
input
);
// read from child stdout
std
::
vector
<
char
>
result
=
read_from_child
(
output
);
WaitForSingleObject
(
process_info
.
hProcess
,
INFINITE
);
DWORD
status
{};
GetExitCodeProcess
(
process_info
.
hProcess
,
&
status
);
CloseHandle
(
process_info
.
hProcess
);
CloseHandle
(
process_info
.
hThread
);
//compare input parent and output child process
EXPECT
(
result
.
data
()
==
string_data
);
}
TEST_CASE
(
binary_data
)
{
std
::
string
cwd
=
get_cwd
();
// binary data
std
::
vector
<
char
>
binary_data
=
{
'B'
,
'i'
,
'n'
,
'a'
,
'r'
,
'y'
};
std
::
string
cwd
=
get_cwd
();
auto
child_path
=
migraphx
::
fs
::
path
{
cwd
};
// write string data to child process
migraphx
::
process
{
"test_child.exe"
}.
cwd
(
child_path
).
write
([
&
](
auto
writer
)
{
migraphx
::
to_msgpack
(
binary_data
,
writer
);
});
//// parent process read from child stdout
// std::vector<char> result;
// HANDLE std_in = GetStdHandle(STD_INPUT_HANDLE);
// if(std_in == INVALID_HANDLE_VALUE)
// MIGRAPHX_THROW("STDIN invalid handle (" + std::to_string(GetLastError()) + ")");
// constexpr std::size_t BUFFER_SIZE = 4096;
// DWORD bytes_read;
// TCHAR buffer[BUFFER_SIZE];
// for(;;)
//{
// BOOL status = ReadFile(std_in, buffer, BUFFER_SIZE, &bytes_read, nullptr);
// if(status == FALSE or bytes_read == 0)
// break;
// result.insert(result.end(), buffer, buffer + bytes_read);
//}
// EXPECT(result.data() == string_data);
std
::
string
child_process_name
=
"test_child.exe"
;
pipe
<
direction
::
input
>
input
{};
pipe
<
direction
::
output
>
output
{};
CreateProcess
(
input
,
output
,
child_process_name
,
cwd
);
write_to_child
(
binary_data
.
data
(),
binary_data
.
size
(),
input
);
// read from child stdout
std
::
vector
<
char
>
result
=
read_from_child
(
output
);
WaitForSingleObject
(
process_info
.
hProcess
,
INFINITE
);
DWORD
status
{};
GetExitCodeProcess
(
process_info
.
hProcess
,
&
status
);
CloseHandle
(
process_info
.
hProcess
);
CloseHandle
(
process_info
.
hThread
);
// compare input parent and output child process
EXPECT
(
result
==
binary_data
);
}
int
main
(
int
argc
,
const
char
*
argv
[])
{
test
::
run
(
argc
,
argv
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment