Nyeste innlegg

Sider: [1] 2 3 ... 10
1
Minecraft / Sv: Minecraft Pjatt
« Nyeste innlegg av Emilpoika 24. Desember 2023, 09:08 am »
2
Generelt teknisk / Rust: How to test a module that uses TcpStream?
« Nyeste innlegg av Floyd-ATC 27. April 2023, 14:06 pm »
How do you make a module testable that requires a std::net::TcpStream?

I had this problem with a (toy) project of mine that used a struct to encapsulate a BufReader and a BufWriter, presenting only the following in order to make it impossible to accidentally leak data into or out of the raw stream:

Kode: [Velg]
    pub fn new(TcpStream) -> Self
    pub fn reader(&mut self) -> &mut BufReader<TcpStream>
    pub fn writer(&mut self) -> &mut BufWriter<TcpStream>
    pub fn close(&mut self)

My initial though was to use generics to allow any type of stream but this turned out to be both really hard (because std::net::TcpStream uses .try_clone() rather than implementing the Clone trait, and it uses .shutdown(Shutdown) instead of .close()) and it would have required all the modules that depended on this one to deal with the generics that weren't needed to begin with. What started as a simple problem was now becoming really complicated in my mind.

I could turn it around by saying that my component now just implements a new trait, but this would not only require a whole lot of extra code just to implement, it would still require all the other modules to deal with the extra generics and most importantly: it would actually bring me no closer to the original goal: Testing this really quite simple module right here.

During my evening walk, it finally dawned on me that the people who designed the IP stack already thought of this exact problem (as well as many other problems) decades ago and they implemented a solution so simple it's easy to forget about it and make things harder than they need be:

The loopback address.

Specifying a port number of 0 means the operating system gets to pick an unused port for you. So I simply added one more function, a double constructor that creates a pair of object instances connected to each other:

Kode: [Velg]
    // Convenience function for testing
    pub fn loopback() -> Result<(Self, Self), std::io::Error> {
        let listener = TcpListener::bind("127.0.0.1:0")?;

        // From viewpoint of the client
        let server_addr = listener.local_addr()?;
        let server = TcpStream::connect(server_addr)?;

        // From viewpoint of the server
        let (client, client_addr) = listener.accept()?;

        let conn1 = Self::new(server, server_addr);
        let conn2 = Self::new(client, client_addr);
        return Ok((conn1, conn2));
    }

Not only did this make it trivial to test this module, it also made it dead simple to test all those other modules that depended on this one! The idea is easily transferred to other types of scenarios where you have to test code that uses TcpStream directly:

Kode: [Velg]
#[cfg(test)]
mod tests {
    use super::*;

    fn loopback() -> Result<(std::net::TcpStream, std::net::TcpStream), std::io::Error> {
        let listener = std::net::TcpListener::bind("127.0.0.1:0")?;
        let server = std::net::TcpStream::connect(listener.local_addr().unwrap())?;
        let (client, _) = listener.accept()?;
        return Ok((server, client));
    }

    // Actual tests here, just call loopback() whenever you need a pair of streams connected to each other
    // Put data into one, read it out of the other.
    // ...

}

Final note: On certain very locked-down platforms you may have to relax local firewall rules in order to allow loopback traffic, but no sane person would ever test their network code on a machine anywhere near production anyway so if this turns out to be a problem then maybe you should re-evaluate how and where you do things.
3
Minecraft / Sv: Minecraft Pjatt
« Nyeste innlegg av Emilpoika 24. Desember 2022, 08:19 am »
4
Eco / Sv: Eksperimentell Eco-server "ATC Sanctuary"
« Nyeste innlegg av Emilpoika 16. August 2022, 20:01 pm »
Tror vi tapte ..
5
Minecraft / Sv: Ny minecraft-update (1.4.2,[...] og 1.10)
« Nyeste innlegg av Emilpoika 22. Februar 2022, 16:40 pm »
Ser at nettsiden er oppe også, men ikke det dynamiske kartet.
Hmm jeg lurer på om jeg vet hvorfor! Funker det nå?

Ja! :D
6
Minecraft / Sv: Ny minecraft-update (1.4.2,[...] og 1.10)
« Nyeste innlegg av Floyd-ATC 21. Februar 2022, 12:40 pm »
Ser at nettsiden er oppe også, men ikke det dynamiske kartet.
Hmm jeg lurer på om jeg vet hvorfor! Funker det nå?
7
Minecraft / Sv: Ny minecraft-update (1.4.2,[...] og 1.10)
« Nyeste innlegg av SpeedNinja 19. Februar 2022, 12:58 pm »
Jeg heter nå ikke SpeedNinja lenger, men gøy å se litt av spawn værtfall, får se om jeg kommer meg innom en annen dag
8
Minecraft / Sv: Ny minecraft-update (1.4.2,[...] og 1.10)
« Nyeste innlegg av SpeedNinja 19. Februar 2022, 12:42 pm »
Nå må jeg prøve å logge inn  ;D
9
Minecraft / Sv: Ny minecraft-update (1.4.2,[...] og 1.10)
« Nyeste innlegg av Emilpoika 19. Februar 2022, 11:18 am »
Serveren skal være oppe nå [...]
Har skrevet på facebook-gruppa, og lagt med en screenshot.

Har sjekket; og det er ingen petitioner som er ugjort, he he!

Ser at nettsiden er oppe også, men ikke det dynamiske kartet.
10
Minecraft / Sv: Ny minecraft-update (1.4.2,[...] og 1.10)
« Nyeste innlegg av Floyd-ATC 18. Februar 2022, 10:09 am »
Serveren skal være oppe nå,

Oppdatering: Etter en del plundring har jeg fått på plass et systemd-oppsett som i teorien skal auto-starte serveren etter reboot pga. strømbrudd eller lignende. Tidligere har jeg måttet logge inn og starte den manuelt. Krysser fingrene for at det gir mer stabilitet.
Sider: [1] 2 3 ... 10