- name: execute a powershell cmdlet
  win_shell: Write-Output "hello from Ansible"
  register: shellout

- name: validate result
  assert:
    that:
    - shellout|success
    - shellout|changed
    - shellout.cmd == 'Write-Output "hello from Ansible"'
    - shellout.delta is match('^\d:(\d){2}:(\d){2}.(\d){6}$')
    - shellout.end is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$')
    - shellout.rc == 0
    - shellout.start is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$')
    - shellout.stderr == ""
    - shellout.stdout == "hello from Ansible\r\n"
    - shellout.stdout_lines == ["hello from Ansible"]
    - shellout.warnings == []

- name: execute a powershell cmdlet with multi-line output
  win_shell: Write-Output "hello from Ansible"; Write-Output "another line"; Write-Output "yet another line"
  register: shellout

- name: validate result
  assert:
    that:
    - shellout|success
    - shellout|changed
    - shellout.cmd == 'Write-Output "hello from Ansible"; Write-Output "another line"; Write-Output "yet another line"'
    - shellout.delta is match('^\d:(\d){2}:(\d){2}.(\d){6}$')
    - shellout.end is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$')
    - shellout.rc == 0
    - shellout.start is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$')
    - shellout.stderr == ""
    - shellout.stdout == "hello from Ansible\r\nanother line\r\nyet another line\r\n"
    - shellout.stdout_lines == ["hello from Ansible","another line", "yet another line"]
    - shellout.warnings == []

- name: execute something nonexistent
  win_shell: bogus_command1234
  register: shellout
  ignore_errors: true

- name: validate result
  assert:
    that:
    - shellout|failed
    - shellout|changed
    - shellout.cmd == 'bogus_command1234'
    - shellout.delta is match('^\d:(\d){2}:(\d){2}.(\d){6}$')
    - shellout.end is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$')
    - shellout.rc == 1
    - shellout.start is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$')
    - shellout.stderr is search('not recognized')
    - shellout.stdout == ""
    - shellout.stdout_lines == []
    - shellout.warnings == []

- name: execute something with error output
  win_shell: Write-Error "it broke"; Write-Output "some output"
  register: shellout

- name: validate result
  assert:
    that:
    - shellout|success
    - shellout|changed
    - shellout.cmd == 'Write-Error "it broke"; Write-Output "some output"'
    - shellout.delta is match('^\d:(\d){2}:(\d){2}.(\d){6}$')
    - shellout.end is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$')
    - shellout.rc == 0
    - shellout.start is match('^(\d){4}\-(\d){2}\-(\d){2} (\d){2}:(\d){2}:(\d){2}.(\d){6}$')
    - shellout.stderr is search('it broke')
    - shellout.stdout == "some output\r\n"
    - shellout.stdout_lines == ["some output"]
    - shellout.warnings == []

- name: ensure test file is absent
  win_file:
    path: c:\testfile.txt
    state: absent

- name: run with creates, should create
  win_shell: echo $null >> c:\testfile.txt
  args:
    creates: c:\testfile.txt
  register: shellout

- name: validate result
  assert:
    that:
    - shellout|success
    - shellout|changed

- name: run again with creates, should skip
  win_shell: echo $null >> c:\testfile.txt
  args:
    creates: c:\testfile.txt
  register: shellout

- name: validate result
  assert:
    that:
    - shellout|skipped
    - shellout.msg is search('exists')

- name: ensure testfile is still present
  win_stat:
    path: c:\testfile.txt
  register: statout

- name: validate result
  assert:
    that:
    - statout.stat.exists == true

- name: run with removes, should remove
  win_shell: Remove-Item c:\testfile.txt
  args:
    removes: c:\testfile.txt
  register: shellout

- name: validate result
  assert:
    that:
    - shellout|success
    - shellout|changed

- name: run again with removes, should skip
  win_shell: echo $null >> c:\testfile.txt
  args:
    removes: c:\testfile.txt
  register: shellout

- name: validate result
  assert:
    that:
    - shellout|skipped
    - shellout.msg is search('does not exist')

- name: run something with known nonzero exit code
  win_shell: exit 254
  register: shellout
  ignore_errors: true

- name: validate result
  assert:
    that:
    - shellout|failed
    - shellout.rc == 254

- name: run something via cmd that will fail in powershell
  win_shell: echo line1 & echo.line2
  args:
    executable: cmd
  register: shellout

- name: validate result
  assert:
    that:
    - shellout|success
    - shellout|changed
    - shellout.rc == 0
    - shellout.stdout == "line1 \r\nline2\r\n"
    - shellout.stdout_lines == ["line1 ", "line2"]
    - shellout.stderr == ""

- name: interleave large writes between stdout/stderr (check for buffer consumption deadlock)
  win_shell: $ba = New-Object byte[] 4096; (New-Object System.Random 32).NextBytes($ba); $text = [Convert]::ToBase64String($ba); Write-Output startout; Write-Error starterror; Write-Error $text; Write-Output $text; Write-Error $text; Write-Output $text; Write-Error $text; Write-Output $text; Write-Output doneout Write-Error doneerror
  register: shellout

- name: ensure that the entirety of both streams were read
  assert:
    that:
    - shellout.stdout is search("startout")
    - shellout.stdout is search("doneout")
    - shellout.stderr is search("starterror")
    - shellout.stderr is search("doneerror")
