github.com/google/fleetspeak@v0.1.15-0.20240426164851-4f31f62c1aea/fleetspeak/src/client/daemonservice/testclient/testclient.go (about) 1 // Copyright 2017 Google Inc. 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 // https://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 testclient implements a daemonservice client meant for testing. 16 package main 17 18 import ( 19 "flag" 20 "fmt" 21 "math/rand" 22 "os" 23 "os/exec" 24 "os/signal" 25 "strconv" 26 "time" 27 28 log "github.com/golang/glog" 29 30 "github.com/google/fleetspeak/fleetspeak/src/client/daemonservice/client" 31 ) 32 33 var mode = flag.String("mode", "loopback", "Mode of operation. Options are: loopback, garbage, freeze, freezeHard, die, stdSpam, subprocess") 34 35 func main() { 36 flag.Parse() 37 38 switch *mode { 39 case "loopback": 40 loopback() 41 case "garbage": 42 garbage() 43 case "freeze": 44 freeze(false) 45 case "die": 46 os.Exit(42) 47 case "stdSpam": 48 stdSpam() 49 case "freezeHard": 50 freeze(true) 51 case "subprocess": 52 subprocess() 53 default: 54 log.Exitf("unknown mode: %v", *mode) 55 } 56 } 57 58 // loopback sends received messages to the server, appending "Response" to the 59 // MessageType field. 60 func loopback() { 61 log.Info("starting loopback") 62 63 ch, err := client.Init("0.5") 64 if err != nil { 65 log.Exitf("Unable to initialize client: %v", err) 66 } 67 68 for { 69 select { 70 case m, ok := <-ch.In: 71 if !ok { 72 return // normal shutdown 73 } 74 m.MessageType = m.MessageType + "Response" 75 ch.Out <- m 76 case e := <-ch.Err: 77 log.Exitf("Channel reported error: %v", e) 78 } 79 } 80 } 81 82 // garbage writes random data to the server. 83 func garbage() { 84 log.Info("starting garbage") 85 86 strOutFd := os.Getenv("FLEETSPEAK_COMMS_CHANNEL_OUTFD") 87 if strOutFd == "" { 88 log.Exit("Environment variable FLEETSPEAK_COMMS_CHANNEL_OUTFD not set") 89 } 90 91 outFd, err := strconv.Atoi(strOutFd) 92 if err != nil { 93 log.Exitf("Unable to parse FLEETSPEAK_COMMS_CHANNEL_OUTFD (%q): %v", strOutFd, err) 94 } 95 96 pw := os.NewFile(uintptr(outFd), "-") 97 98 for { 99 buf := make([]byte, 1024) 100 rand.Read(buf) 101 _, err := pw.Write(buf) 102 if err != nil { 103 log.Exitf("Garbage write failed: %v", err) 104 } 105 } 106 } 107 108 // freeze does nothing for a period of time. 109 func freeze(hard bool) { 110 log.Info("starting freeze") 111 if hard { 112 signal.Ignore(os.Interrupt) 113 } 114 time.Sleep(time.Hour) 115 } 116 117 // stdSpam sets up the interface, but then just writes ~5mb of set text to stdout and ~5mb to stderr. 118 func stdSpam() { 119 _, err := client.Init("0.5") 120 if err != nil { 121 log.Exitf("Unable to initialize client: %v", err) 122 } 123 124 for range 128 * 1024 { 125 fmt.Println("The quick brown fox jumped over the lazy dogs.") 126 fmt.Fprintln(os.Stderr, "The brown quick fox jumped over some lazy dogs.") 127 } 128 } 129 130 // subprocess starts a subprocess tree, writes a leaf pid to stdout, and waits 131 func subprocess() { 132 log.Info("starting subprocess") 133 134 _, err := client.Init("0.5") 135 if err != nil { 136 log.Exitf("Unable to initialize client: %v", err) 137 } 138 139 cmd := exec.Command("/bin/bash", "-c", ` 140 /bin/bash -c ' 141 /bin/echo $$ 142 /bin/sleep infinity 143 ' 144 `) 145 cmd.Stdout = os.Stdout 146 cmd.Stderr = os.Stderr 147 148 if err := cmd.Start(); err != nil { 149 log.Exitf("Unable to spawn tree: %v", err) 150 } 151 cmd.Wait() 152 }