Skip to content

Commit

Permalink
bugfix: do not apply transform function if reading value is nil
Browse files Browse the repository at this point in the history
  • Loading branch information
edaniszewski committed May 5, 2020
1 parent f7356cf commit f187b61
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 25 deletions.
56 changes: 32 additions & 24 deletions sdk/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -479,31 +479,39 @@ func (scheduler *scheduler) scheduleListen() {
// Device to produce the final reading result.
func finalizeReadings(device *Device, rctx *ReadContext) error {
for _, reading := range rctx.Reading {
// Apply all transformations to the reading, in the order in which
// they are defined. Typically, scale should happen before conversion,
// but ultimately, it is up to the configurer to ensure transformations
// are defined in the correct order.
for _, transformer := range device.Transforms {
devlog := log.WithFields(log.Fields{
"device": device.id,
"info": device.Info,
"transformer": transformer.Name(),
})

devlog.WithField(
"value", reading.Value,
).Debug("[scheduler] applying device reading transformer")

if err := transformer.Apply(reading); err != nil {
devlog.WithFields(log.Fields{
"error": err,
"value": reading.Value,
}).Error("[scheduler] failed to apply reading transformer")
return err
// A nil reading value indicates that there is no reading for a particular
// read. In such case, it does not make sense to apply any transformations,
// so skip that step.
if reading.Value != nil {

// Apply all transformations to the reading, in the order in which
// they are defined. Typically, scale should happen before conversion,
// but ultimately, it is up to the configurer to ensure transformations
// are defined in the correct order.
for _, transformer := range device.Transforms {
devlog := log.WithFields(log.Fields{
"device": device.id,
"info": device.Info,
"transformer": transformer.Name(),
})

devlog.WithField(
"value", reading.Value,
).Debug("[scheduler] applying device reading transformer")

if err := transformer.Apply(reading); err != nil {
devlog.WithFields(log.Fields{
"error": err,
"value": reading.Value,
}).Error("[scheduler] failed to apply reading transformer")
return err
}
devlog.WithField(
"value", reading.Value,
).Debug("[scheduler] new value after transform")
}
devlog.WithField(
"value", reading.Value,
).Debug("[scheduler] new value after transform")
} else {
log.Debug("[scheduler] reading value is nil; will not apply transform functions")
}

// Add any context that is specified by the device to the reading.
Expand Down
25 changes: 24 additions & 1 deletion sdk/scheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1019,9 +1019,32 @@ func TestScheduler_finalizeReadings_withContextAndTransform(t *testing.T) {
err := finalizeReadings(device, rctx)
assert.NoError(t, err)

// Verify that the reading value did not change.
// Verify that the reading value changed.
assert.Equal(t, float64(4), rctx.Reading[0].Value.(float64))

// Verify that the device context was set.
assert.Equal(t, map[string]string{"foo": "bar"}, rctx.Reading[0].Context)
}

func TestScheduler_finalizeReadings_nilReading(t *testing.T) {
device := &Device{
Transforms: []Transformer{
&ScaleTransformer{Factor: 2},
},
Context: map[string]string{"foo": "bar"},
}
rctx := &ReadContext{
Reading: []*output.Reading{
{Value: nil},
},
}

err := finalizeReadings(device, rctx)
assert.NoError(t, err)

// Verify that the reading value did not change.
assert.Equal(t, nil, rctx.Reading[0].Value)

// Verify that the device context was set.
assert.Equal(t, map[string]string{"foo": "bar"}, rctx.Reading[0].Context)
}

0 comments on commit f187b61

Please sign in to comment.