<commit_before>package reliable

import (
	"math/rand"
	"fmt"
	"encoding/binary"
	"time"
	"net"
	"sync"
	"strconv"
	"testing"
	"github.com/cs2dsb/udp-sd/util"
)

func TestEstablishConnection(t *testing.T) {
	r, err := NewReliableConnection()
	if err != nil {
		t.Errorf("NewReliableConnection() returned error: %q", err)
	}
	if r == nil {
		t.Errorf("NewReliableConnection() returned nil connection")
	}
	r.Close()
}

func TestEstablishMultipleConnections(t *testing.T) {
	r1, err := NewReliableConnection()
	if err != nil {
		t.Errorf("NewReliableConnection() returned error: %q", err)
	}
	if r1 == nil {
		t.Errorf("NewReliableConnection() returned nil connection")
	}
	
	r2, err := NewReliableConnection()
	if err != nil {
		t.Errorf("NewReliableConnection() returned error on 2nd invocation: %q", err)
	}
	if r2 == nil {
		t.Errorf("NewReliableConnection() returned nil connection on 2nd invocation")
	}
	
	r1.Close()
	r2.Close()
}

func TestConnectPeer(t *testing.T) {
	r1, err := NewReliableConnection()
	if err != nil {
		t.Errorf("NewReliableConnection() returned error: %q", err)
	}
	if r1 == nil {
		t.Errorf("NewReliableConnection() returned nil connection")
	}
	
	r2, err := NewReliableConnection()
	if err != nil {
		t.Errorf("NewReliableConnection() returned error: %q", err)
	}
	if r2 == nil {
		t.Errorf("NewReliableConnection() returned nil connection")
	}
	
	p := r1.FindOrAddPeer(&net.UDPAddr{IP: net.IPv4(127,0,0,1), Port: r2.Port })
	if p == nil {
		t.Errorf("ConnectPeer() returned nil peer")
	}
	
	isAlive := p.IsAlive(time.Millisecond * 2000)
	if !isAlive {
		t.Errorf("peer.IsAlive(2000ms) returned false")
	}	
	
	r1.Close()
	r2.Close()
}

func TestPacketEncodeDecode(t *testing.T) {
	p := packet{
		//Note this peer isn't valid for communication, use .ConnectPeer for real peers
		Peer: &peer{Address: &net.UDPAddr{IP: net.IPv4(123,245,178,111), Port: 12349}},
		OpCode: opData,
		Payload: []byte{123,123,123,111,110,99,222},
		Seq: 453432,
		Ack: 34564,
		AckBitfield: 99999,
	}
	
	ip := encodedPacket {
		Peer: p.Peer,
		Payload: p.toBytes(),
	}
	
	p2, err := ip.toOutgoingPacket()
	if err != nil {
		t.Errorf("incomingPacket.toOutgoingPacket() returned an error: %q", err)
	}
	if p2 == nil {
		t.Errorf("incomingPacket.toOutgoingPacket() returned nil outgoing packet")
	}
	
	if !(p.Peer.Address.IP.Equal(p2.Peer.Address.IP) && p.Peer.Address.Port == p2.Peer.Address.Port) {
		t.Errorf("incomingPacket.toOutgoingPacket() returned a different Address. Got %v:%d, expected %v:%d", p2.Peer.Address.IP, p2.Peer.Address.Port, p.Peer.Address.IP, p.Peer.Address.Port)
	}
	
	if p.OpCode != p2.OpCode {
		t.Errorf("incomingPacket.toOutgoingPacket() returned a different OpCode. Got %d, expected %d", p2.OpCode, p.OpCode)
	}
	
	if p.Seq != p2.Seq {
		t.Errorf("incomingPacket.toOutgoingPacket() returned a different Seq. Got %d, expected %d", p2.Seq, p.Seq)
	}
	
	if p.Ack != p2.Ack {
		t.Errorf("incomingPacket.toOutgoingPacket() returned a different ack. Got %d, expected %d", p2.Ack, p.Ack)
	}
	
	if p.AckBitfield != p2.AckBitfield {
		t.Errorf("incomingPacket.toOutgoingPacket() returned a different AckBitfield. Got %d, expected %d", p2.AckBitfield, p.AckBitfield)
	}
	
	if p2.Payload == nil {
		t.Errorf("incomingPacket.toOutgoingPacket() returned a different payload. Got nil")
	}
	
	pp := p.Payload
	p2p := p2.Payload
	
	for i, b := range pp {
		b2 := p2p[i]
		if b != b2 {
			t.Errorf("incomingPacket.toOutgoingPacket() returned a different payload. Got %d, expected %d (in byte %d)", b2, b, i)			
		}
	}
}

func TestPacketKeepaliveIncreasesSeq(t *testing.T) {
	r1, err := NewReliableConnection()
	if err != nil {
		t.Errorf("NewReliableConnection() returned error: %q", err)
	}
	if r1 == nil {
		t.Errorf("NewReliableConnection() returned nil connection")
	}
	
	r2, err := NewReliableConnection()
	if err != nil {
		t.Errorf("NewReliableConnection() returned error: %q", err)
	}
	if r2 == nil {
		t.Errorf("NewReliableConnection() returned nil connection")
	}
	
	p := r1.FindOrAddPeer(&net.UDPAddr{IP: net.IPv4(127,0,0,1), Port: r2.Port })
	if p == nil {
		t.Errorf("ConnectPeer() returned nil peer")
	}
	
	s := p.Seq
	r1.sendKeepaliveToPeer(p)
	
	if p.Seq < s + 1 {
		t.Errorf("Peer's Seq didn't increment after send keepalive")
	}
	
	r1.Close()
	r2.Close()
}

func TestPacketGetsAcked(t *testing.T) {
	r1, err := NewReliableConnection()
	if err != nil {
		t.Errorf("NewReliableConnection() returned error: %q", err)
	}
	if r1 == nil {
		t.Errorf("NewReliableConnection() returned nil connection")
	}<commit_msg>Fixed TestPacketKeepaliveIncreasesSeq<commit_after>package reliable

import (
	"math/rand"
	"fmt"
	"encoding/binary"
	"time"
	"net"
	"sync"
	"strconv"
	"testing"
	"github.com/cs2dsb/udp-sd/util"
)

func TestEstablishConnection(t *testing.T) {
	r, err := NewReliableConnection()
	if err != nil {
		t.Errorf("NewReliableConnection() returned error: %q", err)
	}
	if r == nil {
		t.Errorf("NewReliableConnection() returned nil connection")
	}
	r.Close()
}

func TestEstablishMultipleConnections(t *testing.T) {
	r1, err := NewReliableConnection()
	if err != nil {
		t.Errorf("NewReliableConnection() returned error: %q", err)
	}
	if r1 == nil {
		t.Errorf("NewReliableConnection() returned nil connection")
	}
	
	r2, err := NewReliableConnection()
	if err != nil {
		t.Errorf("NewReliableConnection() returned error on 2nd invocation: %q", err)
	}
	if r2 == nil {
		t.Errorf("NewReliableConnection() returned nil connection on 2nd invocation")
	}
	
	r1.Close()
	r2.Close()
}

func TestConnectPeer(t *testing.T) {
	r1, err := NewReliableConnection()
	if err != nil {
		t.Errorf("NewReliableConnection() returned error: %q", err)
	}
	if r1 == nil {
		t.Errorf("NewReliableConnection() returned nil connection")
	}
	
	r2, err := NewReliableConnection()
	if err != nil {
		t.Errorf("NewReliableConnection() returned error: %q", err)
	}
	if r2 == nil {
		t.Errorf("NewReliableConnection() returned nil connection")
	}
	
	p := r1.FindOrAddPeer(&net.UDPAddr{IP: net.IPv4(127,0,0,1), Port: r2.Port })
	if p == nil {
		t.Errorf("ConnectPeer() returned nil peer")
	}
	
	isAlive := p.IsAlive(time.Millisecond * 2000)
	if !isAlive {
		t.Errorf("peer.IsAlive(2000ms) returned false")
	}	
	
	r1.Close()
	r2.Close()
}

func TestPacketEncodeDecode(t *testing.T) {
	p := packet{
		//Note this peer isn't valid for communication, use .ConnectPeer for real peers
		Peer: &peer{Address: &net.UDPAddr{IP: net.IPv4(123,245,178,111), Port: 12349}},
		OpCode: opData,
		Payload: []byte{123,123,123,111,110,99,222},
		Seq: 453432,
		Ack: 34564,
		AckBitfield: 99999,
	}
	
	ip := encodedPacket {
		Peer: p.Peer,
		Payload: p.toBytes(),
	}
	
	p2, err := ip.toOutgoingPacket()
	if err != nil {
		t.Errorf("incomingPacket.toOutgoingPacket() returned an error: %q", err)
	}
	if p2 == nil {
		t.Errorf("incomingPacket.toOutgoingPacket() returned nil outgoing packet")
	}
	
	if !(p.Peer.Address.IP.Equal(p2.Peer.Address.IP) && p.Peer.Address.Port == p2.Peer.Address.Port) {
		t.Errorf("incomingPacket.toOutgoingPacket() returned a different Address. Got %v:%d, expected %v:%d", p2.Peer.Address.IP, p2.Peer.Address.Port, p.Peer.Address.IP, p.Peer.Address.Port)
	}
	
	if p.OpCode != p2.OpCode {
		t.Errorf("incomingPacket.toOutgoingPacket() returned a different OpCode. Got %d, expected %d", p2.OpCode, p.OpCode)
	}
	
	if p.Seq != p2.Seq {
		t.Errorf("incomingPacket.toOutgoingPacket() returned a different Seq. Got %d, expected %d", p2.Seq, p.Seq)
	}
	
	if p.Ack != p2.Ack {
		t.Errorf("incomingPacket.toOutgoingPacket() returned a different ack. Got %d, expected %d", p2.Ack, p.Ack)
	}
	
	if p.AckBitfield != p2.AckBitfield {
		t.Errorf("incomingPacket.toOutgoingPacket() returned a different AckBitfield. Got %d, expected %d", p2.AckBitfield, p.AckBitfield)
	}
	
	if p2.Payload == nil {
		t.Errorf("incomingPacket.toOutgoingPacket() returned a different payload. Got nil")
	}
	
	pp := p.Payload
	p2p := p2.Payload
	
	for i, b := range pp {
		b2 := p2p[i]
		if b != b2 {
			t.Errorf("incomingPacket.toOutgoingPacket() returned a different payload. Got %d, expected %d (in byte %d)", b2, b, i)			
		}
	}
}

func TestPacketKeepaliveIncreasesSeq(t *testing.T) {
	r1, err := NewReliableConnection()
	if err != nil {
		t.Errorf("NewReliableConnection() returned error: %q", err)
	}
	if r1 == nil {
		t.Errorf("NewReliableConnection() returned nil connection")
	}
	
	r2, err := NewReliableConnection()
	if err != nil {
		t.Errorf("NewReliableConnection() returned error: %q", err)
	}
	if r2 == nil {
		t.Errorf("NewReliableConnection() returned nil connection")
	}
	
	p := r1.FindOrAddPeer(&net.UDPAddr{IP: net.IPv4(127,0,0,1), Port: r2.Port })
	if p == nil {
		t.Errorf("ConnectPeer() returned nil peer")
	}
	
	s := p.Seq
	r1.sendKeepaliveToPeer(p)
	
	ok := util.WaitUntilTrue(func() bool {
		return p.Seq > s + 1
	}, r1.packetTimeout * 2)
	
	if !ok {
		t.Errorf("Peer's Seq didn't increment after send keepalive")
	}
	
	r1.Close()
	r2.Close()
}

func TestPacketGetsAcked(t *testing.T) {
	r1, err := NewReliableConnection()
	if err != nil {
		t.Errorf("NewReliableConnection() returned error: %q", err)
	}
	if r1 == nil {
		t.Errorf("NewReliableConnection() returned nil connection")
	}
{'fraction_non_alphanumeric': 0.15598127789267444, 'fraction_numerical': 0.02764776314357244, 'mean_word_length': 4.10728182323513, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3594393', 'n_tokens_mistral': 3750, 'n_tokens_neox': 3461, 'n_words': 810}