mirror of
https://github.com/CPunch/gopenfusion.git
synced 2024-11-21 15:00:07 +00:00
testing refactor; use github.com/matryer/is
It is syntactically pretty, simple, and also makes failures have pretty colors. what more could you ask for :)
This commit is contained in:
parent
f4b17906ce
commit
8e65a78d07
1
go.mod
1
go.mod
@ -8,6 +8,7 @@ require (
|
|||||||
github.com/georgysavva/scany/v2 v2.0.0
|
github.com/georgysavva/scany/v2 v2.0.0
|
||||||
github.com/google/subcommands v1.2.0
|
github.com/google/subcommands v1.2.0
|
||||||
github.com/lib/pq v1.10.9
|
github.com/lib/pq v1.10.9
|
||||||
|
github.com/matryer/is v1.4.1
|
||||||
github.com/redis/go-redis/v9 v9.0.5
|
github.com/redis/go-redis/v9 v9.0.5
|
||||||
golang.org/x/crypto v0.7.0
|
golang.org/x/crypto v0.7.0
|
||||||
)
|
)
|
||||||
|
2
go.sum
2
go.sum
@ -48,6 +48,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
|
|||||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
|
github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ=
|
||||||
|
github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
|
||||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||||
|
@ -6,6 +6,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/matryer/is"
|
||||||
|
|
||||||
"github.com/CPunch/gopenfusion/internal/db"
|
"github.com/CPunch/gopenfusion/internal/db"
|
||||||
"github.com/CPunch/gopenfusion/internal/protocol"
|
"github.com/CPunch/gopenfusion/internal/protocol"
|
||||||
"github.com/bitcomplete/sqltestutil"
|
"github.com/bitcomplete/sqltestutil"
|
||||||
@ -37,23 +39,20 @@ func TestMain(m *testing.M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDBAccount(t *testing.T) {
|
func TestDBAccount(t *testing.T) {
|
||||||
if _, err := testDB.NewAccount("test", "test"); err != nil {
|
is := is.New(t)
|
||||||
t.Error(err)
|
|
||||||
}
|
// create new account
|
||||||
|
_, err := testDB.NewAccount("test", "test")
|
||||||
|
is.NoErr(err)
|
||||||
|
|
||||||
// now try to retrieve account data
|
// now try to retrieve account data
|
||||||
acc, err := testDB.TryLogin("test", "test")
|
acc, err := testDB.TryLogin("test", "test")
|
||||||
if err != nil {
|
is.NoErr(err)
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if acc.Login != "test" {
|
_, err = testDB.TryLogin("test", "wrongpassword")
|
||||||
t.Error("account username is not test")
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err = testDB.TryLogin("test", "wrongpassword"); !errors.Is(err, db.ErrLoginInvalidPassword) {
|
is.True(acc.Login == "test") // login data should match created account
|
||||||
t.Error("expected ErrLoginInvalidPassword")
|
is.True(errors.Is(err, db.ErrLoginInvalidPassword)) // wrong password passed to TryLogin() should fail with ErrLoginInvalidPassword
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -81,22 +80,18 @@ gopenfusion=# SELECT * FROM Inventory;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
func TestDBPlayer(t *testing.T) {
|
func TestDBPlayer(t *testing.T) {
|
||||||
if _, err := testDB.NewAccount("testplayer", "test"); err != nil {
|
is := is.New(t)
|
||||||
t.Error(err)
|
_, err := testDB.NewAccount("testplayer", "test")
|
||||||
}
|
is.NoErr(err)
|
||||||
|
|
||||||
// now try to retrieve account data
|
// now try to retrieve account data
|
||||||
acc, err := testDB.TryLogin("testplayer", "test")
|
acc, err := testDB.TryLogin("testplayer", "test")
|
||||||
if err != nil {
|
is.NoErr(err)
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
plrID, err := testDB.NewPlayer(acc.AccountID, "Neil", "Mcscout", 1)
|
plrID, err := testDB.NewPlayer(acc.AccountID, "Neil", "Mcscout", 1)
|
||||||
if err != nil {
|
is.NoErr(err)
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = testDB.FinishPlayer(&protocol.SP_CL2LS_REQ_CHAR_CREATE{
|
err = testDB.FinishPlayer(&protocol.SP_CL2LS_REQ_CHAR_CREATE{
|
||||||
PCStyle: protocol.SPCStyle{
|
PCStyle: protocol.SPCStyle{
|
||||||
IPC_UID: int64(plrID),
|
IPC_UID: int64(plrID),
|
||||||
INameCheck: 1,
|
INameCheck: 1,
|
||||||
@ -116,11 +111,9 @@ func TestDBPlayer(t *testing.T) {
|
|||||||
IEquipLBID: 359,
|
IEquipLBID: 359,
|
||||||
IEquipFootID: 194,
|
IEquipFootID: 194,
|
||||||
},
|
},
|
||||||
}, acc.AccountID); err != nil {
|
}, acc.AccountID)
|
||||||
t.Error(err)
|
is.NoErr(err)
|
||||||
}
|
|
||||||
|
|
||||||
if err = testDB.FinishTutorial(plrID, acc.AccountID); err != nil {
|
err = testDB.FinishTutorial(plrID, acc.AccountID)
|
||||||
t.Error(err)
|
is.NoErr(err)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,11 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/CPunch/gopenfusion/internal/entity"
|
"github.com/CPunch/gopenfusion/internal/entity"
|
||||||
|
"github.com/matryer/is"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestChunkSliceDifference(t *testing.T) {
|
func TestChunkSliceDifference(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
chunks := []*entity.Chunk{
|
chunks := []*entity.Chunk{
|
||||||
entity.NewChunk(entity.MakeChunkPosition(0, 0)),
|
entity.NewChunk(entity.MakeChunkPosition(0, 0)),
|
||||||
entity.NewChunk(entity.MakeChunkPosition(0, 1)),
|
entity.NewChunk(entity.MakeChunkPosition(0, 1)),
|
||||||
@ -28,13 +30,7 @@ func TestChunkSliceDifference(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
diff := entity.ChunkSliceDifference(c1, c2)
|
diff := entity.ChunkSliceDifference(c1, c2)
|
||||||
if len(diff) != 1 {
|
|
||||||
t.Logf("%+v", diff)
|
|
||||||
t.Error("expected 1 chunk in difference")
|
|
||||||
}
|
|
||||||
|
|
||||||
if diff[0] != chunks[3] {
|
is.True(len(diff) == 1) // should be 1 chunk in difference
|
||||||
t.Logf("%+v", diff)
|
is.True(diff[0] == chunks[3]) // should be chunks[3] in difference
|
||||||
t.Error("wrong difference")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/CPunch/gopenfusion/internal/protocol"
|
"github.com/CPunch/gopenfusion/internal/protocol"
|
||||||
|
"github.com/matryer/is"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestPacketData struct {
|
type TestPacketData struct {
|
||||||
@ -53,59 +54,51 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestPacketEncode(t *testing.T) {
|
func TestPacketEncode(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
pkt := protocol.NewPacket(buf)
|
pkt := protocol.NewPacket(buf)
|
||||||
|
|
||||||
if err := pkt.Encode(testStruct); err != nil {
|
err := pkt.Encode(testStruct)
|
||||||
t.Error(err)
|
is.NoErr(err)
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(buf.Bytes(), testData[:]) {
|
is.True(bytes.Equal(buf.Bytes(), testData[:])) // encoded data should match expected data
|
||||||
t.Error("packet data does not match!")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPacketDecode(t *testing.T) {
|
func TestPacketDecode(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
pkt := protocol.NewPacket(buf)
|
pkt := protocol.NewPacket(buf)
|
||||||
buf.Write(testData[:])
|
buf.Write(testData[:])
|
||||||
|
|
||||||
var test TestPacketData
|
var test TestPacketData
|
||||||
if err := pkt.Decode(&test); err != nil {
|
err := pkt.Decode(&test)
|
||||||
t.Error(err)
|
is.NoErr(err)
|
||||||
}
|
is.True(test == testStruct) // decoded data should match testStruct
|
||||||
|
|
||||||
if test != testStruct {
|
|
||||||
t.Error("packet data does not match!")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDataEncrypt(t *testing.T) {
|
func TestDataEncrypt(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
buf := make([]byte, len(testData))
|
buf := make([]byte, len(testData))
|
||||||
copy(buf, testData[:])
|
copy(buf, testData[:])
|
||||||
|
|
||||||
protocol.EncryptData(buf, []byte(protocol.DEFAULT_KEY))
|
protocol.EncryptData(buf, []byte(protocol.DEFAULT_KEY))
|
||||||
|
|
||||||
if !bytes.Equal(buf, encTestData) {
|
is.True(bytes.Equal(buf, encTestData)) // encrypted data should match expected data
|
||||||
t.Error("encrypted data does not match!")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDataDecrypt(t *testing.T) {
|
func TestDataDecrypt(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
buf := make([]byte, len(encTestData))
|
buf := make([]byte, len(encTestData))
|
||||||
copy(buf, encTestData)
|
copy(buf, encTestData)
|
||||||
|
|
||||||
protocol.DecryptData(buf, []byte(protocol.DEFAULT_KEY))
|
protocol.DecryptData(buf, []byte(protocol.DEFAULT_KEY))
|
||||||
|
|
||||||
if !bytes.Equal(buf, testData[:]) {
|
is.True(bytes.Equal(buf, testData[:])) // decrypted data should match expected data
|
||||||
t.Error("decrypted data does not match!")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateNewKey(t *testing.T) {
|
func TestCreateNewKey(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
key := protocol.CreateNewKey(123456789, 0x1234567890abcdef, 0x1234567890abcdef)
|
key := protocol.CreateNewKey(123456789, 0x1234567890abcdef, 0x1234567890abcdef)
|
||||||
|
|
||||||
if !bytes.Equal(key, []byte{0x0, 0x31, 0xb8, 0xcd, 0xd, 0xc3, 0xad, 0x67}) {
|
is.True(bytes.Equal(key, []byte{0x0, 0x31, 0xb8, 0xcd, 0xd, 0xc3, 0xad, 0x67})) // key should match expected data
|
||||||
t.Error("key does not match!")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
"github.com/CPunch/gopenfusion/internal/protocol"
|
"github.com/CPunch/gopenfusion/internal/protocol"
|
||||||
"github.com/CPunch/gopenfusion/internal/service"
|
"github.com/CPunch/gopenfusion/internal/service"
|
||||||
|
"github.com/matryer/is"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -23,6 +24,15 @@ const (
|
|||||||
maxDummyPeers = 5
|
maxDummyPeers = 5
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func selectWithTimeout(ch <-chan struct{}, seconds int) bool {
|
||||||
|
select {
|
||||||
|
case <-ch:
|
||||||
|
return true
|
||||||
|
case <-time.After(time.Duration(seconds) * time.Second):
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func waitWithTimeout(wg *sync.WaitGroup, seconds int) bool {
|
func waitWithTimeout(wg *sync.WaitGroup, seconds int) bool {
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
@ -30,12 +40,7 @@ func waitWithTimeout(wg *sync.WaitGroup, seconds int) bool {
|
|||||||
wg.Wait()
|
wg.Wait()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
return selectWithTimeout(done, seconds)
|
||||||
case <-done:
|
|
||||||
return true
|
|
||||||
case <-time.After(time.Duration(seconds) * time.Second):
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
@ -49,34 +54,38 @@ func TestMain(m *testing.M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestService(t *testing.T) {
|
func TestService(t *testing.T) {
|
||||||
|
is := is.New(t)
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
srvc := service.NewService(ctx, "TEST", srvcPort)
|
srvc := service.NewService(ctx, "TEST", srvcPort)
|
||||||
|
|
||||||
// waitgroup to wait for test packet handler to be called
|
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
|
|
||||||
|
// shutdown service when test is done
|
||||||
|
defer func() {
|
||||||
|
cancel()
|
||||||
|
is.True(selectWithTimeout(srvc.Stopped(), timeout)) // wait for service to stop with timeout
|
||||||
|
}()
|
||||||
|
|
||||||
|
// our dummy packet handler
|
||||||
srvc.AddPacketHandler(0x1234, func(peer *protocol.CNPeer, pkt protocol.Packet) error {
|
srvc.AddPacketHandler(0x1234, func(peer *protocol.CNPeer, pkt protocol.Packet) error {
|
||||||
log.Printf("Received packet %#v", pkt)
|
log.Printf("Received packet %#v", pkt)
|
||||||
wg.Done()
|
wg.Done()
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// run service
|
||||||
go func() {
|
go func() {
|
||||||
if err := srvc.Start(); err != nil {
|
err := srvc.Start()
|
||||||
t.Error(err)
|
is.NoErr(err) // srvc.Start error
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// wait for service to start
|
is.True(selectWithTimeout(srvc.Started(), timeout)) // wait for service to start with timeout
|
||||||
<-srvc.Started()
|
|
||||||
wg.Add(maxDummyPeers * 3) // 2 wg.Done() calls per dummy peer
|
wg.Add(maxDummyPeers * 3) // 2 wg.Done() calls per dummy peer
|
||||||
for i := 0; i < maxDummyPeers; i++ {
|
for i := 0; i < maxDummyPeers; i++ {
|
||||||
go func() {
|
go func() {
|
||||||
// make dummy client
|
// make dummy client
|
||||||
conn, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", srvcPort))
|
conn, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", srvcPort))
|
||||||
if err != nil {
|
is.NoErr(err) // net.Dial error
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
peer := protocol.NewCNPeer(ctx, conn)
|
peer := protocol.NewCNPeer(ctx, conn)
|
||||||
go func() {
|
go func() {
|
||||||
@ -84,9 +93,8 @@ func TestService(t *testing.T) {
|
|||||||
|
|
||||||
// send dummy packets
|
// send dummy packets
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
if err := peer.Send(0x1234); err != nil {
|
err := peer.Send(0x1234)
|
||||||
t.Error(err)
|
is.NoErr(err) // peer.Send error
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -96,10 +104,5 @@ func TestService(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !waitWithTimeout(&wg, timeout) {
|
is.True(waitWithTimeout(&wg, timeout)) // wait for all dummy peers to be done with timeout
|
||||||
t.Error("failed to wait for packet handler to be called")
|
|
||||||
}
|
|
||||||
|
|
||||||
cancel()
|
|
||||||
<-srvc.Stopped()
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user