2020-04-24 03:02:58 +00:00
|
|
|
// +build integration
|
|
|
|
|
|
|
|
package voice
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
|
|
|
"io"
|
|
|
|
"log"
|
|
|
|
"os"
|
2020-04-25 02:36:33 +00:00
|
|
|
"runtime"
|
|
|
|
"strconv"
|
2020-04-24 03:02:58 +00:00
|
|
|
"testing"
|
2020-04-25 02:36:33 +00:00
|
|
|
"time"
|
2020-04-24 03:02:58 +00:00
|
|
|
|
|
|
|
"github.com/diamondburned/arikawa/discord"
|
|
|
|
"github.com/diamondburned/arikawa/state"
|
2020-04-25 02:36:33 +00:00
|
|
|
"github.com/diamondburned/arikawa/utils/wsutil"
|
|
|
|
"github.com/diamondburned/arikawa/voice/voicegateway"
|
2020-04-24 03:02:58 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type testConfig struct {
|
|
|
|
BotToken string
|
|
|
|
VoiceChID discord.Snowflake
|
|
|
|
}
|
|
|
|
|
|
|
|
func mustConfig(t *testing.T) testConfig {
|
|
|
|
var token = os.Getenv("BOT_TOKEN")
|
|
|
|
if token == "" {
|
|
|
|
t.Fatal("Missing $BOT_TOKEN")
|
|
|
|
}
|
|
|
|
|
|
|
|
var sid = os.Getenv("VOICE_ID")
|
|
|
|
if sid == "" {
|
|
|
|
t.Fatal("Missing $VOICE_ID")
|
|
|
|
}
|
|
|
|
|
|
|
|
id, err := discord.ParseSnowflake(sid)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal("Invalid $VOICE_ID:", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return testConfig{
|
|
|
|
BotToken: token,
|
|
|
|
VoiceChID: id,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// file is only a few bytes lolmao
|
2020-04-25 02:36:33 +00:00
|
|
|
func nicoReadTo(t *testing.T, dst io.Writer) {
|
2020-04-24 03:02:58 +00:00
|
|
|
f, err := os.Open("testdata/nico.dca")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal("Failed to open nico.dca:", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Cleanup(func() {
|
|
|
|
f.Close()
|
|
|
|
})
|
|
|
|
|
|
|
|
var lenbuf [4]byte
|
|
|
|
|
2020-04-25 02:36:33 +00:00
|
|
|
for {
|
2020-04-24 03:02:58 +00:00
|
|
|
if _, err := io.ReadFull(f, lenbuf[:]); !catchRead(t, err) {
|
2020-04-25 02:36:33 +00:00
|
|
|
return
|
2020-04-24 03:02:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Read the integer
|
2020-04-25 02:36:33 +00:00
|
|
|
framelen := int64(binary.LittleEndian.Uint32(lenbuf[:]))
|
2020-04-24 03:02:58 +00:00
|
|
|
|
2020-04-25 02:36:33 +00:00
|
|
|
// Copy the frame.
|
|
|
|
if _, err := io.CopyN(dst, f, framelen); !catchRead(t, err) {
|
|
|
|
return
|
2020-04-24 03:02:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func catchRead(t *testing.T, err error) bool {
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
if err == io.EOF {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal("Failed to read:", err)
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestIntegration(t *testing.T) {
|
|
|
|
config := mustConfig(t)
|
|
|
|
|
2020-04-25 02:36:33 +00:00
|
|
|
wsutil.WSDebug = func(v ...interface{}) {
|
|
|
|
_, file, line, _ := runtime.Caller(1)
|
|
|
|
caller := file + ":" + strconv.Itoa(line)
|
|
|
|
log.Println(append([]interface{}{caller}, v...)...)
|
2020-04-24 03:02:58 +00:00
|
|
|
}
|
2020-04-25 02:36:33 +00:00
|
|
|
|
2020-04-24 03:02:58 +00:00
|
|
|
// heart.Debug = func(v ...interface{}) {
|
|
|
|
// log.Println(append([]interface{}{"Pacemaker:"}, v...)...)
|
|
|
|
// }
|
|
|
|
|
|
|
|
s, err := state.New("Bot " + config.BotToken)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal("Failed to create a new session:", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
v := NewVoice(s)
|
|
|
|
|
|
|
|
if err := s.Open(); err != nil {
|
|
|
|
t.Fatal("Failed to connect:", err)
|
|
|
|
}
|
2020-04-25 02:36:33 +00:00
|
|
|
defer s.Close()
|
2020-04-24 03:02:58 +00:00
|
|
|
|
|
|
|
// Validate the given voice channel.
|
|
|
|
c, err := s.Channel(config.VoiceChID)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal("Failed to get channel:", err)
|
|
|
|
}
|
|
|
|
if c.Type != discord.GuildVoice {
|
|
|
|
t.Fatal("Channel isn't a guild voice channel.")
|
|
|
|
}
|
|
|
|
|
2020-04-25 02:36:33 +00:00
|
|
|
// Grab a timer to benchmark things.
|
|
|
|
finish := timer()
|
|
|
|
|
|
|
|
// Join the voice channel.
|
|
|
|
vs, err := v.JoinChannel(c.GuildID, c.ID, false, false)
|
2020-04-24 03:02:58 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal("Failed to join channel:", err)
|
|
|
|
}
|
2020-04-25 02:36:33 +00:00
|
|
|
defer func() {
|
|
|
|
log.Println("Disconnecting from the voice channel.")
|
|
|
|
if err := vs.Disconnect(); err != nil {
|
|
|
|
t.Fatal("Failed to disconnect:", err)
|
|
|
|
}
|
|
|
|
}()
|
2020-04-24 03:02:58 +00:00
|
|
|
|
2020-04-25 02:36:33 +00:00
|
|
|
finish("joining the voice channel")
|
2020-04-24 03:02:58 +00:00
|
|
|
|
|
|
|
// Trigger speaking.
|
2020-04-25 02:36:33 +00:00
|
|
|
if err := vs.Speaking(voicegateway.Microphone); err != nil {
|
2020-04-24 03:02:58 +00:00
|
|
|
t.Fatal("Failed to start speaking:", err)
|
|
|
|
}
|
2020-04-25 02:36:33 +00:00
|
|
|
defer func() {
|
|
|
|
log.Println("Stopping speaking.") // sounds grammatically wrong
|
|
|
|
if err := vs.StopSpeaking(); err != nil {
|
|
|
|
t.Fatal("Failed to stop speaking:", err)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
finish("sending the speaking command")
|
2020-04-24 03:02:58 +00:00
|
|
|
|
|
|
|
// Copy the audio?
|
2020-04-25 02:36:33 +00:00
|
|
|
nicoReadTo(t, vs)
|
2020-04-24 03:02:58 +00:00
|
|
|
|
2020-04-25 02:36:33 +00:00
|
|
|
finish("copying the audio")
|
|
|
|
}
|
|
|
|
|
|
|
|
// simple shitty benchmark thing
|
|
|
|
func timer() func(finished string) {
|
|
|
|
var then = time.Now()
|
2020-04-24 03:02:58 +00:00
|
|
|
|
2020-04-25 02:36:33 +00:00
|
|
|
return func(finished string) {
|
|
|
|
now := time.Now()
|
|
|
|
log.Println("Finished", finished+", took", now.Sub(then))
|
|
|
|
then = now
|
2020-04-24 03:02:58 +00:00
|
|
|
}
|
|
|
|
}
|