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

Test logging interface #463

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

enigbe
Copy link
Contributor

@enigbe enigbe commented Feb 10, 2025

What this PR does

This is another follow-up PR to #407 where we test the log facade and custom logging interfaces.

It follows an earlier conversation to address testing without explicitly configuring the logger in all test cases.

cc @tnull

@enigbe enigbe force-pushed the 2025-02-test-logging-interface branch from da2edcc to d85c5c5 Compare February 10, 2025 14:27
Copy link
Collaborator

@tnull tnull left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

pub log_writer: TestLogWriter,
}

impl Default for TestConfig {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this impl, just add Default to the derive above.

@@ -251,6 +253,34 @@ pub(crate) enum TestChainSource<'a> {
BitcoindRpc(&'a BitcoinD),
}

#[derive(Clone)]
pub(crate) enum TestLogWriter {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While TestConfig could have some general utility going forward, I'm not quite convinced we need all this boilerplate just to switch the logger in a one-off test. We could at least simplify this enum, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplified it a bit to this. We don't really need the fields in the FileWriter variant as we are not really testing this, but the facade and custom variants are left as we test both of them.

#[derive(Clone)]
pub(crate) enum TestLogWriter {
	FileWriter,
	LogFacade(LogLevel),
	Custom(Arc<dyn LogWriter>),
}

}

struct MockLogRecord<'a>(LogRecord<'a>);
struct MockLogLevel(LogLevel);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need these newtypes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we do. We can't implement external traits (log::Log) on external types (LogLevel and LogRecord belong to ldk_node crate) so we work around this by wrapping the external types.

pub(crate) fn init_log_logger(level: LevelFilter) -> Arc<MockLogger> {
let logger = Arc::new(MockLogger::new());
log::set_boxed_logger(Box::new(logger.clone())).unwrap();
log::set_max_level(level);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, if this is part of the log API anyways, should we drop our max_log_level value in the log facade related builder methods and LogWriter variants? Do you have an opinion here? Do we gain much by also limiting on our end?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@enigbe Gentle ping here, as we're looking to ship v0.5 in the coming days. Do you think it makes sense to drop the max_log_level for the log facade logger, too, or do we need it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, if this is part of the log API anyways, should we drop our max_log_level value in the log facade related builder methods and LogWriter variants? Do you have an opinion here? Do we gain much by also limiting on our end

If we keep the max_log_level, we'd have to nudge users to align the facade level with the LevelFilter given that they can be compared directly. However, we won't have any control over this because setting the max level should be done by the active log implementation.

Do you think it makes sense to drop the max_log_level for the log facade logger, too, or do we need it?
It'd be cleaner to remove max_log_level.

If we are going with the latter, would it be okay to add a commit for it to this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, apologies for the late changes. I am ramping up into LDK and got side-tracked.

Copy link
Collaborator

@tnull tnull Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we keep the max_log_level, we'd have to nudge users to align the facade level with the LevelFilter given that they can be compared directly. However, we won't have any control over this because setting the max level should be done by the active log implementation.

Right then it might be better to drop it, at least for now.

If we are going with the latter, would it be okay to add a commit for it to this PR?

Yeah, feel free to append another commit here for it.

Also, apologies for the late changes. I am ramping up into LDK and got side-tracked.

No worries!


let logger = init_log_logger(LevelFilter::Trace);
let mut config = random_config(false);
config.log_writer = TestLogWriter::LogFacade { max_log_level: LogLevel::Gossip };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above, a bit awkward that we have an additional filter on the level.

let _node = setup_node(&chain_source, config, None);
println!("== Facade logging end ==");

assert!(!logger.retrieve_logs().is_empty());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we do more checks to ensure the messages contain something valid (or even check the structure, certain fields, etc?), rather than doing all this work just to check the Vec isn't empty?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we should. I thought to use regular expressions but that would lead to adding another dependency just for testing. Instead, I have added a simple function to validate the log entries.

@enigbe
Copy link
Contributor Author

enigbe commented Feb 19, 2025

@tnull.
Thank for taking a look at this. I have address most of the comments and just have a question about adding a commit that removes max_log_level here or in a new PR.

@enigbe enigbe force-pushed the 2025-02-test-logging-interface branch from bff5778 to 30bee82 Compare February 20, 2025 08:54
TestLogWriter::FileWriter => {
let file_path = format!("{}/{}", DEFAULT_STORAGE_DIR_PATH, DEFAULT_LOG_FILENAME);
let max_log_level = DEFAULT_LOG_LEVEL;
builder.set_filesystem_logger(Some(file_path), Some(max_log_level));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're using defaults anyways, why are we overriding them here? Shouldn't we just use Nones instead?

- `TestConfig` wraps `Config` and other fields, specifically
a log-related field that can be over-written on a per-test
basis.
- With `TestConfig`, we can maintain the general testing
setup/APIs as is and only modify fields based on specific
features we want to test.
Additionally addresses minor issues related to:
- Default impl
- Verbose TestLogWriter enum
- MockLogFacadeLogger and node_config rename
- use uniffi flag for appropriate log objects
- use default filewriter arguments
- remove test for custom logger and the logger
  initialization code
This is now considered unnecessary because the
concrete implementation of the facade has control
over the maximum log level that can be configured.
@enigbe enigbe force-pushed the 2025-02-test-logging-interface branch from 30bee82 to 4e59771 Compare February 23, 2025 22:51
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

Successfully merging this pull request may close these issues.

2 participants