mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-27 01:53:19 +01:00
test: import 38 channelserver test files from v9.2.x-stable
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).
This commit is contained in:
447
server/channelserver/handlers_semaphore_test.go
Normal file
447
server/channelserver/handlers_semaphore_test.go
Normal file
@@ -0,0 +1,447 @@
|
||||
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:
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user