Unverified Commit bf4a7844 authored by Cristian Maglie's avatar Cristian Maglie Committed by GitHub

[skip-changelog] Added process.RunWithinContext method (#1546)

This method allows to bound process execution to a context.
parent c8a3f2ef
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package executils package executils
import ( import (
"context"
"io" "io"
"os" "os"
"os/exec" "os/exec"
...@@ -141,3 +142,19 @@ func (p *Process) Run() error { ...@@ -141,3 +142,19 @@ func (p *Process) Run() error {
func (p *Process) SetEnvironment(values []string) { func (p *Process) SetEnvironment(values []string) {
p.cmd.Env = values p.cmd.Env = values
} }
// RunWithinContext starts the specified command and waits for it to complete. If the given context
// is canceled before the normal process termination, the process is killed.
func (p *Process) RunWithinContext(ctx context.Context) error {
completed := make(chan struct{})
defer close(completed)
go func() {
select {
case <-ctx.Done():
p.Kill()
case <-completed:
}
}()
res := p.cmd.Run()
return res
}
// This file is part of arduino-cli.
//
// Copyright 2021 ARDUINO SA (http://www.arduino.cc/)
//
// This software is released under the GNU General Public License version 3,
// which covers the main part of arduino-cli.
// The terms of this license can be found at:
// https://www.gnu.org/licenses/gpl-3.0.en.html
//
// You can be released from the requirements of the above licenses by purchasing
// a commercial license. Buying such a license is mandatory if you want to
// modify or otherwise use the software for commercial activities involving the
// Arduino software without disclosing the source code of your own applications.
// To purchase a commercial license, send an email to license@arduino.cc.
package executils
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestProcessWithinContext(t *testing.T) {
// Build `delay` helper inside testdata/delay
builder, err := NewProcess("go", "build")
require.NoError(t, err)
builder.SetDir("testdata/delay")
require.NoError(t, builder.Run())
// Run delay and test if the process is terminated correctly due to context
process, err := NewProcess("testdata/delay/delay")
require.NoError(t, err)
start := time.Now()
ctx, cancel := context.WithTimeout(context.Background(), 250*time.Millisecond)
err = process.RunWithinContext(ctx)
require.Error(t, err)
require.Less(t, time.Since(start), 500*time.Millisecond)
cancel()
}
package main
import (
"fmt"
"time"
)
func main() {
time.Sleep(3 * time.Second)
fmt.Println("Elapsed!")
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment