Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ObserveCompositeTimeStampTest failed when running with java 17+ #1575

Closed
sbernard31 opened this issue Jan 16, 2024 · 1 comment
Closed

ObserveCompositeTimeStampTest failed when running with java 17+ #1575

sbernard31 opened this issue Jan 16, 2024 · 1 comment

Comments

@sbernard31
Copy link
Contributor

sbernard31 commented Jan 16, 2024

The nightly build execute tests with java 8, 11, 17, 21 :

And it failed with error like :

[ERROR] org.eclipse.leshan.integration.tests.observe.ObserveCompositeTimeStampTest.can_observecomposite_timestamped_resource(ContentFormat, String)[2] -- Time elapsed: 0.038 s <<< FAILURE!
org.opentest4j.AssertionFailedError: 

expected: TimestampedLwM2mNodes [{2024-01-15T22:12:20.975151116Z={/3/0/15=LwM2mSingleResource [id=15, value=Europe/Paris, type=STRING], /1/0/1=LwM2mSingleResource [id=1, value=500, type=INTEGER]}, 2024-01-15T22:45:40.975150227Z={/3/0/15=LwM2mSingleResource [id=15, value=Europe/Belgrade, type=STRING], /1/0/1=LwM2mSingleResource [id=1, value=3600, type=INTEGER]}}]
 but was: TimestampedLwM2mNodes [{2024-01-15T22:12:20.975151Z={/3/0/15=LwM2mSingleResource [id=15, value=Europe/Paris, type=STRING], /1/0/1=LwM2mSingleResource [id=1, value=500, type=INTEGER]}, 2024-01-15T22:45:40.975150Z={/3/0/15=LwM2mSingleResource [id=15, value=Europe/Belgrade, type=STRING], /1/0/1=LwM2mSingleResource [id=1, value=3600, type=INTEGER]}}]
	at jdk.internal.reflect.GeneratedConstructorAccessor61.newInstance(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
	at org.eclipse.leshan.integration.tests.observe.ObserveCompositeTimeStampTest.can_observecomposite_timestamped_nodes(ObserveCompositeTimeStampTest.java:276)
	at org.eclipse.leshan.integration.tests.observe.ObserveCompositeTimeStampTest.can_observecomposite_timestamped_resource(ObserveCompositeTimeStampTest.java:142)

It seems there is some timestamps precision issue :

expected: TimestampedLwM2mNodes [{2024-01-15T22:12:20.975151116Z={/3/0/15=LwM2mSingleResource [id=15, value=Europe/Paris, type=STRING], /1/0/1=LwM2mSingleResource [id=1, value=500, type=INTEGER]}, 2024-01-15T22:45:40.975150227Z={/3/0/15=LwM2mSingleResource [id=15, value=Europe/Belgrade, type=STRING], /1/0/1=LwM2mSingleResource [id=1, value=3600, type=INTEGER]}}]
 but was: TimestampedLwM2mNodes [{2024-01-15T22:12:20.975151Z={/3/0/15=LwM2mSingleResource [id=15, value=Europe/Paris, type=STRING], /1/0/1=LwM2mSingleResource [id=1, value=500, type=INTEGER]}, 2024-01-15T22:45:40.975150Z={/3/0/15=LwM2mSingleResource [id=15, value=Europe/Belgrade, type=STRING], /1/0/1=LwM2mSingleResource [id=1, value=3600, type=INTEGER]}}]
expected: TimestampedLwM2mNodes [{2024-01-15T22:12:21.013572465Z={/3/0/15=null, /1/0/1=LwM2mSingleResource [id=1, value=500, type=INTEGER]}, 2024-01-15T22:45:41.013571542Z={/3/0/15=LwM2mSingleResource [id=15, value=Europe/Belgrade, type=STRING], /1/0/1=null}}]
 but was: TimestampedLwM2mNodes [{2024-01-15T22:12:21.013572500Z={/3/0/15=null, /1/0/1=LwM2mSingleResource [id=1, value=500, type=INTEGER]}, 2024-01-15T22:45:41.013571500Z={/3/0/15=LwM2mSingleResource [id=15, value=Europe/Belgrade, type=STRING], /1/0/1=null}}]

See : https://ci.eclipse.org/leshan/job/leshan-nightly/job/master/32/consoleFull

If seems that Instant.now() precision changed : https://stackoverflow.com/questions/74781495/changes-in-instant-now-between-java-11-and-java-17-in-aws-ubuntu-standard-6-0

@sbernard31
Copy link
Contributor Author

sbernard31 commented Jan 16, 2024

Explanation :
Since Java17, Instant.now.() has nano precision (at least on linux) where before it was just a millisecond precision.

Tests based on SenML JSON, failed because by default Jackson cast number in double and so lost some precision when nanoseconds are used. (and so equality test failed)

Solutions :
I see 2 possible ways to fix this :

  • a) change the JSON deserializer config to not lost precision using BigDecimal instead of double : using ObjectMapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true) to be able to handle nanoseconds.
  • b) change test to use milliseconds precision in tests.

I don't think a) is a good default behavior because :

  1. I think nanoseconds usecase is not so common (I could be wrong on that one)
  2. It seems that using BIG DECIMAL FOR FLOATS is slower.
  3. SenML/JSON spec says that floating point should be IEEE 754 binary64 (double precision) number. (see Timestamps in seconds or milliseconds ? #1304 (comment) and Safe number convertion ? #1317)

(Note that SenML CBOR test pass and I think that ideally by default it should not for same reason than 3.)

Fix :
Solution b) was implemented in master commit 9693a3d and so now jenkins build pass : https://ci.eclipse.org/leshan/job/leshan-nightly/job/master/33/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant