Repository navigation
Expand file tree
/
Copy pathmodule_execution_test.go
More file actions
113 lines (98 loc) · 2.84 KB
/
Copy pathmodule_execution_test.go
File metadata and controls
113 lines (98 loc) · 2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package main
import (
"errors"
"fmt"
"os"
"syscall"
"testing"
"github.com/mvt-project/androidqf/acquisition"
"github.com/mvt-project/androidqf/adb"
"github.com/mvt-project/androidqf/modules"
)
type contextBlockingModule struct {
name string
started chan struct{}
}
func (m *contextBlockingModule) Name() string { return m.name }
func (m *contextBlockingModule) Run(_ *acquisition.Acquisition, opts *modules.Options) error {
close(m.started)
<-opts.ContextOrBackground().Done()
return opts.ContextOrBackground().Err()
}
type interruptWaitingModule struct {
started chan struct{}
}
func (m *interruptWaitingModule) Name() string { return modules.NewIL().Name() }
func (m *interruptWaitingModule) Run(_ *acquisition.Acquisition, opts *modules.Options) error {
close(m.started)
received := <-opts.Signals
if received != os.Interrupt {
return fmt.Errorf("received %v, want %v", received, os.Interrupt)
}
return nil
}
func TestRunModuleCancelsActiveModuleOnTermination(t *testing.T) {
oldClient := adb.Client
adb.Client = nil
t.Cleanup(func() { adb.Client = oldClient })
started := make(chan struct{})
signals := make(chan os.Signal, 1)
go func() {
<-started
signals <- syscall.SIGTERM
}()
opts := &modules.Options{}
err, interrupted := runModule(
&contextBlockingModule{name: "blocking", started: started},
&acquisition.Acquisition{},
opts,
signals,
)
if !interrupted {
t.Fatal("runModule() interrupted = false")
}
if !errors.Is(err, modules.ErrAcquisitionInterrupted) {
t.Fatalf("runModule() error = %v, want ErrAcquisitionInterrupted", err)
}
if opts.Context != nil || opts.Signals != nil {
t.Fatalf("module options retained runtime state: %+v", opts)
}
}
func TestRunModuleForwardsFirstIntrusionLogInterrupt(t *testing.T) {
oldClient := adb.Client
adb.Client = nil
t.Cleanup(func() { adb.Client = oldClient })
started := make(chan struct{})
signals := make(chan os.Signal, 1)
go func() {
<-started
signals <- os.Interrupt
}()
err, interrupted := runModule(
&interruptWaitingModule{started: started},
&acquisition.Acquisition{},
&modules.Options{},
signals,
)
if err != nil {
t.Fatalf("runModule() error = %v", err)
}
if interrupted {
t.Fatal("runModule() interrupted = true")
}
}
func TestModuleResultStatusDistinguishesPartialCollection(t *testing.T) {
if got := moduleResultStatus(nil); got != "completed" {
t.Fatalf("nil status = %q, want completed", got)
}
if got := moduleResultStatus(fmt.Errorf("%w: missing file", modules.ErrPartialCollection)); got != "partial" {
t.Fatalf("partial status = %q, want partial", got)
}
interruptedPartial := errors.Join(
fmt.Errorf("%w: missing file", modules.ErrPartialCollection),
modules.ErrAcquisitionInterrupted,
)
if got := moduleResultStatus(interruptedPartial); got != "failed" {
t.Fatalf("interrupted partial status = %q, want failed", got)
}
}