github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/aagent/watchers/gossipwatcher/gossip_test.go (about)

     1  // Copyright (c) 2022-2024, R.I. Pienaar and the Choria Project contributors
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  
     5  package gossipwatcher
     6  
     7  import (
     8  	"encoding/json"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/choria-io/go-choria/aagent/model"
    13  	"github.com/golang/mock/gomock"
    14  	. "github.com/onsi/ginkgo/v2"
    15  	. "github.com/onsi/gomega"
    16  )
    17  
    18  func Test(t *testing.T) {
    19  	RegisterFailHandler(Fail)
    20  	RunSpecs(t, "AAgent/Watchers/ExecWatcher")
    21  }
    22  
    23  var _ = Describe("ExecWatcher", func() {
    24  	var (
    25  		mockctl     *gomock.Controller
    26  		mockMachine *model.MockMachine
    27  		watch       *Watcher
    28  		now         time.Time
    29  	)
    30  
    31  	BeforeEach(func() {
    32  		mockctl = gomock.NewController(GinkgoT())
    33  		mockMachine = model.NewMockMachine(mockctl)
    34  
    35  		mockMachine.EXPECT().Name().Return("gossip").AnyTimes()
    36  		mockMachine.EXPECT().Identity().Return("ginkgo").AnyTimes()
    37  		mockMachine.EXPECT().InstanceID().Return("1234567890").AnyTimes()
    38  		mockMachine.EXPECT().Version().Return("1.0.0").AnyTimes()
    39  		mockMachine.EXPECT().TimeStampSeconds().Return(now.Unix()).AnyTimes()
    40  		mockMachine.EXPECT().Debugf(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
    41  		mockMachine.EXPECT().Infof(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
    42  
    43  		now = time.Unix(1606924953, 0)
    44  
    45  		wi, err := New(mockMachine, "ginkgo", []string{"always"}, "fail", "success", "10s", time.Second, map[string]any{
    46  			"subject": "foo.bar",
    47  			"payload": "msg.msg",
    48  		})
    49  		Expect(err).ToNot(HaveOccurred())
    50  		watch = wi.(*Watcher)
    51  	})
    52  
    53  	AfterEach(func() {
    54  		mockctl.Finish()
    55  	})
    56  
    57  	Describe("setProperties", func() {
    58  		It("Should parse valid properties", func() {
    59  			prop := map[string]any{
    60  				"subject": "foo.bar",
    61  				"payload": "pay.load",
    62  			}
    63  			Expect(watch.setProperties(prop)).To(Succeed())
    64  			Expect(watch.properties.Subject).To(Equal("foo.bar"))
    65  			Expect(watch.properties.Payload).To(Equal("pay.load"))
    66  			Expect(watch.properties.Registration).To(BeNil())
    67  
    68  			prop = map[string]any{
    69  				"registration": map[string]any{
    70  					"cluster":  "lon",
    71  					"service":  "ginkgo",
    72  					"protocol": "http",
    73  					"ip":       "192.168.1.1",
    74  					"port":     8080,
    75  					"priority": 1,
    76  					"annotations": map[string]string{
    77  						"test": "annotation",
    78  					},
    79  				},
    80  			}
    81  
    82  			watch.properties = nil
    83  			Expect(watch.setProperties(prop)).To(Succeed())
    84  			Expect(watch.properties.Registration).To(Equal(&Registration{
    85  				Cluster:  "lon",
    86  				Service:  "ginkgo",
    87  				Protocol: "http",
    88  				IP:       "192.168.1.1",
    89  				Port:     8080,
    90  				Priority: 1,
    91  				Annotations: map[string]string{
    92  					"test": "annotation",
    93  				},
    94  			}))
    95  
    96  			rj, err := json.Marshal(watch.properties.Registration)
    97  			Expect(err).ToNot(HaveOccurred())
    98  
    99  			Expect(watch.machine.InstanceID()).To(Equal("1234567890"))
   100  			Expect(watch.properties.Subject).To(Equal("$KV.CHORIA_SERVICES.lon.http.ginkgo.1234567890"))
   101  			Expect(watch.properties.Payload).To(Equal(string(rj)))
   102  		})
   103  
   104  		It("Should handle errors", func() {
   105  			watch.properties = nil
   106  			err := watch.setProperties(map[string]any{})
   107  			Expect(err).To(MatchError("subject is required"))
   108  
   109  			watch.properties = nil
   110  			err = watch.setProperties(map[string]any{
   111  				"subject": "foo.bar",
   112  			})
   113  			Expect(err).To(MatchError("payload is required"))
   114  		})
   115  	})
   116  
   117  	Describe("CurrentState", func() {
   118  		It("Should be a valid state", func() {
   119  			watch.lastSubject = "x.y"
   120  			watch.lastPayload = "a.b"
   121  			watch.lastGossip = now
   122  
   123  			cs := watch.CurrentState()
   124  			csj, err := cs.(*StateNotification).JSON()
   125  			Expect(err).ToNot(HaveOccurred())
   126  
   127  			event := map[string]any{}
   128  			err = json.Unmarshal(csj, &event)
   129  			Expect(err).ToNot(HaveOccurred())
   130  			delete(event, "id")
   131  
   132  			Expect(event).To(Equal(map[string]any{
   133  				"time":            "2020-12-02T16:02:33Z",
   134  				"type":            "io.choria.machine.watcher.gossip.v1.state",
   135  				"subject":         "ginkgo",
   136  				"specversion":     "1.0",
   137  				"source":          "io.choria.machine",
   138  				"datacontenttype": "application/json",
   139  				"data": map[string]any{
   140  					"previous_subject": "x.y",
   141  					"previous_payload": "a.b",
   142  					"previous_gossip":  float64(now.Unix()),
   143  					"id":               "1234567890",
   144  					"identity":         "ginkgo",
   145  					"machine":          "gossip",
   146  					"name":             "ginkgo",
   147  					"protocol":         "io.choria.machine.watcher.gossip.v1.state",
   148  					"type":             "gossip",
   149  					"version":          "1.0.0",
   150  					"timestamp":        float64(now.Unix()),
   151  				},
   152  			}))
   153  		})
   154  	})
   155  })