# file      : tests/test/script/runner/timeout.testscript
# license   : MIT; see accompanying LICENSE file

.include ../common.testscript

: test
:
{{
  : fragment-timeout
  :
  {{
    : set
    :
    $c <<EOI && $b 2>>~%EOE% != 0
      timeout 1;
      $* -l 3
      EOI
      %testscript:.*: error: .+ terminated: execution timeout expired%
      %.
      EOE

    : reset
    :
    $c <<EOI && $b
      timeout 1;
      timeout 0;
      $* -l 3
      EOI

    : override
    :
    $c <<EOI && $b 2>>~%EOE% != 0
      +timeout /10

      {{
        +timeout /10

        timeout 1;
        env -t 10 -- $* -l 3
      }}
      EOI
      %testscript:.*: error: .+ terminated: execution timeout expired%
      %.
      EOE

    : successful
    :
    $c <<EOI && $b
      timeout --success 1;
      $* -l 3
      EOI
  }}

  : missing
  :
  $c <<EOI && $b 2>>~%EOE% != 0
    timeout
    EOI
    testscript:1:1: error: timeout: missing timeout
    %.
    EOE

  : invalid
  :
  $c <<EOI && $b 2>>~%EOE% != 0
    timeout foo
    EOI
    testscript:1:1: error: timeout: invalid test fragment timeout 'foo'
    %.
    EOE
}}

: group
:
{{
  : group-timeout
  :
  {{
    : set
    :
    $c <<EOI && $b 2>>~%EOE% != 0
      {{
        +timeout 1

        $* -l 3
      }}
      EOI
      %testscript:.*: error: .+ terminated: execution timeout expired%
      %.
      EOE

    : reset
    :
    $c <<EOI && $b
      {{
        +timeout 1
        +timeout 0

        $* -l 3
      }}
      EOI

    : override
    :
    : Also test slash usage inside the timeout value.
    :
    $c <<EOI && $b 2>>~%EOE% != 0
      +timeout 10/10

      {{
        +timeout 1/

        timeout 10;
        env -t 10 -- $* -l 3
      }}
      EOI
      %testscript:.*: error: .+ terminated: execution timeout expired%
      %.
      EOE

    : invalid
    :
    $c <<EOI && $b 2>>~%EOE% != 0
      {{
        +timeout foo/
      }}
      EOI
      testscript:2:4: error: timeout: invalid test group timeout 'foo'
      %.
      EOE
  }}

  : test-timeout
  :
  {{
    : set
    :
    $c <<EOI && $b 2>>~%EOE% != 0
      {{
        +timeout /1

        $* -l 3
      }}
      EOI
      %testscript:.*: error: .+ terminated: execution timeout expired%
      %.
      EOE

    : reset
    :
    $c <<EOI && $b
      {{
        +timeout /1
        +timeout /0

        $* -l 3
      }}
      EOI

    : override
    :
    $c <<EOI && $b 2>>~%EOE% != 0
      +timeout 10/10

      {{
        +timeout /1

        timeout 10;
        env -t 10 -- $* -l 3
      }}
      EOI
      %testscript:.*: error: .+ terminated: execution timeout expired%
      %.
      EOE

    : invalid
    :
    $c <<EOI && $b 2>>~%EOE% != 0
      {{
        +timeout /foo
      }}
      EOI
      testscript:2:4: error: timeout: invalid test timeout 'foo'
      %.
      EOE
  }}
}}

: script
:
{{
  : group-timeout
  :
  {{
    : set
    :
    $c <<EOI && $b 2>>~%EOE% != 0
      +timeout 1

      $* -l 3
      EOI
      %testscript:.*: error: .+ terminated: execution timeout expired%
      %.
      EOE

    : reset
    :
    $c <<EOI && $b
      +timeout 1
      +timeout 0

      $* -l 3
      EOI

    : override
    :
    $c <<EOI && $b 2>>~%EOE% != 0
      +timeout 1

      {{
        +timeout 10

        timeout 10;
        env -t 10 -- $* -l 3
      }}
      EOI
      %testscript:.*: error: .+ terminated: execution timeout expired%
      %.
      EOE

    : invalid
    :
    $c <<EOI && $b 2>>~%EOE% != 0
      +timeout foo/
      EOI
      testscript:1:2: error: timeout: invalid testscript timeout 'foo'
      %.
      EOE

    : successful
    :
    $c <<EOI && $b
      +timeout --success 1

      $* -l 3
      EOI
  }}

  : test-timeout
  :
  {{
    : set
    :
    $c <<EOI && $b 2>>~%EOE% != 0
      +timeout /1

      $* -l 3
      EOI
      %testscript:.*: error: .+ terminated: execution timeout expired%
      %.
      EOE

    : reset
    :
    $c <<EOI && $b
      +timeout /1
      +timeout /0

      $* -l 3
      EOI

    : override
    :
    $c <<EOI && $b 2>>~%EOE% != 0
      +timeout /1

      {{
        +timeout --success /1

        {{
          +timeout 10/10

          timeout 10;
          env -t 10 -- $* -l 3
        }}
      }}
      EOI
      %testscript:.*: error: .+ terminated: execution timeout expired%
      %.
      EOE

    : successful
    :
    $c <<EOI && $b
      +timeout --success /1

      $* -l 3
      EOI

    : invalid
    :
    $c <<EOI && $b 2>>~%EOE% != 0
      {{
        +timeout /foo
      }}
      EOI
      testscript:2:4: error: timeout: invalid test timeout 'foo'
      %.
      EOE
  }}
}}

: config
:
{{
  : operation
  :
  {{
    : set
    :
    $c <<EOI && $b config.test.timeout=1 2>>~%EOE% != 0
      timeout 10;
      $* -l 3
      EOI
      %testscript:.*: error: .+ terminated: execution timeout expired%
      %.
      EOE

    : reset
    :
    $c <<EOI && $b config.test.timeout=1 config.test.timeout=0/10
      timeout 10;
      $* -l 3
      EOI

    : override
    :
    $c <<EOI && $b config.test.timeout=1/10 2>>~%EOE% != 0
      +timeout 10

      {{
        +timeout 10/10

        timeout 10;
        env -t 10 -- $* -l 3
      }}
      EOI
      %testscript:.*: error: .+ terminated: execution timeout expired%
      %.
      EOE

    : invalid
    :
    $c && $b config.test.timeout=foo 2>>EOE != 0
      error: invalid config.test.timeout test operation timeout value 'foo'
      EOE
  }}

  : test
  :
  {{
    : set
    :
    $c <<EOI && $b config.test.timeout=/1 2>>~%EOE% != 0
      timeout 10;
      $* -l 3
      EOI
      %testscript:.*: error: .+ terminated: execution timeout expired%
      %.
      EOE

    : reset
    :
    $c <<EOI && $b config.test.timeout=/1 config.test.timeout=10/0
      timeout 10;
      $* -l 3
      EOI

    : override
    :
    $c <<EOI && $b config.test.timeout=10/1 2>>~%EOE% != 0
      +timeout 10

      {{
        +timeout 10/10

        timeout 10;
        env -t 10 -- $* -l 3
      }}
      EOI
      %testscript:.*: error: .+ terminated: execution timeout expired%
      %.
      EOE

    : invalid
    :
    $c && $b config.test.timeout=/foo 2>>EOE != 0
      error: invalid config.test.timeout test timeout value 'foo'
      EOE
  }}
}}

: failures
:
: Here we test that the left-hand side processes are terminated on failure.
:
{{
  : set
  :
  $c <<EOI && $b 2>>~%EOE% != 0
  env -t 1 -- $* -l 86400 -o 'foo' | set --foo bar
  EOI
  %testscript:.*: error: set: unknown option '--foo'%
  %.
  EOE

  : exit
  :
  $c <<EOI && $b 2>>~%EOE% != 0
  env -t 1 -- $* -l 86400 -o 'foo' | exit 0
  EOI
  %testscript:.*: error: exit builtin must be the only pipe command%
  %.
  EOE

  : redirect
  :
  $c <<EOI && $b 2>>~%EOE% != 0
  env -t 1 -- $* -l 86400 -o 'foo' | touch $~/foo/bar
  EOI
  %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
  %.
  %testscript:.*: error: builtin touch exited with code 1%
  %.+
  EOE
}}

: pipeline
:
{{
  : prog-tm-prog
  :
  $c <<EOI && $b 2>>~%EOE% != 0
    $* -l 10 | env -t 1 -- $* -i 0
    EOI
    %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
    %.
    %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
    %.
    EOE

  : tm-prog-prog
  :
  $c <<EOI && $b 2>>~%EOE% != 0
    env -t 1 -- $* -l 10 | $* -i 0
    EOI
    %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
    %.
    %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
    %.
    EOE

  : tm-cat-prog
  :
  $c <<EOI && $b 2>>~%EOE% != 0
    env -t 3 -- cat <"test" | $* -l 10
    EOI
    %testscript:.*: error: builtin cat terminated: execution timeout expired%
    %.
    %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
    %.
    EOE

  : cat-tm-prog
  :
  $c <<EOI && $b 2>>~%EOE% != 0
    cat <"test" | env -t 1 -- $* -l 10
    EOI
    %testscript:.*: error: builtin cat terminated: execution timeout expired%
    %.
    %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
    %.
    EOE

  : tm-prog-cat
  :
  $c <<EOI && $b 2>>~%EOE% != 0
    env -t 1 -- $* -l 10 | cat >-
    EOI
    %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
    %.
    %testscript:.*: error: builtin cat terminated: execution timeout expired%
    %.
    EOE

  : tm-echo-prog
  :
  $c <<EOI && $b 2>>~%EOE% != 0
    env -t 3 -- echo "test" | $* -l 10
    EOI
    %testscript:.*: error: builtin echo terminated: execution timeout expired%
    %.
    %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
    %.
    EOE

  : successful
  :
  {{
    : prog-prog
    :
    $c <<EOI && $b
    timeout --success 1;
    $* -l 10 | $* -i 0
    EOI

    : prog-cat
    :
    $c <<EOI && $b
    timeout --success 1;
    $* -l 10 | cat
    EOI

    : cat-prog
    :
    $c <<EOI && $b
    s="----------------------------------------------------------------------";
    s="$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s";
    s="$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s";
    s="$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s";
    timeout --success 1;
    cat <"$s" 2>>~%EOE% | $* -l 10 -i 0
    %cat: unable to print stdin: .+%
    EOE
    EOI
  }}
}}

: syntax-1
:
{{
  b = [cmdline] $regex.apply($b, '(.+testscript.syntax).+', "\1 = 1'")

  : test
  :
  {{
    : fragment-timeout
    :
    {{
      : set
      :
      $c <<EOI && $b 2>>~%EOE% != 0
        timeout 1;
        $* -l 3
        EOI
        %testscript:.*: error: .+ terminated: execution timeout expired%
        %.
        EOE

      : reset
      :
      $c <<EOI && $b
        timeout 1;
        timeout 0;
        $* -l 3
        EOI

      : override
      :
      $c <<EOI && $b 2>>~%EOE% != 0
        +timeout /10

        {
          +timeout /10

          timeout 1;
          env -t 10 -- $* -l 3
        }
        EOI
        %testscript:.*: error: .+ terminated: execution timeout expired%
        %.
        EOE

      : successful
      :
      $c <<EOI && $b
        timeout --success 1;
        $* -l 3
        EOI
    }}

    : missing
    :
    $c <'timeout' && $b 2>>~%EOE% != 0
      testscript:1:1: error: timeout: missing timeout
      %.
      EOE

    : invalid
    :
    $c <'timeout foo' && $b 2>>~%EOE% != 0
      testscript:1:1: error: timeout: invalid test fragment timeout 'foo'
      %.
      EOE
  }}

  : group
  :
  {{
    : group-timeout
    :
    {{
      : set
      :
      $c <<EOI && $b 2>>~%EOE% != 0
        {
          +timeout 1

          $* -l 3
        }
        EOI
        %testscript:.*: error: .+ terminated: execution timeout expired%
        %.
        EOE

      : reset
      :
      $c <<EOI && $b
        {
          +timeout 1
          +timeout 0

          $* -l 3
        }
        EOI

      : override
      :
      : Also test slash usage inside the timeout value.
      :
      $c <<EOI && $b 2>>~%EOE% != 0
        +timeout 10/10

        {
          +timeout 1/

          timeout 10;
          env -t 10 -- $* -l 3
        }
        EOI
        %testscript:.*: error: .+ terminated: execution timeout expired%
        %.
        EOE

      : invalid
      :
      $c <<EOI && $b 2>>~%EOE% != 0
        {
          +timeout foo/
        }
        EOI
        testscript:2:4: error: timeout: invalid test group timeout 'foo'
        %.
        EOE
    }}

    : test-timeout
    :
    {{
      : set
      :
      $c <<EOI && $b 2>>~%EOE% != 0
        {
          +timeout /1

          $* -l 3
        }
        EOI
        %testscript:.*: error: .+ terminated: execution timeout expired%
        %.
        EOE

      : reset
      :
      $c <<EOI && $b
        {
          +timeout /1
          +timeout /0

          $* -l 3
        }
        EOI

      : override
      :
      $c <<EOI && $b 2>>~%EOE% != 0
        +timeout 10/10

        {
          +timeout /1

          timeout 10;
          env -t 10 -- $* -l 3
        }
        EOI
        %testscript:.*: error: .+ terminated: execution timeout expired%
        %.
        EOE

      : invalid
      :
      $c <<EOI && $b 2>>~%EOE% != 0
        {
          +timeout /foo
        }
        EOI
        testscript:2:4: error: timeout: invalid test timeout 'foo'
        %.
        EOE
    }}
  }}

  : script
  :
  {{
    : group-timeout
    :
    {{
      : set
      :
      $c <<EOI && $b 2>>~%EOE% != 0
        +timeout 1

        $* -l 3
        EOI
        %testscript:.*: error: .+ terminated: execution timeout expired%
        %.
        EOE

      : reset
      :
      $c <<EOI && $b
        +timeout 1
        +timeout 0

        $* -l 3
        EOI

      : override
      :
      $c <<EOI && $b 2>>~%EOE% != 0
        +timeout 1

        {
          +timeout 10

          timeout 10;
          env -t 10 -- $* -l 3
        }
        EOI
        %testscript:.*: error: .+ terminated: execution timeout expired%
        %.
        EOE

      : invalid
      :
      $c <<EOI && $b 2>>~%EOE% != 0
        +timeout foo/
        EOI
        testscript:1:2: error: timeout: invalid testscript timeout 'foo'
        %.
        EOE

      : successful
      :
      $c <<EOI && $b
        +timeout --success 1

        $* -l 3
        EOI
    }}

    : test-timeout
    :
    {{
      : set
      :
      $c <<EOI && $b 2>>~%EOE% != 0
        +timeout /1

        $* -l 3
        EOI
        %testscript:.*: error: .+ terminated: execution timeout expired%
        %.
        EOE

      : reset
      :
      $c <<EOI && $b
        +timeout /1
        +timeout /0

        $* -l 3
        EOI

      : override
      :
      $c <<EOI && $b 2>>~%EOE% != 0
        +timeout /1

        {
          +timeout --success /1

          {
            +timeout 10/10

            timeout 10;
            env -t 10 -- $* -l 3
          }
        }
        EOI
        %testscript:.*: error: .+ terminated: execution timeout expired%
        %.
        EOE

      : successful
      :
      $c <<EOI && $b
        +timeout --success /1

        $* -l 3
        EOI

      : invalid
      :
      $c <<EOI && $b 2>>~%EOE% != 0
        {
          +timeout /foo
        }
        EOI
        testscript:2:4: error: timeout: invalid test timeout 'foo'
        %.
        EOE
    }}
  }}

  : config
  :
  {{
    : operation
    :
    {{
      : set
      :
      $c <<EOI && $b config.test.timeout=1 2>>~%EOE% != 0
        timeout 10;
        $* -l 3
        EOI
        %testscript:.*: error: .+ terminated: execution timeout expired%
        %.
        EOE

      : reset
      :
      $c <<EOI && $b config.test.timeout=1 config.test.timeout=0/10
        timeout 10;
        $* -l 3
        EOI

      : override
      :
      $c <<EOI && $b config.test.timeout=1/10 2>>~%EOE% != 0
        +timeout 10

        {
          +timeout 10/10

          timeout 10;
          env -t 10 -- $* -l 3
        }
        EOI
        %testscript:.*: error: .+ terminated: execution timeout expired%
        %.
        EOE

      : invalid
      :
      $c && $b config.test.timeout=foo 2>>EOE != 0
        error: invalid config.test.timeout test operation timeout value 'foo'
        EOE
    }}

    : test
    :
    {{
      : set
      :
      $c <<EOI && $b config.test.timeout=/1 2>>~%EOE% != 0
        timeout 10;
        $* -l 3
        EOI
        %testscript:.*: error: .+ terminated: execution timeout expired%
        %.
        EOE

      : reset
      :
      $c <<EOI && $b config.test.timeout=/1 config.test.timeout=10/0
        timeout 10;
        $* -l 3
        EOI

      : override
      :
      $c <<EOI && $b config.test.timeout=10/1 2>>~%EOE% != 0
        +timeout 10

        {
          +timeout 10/10

          timeout 10;
          env -t 10 -- $* -l 3
        }
        EOI
        %testscript:.*: error: .+ terminated: execution timeout expired%
        %.
        EOE

      : invalid
      :
      $c && $b config.test.timeout=/foo 2>>EOE != 0
        error: invalid config.test.timeout test timeout value 'foo'
        EOE
    }}
  }}

  : failures
  :
  : Here we test that the left-hand side processes are terminated on failure.
  :
  {{
    : set
    :
    $c <<EOI && $b 2>>~%EOE% != 0
    env -t 1 -- $* -l 86400 -o 'foo' | set --foo bar
    EOI
    %testscript:.*: error: set: unknown option '--foo'%
    %.
    EOE

    : exit
    :
    $c <<EOI && $b 2>>~%EOE% != 0
    env -t 1 -- $* -l 86400 -o 'foo' | exit 0
    EOI
    %testscript:.*: error: exit builtin must be the only pipe command%
    %.
    EOE

    : redirect
    :
    $c <<EOI && $b 2>>~%EOE% != 0
    env -t 1 -- $* -l 86400 -o 'foo' | touch $~/foo/bar
    EOI
    %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
    %.
    %testscript:.*: error: builtin touch exited with code 1%
    %.+
    EOE
  }}

  : pipeline
  :
  {{
    : prog-tm-prog
    :
    $c <'$* -l 10 | env -t 1 -- $* -i 0' && $b 2>>~%EOE% != 0
      %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
      %.
      %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
      %.
      EOE

    : tm-prog-prog
    :
    $c <'env -t 1 -- $* -l 10 | $* -i 0' && $b 2>>~%EOE% != 0
      %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
      %.
      %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
      %.
      EOE

    : tm-cat-prog
    :
    $c <'env -t 3 -- cat <"test" | $* -l 10' && $b 2>>~%EOE% != 0
      %testscript:.*: error: builtin cat terminated: execution timeout expired%
      %.
      %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
      %.
      EOE

    : cat-tm-prog
    :
    $c <'cat <"test" | env -t 1 -- $* -l 10' && $b 2>>~%EOE% != 0
      %testscript:.*: error: builtin cat terminated: execution timeout expired%
      %.
      %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
      %.
      EOE

    : tm-prog-cat
    :
    $c <'env -t 1 -- $* -l 10 | cat >-' && $b 2>>~%EOE% != 0
      %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
      %.
      %testscript:.*: error: builtin cat terminated: execution timeout expired%
      %.
      EOE

    : tm-echo-prog
    :
    $c <'env -t 3 -- echo "test" | $* -l 10' && $b 2>>~%EOE% != 0
      %testscript:.*: error: builtin echo terminated: execution timeout expired%
      %.
      %testscript:.*: error: process .+driver.* terminated: execution timeout expired%
      %.
      EOE

    : successful
    :
    {{
      : prog-prog
      :
      $c <<EOI && $b
      timeout --success 1;
      $* -l 10 | $* -i 0
      EOI

      : prog-cat
      :
      $c <<EOI && $b
      timeout --success 1;
      $* -l 10 | cat
      EOI

      : cat-prog
      :
      $c <<EOI && $b
      s="----------------------------------------------------------------------";
      s="$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s";
      s="$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s";
      s="$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s$s";
      timeout --success 1;
      cat <"$s" 2>>~%EOE% | $* -l 10 -i 0
      %cat: unable to print stdin: .+%
      EOE
      EOI
    }}
  }}
}}
