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
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 <iostream>
#include <array>
#include <string>
#include <string>
#include <vector>
#include <vector>
#include <Windows.h>
#include <Windows.h>
#include <migraphx/ranges.hpp>
#include <migraphx/errors.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
;
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_in
=
GetStdHandle
(
STD_INPUT_HANDLE
);
HANDLE
std_out
=
GetStdHandle
(
STD_OUTPUT_HANDLE
);
HANDLE
std_out
=
GetStdHandle
(
STD_OUTPUT_HANDLE
);
if
(
std_in
==
INVALID_HANDLE_VALUE
)
if
(
std_in
==
INVALID_HANDLE_VALUE
)
MIGRAPHX_THROW
(
"STDIN invalid handle ("
+
std
::
to_string
(
GetLastError
())
+
")"
);
MIGRAPHX_THROW
(
"STDIN invalid handle ("
+
std
::
to_string
(
GetLastError
())
+
")"
);
constexpr
std
::
size_t
BUFFER_SIZE
=
1024
;
if
(
std_out
==
INVALID_HANDLE_VALUE
)
DWORD
bytes_read
;
MIGRAPHX_THROW
(
"STDOUT invalid handle ("
+
std
::
to_string
(
GetLastError
())
+
")"
)
;
TCHAR
buffer
[
BUFFER_SIZE
];
for
(;;)
for
(;;)
{
{
BOOL
status
=
ReadFile
(
std_in
,
buffer
,
BUFFER_SIZE
,
&
bytes_read
,
nullptr
);
BOOL
status
=
ReadFile
(
std_in
,
buffer
,
BUFFER_SIZE
,
&
bytes_read
,
nullptr
);
...
@@ -25,8 +32,9 @@ int main()
...
@@ -25,8 +32,9 @@ int main()
DWORD
written
;
DWORD
written
;
if
(
WriteFile
(
std_out
,
buffer
,
bytes_read
,
&
written
,
nullptr
)
==
FALSE
)
if
(
WriteFile
(
std_out
,
buffer
,
bytes_read
,
&
written
,
nullptr
)
==
FALSE
)
break
;
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 <Windows.h>
#include <tchar.h>
#include <iostream>
#include <iostream>
#include <string>
#include <
c
string>
#include "test.hpp"
#include "test.hpp"
#include <migraphx/errors.hpp>
#include <migraphx/file_buffer.hpp>
#include <migraphx/filesystem.hpp>
#include <migraphx/msgpack.hpp>
#include <migraphx/msgpack.hpp>
#include <migraphx/process.hpp>
#include <migraphx/process.hpp>
#include <migraphx/filesystem.hpp>
#include <migraphx/errors.hpp>
#include <tchar.h>
#define BUFSIZE MAX_PATH
#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
()
std
::
string
get_cwd
()
{
{
...
@@ -21,69 +123,138 @@ std::string get_cwd()
...
@@ -21,69 +123,138 @@ std::string get_cwd()
return
std
::
string
(
Buffer
);
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
)
TEST_CASE
(
string_data
)
{
{
std
::
string
cwd
=
get_cwd
();
std
::
string
cwd
=
get_cwd
();
auto
child_path
=
migraphx
::
fs
::
path
{
cwd
};
std
::
string
string_data
=
"Parent string"
;
std
::
string
string_data
=
"Parent string"
;
// write string data to child process
std
::
string
child_process_name
=
"test_child.exe"
;
migraphx
::
process
{
"test_child.exe"
}.
cwd
(
child_path
).
write
([
&
](
auto
writer
)
{
migraphx
::
to_msgpack
(
string_data
,
writer
);
pipe
<
direction
::
input
>
input
{};
});
pipe
<
direction
::
output
>
output
{};
//// parent process read from child stdout
CreateProcess
(
input
,
output
,
child_process_name
,
cwd
);
// std::vector<char> result;
// HANDLE std_in = GetStdHandle(STD_INPUT_HANDLE);
// write to child process
// if(std_in == INVALID_HANDLE_VALUE)
TCHAR
buffer
[
BUFFER_SIZE
];
// MIGRAPHX_THROW("STDIN invalid handle (" + std::to_string(GetLastError()) + ")");
std
::
strncpy
(
buffer
,
string_data
.
c_str
(),
BUFFER_SIZE
);
// constexpr std::size_t BUFFER_SIZE = 4096;
write_to_child
(
buffer
,
BUFFER_SIZE
,
input
);
// DWORD bytes_read;
// TCHAR buffer[BUFFER_SIZE];
// read from child stdout
// for(;;)
std
::
vector
<
char
>
result
=
read_from_child
(
output
);
// {
// BOOL status = ReadFile(std_in, buffer, BUFFER_SIZE, &bytes_read, nullptr);
WaitForSingleObject
(
process_info
.
hProcess
,
INFINITE
);
// if(status == FALSE or bytes_read == 0)
// break;
DWORD
status
{};
GetExitCodeProcess
(
process_info
.
hProcess
,
&
status
);
// result.insert(result.end(), buffer, buffer + bytes_read);
// }
CloseHandle
(
process_info
.
hProcess
);
CloseHandle
(
process_info
.
hThread
);
// EXPECT(result.data() == string_data);
//compare input parent and output child process
EXPECT
(
result
.
data
()
==
string_data
);
}
}
TEST_CASE
(
binary_data
)
TEST_CASE
(
binary_data
)
{
{
std
::
string
cwd
=
get_cwd
();
// binary data
std
::
vector
<
char
>
binary_data
=
{
'B'
,
'i'
,
'n'
,
'a'
,
'r'
,
'y'
};
std
::
vector
<
char
>
binary_data
=
{
'B'
,
'i'
,
'n'
,
'a'
,
'r'
,
'y'
};
std
::
string
cwd
=
get_cwd
();
auto
child_path
=
migraphx
::
fs
::
path
{
cwd
};
std
::
string
child_process_name
=
"test_child.exe"
;
// write string data to child process
pipe
<
direction
::
input
>
input
{};
migraphx
::
process
{
"test_child.exe"
}.
cwd
(
child_path
).
write
([
&
](
auto
writer
)
{
pipe
<
direction
::
output
>
output
{};
migraphx
::
to_msgpack
(
binary_data
,
writer
);
});
CreateProcess
(
input
,
output
,
child_process_name
,
cwd
);
//// parent process read from child stdout
write_to_child
(
binary_data
.
data
(),
binary_data
.
size
(),
input
);
// std::vector<char> result;
// HANDLE std_in = GetStdHandle(STD_INPUT_HANDLE);
// read from child stdout
// if(std_in == INVALID_HANDLE_VALUE)
std
::
vector
<
char
>
result
=
read_from_child
(
output
);
// MIGRAPHX_THROW("STDIN invalid handle (" + std::to_string(GetLastError()) + ")");
// constexpr std::size_t BUFFER_SIZE = 4096;
WaitForSingleObject
(
process_info
.
hProcess
,
INFINITE
);
// DWORD bytes_read;
// TCHAR buffer[BUFFER_SIZE];
DWORD
status
{};
// for(;;)
GetExitCodeProcess
(
process_info
.
hProcess
,
&
status
);
//{
// BOOL status = ReadFile(std_in, buffer, BUFFER_SIZE, &bytes_read, nullptr);
CloseHandle
(
process_info
.
hProcess
);
// if(status == FALSE or bytes_read == 0)
CloseHandle
(
process_info
.
hThread
);
// break;
// compare input parent and output child process
// result.insert(result.end(), buffer, buffer + bytes_read);
EXPECT
(
result
==
binary_data
);
//}
// EXPECT(result.data() == string_data);
}
}
int
main
(
int
argc
,
const
char
*
argv
[])
{
test
::
run
(
argc
,
argv
);
}
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