/
android_init_crash.go
102 lines (90 loc) · 2.62 KB
/
android_init_crash.go
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
// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package arc
import (
"context"
"syscall"
"time"
"golang.org/x/sys/unix"
"chromiumos/tast/ctxutil"
"chromiumos/tast/errors"
"chromiumos/tast/local/arc"
"chromiumos/tast/local/chrome"
"chromiumos/tast/testing"
)
func init() {
testing.AddTest(&testing.Test{
Func: AndroidInitCrash,
LacrosStatus: testing.LacrosVariantUnneeded,
Desc: "Test Android init crash handling",
Contacts: []string{"hashimoto@chromium.org", "arc-eng@google.com"},
Attr: []string{"group:mainline", "informational"},
SoftwareDeps: []string{"chrome"},
Params: []testing.Param{{
ExtraSoftwareDeps: []string{"android_p"},
}, {
Name: "vm",
ExtraSoftwareDeps: []string{"android_vm"},
}},
Timeout: 10 * time.Minute,
})
}
func AndroidInitCrash(ctx context.Context, s *testing.State) {
// Shorten the context to save time for cleanup.
cleanupCtx := ctx
ctx, cancel := ctxutil.Shorten(ctx, 10*time.Second)
defer cancel()
cr, err := chrome.New(ctx, chrome.ARCEnabled())
if err != nil {
s.Fatal("Failed to connect to Chrome: ", err)
}
defer func() {
if err := cr.Close(cleanupCtx); err != nil {
s.Fatal("Failed to close Chrome while (re)booting ARC: ", err)
}
}()
a, err := arc.New(ctx, s.OutDir())
if err != nil {
s.Fatal("Failed to start ARC: ", err)
}
defer func() {
// Note: |a| can be the arc.New() result above, or the one below after reboot.
if a != nil {
a.Close(ctx)
}
}()
oldPID, err := arc.InitPID()
if err != nil {
s.Fatal("Failed to get init PID before reboot: ", err)
}
// Android init crash should result in Android reboot.
s.Log("Inducing Android init crash")
if err := unix.Kill(int(oldPID), syscall.SIGTERM); err != nil {
s.Fatal("Failed to kill Android init: ", err)
}
if err = testing.Poll(ctx, func(ctx context.Context) error {
pid, err := arc.InitPID()
if err == nil && pid == oldPID {
return errors.New("Old init still exists")
}
return nil
}, &testing.PollOptions{Timeout: 60 * time.Second}); err != nil {
s.Fatal("Failed to wait for old Android init to stop: ", err)
}
a.Close(ctx) // Ignore error and continue.
a = nil
// Make sure Android successfully boots.
a, err = arc.New(ctx, s.OutDir())
if err != nil {
s.Fatal("Failed to restart ARC: ", err)
}
// Additional check just to be sure.
newPID, err := arc.InitPID()
if err != nil {
s.Fatal("Failed to get init PID after reboot: ", err)
}
if newPID == oldPID {
s.Fatal("Failure: init PID did not change")
}
}