Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

main, win: create test runner in windows #3

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# mini-test.c

**Does not work on Windows yet. See [#1][1]**

Minimalistic portable test runner for C projects.

## Usage
Expand Down
9 changes: 8 additions & 1 deletion include/mini/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,19 @@
#include <string.h>
#include <errno.h>

#ifdef _WIN32
#include <Windows.h>
#define ABORT ExitProcess(42)
#else
#define ABORT abort()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no abort on Windows? How do they live?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have but it makes allot of noise (Tries to find a debugger and creates a useless coredump)

#endif

#define CHECK(VALUE, MESSAGE) \
do { \
if ((VALUE)) break; \
fprintf(stderr, "%s[%d] Assertion failure: " #MESSAGE "\n", \
__FILE__, __LINE__); \
abort(); \
ABORT; \
} while (0)

#define CHECK_EQ(A, B, MESSAGE) CHECK((A) == (B), MESSAGE)
Expand Down
72 changes: 70 additions & 2 deletions src/spawn-win.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,78 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <strsafe.h>

#include "include/mini/common.h"

#define BUFSIZE 4096

static char executable_path[BUFSIZE];

static int popen_complete(const char* cmd) {
STARTUPINFO StartupInfo;
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof(StartupInfo);

PROCESS_INFORMATION ProcessInformation;
ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));

/*
BOOL WINAPI CreateProcess(
_In_opt_ LPCTSTR lpApplicationName,
_Inout_opt_ LPTSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCTSTR lpCurrentDirectory,
_In_ LPSTARTUPINFO lpStartupInfo,
Out_ LPPROCESS_INFORMATION lpProcessInformation
);
*/
BOOL ret = CreateProcess(
NULL, // No module name (use command line)
(char*)cmd, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0,
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&StartupInfo, // Pointer to STARTUPINFO structure
&ProcessInformation // Pointer to PROCESS_INFORMATION structure
);
CHECK_EQ(ret, TRUE, "CreateProcess failed");

// Wait until child process exits.
DWORD wait_ret = WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
CHECK_EQ(wait_ret, WAIT_OBJECT_0, "Process ended strange");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it happen on non-zero exit code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, only on strage cases

Return code/value Description
WAIT_ABANDONED 0x00000080L The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread terminated. Ownership of the mutex object is granted to the calling thread and the mutex state is set to nonsignaled. If the mutex was protecting persistent state information, you should check it for consistency.
WAIT_OBJECT_0 0x00000000L The state of the specified object is signaled.
WAIT_TIMEOUT 0x00000102L The time-out interval elapsed, and the object's state is nonsignaled.
WAIT_FAILED 0xFFFFFFFF The function has failed. To get extended error information, call GetLastError.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok. Thanks!


// Get exit code (-1 is good)
DWORD lpExitCode = 0;
BOOL exit_ret = GetExitCodeProcess(ProcessInformation.hProcess, &lpExitCode);

// Close process and thread handles.
CloseHandle(ProcessInformation.hProcess);
CloseHandle(ProcessInformation.hThread);

return lpExitCode;
}


void mini_prepare_runner(const char* main) {
CHECK(0, "implement me");
TCHAR** lppPart = { NULL };
GetFullPathName(main, BUFSIZE, executable_path, lppPart);
CHECK_NE(executable_path, NULL, "realpath(argv[0])");
}


int mini_run_single(const char* test) {
CHECK(0, "implement me");
char cmd[BUFSIZE];
int print_len = sprintf_s(cmd, BUFSIZE, "\"%s\" %s", executable_path, test);
CHECK_NE(print_len, -1, "sprintf_s to format cmd failed");
int ret = popen_complete(cmd);
return ret;
}