[PATCH 2 2/7] programs/cmd/tests: added ability to run tests in interactive mode

Eric Pouech eric.pouech at gmail.com
Wed Feb 2 11:38:36 CST 2022


Signed-off-by: Eric Pouech <eric.pouech at gmail.com>

---
 programs/cmd/tests/batch.c                      |   58 +++++++++++++++--------
 programs/cmd/tests/interactive_builtins.cmd     |    1 
 programs/cmd/tests/interactive_builtins.cmd.exp |    1 
 programs/cmd/tests/rsrc.rc                      |   10 ++++
 programs/cmd/wcmdmain.c                         |    9 +++-
 5 files changed, 58 insertions(+), 21 deletions(-)
 create mode 100644 programs/cmd/tests/interactive_builtins.cmd
 create mode 100644 programs/cmd/tests/interactive_builtins.cmd.exp

diff --git a/programs/cmd/tests/batch.c b/programs/cmd/tests/batch.c
index 0e8fbf89d6d..0d6832df30f 100644
--- a/programs/cmd/tests/batch.c
+++ b/programs/cmd/tests/batch.c
@@ -74,32 +74,39 @@ static const char* convert_input_data(const char *data, DWORD size, DWORD *new_s
     return new_data;
 }
 
-static BOOL run_cmd(const char *cmd_data, DWORD cmd_size)
+static BOOL run_cmd(const char *cmd_data, DWORD cmd_size, BOOL interactive)
 {
     SECURITY_ATTRIBUTES sa = {sizeof(sa), 0, TRUE};
     char command[] = "test.cmd";
+    char interactive_command[] = "cmd /k"; /* so that we don't get version info before interactive mode */
     STARTUPINFOA si = {sizeof(si)};
     PROCESS_INFORMATION pi;
-    HANDLE file,fileerr;
+    HANDLE filein,fileout,fileerr;
     DWORD size;
     BOOL bres;
 
-    file = CreateFileA("test.cmd", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
-            FILE_ATTRIBUTE_NORMAL, NULL);
-    ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
-    if(file == INVALID_HANDLE_VALUE)
+    filein = CreateFileA("test.cmd", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ,
+                         interactive ? &sa : NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+    ok(filein != INVALID_HANDLE_VALUE, "CreateFile failed\n");
+    if(filein == INVALID_HANDLE_VALUE)
         return FALSE;
 
-    bres = WriteFile(file, cmd_data, cmd_size, &size, NULL);
-    CloseHandle(file);
+    bres = WriteFile(filein, cmd_data, cmd_size, &size, NULL);
     ok(bres, "Could not write to file: %u\n", GetLastError());
     if(!bres)
         return FALSE;
+    if (interactive)
+    {
+        SetEndOfFile(filein);
+        SetFilePointer(filein, 0, NULL, FILE_BEGIN);
+    }
+    else
+        CloseHandle(filein);
 
-    file = CreateFileA("test.out", GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, &sa, CREATE_ALWAYS,
+    fileout = CreateFileA("test.out", GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, &sa, CREATE_ALWAYS,
             FILE_ATTRIBUTE_NORMAL, NULL);
-    ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n");
-    if(file == INVALID_HANDLE_VALUE)
+    ok(fileout != INVALID_HANDLE_VALUE, "CreateFile failed\n");
+    if(fileout == INVALID_HANDLE_VALUE)
         return FALSE;
 
     fileerr = CreateFileA("test.err", GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, &sa, CREATE_ALWAYS,
@@ -109,9 +116,10 @@ static BOOL run_cmd(const char *cmd_data, DWORD cmd_size)
         return FALSE;
 
     si.dwFlags = STARTF_USESTDHANDLES;
-    si.hStdOutput = file;
+    si.hStdInput = interactive ? filein : INVALID_HANDLE_VALUE;
+    si.hStdOutput = fileout;
     si.hStdError = fileerr;
-    bres = CreateProcessA(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
+    bres = CreateProcessA(NULL, interactive ? interactive_command : command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
     ok(bres, "CreateProcess failed: %u\n", GetLastError());
     if(!bres) {
         DeleteFileA("test.out");
@@ -121,7 +129,9 @@ static BOOL run_cmd(const char *cmd_data, DWORD cmd_size)
     WaitForSingleObject(pi.hProcess, INFINITE);
     CloseHandle(pi.hThread);
     CloseHandle(pi.hProcess);
-    CloseHandle(file);
+    if (interactive)
+        CloseHandle(filein);
+    CloseHandle(fileout);
     CloseHandle(fileerr);
     DeleteFileA("test.cmd");
     return TRUE;
@@ -350,7 +360,7 @@ static void test_output(const char *out_data, DWORD out_size, const char *exp_da
        out_data + out_size - out_ptr, out_ptr);
 }
 
-static void run_test(const char *cmd_data, DWORD cmd_size, const char *exp_data, DWORD exp_size)
+static void run_test(const char *cmd_data, DWORD cmd_size, const char *exp_data, DWORD exp_size, BOOL interactive)
 {
     const char *out_data, *actual_cmd_data;
     DWORD out_size, actual_cmd_size;
@@ -359,7 +369,7 @@ static void run_test(const char *cmd_data, DWORD cmd_size, const char *exp_data,
     if(!actual_cmd_size || !actual_cmd_data)
         goto cleanup;
 
-    if(!run_cmd(actual_cmd_data, actual_cmd_size))
+    if(!run_cmd(actual_cmd_data, actual_cmd_size, interactive))
         goto cleanup;
 
     out_size = map_file("test.out", &out_data);
@@ -394,7 +404,7 @@ static void run_from_file(const char *file_name)
         return;
     }
 
-    run_test(test_data, test_size, out_data, out_size);
+    run_test(test_data, test_size, out_data, out_size, FALSE);
 
     UnmapViewOfFile(test_data);
     UnmapViewOfFile(out_data);
@@ -433,11 +443,11 @@ static BOOL WINAPI test_enum_proc(HMODULE module, LPCSTR type, LPSTR name, LONG_
         return TRUE;
 
     sprintf(res_name, "%s.exp", name);
-    out_size = load_resource(res_name, "TESTOUT", &out_data);
+    out_size = load_resource(res_name, param ? "INTERACTIVEOUT" : "TESTOUT", &out_data);
     if(!out_size)
         return TRUE;
 
-    run_test(cmd_data, cmd_size, out_data, out_size);
+    run_test(cmd_data, cmd_size, out_data, out_size, param);
     return TRUE;
 }
 
@@ -483,7 +493,15 @@ START_TEST(batch)
 
     argc = winetest_get_mainargs(&argv);
     if(argc > 2)
-        run_from_file(argv[2]);
+    {
+        if (!strcmp(argv[2], "--interactive"))
+            EnumResourceNamesA(NULL, "INTERACTIVECMD", test_enum_proc, 1);
+        else
+            run_from_file(argv[2]);
+    }
     else
+    {
         EnumResourceNamesA(NULL, "TESTCMD", test_enum_proc, 0);
+        EnumResourceNamesA(NULL, "INTERACTIVECMD", test_enum_proc, 1);
+    }
 }
diff --git a/programs/cmd/tests/interactive_builtins.cmd b/programs/cmd/tests/interactive_builtins.cmd
new file mode 100644
index 00000000000..546bad4eda5
--- /dev/null
+++ b/programs/cmd/tests/interactive_builtins.cmd
@@ -0,0 +1 @@
+ at exit 0
diff --git a/programs/cmd/tests/interactive_builtins.cmd.exp b/programs/cmd/tests/interactive_builtins.cmd.exp
new file mode 100644
index 00000000000..fe6f88e5414
--- /dev/null
+++ b/programs/cmd/tests/interactive_builtins.cmd.exp
@@ -0,0 +1 @@
+ at pwd@>@exit 0
diff --git a/programs/cmd/tests/rsrc.rc b/programs/cmd/tests/rsrc.rc
index affe04c2bdd..2d14bd25473 100644
--- a/programs/cmd/tests/rsrc.rc
+++ b/programs/cmd/tests/rsrc.rc
@@ -16,6 +16,10 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+/* the TEST(CMD|OUT) are run in batch mode,
+ *  while the INTERACTIVE(CMD|OUT) are run in interactive mode.
+ */
+
 /* @makedep: test_builtins.cmd */
 test_builtins.cmd TESTCMD "test_builtins.cmd"
 
@@ -27,3 +31,9 @@ test_cmdline.cmd TESTCMD "test_cmdline.cmd"
 
 /* @makedep: test_cmdline.cmd.exp */
 test_cmdline.cmd.exp TESTOUT "test_cmdline.cmd.exp"
+
+/* @makedep: interactive_builtins.cmd */
+interactive_builtins.cmd INTERACTIVECMD "interactive_builtins.cmd"
+
+/* @makedep: interactive_builtins.cmd.exp */
+interactive_builtins.cmd.exp INTERACTIVEOUT "interactive_builtins.cmd.exp"
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index 65601348b05..ee863856ec9 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -1897,6 +1897,13 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
       WCMD_output_asis(L"\r\n");
     }
 
+    /* echo input stream if naturally not echoed */
+    if (!context && !optionalcmd && GetFileType(readFrom) != FILE_TYPE_CHAR)
+    {
+      WCMD_output_asis(curPos);
+      WCMD_output_asis(L"\r\n");
+      /* FIXME: same quirk as above for trailing space? */
+    }
     /* Skip repeated 'no echo' characters */
     while (*curPos == '@') curPos++;
 
@@ -2762,7 +2769,7 @@ int __cdecl wmain (int argc, WCHAR *argvW[])
  */
 
   interactive = TRUE;
-  if (!opt_k) WCMD_version ();
+  if (!opt_k) WCMD_version (); else promptNewLine = FALSE;
   while (TRUE) {
 
     /* Read until EOF (which for std input is never, but if redirect




More information about the wine-devel mailing list