tboy

package
v1.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 11, 2025 License: MIT Imports: 15 Imported by: 1

README

Test Boy

TBoy是一个测试框架,模拟FreeSWITCH的行为。

核心模拟一些基本的操作,可以直接使用,也可以根据需要进行扩展。参见ecc/ttboy的扩展用法。

考虑呼叫的各种情况,秒接,30秒接,不接,拒接,等等,都可以扩展tboy。我们吸收了多种情况下的tboy,在测试的时候选个合适的boy,给定适当的参数配置就可以测试多种情况,而不用自己拿着3个话机互相打。

点对点呼叫

node_uuid    = "simple-test.simple"
domain       = "test.test"
  • 秒接

    boy := tboy.NewSimple(node_uuid, domain, tboy.OptionPeerAnswer(true))
    
  • 30秒接

    boy := tboy.NewSimple(node_uuid, domain, tboy.OptionPeerAnswer(true), tboy.OptionPeerWait(30))
    
  • 拒接

    boy := tboy.NewSimple(node_uuid, domain, tboy.OptionPeerReject(true))
    

队列呼叫

  • 未分配坐席

    boy := tboy.NewACD(node_uuid, domain, tboy.OptionAcdAssign(false))
    
  • 分配坐席未接

    boy := tboy.NewACD(node_uuid, domain, tboy.OptionAcdAssign(true), tboy.OptionPeerAnswer(false))
    
  • 分配坐席接听

boy := tboy.NewACD(node_uuid, domain, tboy.OptionAcdAssign(true), tboy.OptionPeerAnswer(true))

使用方式

1,预先启动一个nats服务器

2,根据呼叫测试情况,启用一个呼叫boy

node_uuid    = "simple-test.simple"
node_topic   = "simple-test"
domain       = "test.test"
boy := tboy.NewSimple(node_uuid, domain, tboy.OptionPeerAnswer(true))
err := ctrl.Init(boy, true, natsAddress)
	fmt.Println(err)

ctrl.Subscribe("cn.xswitch.node.test", boy.EventCallback, "node")
ctrl.Subscribe("cn.xswitch.node.test."+node_topic, boy.EventCallback, "node")
ctrl.Subscribe("cn.xswitch.node.test."+node_uuid, boy.EventCallback, "")

3,调用dial接口测试呼叫流程

nodejs调用单个方法

var rpc = {
	jsonrpc: "2.0",
	method: "XNode.Play",
	id: id,
	params: {
		ctrl_uuid: 'test-nodejs-controller',
		data: file
		uuid: uuid
	}
}
service = "cn.xswitch.node.test"
const msg = JSON.stringify(rpc);
console.log("sending " + msg);
nc.subscribe('cn.xswitch.ctrl.test-nodejs-controller',function (msg, reply, subject, sid) {...});
nc.request(service, msg, { max: 1, timeout: 5000 }, (msg) => {...});

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Channels map[string]*FakeChannel

Functions

func CacheChannel

func CacheChannel(uuid string, channel *FakeChannel)

Types

type App

type App struct {
	App  string `json:"app,omitempty"`
	Data string `json:"data,omitempty"`
}

App .

type CallDetailRecord

type CallDetailRecord struct {
	UUID                        string `json:"uuid" validate:"required"`       // 话单UUID
	Domain                      string `json:"xcc_domain"`                     // 域
	Mark                        string `json:"xcc_mark"`                       // 号码方向
	UID                         string `json:"xcc_uid"`                        // 用户UID
	Context                     string `json:"context"`                        // context
	Billsec                     int    `json:"billsec,string"`                 // 通话时长
	CallerIDName                string `json:"caller_id_name"`                 // 主叫名称
	CallerIDNumber              string `json:"caller_id_number"`               // 主叫号码
	DestinationNumber           string `json:"destination_number"`             // 被叫号码
	OriginCidNumber             string `json:"xcc_origin_cid_number"`          // 原始主叫号码
	OriginDestNumber            string `json:"xcc_origin_dest_number"`         // 原始被叫号码
	OriginOutboundCidNumber     string `json:"xcc_origin_outbound_cid_number"` // 原始外显号码
	StationType                 string `json:"xcc_stationtype"`                // SIP | PSTN
	Direction                   string `json:"direction"`                      // 逻辑方向
	Duration                    int    `json:"duration,string"`                // 花费时长
	HangupCause                 string `json:"hangup_cause"`                   // 挂机原因
	PeerUUID                    string `json:"peer_uuid"`                      // 对端UUID
	SipToHost                   string `json:"sip_to_host"`                    //
	SipFromHost                 string `json:"sip_from_host"`                  //
	SipDisplay                  string `json:"sip_from_display"`               //
	SipNetworkAddr              string `json:"sip_local_network_addr"`         //
	SipNetworkPort              int    `json:"sip_network_port,string"`        //
	SipHangupDisposition        string `json:"sip_hangup_disposition,omitempty"`
	SofiaProfileName            string `json:"sofia_profile_name"`               // default 分机号码, public 外线号码, interconnect 转移
	SofiaProfileURL             string `json:"sofia_profile_url"`                //
	StartStamp                  string `json:"start_stamp"`                      // 开始时间
	AnswerStamp                 string `json:"answer_stamp"`                     // 接听时间
	EndStamp                    string `json:"end_stamp"`                        // 结束时间
	Leg                         string `json:"leg"`                              //
	ServingSide                 string `json:"cc_side"`                          //
	ServingAgentUUID            string `json:"cc_agent"`                         // 坐席UUID
	ServingAgentName            string `json:"cc_agent_name"`                    // 坐席名称
	ServingAgentScore           int    `json:"cc_agent_rating_score,string"`     // 评分
	ServingAgentSession         string `json:"cc_agent_session_uuid"`            //
	ServingAgentEmployeeNumber  string `json:"cc_agent_employee_number"`         // 工号
	ServingQueueUUID            string `json:"cc_queue"`                         // 队列UUID
	ServingQueueName            string `json:"cc_queue_name"`                    // 队列名称
	ServingQueueJoinedEpoch     int64  `json:"cc_queue_joined_epoch,string"`     // 加入队列时间
	ServingQueueAnsweredEpoch   int64  `json:"cc_queue_answered_epoch,string"`   // 坐席应答时间
	ServingQueueTerminatedEpoch int64  `json:"cc_queue_terminated_epoch,string"` // 坐席挂机时间
	ServingContact              string `json:"cc_contact"`                       //
	MemberUUID                  string `json:"cc_member_uuid"`                   // 成员UUID
	MemberSession               string `json:"cc_member_session_uuid"`           //
	Session                     string `json:"xcc_session"`                      // session
}

CallDetailRecord 话单详情

type ConfControlRequest added in v1.3.1

type ConfControlRequest struct {
	Command        string `json:"command"`
	ConferenceName string `json:"conference_name"`
	AgoraUID       string `json:"agora_uid,omitempty"`
	Value          string `json:"value,omitempty"`
}

type ConfControlResponse added in v1.3.1

type ConfControlResponse struct {
	Code     int32  `json:"code"`
	Message  string `json:"message"`
	NodeUuid string `json:"node_uuid"`
}

type ConferenceEvent added in v1.3.1

type ConferenceEvent struct {
	NodeUuid   string `json:"node_uuid"`
	Uuid       string `json:"uuid"`
	Action     string `json:"action"`
	Conference string `json:"conference"`
	Muted      bool   `json:"muted,omitempty"`
	VMuted     bool   `json:"vmute,omitempty"`
}

type Dialplan

type Dialplan struct {
	UID                string `json:"xcc_uid,omitempty"`
	UUID               string `json:"uuid,omitempty"`
	NodeUUID           string `json:"node_uuid,omitempty"`
	Domain             string `json:"xcc_domain,omitempty"`
	Context            string `json:"context,omitempty"`
	FromHost           string `json:"sip_from_host,omitempty"`
	ToHost             string `json:"sip_to_host,omitempty"`
	Network            string `json:"sip_network,omitempty"`
	Date               string `json:"date_local,omitempty"`
	Direction          string `json:"caller_direction,omitempty"`
	CallerName         string `json:"caller_name,omitempty"`
	CallerNumber       string `json:"caller_number,omitempty"`
	DestinationNumber  string `json:"destination_number,omitempty"`
	RoutingTag         string `json:"xcc_routing_tag,omitempty"`
	RouteUuid          string `json:"xcc_route_uuid,omitempty"`
	RedlistExecChecked string `json:"xcc_redlist_exec_checked,omitempty"` // 判断是否已经执行过红名单

	OriginCidNumber  string // 内部转发带不过来,需从 session 中取
	OriginDestNumber string // 内部转发带不过来,需从 session 中取

	Session string `json:"xcc_session,omitempty"`
}

Dialplan .

type FakeChannel

type FakeChannel struct {
	CtrlUuid string
	PeerUuid string
	Lock     sync.RWMutex
	Data     *xctrl.ChannelEvent
	Context  context.Context
	Cancel   context.CancelFunc
}

type FakeConferenceChannel added in v1.3.1

type FakeConferenceChannel struct {
	*FakeChannel
	ConferenceId string
	Muted        bool
	VMuted       bool
}

type FakeFakeCdrChannel added in v1.3.1

type FakeFakeCdrChannel struct {
	CtrlUuid string
	UUID     string
	Lock     sync.RWMutex
	Data     *xctrl.ChannelEvent
	Context  context.Context
	Cancel   context.CancelFunc
	// store cdr data
	CDRData *CallDetailRecord
}

type FakeFakeCdrServer added in v1.3.1

type FakeFakeCdrServer struct {
	NodeUUID string
	Domain   string
	Channels map[string]*FakeFakeCdrChannel
	Lock     sync.RWMutex
}

func NewFakeFakeCdrServer added in v1.3.1

func NewFakeFakeCdrServer(nodeUUID, domain string) *FakeFakeCdrServer

func (*FakeFakeCdrServer) Answer added in v1.3.1

func (server *FakeFakeCdrServer) Answer(ctx context.Context, msg *ctrl.Message, reply string)

func (*FakeFakeCdrServer) CacheChannel added in v1.3.1

func (server *FakeFakeCdrServer) CacheChannel(uuid string, channel *FakeFakeCdrChannel)

func (*FakeFakeCdrServer) DeleteChannel added in v1.3.1

func (server *FakeFakeCdrServer) DeleteChannel(uuid string)

func (*FakeFakeCdrServer) Dial added in v1.3.1

func (server *FakeFakeCdrServer) Dial(ctx context.Context, msg *ctrl.Message, reply string)

func (*FakeFakeCdrServer) Error added in v1.3.1

func (server *FakeFakeCdrServer) Error(ctx context.Context, msg *ctrl.Message, reply string)

func (*FakeFakeCdrServer) Event added in v1.3.1

func (server *FakeFakeCdrServer) Event(msg *ctrl.Message, natsEvent nats.Event)

func (*FakeFakeCdrServer) GetChannel added in v1.3.1

func (server *FakeFakeCdrServer) GetChannel(uuid string) (*FakeFakeCdrChannel, bool)

func (*FakeFakeCdrServer) Hangup added in v1.3.1

func (server *FakeFakeCdrServer) Hangup(ctx context.Context, msg *ctrl.Message, reply string)

func (*FakeFakeCdrServer) OK added in v1.3.1

func (server *FakeFakeCdrServer) OK(ctx context.Context, msg *ctrl.Message, reply string)

func (*FakeFakeCdrServer) SendCDR added in v1.3.1

func (server *FakeFakeCdrServer) SendCDR(channel *FakeFakeCdrChannel)

type FakeFakeIvrChannel added in v1.3.1

type FakeFakeIvrChannel struct {
	CtrlUuid string
	UUID     string
	Lock     sync.RWMutex
	Data     *xctrl.ChannelEvent
	Context  context.Context
	Cancel   context.CancelFunc
	DTMF     string // 存储接收到的DTMF按键
}

FakeFakeIvrChannel 模拟IVR通道

type FakeFakeIvrServer added in v1.3.1

type FakeFakeIvrServer struct {
	NodeUUID string
	Domain   string
	Channels map[string]*FakeFakeIvrChannel
	Lock     sync.RWMutex
}

FakeFakeIvrServer IVR服务器

func NewFakeFakeIvrServer added in v1.3.1

func NewFakeFakeIvrServer(nodeUUID, domain string) *FakeFakeIvrServer

NewFakeFakeIvrServer 创建新的IVR服务器

func (*FakeFakeIvrServer) Answer added in v1.3.1

func (server *FakeFakeIvrServer) Answer(ctx context.Context, msg *ctrl.Message, reply string)

Answer 处理应答请求

func (*FakeFakeIvrServer) CacheChannel added in v1.3.1

func (server *FakeFakeIvrServer) CacheChannel(uuid string, channel *FakeFakeIvrChannel)

CacheChannel 缓存通道

func (*FakeFakeIvrServer) CreateTestCall added in v1.3.1

func (server *FakeFakeIvrServer) CreateTestCall(ctrlUUID, caller, callee string)

CreateTestCall 创建测试通话

func (*FakeFakeIvrServer) DeleteChannel added in v1.3.1

func (server *FakeFakeIvrServer) DeleteChannel(uuid string)

DeleteChannel 删除通道

func (*FakeFakeIvrServer) Error added in v1.3.1

func (server *FakeFakeIvrServer) Error(ctx context.Context, msg *ctrl.Message, reply string)

Error 发送错误响应

func (*FakeFakeIvrServer) Event added in v1.3.1

func (server *FakeFakeIvrServer) Event(msg *ctrl.Message, natsEvent nats.Event)

Event 处理事件

func (*FakeFakeIvrServer) GetChannel added in v1.3.1

func (server *FakeFakeIvrServer) GetChannel(uuid string) (*FakeFakeIvrChannel, bool)

GetChannel 获取通道

func (*FakeFakeIvrServer) Hangup added in v1.3.1

func (server *FakeFakeIvrServer) Hangup(ctx context.Context, msg *ctrl.Message, reply string)

Hangup 处理挂机请求

func (*FakeFakeIvrServer) OK added in v1.3.1

func (server *FakeFakeIvrServer) OK(ctx context.Context, msg *ctrl.Message, reply string)

OK 发送成功响应

func (*FakeFakeIvrServer) Play added in v1.3.1

func (server *FakeFakeIvrServer) Play(ctx context.Context, msg *ctrl.Message, reply string)

Play 处理播放请求

func (*FakeFakeIvrServer) ReadDTMF added in v1.3.1

func (server *FakeFakeIvrServer) ReadDTMF(ctx context.Context, msg *ctrl.Message, reply string)

ReadDTMF 处理DTMF读取请求

func (*FakeFakeIvrServer) SetDTMF added in v1.3.1

func (server *FakeFakeIvrServer) SetDTMF(callUUID, dtmf string) bool

SetDTMF 设置DTMF输入(用于测试)

func (*FakeFakeIvrServer) SetVar added in v1.3.1

func (server *FakeFakeIvrServer) SetVar(ctx context.Context, msg *ctrl.Message, reply string)

SetVar 处理设置变量请求

type FakeLayoutChannel added in v1.3.1

type FakeLayoutChannel struct {
	*FakeChannel
	ConferenceName string
	Layout         string
	AgoraUID       string
}

type Layout added in v1.3.1

type Layout struct {
	*TBoy
	LayoutChannels map[string]*FakeLayoutChannel
	LayoutLock     sync.RWMutex
}

func NewTBoyLayout added in v1.3.1

func NewTBoyLayout(tboy *TBoy) *Layout

func (*Layout) CacheLayoutChannel added in v1.3.1

func (boy *Layout) CacheLayoutChannel(uuid string, channel *FakeLayoutChannel)

func (*Layout) ConfControl added in v1.3.1

func (boy *Layout) ConfControl(ctx context.Context, msg *ctrl.Message, reply string)

func (*Layout) ConfControlError added in v1.3.1

func (boy *Layout) ConfControlError(ctx context.Context, msg *ctrl.Message, reply string, errorMsg string)

func (*Layout) ConfControlOK added in v1.3.1

func (boy *Layout) ConfControlOK(ctx context.Context, msg *ctrl.Message, reply string)

func (*Layout) Event added in v1.3.1

func (boy *Layout) Event(msg *ctrl.Message, natsEvent nats.Event)

func (*Layout) GetConferenceLayout added in v1.3.1

func (boy *Layout) GetConferenceLayout(conferenceName string) string

func (*Layout) GetConferenceMembers added in v1.3.1

func (boy *Layout) GetConferenceMembers(conferenceName string) []*FakeLayoutChannel

func (*Layout) GetConferenceStats added in v1.3.1

func (boy *Layout) GetConferenceStats(conferenceName string) map[string]interface{}

func (*Layout) GetLayoutChannel added in v1.3.1

func (boy *Layout) GetLayoutChannel(uuid string) (*FakeLayoutChannel, bool)

func (*Layout) Hangup added in v1.3.1

func (boy *Layout) Hangup(ctx context.Context, msg *ctrl.Message, reply string)

func (*Layout) Init added in v1.3.1

func (boy *Layout) Init()

func (*Layout) JoinConference added in v1.3.1

func (boy *Layout) JoinConference(uuid, conferenceName, agoraUID string)

func (*Layout) RemoveFromLayout added in v1.3.1

func (boy *Layout) RemoveFromLayout(uuid string)

func (*Layout) SetConferenceLayout added in v1.3.1

func (boy *Layout) SetConferenceLayout(conferenceName, layout string)

type LayoutEvent added in v1.3.1

type LayoutEvent struct {
	NodeUuid       string `json:"node_uuid"`
	ConferenceName string `json:"conference_name"`
	AgoraUID       string `json:"agora_uid,omitempty"`
	Action         string `json:"action"`
	Layout         string `json:"layout,omitempty"`
	Value          string `json:"value,omitempty"`
}

type OptionFn

type OptionFn func(*Options)

func OptionAcdAssign

func OptionAcdAssign(assgin bool) OptionFn

func OptionActualPlay

func OptionActualPlay(play bool) OptionFn

func OptionPeerAnswer

func OptionPeerAnswer(answer bool) OptionFn

func OptionPeerReject

func OptionPeerReject(reject bool) OptionFn

func OptionPeerWait

func OptionPeerWait(wait int) OptionFn

type Options

type Options struct {
	PeerWait   int
	PeerAnswer bool
	PeerReject bool
	AcdAssign  bool
	ActualPlay bool
}

type RequestParam

type RequestParam struct {
	UUID     string `json:"uuid"`
	NodeIP   string `json:"node_ip"`
	NodeUUID string `json:"node_uuid"`

	CDR *CallDetailRecord `json:"cdr" validate:"required"`
}

RequestParam .

type TBoy

type TBoy struct {
	NodeUUID string
	Domain   string
	*Options
}

TBoy .

func (*TBoy) Accept

func (boy *TBoy) Accept(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoy) Answer

func (boy *TBoy) Answer(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoy) Bridge

func (boy *TBoy) Bridge(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoy) ChannelBridge

func (boy *TBoy) ChannelBridge(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoy) Dial

func (boy *TBoy) Dial(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoy) DialError

func (boy *TBoy) DialError(ctx context.Context, msg *ctrl.Message, reply string, code int32)

func (*TBoy) Error

func (boy *TBoy) Error(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoy) Event

func (boy *TBoy) Event(msg *ctrl.Message, natsEvent nats.Event)

func (*TBoy) GetVar

func (boy *TBoy) GetVar(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoy) Hangup

func (boy *TBoy) Hangup(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoy) Init

func (boy *TBoy) Init()

func (*TBoy) NativeAPI

func (boy *TBoy) NativeAPI(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoy) NativeAPIStatus

func (boy *TBoy) NativeAPIStatus(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoy) NativeJSAPI

func (boy *TBoy) NativeJSAPI(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoy) NativeJSAPIStatus

func (boy *TBoy) NativeJSAPIStatus(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoy) OK

func (boy *TBoy) OK(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoy) ReadDTMF

func (boy *TBoy) ReadDTMF(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoy) Record

func (boy *TBoy) Record(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoy) SetDomain

func (boy *TBoy) SetDomain(domain string)

func (*TBoy) SetUUID

func (boy *TBoy) SetUUID(uuid string)

func (*TBoy) SetVar

func (boy *TBoy) SetVar(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoy) Stop

func (boy *TBoy) Stop(ctx context.Context, msg *ctrl.Message, reply string)

type TBoyACD

type TBoyACD struct {
	*TBoy
}

func NewACD

func NewACD(node_uuid string, domain string, fn ...OptionFn) *TBoyACD

NewTBoy .

func (*TBoyACD) AddChannel

func (boy *TBoyACD) AddChannel(key string, channel *FakeChannel)

func (*TBoyACD) Dial

func (boy *TBoyACD) Dial(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoyACD) Event

func (boy *TBoyACD) Event(msg *ctrl.Message, natsEvent nats.Event)

func (*TBoyACD) Play

func (boy *TBoyACD) Play(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoyACD) Transfer

func (boy *TBoyACD) Transfer(ctx context.Context, msg *ctrl.Message, reply string)

type TBoyConference added in v1.3.1

type TBoyConference struct {
	*TBoy
	ConferenceChannels map[string]*FakeConferenceChannel
	ConfLock           sync.RWMutex
}

func NewTBoyConference added in v1.3.1

func NewTBoyConference(tboy *TBoy) *TBoyConference

func (*TBoyConference) CacheConferenceChannel added in v1.3.1

func (boy *TBoyConference) CacheConferenceChannel(uuid string, channel *FakeConferenceChannel)

func (*TBoyConference) Conference added in v1.3.1

func (boy *TBoyConference) Conference(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoyConference) ConferenceInfo added in v1.3.1

func (boy *TBoyConference) ConferenceInfo(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoyConference) Event added in v1.3.1

func (boy *TBoyConference) Event(msg *ctrl.Message, natsEvent nats.Event)

func (*TBoyConference) GetConferenceChannel added in v1.3.1

func (boy *TBoyConference) GetConferenceChannel(uuid string) (*FakeConferenceChannel, bool)

func (*TBoyConference) GetConferenceMembers added in v1.3.1

func (boy *TBoyConference) GetConferenceMembers(conferenceName string) []*FakeConferenceChannel

func (*TBoyConference) Hangup added in v1.3.1

func (boy *TBoyConference) Hangup(ctx context.Context, msg *ctrl.Message, reply string)

func (*TBoyConference) Init added in v1.3.1

func (boy *TBoyConference) Init()

func (*TBoyConference) RemoveFromConference added in v1.3.1

func (boy *TBoyConference) RemoveFromConference(uuid string)

type TBoySimple

type TBoySimple struct {
	*TBoy
}

func NewSimple

func NewSimple(node_uuid string, domain string, fn ...OptionFn) *TBoySimple

NewTBoy .

func (*TBoySimple) AddChannel

func (boy *TBoySimple) AddChannel(key string, channel *FakeChannel)

func (*TBoySimple) ChannelEvent

func (boy *TBoySimple) ChannelEvent(ctx context.Context, channel *ctrl.Channel)

we don't use this method in node side

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL