...

Source file src/github.com/chaos-mesh/chaos-mesh/test/pkg/timer/timer.go

Documentation: github.com/chaos-mesh/chaos-mesh/test/pkg/timer

     1  // Copyright 2021 Chaos Mesh Authors.
     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  
    16  package timer
    17  
    18  import (
    19  	"bufio"
    20  	"fmt"
    21  	"io"
    22  	"os/exec"
    23  	"strconv"
    24  	"strings"
    25  	"time"
    26  )
    27  
    28  // Timer represents a running timer process
    29  type Timer struct {
    30  	Stdin    io.WriteCloser
    31  	TimeChan chan TimeResult
    32  	process  *exec.Cmd
    33  	pid      int
    34  }
    35  
    36  // Pid returns the pid of timer
    37  func (timer *Timer) Pid() int {
    38  	return timer.pid
    39  }
    40  
    41  // TimeResult represents a get time result with an error
    42  type TimeResult struct {
    43  	Time  *time.Time
    44  	Error error
    45  }
    46  
    47  // StartTimer will start a timer process
    48  func StartTimer() (*Timer, error) {
    49  	process := exec.Command("./bin/test/timer")
    50  
    51  	stdout, err := process.StdoutPipe()
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  	stdoutScanner := bufio.NewScanner(stdout)
    56  
    57  	output := make(chan TimeResult)
    58  	go func() {
    59  		for stdoutScanner.Scan() {
    60  			line := stdoutScanner.Text()
    61  			sections := strings.Split(line, " ")
    62  
    63  			sec, err := strconv.ParseInt(sections[0], 10, 64)
    64  			if err != nil {
    65  				output <- TimeResult{
    66  					Error: err,
    67  				}
    68  			}
    69  			nsec, err := strconv.ParseInt(sections[1], 10, 64)
    70  			if err != nil {
    71  				output <- TimeResult{
    72  					Error: err,
    73  				}
    74  			}
    75  
    76  			t := time.Unix(sec, nsec)
    77  			output <- TimeResult{
    78  				Time: &t,
    79  			}
    80  		}
    81  		if err := stdoutScanner.Err(); err != nil {
    82  			output <- TimeResult{
    83  				Error: err,
    84  			}
    85  		}
    86  	}()
    87  
    88  	stdin, err := process.StdinPipe()
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  
    93  	err = process.Start()
    94  	if err != nil {
    95  		return nil, err
    96  	}
    97  
    98  	return &Timer{
    99  		Stdin:    stdin,
   100  		TimeChan: output,
   101  		pid:      process.Process.Pid,
   102  		process:  process,
   103  	}, nil
   104  }
   105  
   106  // GetTime will run `time.Now()` in timer
   107  func (timer *Timer) GetTime() (*time.Time, error) {
   108  	_, err := fmt.Fprintf(timer.Stdin, "\n")
   109  	if err != nil {
   110  		return nil, err
   111  	}
   112  
   113  	result := <-timer.TimeChan
   114  	if result.Error != nil {
   115  		return nil, result.Error
   116  	}
   117  
   118  	return result.Time, nil
   119  }
   120  
   121  // Stop stops the process
   122  func (timer *Timer) Stop() error {
   123  	_, err := fmt.Fprintf(timer.Stdin, "STOP\n")
   124  
   125  	return err
   126  }
   127