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

     1  // Copyright (c) 2020-2022, R.I. Pienaar and the Choria Project contributors
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  
     5  package schedulewatcher
     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/ScheduleWatcher")
    21  }
    22  
    23  var _ = Describe("ScheduleWatcher", 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  		now = time.Unix(1606924953, 0)
    36  		mockMachine.EXPECT().Name().Return("schedule").AnyTimes()
    37  		mockMachine.EXPECT().Identity().Return("ginkgo").AnyTimes()
    38  		mockMachine.EXPECT().InstanceID().Return("1234567890").AnyTimes()
    39  		mockMachine.EXPECT().Version().Return("1.0.0").AnyTimes()
    40  		mockMachine.EXPECT().TimeStampSeconds().Return(now.Unix()).AnyTimes()
    41  
    42  		wi, err := New(mockMachine, "ginkgo", []string{"always"}, "fail", "success", "2m", time.Second, map[string]any{
    43  			"schedules": []string{"1 * * * *"},
    44  		})
    45  		Expect(err).ToNot(HaveOccurred())
    46  		watch = wi.(*Watcher)
    47  		watch.properties = nil
    48  		watch.items = []*scheduleItem{}
    49  		watch.state = On
    50  	})
    51  
    52  	AfterEach(func() {
    53  		mockctl.Finish()
    54  	})
    55  
    56  	Describe("setProperties", func() {
    57  		It("Should parse valid properties", func() {
    58  			err := watch.setProperties(map[string]any{
    59  				"duration":  "1h",
    60  				"schedules": []string{"* * * * *", "1 * * * *"},
    61  			})
    62  			Expect(err).ToNot(HaveOccurred())
    63  			Expect(watch.properties.Duration).To(Equal(time.Hour))
    64  			Expect(watch.properties.Schedules).To(HaveLen(2))
    65  			Expect(watch.items).To(HaveLen(2))
    66  			Expect(watch.items[0].spec).To(Equal("* * * * *"))
    67  			Expect(watch.items[1].spec).To(Equal("1 * * * *"))
    68  		})
    69  
    70  		It("Should handle errors", func() {
    71  			err := watch.setProperties(map[string]any{})
    72  			Expect(err).To(MatchError("no schedules defined"))
    73  
    74  			watch.properties = nil
    75  			err = watch.setProperties(map[string]any{
    76  				"schedules": []string{"* * * * *", "1 * * * *"},
    77  			})
    78  			Expect(err).ToNot(HaveOccurred())
    79  			Expect(watch.properties.Duration).To(Equal(time.Minute))
    80  			Expect(watch.items).To(HaveLen(2))
    81  			Expect(watch.properties.Schedules).To(HaveLen(2))
    82  		})
    83  
    84  		It("Should handle startup splays", func() {
    85  			err := watch.setProperties(map[string]any{
    86  				"start_splay": "1m",
    87  				"duration":    "1m",
    88  				"schedules":   []string{"* * * * *", "1 * * * *"},
    89  			})
    90  			Expect(err).To(MatchError("start splay 1m0s is bigger than half the duration 1m0s"))
    91  
    92  			err = watch.setProperties(map[string]any{
    93  				"start_splay": "10s",
    94  				"duration":    "1m",
    95  				"schedules":   []string{"* * * * *", "1 * * * *"},
    96  			})
    97  			Expect(err).ToNot(HaveOccurred())
    98  		})
    99  	})
   100  
   101  	Describe("CurrentState", func() {
   102  		It("Should be a valid state", func() {
   103  			cs := watch.CurrentState()
   104  			csj, err := cs.(*StateNotification).JSON()
   105  			Expect(err).ToNot(HaveOccurred())
   106  
   107  			event := map[string]any{}
   108  			err = json.Unmarshal(csj, &event)
   109  			Expect(err).ToNot(HaveOccurred())
   110  			delete(event, "id")
   111  
   112  			Expect(event).To(Equal(map[string]any{
   113  				"time":            "2020-12-02T16:02:33Z",
   114  				"type":            "io.choria.machine.watcher.schedule.v1.state",
   115  				"subject":         "ginkgo",
   116  				"specversion":     "1.0",
   117  				"source":          "io.choria.machine",
   118  				"datacontenttype": "application/json",
   119  				"data": map[string]any{
   120  					"id":        "1234567890",
   121  					"identity":  "ginkgo",
   122  					"machine":   "schedule",
   123  					"name":      "ginkgo",
   124  					"protocol":  "io.choria.machine.watcher.schedule.v1.state",
   125  					"type":      "schedule",
   126  					"version":   "1.0.0",
   127  					"timestamp": float64(now.Unix()),
   128  					"state":     "on",
   129  				},
   130  			}))
   131  		})
   132  	})
   133  })