-
Notifications
You must be signed in to change notification settings - Fork 16
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
Rule information during integration testing #393
base: main
Are you sure you want to change the base?
Conversation
I think this prints the name of the rule only, and not the expression it was applied to. See
|
LGTM! Just have a few comments below to provide context on how we use
For example, here's how we log the parser: conjure-oxide/crates/conjure_core/src/parse/parse_model.rs Lines 14 to 24 in c00a2b5
conjure-oxide/crates/conjure_core/src/parse/parse_model.rs Lines 304 to 308 in c00a2b5
conjure-oxide/conjure_oxide/src/main.rs Lines 100 to 104 in c00a2b5
|
…an epxression at a time
@@ -347,9 +351,13 @@ fn apply_all_rules<'a>( | |||
/// } | |||
/// | |||
fn choose_rewrite(results: &[RuleResult]) -> Option<Reduction> { | |||
if results.len() > 1 { | |||
bug!("There should be only 1 rule that can be applied to an expression at a time"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good! if it actually happens we would probably also want to print the names of the rules etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also: let's see if it code coverage correctly ignores this line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This caused a lot of integration tests to fail, does that mean there is a problem with our rules or the if statement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course! I will have it print to the console for now and once I figure out the logging will implement that there
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh I was just meaning string concatanation to make the message you pass to bug! more descriptive. I'll check the failing tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, we need that message to tell us a bit more :)
it looks like multiple rules were applicable all over the place. good if statement!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest we separate the two changes, as they are orthogonal. adding tracing (which is what this PR started as) is one change, adding the if statement and working on its implications should be another PR.
To enable the following line |
The latter sounds right 👍 Note that tests run in parallel, so you might want to wrap your builder in a OnceLock: https://doc.rust-lang.org/std/sync/struct.OnceLock.html. This guarantees that the variable is initialised exactly once. |
Lazylock now exists, which seems much simpler than Oncelock |
We want a separate log file per integration test, that is checked like we checked the other 3 files (expected/output style). Keep that in mind as well when choosing a logging library. |
I have managed to capture the trace from
|
This does not produce an error though, only when I use tracing::subscriber.set_global it panics and says that a global one already exists. I was just wondering where is the global one defined in our repo so I could maybe try adding mother target to it? |
Sorry, I deleted my message as I looked deeper into the library you used and it does seem like the right tool for the job! |
Do we need a global logger? Does having the scoped ones as you've shown above work? |
It only works if I put the function call inside the brackets of tracing::subscriber which leads to many issues, like inability to use |
It might be easier to use the logger for the entire lifetime of the thread, instead of just for the rewrite model bit? (I am also not too familiar with |
With closures the usual solution is to use smart pointers / let model_ptr1 = Arc::new(my_model);
let model_ptr2 = model_ptr1.clone();
do_some_stuff(move ||{
check_my_model(*model_ptr1)
})
do_some_more_stuff(*model_ptr2) The above code makes 2 pointers for the model, then gives ownership of the first pointer to the inside of do_some_stuff, to do some stuff with. The main code keeps ownership of the second pointer, allowing it to also access the model. |
For mutability, you would need to add a This can be messy, so I will defer the giving of an example to stack overflow:(https://stackoverflow.com/questions/31373255/how-do-i-share-a-mutable-object-between-threads-using-arc): fn main() {
let shared_stats = Arc::new(Mutex::new(Stats));
let threads = 5;
for _ in 0..threads {
let my_stats = shared_stats.clone();
thread::spawn(move || {
let mut shared = my_stats.lock().unwrap();
shared.add_stats(&Stats);
});
// Note: Immediately joining, no multithreading happening!
// THIS WAS A LIE, see below
} |
Code and Documentation Coverage ReportDocumentation CoverageClick to view documentation coverage for this PR
Click to view documentation coverage for main
Code Coverage SummaryThis PR: Detailed Report
Main: Detailed Report
Coverage Main & PR Coverage ChangeLines coverage changed by 0.10% and covered lines changed by 8
Functions coverage changed by 0.10% and covered lines changed by 1
Branches... coverage: No comparison data available |
This is looking good so far. Should we change the filenames to something like: BASENAME.expected-rule-trace.txt like the other 3 files? We would then update the accept code paths as well. |
That would be my next step. Just wanted to make it work first:) |
- Replace `structured_logger` with `tracing-subscribers` for log output. - Add stderr logging, configurable with the --verbose flag, and the RUST_LOG environment variable. The former changes the default log level to DEBUG and makes print format more verbose, the latter adjusts the log level. Previously, we were using `log` to produce logs, and `structured_logger` to put them in a file. For debugging, I want configurable logging to stderr; however, `structured_logger` does not allow different outputs to have different formats or log levels. We begin to use the `tracing` library as well as `log` for the rule engine in PR conjure-cp#393 due to its better multi-threading support. `trace_subscriber::fmt`, the `tracing` log writer used in this patch, automatically intercepts `log` messages. Thus, the logger can now see messages from both systems, instead of just `log`. Long term I believe that `tracing` will be a better choice than `log` and should be used everywhere; however, for now, supporting both in our log output is sensible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good so far, just a few comments.
Cloning this branch caused my git submodules to freakout and minion to fail the build, but this could just be me.
@@ -0,0 +1 @@ | |||
Event { fields: ValueSet { message: trace test, callsite: Identifier(0x557b0aba4020) }, metadata: Metadata { name: "event conjure_oxide/tests/generated_tests.rs:77", target: "rule_engine", level: Level(Trace), module_path: "generated_tests", location: conjure_oxide/tests/generated_tests.rs:77, fields: {message}, callsite: Identifier(0x557b0aba4020), kind: Kind(EVENT) }, parent: Current } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
callsite: ...
might cause issues on different computers?
readme 2.md
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete this
@@ -310,10 +325,10 @@ fn assert_constants_leq_one(parent_expr: &Expression, exprs: &[Expression]) { | |||
assert!(count <= 1, "assert_vector_operators_have_partially_evaluated: expression {} is not partially evaluated",parent_expr) | |||
} | |||
|
|||
// using a custom formatter to ommit the span name in the log | |||
struct CustomFormatter; | |||
// using a custom formatter to omit the span name in the log |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to do this ourselves instead of using builtin stuff, such as:
layer = fmt::layer()
.with_writer(non_blocking)
.json()
.with_current_span(false)
.with_span_list(false)
or, via format:
let format = fmt::format().
.with_current_span(false)
.with_span_list(false)
.json()
layer = fmt::layer()
.with_writer(non_blocking)
.event_format(format),
(https://docs.rs/tracing-subscriber/0.3.18/tracing_subscriber/fmt/index.html#customizing-formatters)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More options for layers here: https://docs.rs/tracing-subscriber/0.3.18/tracing_subscriber/fmt/struct.Layer.html
Enable getting all the rules in order of their application to a an essence problem and store them in a file. When cargo test is run, in addition to getting the parsed, rewritten model and the solutions, a list of rules for each test case will be generated and tested against the expected file.