DHT-kademlia-P2Psec/cmd/dht_test.go

246 lines
6.3 KiB
Go
Raw Normal View History

2024-09-13 07:04:40 +02:00
package main
import (
"fmt"
kademlia "gitlab.lrz.de/netintum/teaching/p2psec_projects_2024/DHT-6/pkg"
"strconv"
"testing"
"time"
)
func startServer(config *kademlia.Config) *kademlia.DHT {
dht := kademlia.NewDHT(config)
go initializeAPIServer(config, dht)
go initializeP2PServer(config, dht)
return dht
}
func TestBasicStartAPI(t *testing.T) {
config := &kademlia.Config{
P2PPort: 6001,
APIPort: 7001,
P2PAddress: "127.0.0.2",
APIAddress: "127.0.0.2",
KeyFile: "certs/key.pem",
CertFile: "certs/cert.pem",
PrefixLength: 5,
RepublishInterval: 3600,
}
startServer(config)
time.Sleep(1 * time.Second)
var key [32]byte
value := []byte("Hello World")
packet := kademlia.SerialisePutPacket(&kademlia.DHTPutPacket{
TTL: 20,
Replication: 20,
Key: key,
Value: value,
})
conn, err := kademlia.ConnectToApi("127.0.0.2", 7001)
if err != nil {
t.Fatalf("Failed to connect %v", err)
}
conn.Write(packet)
conn.Close()
packet = kademlia.SerialiseGetPacket(&kademlia.DHTGetPacket{Key: key})
conn, err = kademlia.ConnectToApi("127.0.0.2", 7001)
if err != nil {
t.Fatalf("Failed to connect %v", err)
}
conn.Write(packet)
response := make([]byte, 100)
n, _ := conn.Read(response)
t.Logf("Response: %v Num: %d", response, n)
}
/*
Testing whether or not the boostrapping process works as intended. By running the second node configured with
the first as boostrapper, they both should appear in each others routing tables.
*/
func TestBoostrap(t *testing.T) {
config1 := &kademlia.Config{
P2PPort: 6001,
APIPort: 7001,
P2PAddress: "127.0.0.2",
APIAddress: "127.0.0.2",
KeyFile: "certs/key.pem",
CertFile: "certs/cert.pem",
}
config2 := &kademlia.Config{
P2PPort: 6001,
APIPort: 7001,
P2PAddress: "127.0.0.1",
APIAddress: "127.0.0.1",
Bootstrapper: "127.0.0.2",
BootstrapperPort: 6001,
BootstrapperCert: "certs/cert.pem",
KeyFile: "certs/key1.pem",
CertFile: "certs/cert1.pem",
}
dht := startServer(config1)
time.Sleep(100 * time.Millisecond)
dht2 := startServer(config2)
time.Sleep(100 * time.Millisecond)
if !kademlia.ContainsNode(*dht.RoutingTable.FindClosest(dht2.SelfNode.NodeID, 10), dht2.SelfNode) {
t.Fatalf("Boostrapping failed, node1 did not add node2 to table")
}
if !kademlia.ContainsNode(*dht2.RoutingTable.FindClosest(dht.SelfNode.NodeID, 10), dht2.SelfNode) {
t.Fatalf("Boostrapping failed, node2 did not add node1 to table")
}
}
/*
This test covers most of the DHTs functionality. One node acts as bootstrapper for the others,
two values are stored with different replication counts. It is tested whether finding these values works from
any node in the network and whether the replication works correctly.
*/
func TestStoreReceiveReplication(t *testing.T) {
dhts := make([]kademlia.DHT, 0)
for i := 2; i < 40; i++ {
config := &kademlia.Config{
P2PPort: 7001,
APIPort: 6001,
P2PAddress: "127.0.0." + strconv.Itoa(i),
APIAddress: "127.0.0." + strconv.Itoa(i),
Bootstrapper: "127.0.0.2",
BootstrapperPort: 7001,
BootstrapperCert: "certs/cert2.pem",
KeyFile: fmt.Sprintf("certs/key%d.pem", i),
CertFile: fmt.Sprintf("certs/cert%d.pem", i),
PrefixLength: 5,
RepublishInterval: 3600 * time.Second,
}
if i == 2 {
config.Bootstrapper = ""
}
time.Sleep(100 * time.Millisecond)
dht := startServer(config)
dhts = append(dhts, *dht)
}
time.Sleep(100 * time.Millisecond)
var key, key2 [32]byte
key2[0] = 1
value := []byte("Hello World")
packet := kademlia.SerialisePutPacket(&kademlia.DHTPutPacket{
TTL: 200,
Replication: 20,
Key: key,
Value: value,
})
conn, err := kademlia.ConnectToApi("127.0.0.2", 6001)
if err != nil {
t.Fatalf("Failed to connect %v", err)
}
conn.Write(packet)
conn.Close()
conn, err = kademlia.ConnectToApi("127.0.0.2", 6001)
packet = kademlia.SerialisePutPacket(&kademlia.DHTPutPacket{
TTL: 200,
Replication: 5,
Key: key2,
Value: value,
})
conn.Write(packet)
conn.Close()
time.Sleep(3 * time.Second)
for n, client := range dhts {
v, ex := client.Get(key)
if ex {
for i, b := range v {
if value[i] != b {
t.Fatalf("Incorrect value found by node %d", n)
}
}
t.Logf("found key one at node %d", n)
} else {
t.Fatalf("Value coud not be found by node %d", n)
}
}
c1, c2 := 0, 0
for _, client := range dhts {
_, e := client.Storage.GetValue(key)
if e {
c1++
}
_, e = client.Storage.GetValue(key2)
if e {
c2++
}
}
t.Logf("Key 1 stored %d times and Key 2 stored %d times", c1, c2)
}
func TestExpireRepublish(t *testing.T) {
configs := make([]kademlia.Config, 0)
for i := 2; i < 4; i++ {
config := &kademlia.Config{
P2PPort: 7001,
APIPort: 6001,
P2PAddress: "127.0.0." + strconv.Itoa(i),
APIAddress: "127.0.0." + strconv.Itoa(i),
Bootstrapper: "127.0.0.2",
BootstrapperPort: 7001,
BootstrapperCert: "certs/cert2.pem",
KeyFile: fmt.Sprintf("certs/key%d.pem", i),
CertFile: fmt.Sprintf("certs/cert%d.pem", i),
PrefixLength: 5,
RepublishInterval: 10 * time.Second,
}
if i == 2 {
config.Bootstrapper = ""
}
time.Sleep(100 * time.Millisecond)
configs = append(configs, *config)
}
configs[0].Bootstrapper = ""
dht1 := startServer(&configs[0])
var key [32]byte
var key2 [32]byte
key2[0] = 1
value := []byte("Hello World")
dht1.Store(key, value, 5, 10)
dht1.Store(key2, value, 1000, 10)
dht2 := startServer(&configs[1])
time.Sleep(100 * time.Millisecond)
if _, e := dht1.Storage.GetValue(key); !e {
t.Fatal("Key not stored!")
}
if _, e := dht1.Storage.GetValue(key2); !e {
t.Fatal("Key not stored!")
}
if _, e := dht2.Storage.GetValue(key2); e {
t.Fatal("Key should not be present yet!")
}
// Trigger republishing
time.Sleep(10 * time.Second)
kademlia.Ping(dht1.SelfNode, dht2.SelfNode)
time.Sleep(1 * time.Second)
if _, e := dht1.Storage.GetValue(key); e {
t.Fatal("Key should have been deleted!")
}
if _, e := dht1.Storage.GetValue(key2); !e {
t.Fatal("Key not stored!")
}
if _, e := dht2.Storage.GetValue(key2); !e {
t.Fatal("Key should have been republished!")
}
}