Skip to content

Commit

Permalink
Option for sample interval (#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
DanG100 authored Sep 13, 2023
1 parent d36b514 commit 4b6649a
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 7 deletions.
3 changes: 2 additions & 1 deletion ygnmi/gnmi.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ func subscribe[T any](ctx context.Context, c *Client, q AnyQuery[T], mode gpb.Su
Elem: path.GetElem(),
Origin: path.GetOrigin(),
},
Mode: o.mode,
Mode: o.mode,
SampleInterval: o.sampleInterval,
})
}

Expand Down
22 changes: 17 additions & 5 deletions ygnmi/ygnmi.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,12 @@ func NewClient(c gpb.GNMIClient, opts ...ClientOption) (*Client, error) {
type Option func(*opt)

type opt struct {
useGet bool
mode gpb.SubscriptionMode
encoding gpb.Encoding
preferProto bool
setFallback bool
useGet bool
mode gpb.SubscriptionMode
encoding gpb.Encoding
preferProto bool
setFallback bool
sampleInterval uint64
}

// resolveOpts applies all the options and returns a struct containing the result.
Expand All @@ -211,12 +212,23 @@ func WithUseGet() Option {

// WithSubscriptionMode creates an option to use input instead of the default (TARGET_DEFINED).
// This option is only relevant for Watch, WatchAll, Collect, CollectAll, Await which are STREAM subscriptions.
// The mode applies to all paths in the Subcription.
func WithSubscriptionMode(mode gpb.SubscriptionMode) Option {
return func(o *opt) {
o.mode = mode
}
}

// WithSampleInterval creates an option to set the sample interval in the Subcribe request.
// NOTE: The subscription mode must be set to SAMPLE for this to have an effect.
// This option is only relevant for Watch, WatchAll, Collect, CollectAll, Await which are STREAM subscriptions.
// The mode applies to all paths in the Subcription.
func WithSampleInterval(d time.Duration) Option {
return func(o *opt) {
o.sampleInterval = uint64(d.Nanoseconds())
}
}

// WithEncoding creates an option to set the Encoding for all Subscribe or Get requests.
// The default encoding is PROTO. This does not apply when using WithUseGet, whith uses JSON_IETF encoding.
func WithEncoding(enc gpb.Encoding) Option {
Expand Down
52 changes: 51 additions & 1 deletion ygnmi/ygnmi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ func getCheckFn[T any](t *testing.T, fakeGNMI *testutil.FakeGNMI, c *ygnmi.Clien
}
}

func watchCheckFn[T any](t *testing.T, fakeGNMI *testutil.FakeGNMI, duration time.Duration, c *ygnmi.Client, inQuery ygnmi.SingletonQuery[T], inOpts []ygnmi.Option, valPred func(T) bool, wantErrSubstring string, wantSubscriptionPath *gpb.Path, wantMode gpb.SubscriptionMode, wantVals []*ygnmi.Value[T], wantLastVal *ygnmi.Value[T]) {
func watchCheckFn[T any](t *testing.T, fakeGNMI *testutil.FakeGNMI, duration time.Duration, c *ygnmi.Client, inQuery ygnmi.SingletonQuery[T],
inOpts []ygnmi.Option, valPred func(T) bool, wantErrSubstring string, wantSubscriptionPath *gpb.Path, wantMode gpb.SubscriptionMode, wantInterval uint64, wantVals []*ygnmi.Value[T], wantLastVal *ygnmi.Value[T]) {
t.Helper()
i := 0
ctx, cancel := context.WithTimeout(context.Background(), duration)
Expand Down Expand Up @@ -192,6 +193,7 @@ func watchCheckFn[T any](t *testing.T, fakeGNMI *testutil.FakeGNMI, duration tim
}
verifySubscriptionPathsSent(t, fakeGNMI, wantSubscriptionPath)
verifySubscriptionModesSent(t, fakeGNMI, wantMode)
verifySubscriptionSampleIntervalsSent(t, fakeGNMI, wantInterval)
if val != nil {
checkJustReceived(t, val.RecvTimestamp)
wantLastVal.RecvTimestamp = val.RecvTimestamp
Expand Down Expand Up @@ -1176,6 +1178,7 @@ func TestWatch(t *testing.T) {
wantVals []*ygnmi.Value[string]
wantErr string
wantMode gpb.SubscriptionMode
wantInterval uint64
opts []ygnmi.Option
}{{
desc: "single notif and pred true",
Expand Down Expand Up @@ -1223,6 +1226,30 @@ func TestWatch(t *testing.T) {
Timestamp: startTime,
Path: path,
}).SetVal("foo"),
}, {
desc: "single notif and pred true with custom interval",
stub: func(s *testutil.Stubber) {
s.Notification(&gpb.Notification{
Timestamp: startTime.UnixNano(),
Update: []*gpb.Update{{
Path: path,
Val: &gpb.TypedValue{Value: &gpb.TypedValue_StringVal{StringVal: "foo"}},
}},
}).Sync()
},
dur: time.Second,
opts: []ygnmi.Option{ygnmi.WithSampleInterval(time.Millisecond)},
wantInterval: 1000000,
wantVals: []*ygnmi.Value[string]{
(&ygnmi.Value[string]{
Timestamp: startTime,
Path: path,
}).SetVal("foo")},
wantSubscriptionPath: path,
wantLastVal: (&ygnmi.Value[string]{
Timestamp: startTime,
Path: path,
}).SetVal("foo"),
}, {
desc: "single notif and pred false error EOF",
stub: func(s *testutil.Stubber) {
Expand Down Expand Up @@ -1329,6 +1356,7 @@ func TestWatch(t *testing.T) {
tt.wantErr,
tt.wantSubscriptionPath,
tt.wantMode,
tt.wantInterval,
tt.wantVals,
tt.wantLastVal,
)
Expand Down Expand Up @@ -1560,6 +1588,7 @@ func TestWatch(t *testing.T) {
tt.wantErr,
tt.wantSubscriptionPath,
gpb.SubscriptionMode_TARGET_DEFINED,
0,
tt.wantVals,
tt.wantLastVal,
)
Expand Down Expand Up @@ -1634,6 +1663,7 @@ func TestWatch(t *testing.T) {
"",
testutil.GNMIPath(t, "/model/a/single-key[key=foo]/ordered-lists"),
gpb.SubscriptionMode_TARGET_DEFINED,
0,
[]*ygnmi.Value[*exampleoc.Model_SingleKey_OrderedList_OrderedMap]{
(&ygnmi.Value[*exampleoc.Model_SingleKey_OrderedList_OrderedMap]{
Path: testutil.GNMIPath(t, "/model/a/single-key[key=foo]/ordered-lists"),
Expand Down Expand Up @@ -1717,6 +1747,7 @@ func TestWatch(t *testing.T) {
"",
testutil.GNMIPath(t, "/model/a"),
gpb.SubscriptionMode_TARGET_DEFINED,
0,
[]*ygnmi.Value[map[string]*exampleoc.Model_SingleKey]{
(&ygnmi.Value[map[string]*exampleoc.Model_SingleKey]{
Path: testutil.GNMIPath(t, "/model/a"),
Expand Down Expand Up @@ -4447,6 +4478,25 @@ func verifySubscriptionModesSent(t *testing.T, fakeGNMI *testutil.FakeGNMI, want
}
}

// verifySubscriptionSampleIntervalsSent verifies the modes of the sent subscription requests is the same as wantModes.
func verifySubscriptionSampleIntervalsSent(t *testing.T, fakeGNMI *testutil.FakeGNMI, wantIntervals ...uint64) {
t.Helper()
requests := fakeGNMI.Requests()
if len(requests) != 1 {
t.Errorf("Number of subscription requests sent is not 1: %v", requests)
return
}

var gotIntervals []uint64
req := requests[0].GetSubscribe()
for _, sub := range req.GetSubscription() {
gotIntervals = append(gotIntervals, sub.SampleInterval)
}
if diff := cmp.Diff(wantIntervals, gotIntervals); diff != "" {
t.Errorf("Subscription sample intervals (-want, +got):\n%s", diff)
}
}

type gnmiS struct {
gpb.UnimplementedGNMIServer
errCh chan error
Expand Down

0 comments on commit 4b6649a

Please sign in to comment.