github.com/mier85/go-sensor@v1.30.1-0.20220920111756-9bf41b3bc7e0/fsm_test.go (about)

     1  // (c) Copyright IBM Corp. 2022
     2  
     3  package instana
     4  
     5  import (
     6  	"errors"
     7  	"github.com/instana/testify/assert"
     8  	f "github.com/looplab/fsm"
     9  	"testing"
    10  	"time"
    11  )
    12  
    13  func Test_fsmS_testAgent(t *testing.T) {
    14  	// init channels for agent mock
    15  	rCh := make(chan string, 2)
    16  	errCh := make(chan error, 2)
    17  
    18  	res := make(chan bool, 1)
    19  
    20  	r := &fsmS{
    21  		agent: &mockFsmAgent{
    22  			headRequestResponse: rCh,
    23  			headRequestErr:      errCh,
    24  		},
    25  		fsm: f.NewFSM(
    26  			"announced",
    27  			f.Events{
    28  				{Name: eTest, Src: []string{"announced"}, Dst: "ready"}},
    29  			f.Callbacks{
    30  				"ready": func(event *f.Event) {
    31  					res <- true
    32  				},
    33  			}),
    34  		retriesLeft: maximumRetries,
    35  		expDelayFunc: func(retryNumber int) time.Duration {
    36  			return 0
    37  		},
    38  		logger: defaultLogger,
    39  	}
    40  
    41  	// simulate errors and successful requests
    42  	rCh <- ""
    43  	errCh <- errors.New("some error")
    44  
    45  	rCh <- "Hello"
    46  	errCh <- nil
    47  
    48  	r.testAgent(&f.Event{})
    49  
    50  	assert.True(t, <-res)
    51  	assert.Empty(t, rCh)
    52  	assert.Empty(t, errCh)
    53  	assert.Equal(t, maximumRetries, r.retriesLeft)
    54  }
    55  
    56  func Test_fsmS_testAgent_Error(t *testing.T) {
    57  	// init channels for agent mock
    58  	rCh := make(chan string, 3)
    59  	errCh := make(chan error, 3)
    60  
    61  	res := make(chan bool, 1)
    62  
    63  	r := &fsmS{
    64  		agent: &mockFsmAgent{
    65  			headRequestResponse: rCh,
    66  			headRequestErr:      errCh,
    67  		},
    68  		fsm: f.NewFSM(
    69  			"announced",
    70  			f.Events{
    71  				{Name: eInit, Src: []string{"announced"}, Dst: "init"}},
    72  			f.Callbacks{
    73  				"init": func(event *f.Event) {
    74  					res <- true
    75  				},
    76  			}),
    77  		retriesLeft: maximumRetries,
    78  		expDelayFunc: func(retryNumber int) time.Duration {
    79  			return 0
    80  		},
    81  		logger: defaultLogger,
    82  	}
    83  
    84  	// simulate errors
    85  	rCh <- ""
    86  	errCh <- errors.New("error #1")
    87  	rCh <- ""
    88  	errCh <- errors.New("error #2")
    89  	rCh <- ""
    90  	errCh <- errors.New("error #3")
    91  
    92  	r.testAgent(&f.Event{})
    93  
    94  	assert.True(t, <-res)
    95  	assert.Empty(t, rCh)
    96  	assert.Empty(t, errCh)
    97  	assert.Equal(t, 0, r.retriesLeft)
    98  }
    99  
   100  func Test_fsmS_announceSensor(t *testing.T) {
   101  	// init channels for agent mock
   102  	rCh := make(chan string, 2)
   103  	errCh := make(chan error, 2)
   104  
   105  	res := make(chan bool, 1)
   106  
   107  	r := &fsmS{
   108  		agent: &mockFsmAgent{
   109  			announceRequestResponse: rCh,
   110  			announceRequestErr:      errCh,
   111  		},
   112  		fsm: f.NewFSM(
   113  			"unannounced",
   114  			f.Events{
   115  				{Name: eAnnounce, Src: []string{"unannounced"}, Dst: "announced"}},
   116  			f.Callbacks{
   117  				"announced": func(event *f.Event) {
   118  					res <- true
   119  				},
   120  			}),
   121  		retriesLeft: maximumRetries,
   122  		expDelayFunc: func(retryNumber int) time.Duration {
   123  			return 0
   124  		},
   125  		logger: defaultLogger,
   126  	}
   127  
   128  	// simulate errors and successful requests
   129  	rCh <- ""
   130  	errCh <- errors.New("some error")
   131  
   132  	rCh <- "Hello"
   133  	errCh <- nil
   134  
   135  	r.announceSensor(&f.Event{})
   136  
   137  	assert.True(t, <-res)
   138  	assert.Empty(t, rCh)
   139  	assert.Empty(t, errCh)
   140  	assert.Equal(t, maximumRetries, r.retriesLeft)
   141  }
   142  
   143  func Test_fsmS_announceSensor_Error(t *testing.T) {
   144  	// init channels for agent mock
   145  	rCh := make(chan string, 3)
   146  	errCh := make(chan error, 3)
   147  
   148  	res := make(chan bool, 1)
   149  
   150  	r := &fsmS{
   151  		agent: &mockFsmAgent{
   152  			announceRequestResponse: rCh,
   153  			announceRequestErr:      errCh,
   154  		},
   155  		fsm: f.NewFSM(
   156  			"unannounced",
   157  			f.Events{
   158  				{Name: eInit, Src: []string{"unannounced"}, Dst: "init"}},
   159  			f.Callbacks{
   160  				"init": func(event *f.Event) {
   161  					res <- true
   162  				},
   163  			}),
   164  		retriesLeft: maximumRetries,
   165  		expDelayFunc: func(retryNumber int) time.Duration {
   166  			return 0
   167  		},
   168  		logger: defaultLogger,
   169  	}
   170  
   171  	// simulate errors
   172  	rCh <- ""
   173  	errCh <- errors.New("error #1")
   174  	rCh <- ""
   175  	errCh <- errors.New("error #2")
   176  	rCh <- ""
   177  	errCh <- errors.New("error #3")
   178  
   179  	r.announceSensor(&f.Event{})
   180  
   181  	assert.True(t, <-res)
   182  	assert.Empty(t, rCh)
   183  	assert.Empty(t, errCh)
   184  	assert.Equal(t, 0, r.retriesLeft)
   185  }
   186  
   187  func Test_fsmS_lookupAgentHost(t *testing.T) {
   188  	// init channels for agent mock
   189  	rCh := make(chan string, 2)
   190  	errCh := make(chan error, 2)
   191  
   192  	res := make(chan bool, 1)
   193  
   194  	r := &fsmS{
   195  		agent: &mockFsmAgent{
   196  			requestHeaderResponse: rCh,
   197  			requestHeaderErr:      errCh,
   198  		},
   199  		lookupAgentHostRetryPeriod: 0,
   200  		fsm: f.NewFSM(
   201  			"init",
   202  			f.Events{
   203  				{Name: eLookup, Src: []string{"init"}, Dst: "unannounced"}},
   204  			f.Callbacks{
   205  				"enter_unannounced": func(event *f.Event) {
   206  					res <- true
   207  				},
   208  			}),
   209  		retriesLeft: maximumRetries,
   210  		expDelayFunc: func(retryNumber int) time.Duration {
   211  			return 0
   212  		},
   213  		logger: defaultLogger,
   214  	}
   215  
   216  	// simulate errors and successful requests
   217  	rCh <- ""
   218  	errCh <- errors.New("some error")
   219  
   220  	rCh <- agentHeader
   221  	errCh <- nil
   222  
   223  	r.lookupAgentHost(&f.Event{})
   224  
   225  	assert.True(t, <-res)
   226  	assert.Empty(t, rCh)
   227  	assert.Empty(t, errCh)
   228  	assert.Equal(t, maximumRetries, r.retriesLeft)
   229  }
   230  
   231  type mockFsmAgent struct {
   232  	host string
   233  
   234  	requestHeaderResponse chan string
   235  	requestHeaderErr      chan error
   236  
   237  	announceRequestResponse chan string
   238  	announceRequestErr      chan error
   239  
   240  	headRequestResponse chan string
   241  	headRequestErr      chan error
   242  }
   243  
   244  func (a *mockFsmAgent) getHost() string {
   245  	return a.host
   246  }
   247  
   248  func (a *mockFsmAgent) setHost(host string) {
   249  	a.host = host
   250  }
   251  
   252  func (a *mockFsmAgent) requestHeader(url string, method string, header string) (string, error) {
   253  	return <-a.requestHeaderResponse, <-a.requestHeaderErr
   254  }
   255  
   256  func (a *mockFsmAgent) makeHostURL(host string, prefix string) string {
   257  	return "http://" + host + ":5555" + prefix
   258  }
   259  
   260  func (a *mockFsmAgent) applyHostAgentSettings(resp agentResponse) {
   261  	return
   262  }
   263  
   264  func (a *mockFsmAgent) announceRequest(url string, method string, data interface{}, ret *agentResponse) (string, error) {
   265  	return <-a.announceRequestResponse, <-a.announceRequestErr
   266  }
   267  
   268  func (a *mockFsmAgent) makeURL(prefix string) string {
   269  	return a.makeHostURL(a.getHost(), prefix)
   270  }
   271  
   272  func (a *mockFsmAgent) head(url string) (string, error) {
   273  	return <-a.headRequestResponse, <-a.headRequestErr
   274  }