github.com/bazelbuild/bazel-watcher@v0.25.2/internal/ibazel/command/notify_command_test.go (about) 1 // Copyright 2017 The Bazel Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package command 16 17 import ( 18 "errors" 19 "testing" 20 21 "github.com/bazelbuild/bazel-watcher/internal/bazel" 22 mock_bazel "github.com/bazelbuild/bazel-watcher/internal/bazel/testing" 23 "github.com/bazelbuild/bazel-watcher/internal/ibazel/log" 24 "github.com/bazelbuild/bazel-watcher/internal/ibazel/process_group" 25 ) 26 27 func TestNotifyCommand(t *testing.T) { 28 log.SetLogger(t) 29 30 pg := process_group.Command("cat") 31 32 c := ¬ifyCommand{ 33 args: []string{"moo"}, 34 bazelArgs: []string{}, 35 pg: pg, 36 target: "//path/to:target", 37 } 38 39 if c.IsSubprocessRunning() { 40 t.Errorf("New subprocess shouldn't have been started yet. State: %v", pg.RootProcess().ProcessState) 41 } 42 43 var err error 44 c.stdin, err = pg.RootProcess().StdinPipe() 45 if err != nil { 46 t.Error(err) 47 } 48 49 // Mock out bazel to return non-error on test 50 b := &mock_bazel.MockBazel{} 51 b.BuildError(nil) 52 bazelNew = func() bazel.Bazel { return b } 53 defer func() { bazelNew = oldBazelNew }() 54 55 c.NotifyOfChanges() 56 b.BuildError(errors.New("Demo error")) 57 c.NotifyOfChanges() 58 b.BuildError(nil) 59 c.NotifyOfChanges() 60 61 b.AssertActions(t, [][]string{ 62 {"SetStartupArgs"}, 63 {"SetArguments"}, 64 {"WriteToStderr", "true"}, 65 {"WriteToStdout", "true"}, 66 {"Build", "//path/to:target"}, 67 {"SetStartupArgs"}, 68 {"SetArguments"}, 69 {"WriteToStderr", "true"}, 70 {"WriteToStdout", "true"}, 71 {"Run", "--script_path=.*", "//path/to:target"}, 72 {"SetStartupArgs"}, 73 {"SetArguments"}, 74 {"WriteToStderr", "true"}, 75 {"WriteToStdout", "true"}, 76 {"Build", "//path/to:target"}, 77 {"SetStartupArgs"}, 78 {"SetArguments"}, 79 {"WriteToStderr", "true"}, 80 {"WriteToStdout", "true"}, 81 {"Build", "//path/to:target"}, 82 {"SetStartupArgs"}, 83 {"SetArguments"}, 84 {"WriteToStderr", "true"}, 85 {"WriteToStdout", "true"}, 86 {"Run", "--script_path=.*", "//path/to:target"}, 87 }) 88 } 89 90 func TestNotifyCommand_Restart(t *testing.T) { 91 log.SetLogger(t) 92 93 var pg process_group.ProcessGroup 94 95 pg = process_group.Command("ls") 96 execCommand = func(name string, args ...string) process_group.ProcessGroup { 97 return oldExecCommand("ls") 98 } 99 defer func() { execCommand = oldExecCommand }() 100 101 c := ¬ifyCommand{ 102 args: []string{"moo"}, 103 bazelArgs: []string{}, 104 pg: pg, 105 target: "//path/to:target", 106 } 107 108 var err error 109 c.stdin, err = pg.RootProcess().StdinPipe() 110 if err != nil { 111 t.Error(err) 112 } 113 114 b := &mock_bazel.MockBazel{} 115 b.BuildError(errors.New("Demo error")) 116 bazelNew = func() bazel.Bazel { return b } 117 defer func() { bazelNew = oldBazelNew }() 118 119 if c.IsSubprocessRunning() { 120 t.Errorf("new subprocess shouldn't have been started yet. State: %v", pg.RootProcess().ProcessState) 121 } 122 123 c.NotifyOfChanges() 124 if c.IsSubprocessRunning() { 125 t.Errorf("process should not start with build errors. State: %v", pg.RootProcess().ProcessState) 126 } 127 128 // Since the process isn't currently running, this should start it. 129 b.BuildError(nil) 130 c.NotifyOfChanges() 131 if !c.IsSubprocessRunning() { 132 t.Errorf("subprocess should have started. State: %v", pg.RootProcess().ProcessState) 133 } 134 135 pid1 := c.pg.RootProcess().Process.Pid 136 137 c.Terminate() 138 if c.IsSubprocessRunning() { 139 t.Errorf("subprocess should have been terminated. State: %v", pg.RootProcess().ProcessState) 140 } 141 142 b.BuildError(errors.New("Demo error")) 143 c.NotifyOfChanges() 144 if c.IsSubprocessRunning() { 145 t.Errorf("subprocess should not restart with build errors. State: %v", pg.RootProcess().ProcessState) 146 } 147 148 // Since the process isn't currently running, this should re-start it. 149 b.BuildError(nil) 150 c.NotifyOfChanges() 151 if !c.IsSubprocessRunning() { 152 t.Errorf("subprocess should have been restarted. State: %v", pg.RootProcess().ProcessState) 153 } 154 155 pid2 := c.pg.RootProcess().Process.Pid 156 if pid2 == pid1 { 157 t.Error("PIDs of restarted process should be different that original process") 158 } 159 160 c.NotifyOfChanges() 161 if pid2 != c.pg.RootProcess().Process.Pid { 162 t.Error("non-dead process was restarted") 163 } 164 }