-
Notifications
You must be signed in to change notification settings - Fork 44
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
Integration tests for UDP Tracker #96
Conversation
e6bb34b
to
7c20041
Compare
hi @da2ce7 @WarmBeer I have added three tests:
After adding the third one, I started having random failures for the third one. First, I send the "connect" request and then the "announce" request. For some reason, the client does not receive the "announce" response, but the server is sending it (I see it in the log). If I comment out the first two tests, It always works, so tests must not be isolated. |
Sometimes I get this message:
And sometimes, the tests stop at the third test (there is no timeout for the "receive" data function). If I stop the test execution with "CTRL+C" the socket is not close because there is still a thread (I suppose it is the udp server). |
Hey @josecelano , When you run the tests synchronously Eg: #[tokio::test]
async fn test() {
should_return_a_bad_request_response_when_the_client_sends_an_empty_request().await;
should_return_a_connect_response_when_the_client_sends_a_connection_request().await;
should_return_an_announce_response_when_the_client_sends_an_announce_request().await;
} They pass 100% of the time. I think when you run the tests at the same time, each of the tests will try and boot up a new udp tracker while all the tests are ongoing. This probably leads to packet loss. So to fix it, we either have to run the tests synchronously or provide each test with its own UdpServer (on a unique port). |
91250f6
to
35e1dac
Compare
hi @WarmBeer @da2ce7, I've also added the test for the scrape request. I think it's ready for review. I only check basic behaviour. Only the happy path, and I only check the response type. Particular cases are (or should) be covered by unit tests. If you think that other tests could be helpful, let me know. Maybe adding more tests to cover the full specification would be nice. That would be useful to run smoke tests against live UDP servers. But maybe it makes more sense to use a real client for that and make it an independent project. |
a5f33f3
to
301969c
Compare
src/logging.rs
Outdated
@@ -18,6 +18,10 @@ pub fn setup_logging(cfg: &Configuration) { | |||
}, | |||
}; | |||
|
|||
if log_level == log::LevelFilter::Off { |
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.
@WarmBeer Why do you introduce this change here? It seems unrelated.
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.
hi @da2ce7 We're using an independent UdpServer for each test, so we isolate tests.
impl UdpServer {
// ..
pub async fn start(&mut self, configuration: Arc<Configuration>) {
if !self.started.load(Ordering::Relaxed) {
// ...
// Initialize logging
logging::setup_logging(&configuration);
// ...
}
}
}
The problem is each UdpServer instance tries to setup logging again with:
if let Err(_err) = fern::Dispatch::new()
.format(|out, message, record| {
out.finish(format_args!(
"{} [{}][{}] {}",
chrono::Local::now().format("%+"),
record.target(),
record.level(),
message
))
})
.level(log_level)
.chain(std::io::stdout())
.apply()
{
panic!("Failed to initialize logging.")
}
I do not know how that code works, but I suppose is a kind of "pipe" to redirect the log to the stdout, and probably that can be done only once. If that is the case, we have these options:
- What @WarmBeer did. We can disable log for testing. I do not like this solution because, very often, logging is helpful during testing. I use it a lot.
- We can setup logging in a different way for testing, for example, using a different log file for each server. I do not like this option. It generates too much garbage.
- We can use a different
setup_logging
for tests where we ensure we only call once the "pipe" generation code. - We can change
setup_logging
function in the production code to avoid calling that part twice, regardless the log level you want.
I would go for option 4.
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.
hi @da2ce7 @WarmBeer, I've changed the setup_logging
function to avoid panicking if it's called more than once. This way, we can enable logging even for testing (using more than one UdpServe). I still use the "off" level in testing because I prefer to keep the test output clean. You can enable it whenever you needed it.
tests/udp.rs
Outdated
|
||
fn tracker_configuration() -> Arc<Configuration> { | ||
let mut config = Configuration::default(); | ||
config.log_level = Some("off".to_owned()); // "off" is necessary when running multiple trackers |
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.
What happens, is it not possible for the logs to be tracker-local?
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.
Yes, I think it's possible. Read my comment avobe.
* refactor: run tests with own udp tracker * fixup! refactor: run tests with own udp tracker
301969c
to
508803a
Compare
`setup_logging` cannot be called twice becuase it panics.
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.
ACK 5dcea43
I'm trying to reproduce the error in issue #42. I've only created the scaffolding for integration tests so far.
If there is no bug I want to use this scaffolding for other integration tests. If we consider them helpful.