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  }