package service_test import ( "fmt" "sync" "time" "apigo.cc/gojs" _ "apigo.cc/gojs/console" _ "apigo.cc/gojs/http" "apigo.cc/gojs/service" _ "apigo.cc/gojs/service" _ "apigo.cc/gojs/util" "github.com/ssgo/discover" "github.com/ssgo/httpclient" "github.com/ssgo/u" //"go.uber.org/goleak" //_ "net/http/pprof" "runtime" "testing" ) var rt2 *gojs.Runtime var addrByPool = "" const runTimes2 = 100 //func TestMain(m *testing.M) { // // Verify no goroutines are leaked after tests // goleak.VerifyTestMain(m) //} func TestStartByPool(t *testing.T) { //go func() { // fmt.Println(u.BYellow(http.ListenAndServe("localhost:6060", nil))) //}() gojs.ExportForDev() rt2 = gojs.New() err := rt2.StartFromFile("start.js") if err != nil { t.Fatal("start failed", err) } r, err := rt2.RunMain() if err != nil { t.Fatal("start failed", err) } addrByPool = u.String(r) discover.SetNode("user", addrByPool, 100) } // TODO Caller // TODO WS // func TestWS(t *testing.T) { // r, err := rt2.RunCode("testWS()") // if err != nil { // t.Fatal("test ws failed, got error", err) // } else if r != true { // t.Fatal("test ws failed", r, err) // } else { // fmt.Println(u.BGreen("test ws success")) // } // } func TestSession(t *testing.T) { r, err := rt2.RunCode("testUser()") if err != nil { t.Fatal("test user failed, got error", err, r) } else if r != true { t.Fatal("test user failed", r) } } func TestJsEchoByPool(t *testing.T) { for i := 0; i < runTimes2; i++ { name := u.UniqueId() r, err := rt2.RunCode("test2('" + name + "')") if err != nil { t.Fatal("test js get failed, got error", err) } else if r != name { t.Fatal("test js get failed, name not match", r, name) } } } func TestGoEchoByPool(t *testing.T) { hc := httpclient.GetClientH2C(0) for i := 0; i < runTimes2; i++ { name := u.UniqueId() r := hc.Get("http://" + addrByPool + "/echo2?name=" + name) if r.Error != nil { t.Fatal("test go get failed, got error", r.Error) } else if r.String() != name { t.Fatal("test go get failed, name not match", r, name) } } } func TestJsAsyncEchoByPool(t *testing.T) { ch := make(chan bool, runTimes2) t1 := time.Now().UnixMilli() for i := 0; i < runTimes2; i++ { go func() { name := u.UniqueId() r, err := rt2.RunCode("test2('" + name + "')") ch <- true if err != nil { t.Fatal("test js async get failed, got error", err) } else if r != name { t.Fatal("test js async get failed, name not match", r, name) } }() } for i := 0; i < runTimes2; i++ { <-ch } t2 := time.Now().UnixMilli() - t1 fmt.Println(u.BGreen("js async test time:"), t2, "ms") } func TestGoAsyncEchoByPool(t *testing.T) { //defer goleak.VerifyNone(t) hc := httpclient.GetClientH2C(0) const taskNum = 100 const taskRunTimes = 100 for j := 0; j < 10; j++ { ch := make(chan bool, taskNum*taskRunTimes) t1 := time.Now().UnixMilli() //for j := 0; j < 10; j++ { ms1 := runtime.MemStats{} runtime.ReadMemStats(&ms1) okNum := 0 failedNum := 0 startNum := 0 endNum := 0 lastName := fmt.Sprint("Task_", taskNum-1, "_", taskRunTimes-1) lastResult := "" lastOK := false okMap := map[string]int{} okMapLock := sync.Mutex{} for i1 := 0; i1 < taskNum; i1++ { name1 := fmt.Sprint("Task_", i1, "_") go func() { for i2 := 0; i2 < taskRunTimes; i2++ { name := fmt.Sprint(name1, i2) okMapLock.Lock() okMap[name] = 1 startNum++ okMapLock.Unlock() r := hc.Get("http://" + addrByPool + "/echo2?name=" + name) okMapLock.Lock() if name == lastName { lastResult = r.String() lastOK = lastName == lastResult } if r.Error != nil { failedNum++ t.Fatal("test go async get failed, got error", r.Error) } else if r.String() != name { failedNum++ t.Fatal("test go async get failed, name not match", r, name) } else { okMap[name] = 2 okNum++ } endNum++ okMapLock.Unlock() ch <- true } }() } for i := 0; i < taskNum*taskRunTimes; i++ { <-ch } for i1 := 0; i1 < taskNum; i1++ { for i2 := 0; i2 < taskRunTimes; i2++ { name := fmt.Sprint("Task_", i1, "_", i2) if okMap[name] != 2 { fmt.Println(i1, i2, okMap[name]) } } } if okNum != taskNum*taskRunTimes { t.Fatal("test go async get failed, ok num is error", okNum, taskNum*taskRunTimes, failedNum, "|", startNum, ">", endNum, "||", lastName, lastResult, lastOK) } t2 := time.Now().UnixMilli() - t1 fmt.Println(u.Green("go async test time:"), u.BGreen(t2), "ms") for k, status := range service.GetPoolStatus() { fmt.Println(u.Magenta(k), u.Magenta("total"), u.BMagenta(status.Total), u.Magenta("maxTotal"), u.BMagenta(status.MaxTotal), u.Magenta("createTimes"), u.BMagenta(status.CreateTimes), u.Magenta("maxWaiting"), u.BMagenta(status.MaxWaiting)) } //fmt.Println(u.BGreen("last name:"), lastName, lastResult, lastOK) if !lastOK { t.Fatal("test go async get failed, last name not match", lastName, lastResult, lastOK) } ms2 := runtime.MemStats{} runtime.ReadMemStats(&ms2) runtime.GC() ms3 := runtime.MemStats{} runtime.ReadMemStats(&ms3) fmt.Println(u.Cyan("MEMORY >>"), u.BCyan(fmt.Sprintln(ms1.HeapInuse/1000000, ms2.HeapInuse/1000000, ms3.HeapInuse/1000000))) } //hc.Destroy() //time.Sleep(1000 * time.Second) } func TestStopByPool(t *testing.T) { _, err := rt2.RunCode("s.stop()") if err != nil { t.Fatal("stop failed", err) } gojs.WaitAll() runtime.GC() ms3 := runtime.MemStats{} runtime.ReadMemStats(&ms3) fmt.Println(u.Cyan("END MEMORY >>"), u.BCyan(ms3.HeapInuse/1000000)) }