Adding tests for creating processes on MS Windows
Testing:
- correct execution of CreateProcessW()
- Too long arguments for dir name, command path, command line
--- 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