Adding tests for creating processes on MS Windows jv
authorPatrik Svestka <patrik.svestka@gmail.com>
Wed, 20 Oct 2021 13:26:34 +0200
branchjv
changeset 2604 d6d5dfaa3e00
parent 2603 6ac9ae0a4987
child 2605 06d49352dc54
Adding tests for creating processes on MS Windows Testing: - correct execution of CreateProcessW() - Too long arguments for dir name, command path, command line
RegressionTests__Win32OperatingSystemTest.st
--- a/RegressionTests__Win32OperatingSystemTest.st	Fri Feb 19 13:58:24 2021 +0100
+++ b/RegressionTests__Win32OperatingSystemTest.st	Wed Oct 20 13:26:34 2021 +0200
@@ -3,6 +3,8 @@
 "
  COPYRIGHT (c) Claus Gittinger / eXept Software AG
  COPYRIGHT (c) 2016 Jan Vrany
+ COPYRIGHT (c) 2021 svestkap
+ COPYRIGHT (c) 2021 Patrik Svestka
               All Rights Reserved
 
  This software is furnished under a license and may be used
@@ -29,6 +31,8 @@
 "
  COPYRIGHT (c) Claus Gittinger / eXept Software AG
  COPYRIGHT (c) 2016 Jan Vrany
+ COPYRIGHT (c) 2021 svestkap
+ COPYRIGHT (c) 2021 Patrik Svestka
               All Rights Reserved
 
  This software is furnished under a license and may be used
@@ -443,6 +447,301 @@
     "Created: / 16-11-2018 / 11:29:12 / svestkap"
 ! !
 
+!Win32OperatingSystemTest methodsFor:'test-creatingProcess'!
+
+testCorrectExec
+    "Testing correctly executed cmd with arguments as string"
+    | createProcessArgumentsLimit cmdInterpreterPath commandLineArguments atDir handle |
+    
+    "CreateProcess supports 32767 characters/bytes including all variables and values
+     so take a good average for its arguments 4096"
+    createProcessArgumentsLimit:= 4096.
+    
+    cmdInterpreterPath := OperatingSystem pathOfCommand: 'cmd'.
+    self assert: cmdInterpreterPath size < createProcessArgumentsLimit. "/
+    
+    "/ cmd.exe - /C Carries out the command specified by string and then terminates
+    commandLineArguments := '/C cd'.      
+    self assert: commandLineArguments size = 5.
+    
+    atDir := Filename currentDirectory pathName.
+    self assert: atDir size < createProcessArgumentsLimit.
+    
+    self shouldnt: [
+         handle := OperatingSystem exec: cmdInterpreterPath withArguments: commandLineArguments
+                     environment:nil
+                 fileDescriptors:nil
+                            fork:true
+                         newPgrp:false
+                     inDirectory: atDir.
+    ] raise: Exception.
+    
+    self assert: handle notNil.
+    self assert: (handle isKindOf: Win32OperatingSystem::Win32ProcessHandle).
+    self assert: (OperatingSystem isProcessIdPresent: handle pid)
+
+    "Created: / 21-10-2021 / 12:24:18 / svestkap"
+!
+
+testCorrectExec2
+    "Testing correctly executed cmd with arguments as array"
+    | createProcessArgumentsLimit cmdInterpreterPath commandLineArguments atDir handle |
+    
+    "CreateProcess supports 32767 characters/bytes including all variables and values
+     so take a good average for its arguments 4096"
+    createProcessArgumentsLimit:= 4096.          
+    
+    cmdInterpreterPath := OperatingSystem pathOfCommand: 'cmd'.
+    self assert: cmdInterpreterPath size < createProcessArgumentsLimit.
+    
+    commandLineArguments := Array new: 2.
+    commandLineArguments at: 1 put: '/C'. "/Carries out the command specified by string and then terminates
+    commandLineArguments at: 2 put: 'cd'.
+    self assert: commandLineArguments size = 2.
+    
+    atDir := Filename currentDirectory pathName.
+    self assert: atDir size < createProcessArgumentsLimit.      
+    
+    self shouldnt: [
+         handle := OperatingSystem exec: cmdInterpreterPath withArguments: commandLineArguments
+                     environment:nil
+                 fileDescriptors:nil
+                            fork:true
+                         newPgrp:false
+                     inDirectory: Filename currentDirectory pathName.
+    ] raise: Exception.
+    
+    self assert: handle notNil.
+    self assert: (handle isKindOf: Win32OperatingSystem::Win32ProcessHandle).
+    self assert: (OperatingSystem isProcessIdPresent: handle pid)
+
+    "Created: / 21-10-2021 / 12:24:31 / svestkap"
+!
+
+testExecCreatedProcessError
+    "Testing created process exception is proceedable"
+    | commandLine savedException |
+      
+    commandLine := '..'.
+    self assert: commandLine size = 2.
+        
+    self should: [
+         OperatingSystem exec: 'cd' withArguments: commandLine
+                  environment:nil
+              fileDescriptors:nil
+                         fork:true
+                      newPgrp:false
+                  inDirectory: Filename currentDirectory pathName
+    ] raise: Exception
+    suchThat: [ :ex | 
+        savedException := ex.
+        ex description includesString: 'File does not exist - CreateProcessW() has failed (File not found)'
+    ].
+    "/ the error is NOT proceedable
+    self deny: savedException willProceed
+
+    "Created: / 21-10-2021 / 12:16:45 / svestkap"
+    "Modified: / 26-11-2021 / 09:51:15 / Patrik Svestka <patrik.svestka@gmail.com>"
+!
+
+testExecCreatedProcessError2
+    "Testing if created process exception proceeds with nil"
+    | commandLine handle |
+      
+    commandLine := '..'.
+    self assert: commandLine size = 2.
+    
+    handle := Win32OperatingSystem::Win32ProcessHandle new.
+    self assert: handle notNil.
+    self assert: (handle isKindOf: Win32OperatingSystem::Win32ProcessHandle).
+    self assert: handle pid isNil.       
+    
+    Exception handle: [ :ex |
+        ex proceed
+    ] do: [ 
+        handle := OperatingSystem exec: 'cd' withArguments: commandLine
+                           environment:nil
+                       fileDescriptors:nil
+                                  fork:true
+                               newPgrp:false
+                           inDirectory: Filename currentDirectory pathName
+    ].
+    "/ after exception has occured, continue to see if handle is nil    
+    self assert: handle isNil.
+
+    "Created: / 21-10-2021 / 12:54:07 / svestkap"
+!
+
+testExecWithTooLongCommandLine
+    "Creating process with too long command line - should raise an exception"
+    | beyondCreateProcessArgumentsLimit commandLine savedException |
+    
+    beyondCreateProcessArgumentsLimit := 4096.    
+    commandLine := RandomGenerator new nextCharacters: beyondCreateProcessArgumentsLimit.
+    self assert: commandLine size = beyondCreateProcessArgumentsLimit.
+    
+    self should: [
+        OperatingSystem exec: '' withArguments: commandLine
+                 environment:nil
+             fileDescriptors:nil
+                        fork:true
+                     newPgrp:false
+                 inDirectory: Filename currentDirectory pathName
+    ] raise: Exception
+    suchThat: [ :ex | 
+        savedException := ex.
+        ex description includesString: 'Invalid Arguments - commandLineUni16 exceeded size limit (4096 characters) (Invalid parameter)'.
+    ].
+    "/ the exception is NOT proceedable
+    self deny: savedException willProceed
+
+    "Created: / 21-10-2021 / 12:16:53 / svestkap"
+    "Modified (comment): / 26-11-2021 / 09:49:21 / Patrik Svestka <patrik.svestka@gmail.com>"
+!
+
+testExecWithTooLongCommandLine2
+    "Testing if the exception is proceedable and if it returns nil"
+    | beyondCreateProcessArgumentsLimit commandLine handle |
+    
+    beyondCreateProcessArgumentsLimit := 4097.         
+    "/ created random String size 4097
+    commandLine := RandomGenerator new nextCharacters: beyondCreateProcessArgumentsLimit.
+    self assert: commandLine size = beyondCreateProcessArgumentsLimit.
+    
+    handle := Win32OperatingSystem::Win32ProcessHandle new.
+    self assert: handle notNil.
+    self assert: (handle isKindOf: Win32OperatingSystem::Win32ProcessHandle).
+    self assert: handle pid isNil.
+    
+    Exception handle: [ :ex | 
+        ex proceed
+    ] do: [ 
+         handle := OperatingSystem exec: '' withArguments: commandLine
+                     environment:nil
+                 fileDescriptors:nil
+                            fork:true
+                         newPgrp:false
+                     inDirectory: Filename currentDirectory pathName
+    ]. 
+    "/ after exception has occured, continue to see if handle is nil    
+    self assert: handle isNil.
+
+    "Created: / 21-10-2021 / 12:17:02 / svestkap"
+!
+
+testExecWithTooLongCommandPath
+    "Creating process with too long command path - should raise an exception"
+    | beyondCreateProcessArgumentsLimit commandPath savedException |
+    
+    beyondCreateProcessArgumentsLimit := 4096.
+    commandPath := RandomGenerator new nextCharacters: beyondCreateProcessArgumentsLimit.
+    self assert: commandPath size = beyondCreateProcessArgumentsLimit.
+    
+    self should: [
+        OperatingSystem exec: commandPath withArguments: ''
+                 environment:nil
+             fileDescriptors:nil
+                        fork:true
+                     newPgrp:false
+                 inDirectory: Filename currentDirectory pathName
+    ] raise: Exception
+    suchThat: [ :ex | 
+        savedException := ex.
+        ex description includesString: 'Invalid Arguments - commandPathUni16 exceeded size limit (4096 characters) (Invalid parameter)'.
+    ].
+    "/ the error is NOT proceedable
+    self deny: savedException willProceed
+
+    "Created: / 21-10-2021 / 12:18:26 / svestkap"
+    "Modified (comment): / 26-11-2021 / 09:49:30 / Patrik Svestka <patrik.svestka@gmail.com>"
+!
+
+testExecWithTooLongCommandPath2
+    "Testing if the exception is proceedable and if it returns nil"
+    | beyondCreateProcessArgumentsLimit commandPath handle |
+    
+    beyondCreateProcessArgumentsLimit := 4097.
+    "/ created random String size 4097
+    commandPath := RandomGenerator new nextCharacters: beyondCreateProcessArgumentsLimit.
+    self assert: commandPath size = beyondCreateProcessArgumentsLimit.
+    
+    handle := Win32OperatingSystem::Win32ProcessHandle new.
+    self assert: handle notNil.
+    self assert: (handle isKindOf: Win32OperatingSystem::Win32ProcessHandle).
+    self assert: handle pid isNil.
+    
+    Exception handle: [ :ex | 
+        ex proceed
+    ] do: [ 
+         handle := OperatingSystem exec: commandPath withArguments: ''
+                     environment:nil
+                 fileDescriptors:nil
+                            fork:true
+                         newPgrp:false
+                     inDirectory: Filename currentDirectory pathName
+    ]. 
+    "/ after exception has occured, continue to see if handle is nil    
+    self assert: handle isNil.
+
+    "Created: / 21-10-2021 / 12:19:37 / svestkap"
+!
+
+testExecWithTooLongDirName
+    "Creating process with too long command path - should raise an exception"
+    | beyondCreateProcessArgumentsLimit dirName savedException |
+    
+    beyondCreateProcessArgumentsLimit := 4096.
+    dirName := RandomGenerator new nextCharacters: beyondCreateProcessArgumentsLimit.
+    self assert: dirName size = beyondCreateProcessArgumentsLimit.
+    
+    self should: [
+        OperatingSystem exec: '' withArguments: ''
+                 environment:nil
+             fileDescriptors:nil
+                        fork:true
+                     newPgrp:false
+                 inDirectory: dirName
+    ] raise: Exception
+    suchThat: [ :ex | 
+        savedException := ex.
+        ex description includesString: 'Invalid Arguments - dirNameUni16 exceeded size limit (4096 characters) (Invalid parameter)'.
+    ].
+    "/ the exception is NOT proceedable
+    self deny: savedException willProceed
+
+    "Created: / 21-10-2021 / 12:22:38 / svestkap"
+    "Modified (comment): / 26-11-2021 / 09:49:38 / Patrik Svestka <patrik.svestka@gmail.com>"
+!
+
+testExecWithTooLongDirName2
+    "Testing if the exception is proceedable and if it returns nil"
+    | beyondCreateProcessArgumentsLimit dirName handle |
+    
+    beyondCreateProcessArgumentsLimit := 4097.
+    dirName := RandomGenerator new nextCharacters: beyondCreateProcessArgumentsLimit.
+    self assert: dirName size = beyondCreateProcessArgumentsLimit.
+    
+    handle := Win32OperatingSystem::Win32ProcessHandle new.
+    self assert: handle notNil.
+    self assert: (handle isKindOf: Win32OperatingSystem::Win32ProcessHandle).
+    self assert: handle pid isNil.
+    
+    Exception handle: [ :ex | 
+        ex proceed
+    ] do: [ 
+         handle := OperatingSystem exec: '' withArguments: ''
+                     environment:nil
+                 fileDescriptors:nil
+                            fork:true
+                         newPgrp:false
+                     inDirectory: dirName
+    ]. 
+    "/ after exception has occured, continue to see if handle is nil    
+    self assert: handle isNil.
+
+    "Created: / 21-10-2021 / 12:21:54 / svestkap"
+! !
+
 !Win32OperatingSystemTest methodsFor:'tests'!
 
 testMutex