mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-22 23:54:33 +01:00
Port test files from v9.2.x-stable branch to increase channelserver coverage from 13.8% to 25.6% (556 tests passing). Adapted all files to main's struct definitions: config import alias, Airou/CatDefinition rename, packet field mismatches, Raviente struct differences, and maxPlayers defaults. Removed tests referencing production code not yet on main (Player, FestivalColour, etc.). Excluded handlers_register_test.go (Raviente completely redesigned).
448 lines
11 KiB
Go
448 lines
11 KiB
Go
package channelserver
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"erupe-ce/network/mhfpacket"
|
|
)
|
|
|
|
func TestHandleMsgSysCreateSemaphore(t *testing.T) {
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgSysCreateSemaphore{
|
|
AckHandle: 12345,
|
|
Unk0: 0,
|
|
}
|
|
|
|
handleMsgSysCreateSemaphore(session, pkt)
|
|
|
|
// Verify response packet was queued
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgSysDeleteSemaphore_NoSemaphores(t *testing.T) {
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgSysDeleteSemaphore{
|
|
SemaphoreID: 12345,
|
|
}
|
|
|
|
// Should not panic when no semaphores exist
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
t.Errorf("handleMsgSysDeleteSemaphore panicked: %v", r)
|
|
}
|
|
}()
|
|
|
|
handleMsgSysDeleteSemaphore(session, pkt)
|
|
}
|
|
|
|
func TestHandleMsgSysDeleteSemaphore_WithSemaphore(t *testing.T) {
|
|
server := createMockServer()
|
|
server.semaphore = make(map[string]*Semaphore)
|
|
session := createMockSession(1, server)
|
|
|
|
// Create a semaphore
|
|
sema := NewSemaphore(session, "test_sema", 4)
|
|
server.semaphore["test_sema"] = sema
|
|
|
|
pkt := &mhfpacket.MsgSysDeleteSemaphore{
|
|
SemaphoreID: sema.id,
|
|
}
|
|
|
|
handleMsgSysDeleteSemaphore(session, pkt)
|
|
|
|
// Semaphore should be deleted
|
|
if _, exists := server.semaphore["test_sema"]; exists {
|
|
t.Error("Semaphore should be deleted")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgSysCreateAcquireSemaphore_NewSemaphore(t *testing.T) {
|
|
server := createMockServer()
|
|
server.semaphore = make(map[string]*Semaphore)
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgSysCreateAcquireSemaphore{
|
|
AckHandle: 12345,
|
|
Unk0: 0,
|
|
PlayerCount: 4,
|
|
SemaphoreID: "test_semaphore",
|
|
}
|
|
|
|
handleMsgSysCreateAcquireSemaphore(session, pkt)
|
|
|
|
// Verify response packet was queued
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
|
|
// Verify semaphore was created
|
|
if _, exists := server.semaphore["test_semaphore"]; !exists {
|
|
t.Error("Semaphore should be created")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgSysCreateAcquireSemaphore_ExistingSemaphore(t *testing.T) {
|
|
server := createMockServer()
|
|
server.semaphore = make(map[string]*Semaphore)
|
|
session := createMockSession(1, server)
|
|
|
|
// Pre-create semaphore
|
|
sema := NewSemaphore(session, "existing_sema", 4)
|
|
server.semaphore["existing_sema"] = sema
|
|
|
|
pkt := &mhfpacket.MsgSysCreateAcquireSemaphore{
|
|
AckHandle: 12345,
|
|
Unk0: 0,
|
|
PlayerCount: 4,
|
|
SemaphoreID: "existing_sema",
|
|
}
|
|
|
|
handleMsgSysCreateAcquireSemaphore(session, pkt)
|
|
|
|
// Verify response packet was queued
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
|
|
// Verify client was added to semaphore
|
|
if len(sema.clients) == 0 {
|
|
t.Error("Session should be added to semaphore")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgSysCreateAcquireSemaphore_RavienteSemaphore(t *testing.T) {
|
|
server := createMockServer()
|
|
server.semaphore = make(map[string]*Semaphore)
|
|
session := createMockSession(1, server)
|
|
|
|
// Test raviente semaphore (special prefix)
|
|
pkt := &mhfpacket.MsgSysCreateAcquireSemaphore{
|
|
AckHandle: 12345,
|
|
Unk0: 0,
|
|
PlayerCount: 32,
|
|
SemaphoreID: "hs_l0u3B51", // Raviente prefix + suffix
|
|
}
|
|
|
|
handleMsgSysCreateAcquireSemaphore(session, pkt)
|
|
|
|
// Verify response packet was queued
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
|
|
// Verify raviente semaphore was created with special settings
|
|
if sema, exists := server.semaphore["hs_l0u3B51"]; !exists {
|
|
t.Error("Raviente semaphore should be created")
|
|
} else if sema.maxPlayers != 127 {
|
|
t.Errorf("Raviente semaphore maxPlayers = %d, want 127", sema.maxPlayers)
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgSysCreateAcquireSemaphore_Full(t *testing.T) {
|
|
server := createMockServer()
|
|
server.semaphore = make(map[string]*Semaphore)
|
|
|
|
// Create semaphore with 1 player max
|
|
session1 := createMockSession(1, server)
|
|
sema := NewSemaphore(session1, "full_sema", 1)
|
|
server.semaphore["full_sema"] = sema
|
|
|
|
// Fill the semaphore
|
|
sema.clients[session1] = session1.charID
|
|
|
|
// Try to acquire with another session
|
|
session2 := createMockSession(2, server)
|
|
pkt := &mhfpacket.MsgSysCreateAcquireSemaphore{
|
|
AckHandle: 12345,
|
|
Unk0: 0,
|
|
PlayerCount: 1,
|
|
SemaphoreID: "full_sema",
|
|
}
|
|
|
|
handleMsgSysCreateAcquireSemaphore(session2, pkt)
|
|
|
|
// Should still respond (with failure indication)
|
|
select {
|
|
case p := <-session2.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data even for full semaphore")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgSysAcquireSemaphore_Exists(t *testing.T) {
|
|
server := createMockServer()
|
|
server.semaphore = make(map[string]*Semaphore)
|
|
session := createMockSession(1, server)
|
|
|
|
// Create semaphore
|
|
sema := NewSemaphore(session, "acquire_test", 4)
|
|
server.semaphore["acquire_test"] = sema
|
|
|
|
pkt := &mhfpacket.MsgSysAcquireSemaphore{
|
|
AckHandle: 12345,
|
|
SemaphoreID: "acquire_test",
|
|
}
|
|
|
|
handleMsgSysAcquireSemaphore(session, pkt)
|
|
|
|
// Verify response packet was queued
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
|
|
// Verify host was set
|
|
if sema.host != session {
|
|
t.Error("Session should be set as semaphore host")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgSysAcquireSemaphore_NotExists(t *testing.T) {
|
|
server := createMockServer()
|
|
server.semaphore = make(map[string]*Semaphore)
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgSysAcquireSemaphore{
|
|
AckHandle: 12345,
|
|
SemaphoreID: "nonexistent",
|
|
}
|
|
|
|
handleMsgSysAcquireSemaphore(session, pkt)
|
|
|
|
// Should respond with failure
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) == 0 {
|
|
t.Error("Response packet should have data")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgSysReleaseSemaphore(t *testing.T) {
|
|
server := createMockServer()
|
|
session := createMockSession(1, server)
|
|
|
|
// Should not panic (mostly empty handler)
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
t.Errorf("handleMsgSysReleaseSemaphore panicked: %v", r)
|
|
}
|
|
}()
|
|
|
|
pkt := &mhfpacket.MsgSysReleaseSemaphore{}
|
|
handleMsgSysReleaseSemaphore(session, pkt)
|
|
}
|
|
|
|
func TestHandleMsgSysCheckSemaphore_Exists(t *testing.T) {
|
|
server := createMockServer()
|
|
server.semaphore = make(map[string]*Semaphore)
|
|
session := createMockSession(1, server)
|
|
|
|
// Create semaphore
|
|
sema := NewSemaphore(session, "check_test", 4)
|
|
server.semaphore["check_test"] = sema
|
|
|
|
pkt := &mhfpacket.MsgSysCheckSemaphore{
|
|
AckHandle: 12345,
|
|
SemaphoreID: "check_test",
|
|
}
|
|
|
|
handleMsgSysCheckSemaphore(session, pkt)
|
|
|
|
// Verify response indicates semaphore exists
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) < 4 {
|
|
t.Error("Response packet should have at least 4 bytes")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestHandleMsgSysCheckSemaphore_NotExists(t *testing.T) {
|
|
server := createMockServer()
|
|
server.semaphore = make(map[string]*Semaphore)
|
|
session := createMockSession(1, server)
|
|
|
|
pkt := &mhfpacket.MsgSysCheckSemaphore{
|
|
AckHandle: 12345,
|
|
SemaphoreID: "nonexistent",
|
|
}
|
|
|
|
handleMsgSysCheckSemaphore(session, pkt)
|
|
|
|
// Verify response indicates semaphore does not exist
|
|
select {
|
|
case p := <-session.sendPackets:
|
|
if len(p.data) < 4 {
|
|
t.Error("Response packet should have at least 4 bytes")
|
|
}
|
|
default:
|
|
t.Error("No response packet queued")
|
|
}
|
|
}
|
|
|
|
func TestRemoveSessionFromSemaphore(t *testing.T) {
|
|
server := createMockServer()
|
|
server.semaphore = make(map[string]*Semaphore)
|
|
session := createMockSession(1, server)
|
|
|
|
// Create semaphore and add session
|
|
sema := NewSemaphore(session, "remove_test", 4)
|
|
sema.clients[session] = session.charID
|
|
server.semaphore["remove_test"] = sema
|
|
|
|
// Remove session
|
|
removeSessionFromSemaphore(session)
|
|
|
|
// Verify session was removed
|
|
if _, exists := sema.clients[session]; exists {
|
|
t.Error("Session should be removed from clients")
|
|
}
|
|
}
|
|
|
|
func TestRemoveSessionFromSemaphore_MultipleSemaphores(t *testing.T) {
|
|
server := createMockServer()
|
|
server.semaphore = make(map[string]*Semaphore)
|
|
session := createMockSession(1, server)
|
|
|
|
// Create multiple semaphores with the session
|
|
for i := 0; i < 3; i++ {
|
|
sema := NewSemaphore(session, "multi_test_"+string(rune('a'+i)), 4)
|
|
sema.clients[session] = session.charID
|
|
server.semaphore["multi_test_"+string(rune('a'+i))] = sema
|
|
}
|
|
|
|
// Remove session from all
|
|
removeSessionFromSemaphore(session)
|
|
|
|
// Verify session was removed from all semaphores
|
|
for _, sema := range server.semaphore {
|
|
if _, exists := sema.clients[session]; exists {
|
|
t.Error("Session should be removed from all semaphore clients")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDestructEmptySemaphores(t *testing.T) {
|
|
server := createMockServer()
|
|
server.semaphore = make(map[string]*Semaphore)
|
|
session := createMockSession(1, server)
|
|
|
|
// Create empty semaphore
|
|
sema := NewSemaphore(session, "empty_sema", 4)
|
|
server.semaphore["empty_sema"] = sema
|
|
|
|
// Create non-empty semaphore
|
|
semaWithClients := NewSemaphore(session, "with_clients", 4)
|
|
semaWithClients.clients[session] = session.charID
|
|
server.semaphore["with_clients"] = semaWithClients
|
|
|
|
destructEmptySemaphores(session)
|
|
|
|
// Empty semaphore should be deleted
|
|
if _, exists := server.semaphore["empty_sema"]; exists {
|
|
t.Error("Empty semaphore should be deleted")
|
|
}
|
|
|
|
// Non-empty semaphore should remain
|
|
if _, exists := server.semaphore["with_clients"]; !exists {
|
|
t.Error("Non-empty semaphore should remain")
|
|
}
|
|
}
|
|
|
|
func TestSemaphoreHandlers_SequentialAcquire(t *testing.T) {
|
|
server := createMockServer()
|
|
server.semaphore = make(map[string]*Semaphore)
|
|
|
|
// Sequentially try to create/acquire the same semaphore
|
|
// Note: the handler has race conditions when accessed concurrently
|
|
for i := 0; i < 5; i++ {
|
|
session := createMockSession(uint32(i), server)
|
|
|
|
pkt := &mhfpacket.MsgSysCreateAcquireSemaphore{
|
|
AckHandle: uint32(i),
|
|
Unk0: 0,
|
|
PlayerCount: 4,
|
|
SemaphoreID: "sequential_test",
|
|
}
|
|
|
|
handleMsgSysCreateAcquireSemaphore(session, pkt)
|
|
|
|
// Drain send queue
|
|
select {
|
|
case <-session.sendPackets:
|
|
default:
|
|
}
|
|
}
|
|
|
|
// Semaphore should exist
|
|
if _, exists := server.semaphore["sequential_test"]; !exists {
|
|
t.Error("Semaphore should exist after sequential acquires")
|
|
}
|
|
}
|
|
|
|
func TestSemaphoreHandlers_MultipleCheck(t *testing.T) {
|
|
server := createMockServer()
|
|
server.semaphore = make(map[string]*Semaphore)
|
|
|
|
// Create semaphore
|
|
helperSession := createMockSession(99, server)
|
|
sema := NewSemaphore(helperSession, "check_multiple", 4)
|
|
server.semaphore["check_multiple"] = sema
|
|
|
|
// Check the semaphore from multiple sessions sequentially
|
|
for i := 0; i < 5; i++ {
|
|
session := createMockSession(uint32(i), server)
|
|
|
|
pkt := &mhfpacket.MsgSysCheckSemaphore{
|
|
AckHandle: uint32(i),
|
|
SemaphoreID: "check_multiple",
|
|
}
|
|
|
|
handleMsgSysCheckSemaphore(session, pkt)
|
|
|
|
// Drain send queue
|
|
select {
|
|
case <-session.sendPackets:
|
|
default:
|
|
}
|
|
}
|
|
}
|