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
Commit
691fa499
authored
Dec 05, 2023
by
Tijana Vukovic
Browse files
Added windows process test for string and binary input
parent
48b2c661
Changes
2
Hide 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
;
}
\ No newline at end of file
}
}
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
()
{
char
Buffer
[
BUFSIZE
];
...
...
@@ -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