-
Notifications
You must be signed in to change notification settings - Fork 179
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
Unable to resolve expression during build #1306
Comments
I don't yet know what's the reason, but at least I know how to reproduce it. Now test will be re-running endlessly, and sooner or later will fail with the expected error. |
@RVRhub I remember you also mentioned some findings about this |
@bodiam @snuyanzin I could reproduce the failure, but still don't understand why it happens. |
I'm good with that 👆 Though I'm not exactly an authority for the project 😁 |
I don't mind that, but perhaps for narrowing down the problem here only? It's probably not something we need to merge right, the debugging can happen on a branch? |
@bodiam It depends on the logging itself. But generally I think it's a good idea to add the logging to main branch. |
Yes, this is one of my findings too. And proper logging would help to find this issue sooner. ;) |
@asolntsev See screenshot. There is a log message exactly there: But I think it's related to the initial problem, since the above exception happens when some method returns null. In this case, null is returned when we get the NPE. Why do we get the NPE? I have no idea yet. |
As a rule, exceptions must be logged with stack trace: Then we would know why it happens. Anyway, I am working on it. |
it's a simplified version of what happens with FakeValuesService.MAP_OF_METHOD_AND_COERCED_ARGS
it's a simplified version of what happens with FakeValuesService.MAP_OF_METHOD_AND_COERCED_ARGS
@bodiam @snuyanzin After some investigation, I came to a conclusion that this is a bug in I reproduced this problem in a dedicated unit-tests here: #1310 P.S. This is how final Map<String, Map<String[], MethodAndCoercedArgs>> stringMapMap =
MAP_OF_METHOD_AND_COERCED_ARGS.computeIfAbsent(clazz, t -> new CopyOnWriteMap<>(WeakHashMap::new));
// Step 1: we PUT value to map, but...
stringMapMap.putIfAbsent(methodName, new CopyOnWriteMap<>(WeakHashMap::new));
// Step 2: `map.get` returns NULL!
stringMapMap.get(methodName).putIfAbsent(args, accessor); // here `stringMapMap.get(methodName)` is NULL Assumably, null is returned after GC run. |
…olver) it allows to log what objects were returned when debugging flaky test failures.
... to make it easier to read these values in logs
... especially with FINE level (== DEBUG). This pattern causes flaky failures that are very hard to debug. If something went wrong, it's always safer to throw it with a clear description of what happened. See "Throw early, catch late" principle.
…fore() It was WTF moment when I realized that method BaseFakerTest.before() resets all logger levels to INFO. It took few hours to find out why my logging configuration doesn't work. :(
* by default, FINE logs are NOT written to console, BUT * if some test failed, all its FINE logs are written to console. Thus we can investigate flaky tests.
there is no need to initialize static Faker's vars in some specific way. They should stably work in any order.
... especially with FINE level (== DEBUG). This pattern causes flaky failures that are very hard to debug. If something went wrong, it's always safer to throw it with a clear description of what happened. See "Throw early, catch late" principle.
…fore() It was WTF moment when I realized that method BaseFakerTest.before() resets all logger levels to INFO. It took few hours to find out why my logging configuration doesn't work. :(
* by default, FINE logs are NOT written to console, BUT * if some test failed, all its FINE logs are written to console. Thus we can investigate flaky tests.
there is no need to initialize static Faker's vars in some specific way. They should stably work in any order.
My recommendation:
|
Instead of two separate calls `putIfAbsent` and `get`, now we use `computeIfAbsent`. Before this change, `get` sometimes returned null (apparently, because of GC or parallel threads or something similar).
…ervice Instead of three separate calls `containsKey`, `get` and `put`, now we use a single `computeIfAbsent`.
this partially reverts commit 43e1fff
…olver) it allows to log what objects were returned when debugging flaky test failures.
... to make it easier to read these values in logs
... especially with FINE level (== DEBUG). This pattern causes flaky failures that are very hard to debug. If something went wrong, it's always safer to throw it with a clear description of what happened. See "Throw early, catch late" principle.
…fore() It was WTF moment when I realized that method BaseFakerTest.before() resets all logger levels to INFO. It took few hours to find out why my logging configuration doesn't work. :(
* by default, FINE logs are NOT written to console, BUT * if some test failed, all its FINE logs are written to console. Thus we can investigate flaky tests.
there is no need to initialize static Faker's vars in some specific way. They should stably work in any order.
…olver) it allows to log what objects were returned when debugging flaky test failures.
... to make it easier to read these values in logs
... especially with FINE level (== DEBUG). This pattern causes flaky failures that are very hard to debug. If something went wrong, it's always safer to throw it with a clear description of what happened. See "Throw early, catch late" principle.
…fore() It was WTF moment when I realized that method BaseFakerTest.before() resets all logger levels to INFO. It took few hours to find out why my logging configuration doesn't work. :(
* by default, FINE logs are NOT written to console, BUT * if some test failed, all its FINE logs are written to console. Thus we can investigate flaky tests.
there is no need to initialize static Faker's vars in some specific way. They should stably work in any order.
Instead of two-three separate calls like `containsKey`, `get` and `put`, now we use a single `computeIfAbsent`.
Instead of two-three separate calls like `containsKey`, `get` and `put`, now we use a single `computeIfAbsent`. P.S. I would like to also deny method `CopyOnWriteMap.put()`, but it's still used in one place (that was harder to refactor).
Instead of two-three separate calls like `containsKey`, `get` and `put`, now we use a single `computeIfAbsent`. P.S. I would like to also deny method `CopyOnWriteMap.put()`, but it's still used in one place (that was harder to refactor).
Hi all,
I have another build where an expression couldn't be resolved:
https://github.com/datafaker-net/datafaker/actions/runs/9940728395/job/27458128814?pr=1305
I was hoping it was resolved in one of the earlier 2.3.x PRs, but it seems it's still happening, I had a few failures earlier today too.
If someone could have a look, that would be great!
The text was updated successfully, but these errors were encountered: