add more unit test cases for web server

This commit is contained in:
John 2018-12-30 22:02:46 +08:00
parent 1efeb2515d
commit 98619f9bc9
7 changed files with 245 additions and 15 deletions

View File

@ -3,6 +3,7 @@
// This Source Code Form is subject to the terms of the MIT License. // This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file, // If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf. // You can obtain one at https://gitee.com/johng/gf.
// HTTP客户端请求. // HTTP客户端请求.
package ghttp package ghttp
@ -40,7 +41,7 @@ func NewClient() (*Client) {
} }
} }
// 设置HTTP Headerss // 设置HTTP Header
func (c *Client) SetHeader(key, value string) { func (c *Client) SetHeader(key, value string) {
c.header[key] = value c.header[key] = value
} }
@ -223,3 +224,58 @@ func Trace(url, data string) (*ClientResponse, error) {
func DoRequest(method, url string, data []byte) (*ClientResponse, error) { func DoRequest(method, url string, data []byte) (*ClientResponse, error) {
return NewClient().DoRequest(method, url, data) return NewClient().DoRequest(method, url, data)
} }
// GET请求并返回服务端结果(内部会自动读取服务端返回结果并关闭缓冲区指针)
func GetContent(url string, data...string) string {
return RequestContent("GET", url, data...)
}
// PUT请求并返回服务端结果(内部会自动读取服务端返回结果并关闭缓冲区指针)
func PutContent(url string, data...string) string {
return RequestContent("PUT", url, data...)
}
// POST请求并返回服务端结果(内部会自动读取服务端返回结果并关闭缓冲区指针)
func PostContent(url string, data...string) string {
return RequestContent("POST", url, data...)
}
// DELETE请求并返回服务端结果(内部会自动读取服务端返回结果并关闭缓冲区指针)
func DeleteContent(url string, data...string) string {
return RequestContent("DELETE", url, data...)
}
func HeadContent(url string, data...string) string {
return RequestContent("HEAD", url, data...)
}
func PatchContent(url string, data...string) string {
return RequestContent("PATCH", url, data...)
}
func ConnectContent(url string, data...string) string {
return RequestContent("CONNECT", url, data...)
}
func OptionsContent(url string, data...string) string {
return RequestContent("OPTIONS", url, data...)
}
func TraceContent(url string, data...string) string {
return RequestContent("TRACE", url, data...)
}
// 请求并返回服务端结果(内部会自动读取服务端返回结果并关闭缓冲区指针)
func RequestContent(method string, url string, data...string) string {
content := ""
if len(data) > 0 {
content = data[0]
}
response, err := NewClient().DoRequest(method, url, []byte(content))
if err != nil {
return ""
}
defer response.Close()
return string(response.ReadAll())
}

View File

@ -0,0 +1,49 @@
// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
package ghttp_test
import (
"gitee.com/johng/gf/g"
"gitee.com/johng/gf/g/net/ghttp"
"gitee.com/johng/gf/g/os/gtime"
"gitee.com/johng/gf/g/util/gtest"
"testing"
"time"
)
// 基本路由功能以及优先级测试
func Test_Router_Basic(t *testing.T) {
s := g.Server(gtime.Nanosecond())
s.BindHandler("/:name", func(r *ghttp.Request){
r.Response.Write("/:name")
})
s.BindHandler("/:name/update", func(r *ghttp.Request){
r.Response.Write(r.Get("name"))
})
s.BindHandler("/:name/:action", func(r *ghttp.Request){
r.Response.Write(r.Get("action"))
})
s.BindHandler("/:name/*any", func(r *ghttp.Request){
r.Response.Write(r.Get("any"))
})
s.BindHandler("/user/list/{field}.html", func(r *ghttp.Request){
r.Response.Write(r.Get("field"))
})
s.SetPort(8199)
s.SetDumpRouteMap(false)
go s.Run()
defer s.Shutdown()
// 等待启动完成
time.Sleep(time.Second)
gtest.Case(func() {
gtest.Assert(ghttp.GetContent("http://127.0.0.1:8199/john"), "")
gtest.Assert(ghttp.GetContent("http://127.0.0.1:8199/john/update"), "john")
gtest.Assert(ghttp.GetContent("http://127.0.0.1:8199/john/edit"), "edit")
gtest.Assert(ghttp.GetContent("http://127.0.0.1:8199/user/list/100.html"), "100")
})
}

View File

@ -0,0 +1,115 @@
// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
// 分组路由测试
package ghttp_test
import (
"gitee.com/johng/gf/g"
"gitee.com/johng/gf/g/frame/gmvc"
"gitee.com/johng/gf/g/net/ghttp"
"gitee.com/johng/gf/g/os/gtime"
"gitee.com/johng/gf/g/util/gtest"
"testing"
"time"
)
// 执行对象
type Object struct {}
func (o *Object) Show(r *ghttp.Request) {
r.Response.Write("Object Show")
}
func (o *Object) Delete(r *ghttp.Request) {
r.Response.Write("Object REST Delete")
}
// 控制器
type Controller struct {
gmvc.Controller
}
func (c *Controller) Show() {
c.Response.Write("Controller Show")
}
func (c *Controller) Post() {
c.Response.Write("Controller REST Post")
}
func Handler(r *ghttp.Request) {
r.Response.Write("Handler")
}
func Test_Router_Group1(t *testing.T) {
s := g.Server(gtime.Nanosecond())
obj := new(Object)
ctl := new(Controller)
// 分组路由方法注册
g := s.Group("/api")
g.ALL ("/handler", Handler)
g.ALL ("/ctl", ctl)
g.GET ("/ctl/my-show", ctl, "Show")
g.REST("/ctl/rest", ctl)
g.ALL ("/obj", obj)
g.GET ("/obj/my-show", obj, "Show")
g.REST("/obj/rest", obj)
s.SetPort(8199)
s.SetDumpRouteMap(false)
go s.Run()
defer s.Shutdown()
time.Sleep(time.Second)
gtest.Case(func() {
gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/handler"), "Handler")
gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/ctl/my-show"), "Controller Show")
gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/ctl/post"), "Controller REST Post")
gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/ctl/show"), "Controller Show")
gtest.Assert(ghttp.PostContent("http://127.0.0.1:8199/api/ctl/rest"), "Controller REST Post")
gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/obj/delete"), "Object REST Delete")
gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/obj/my-show"), "Object Show")
gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/obj/show"), "Object Show")
gtest.Assert(ghttp.DeleteContent("http://127.0.0.1:8199/api/obj/rest"), "Object REST Delete")
})
}
func Test_Router_Group2(t *testing.T) {
s := g.Server(gtime.Nanosecond())
obj := new(Object)
ctl := new(Controller)
// 分组路由批量注册
s.Group("/api").Bind("/api", []ghttp.GroupItem{
{"ALL", "/handler", Handler},
{"ALL", "/ctl", ctl},
{"GET", "/ctl/my-show", ctl, "Show"},
{"REST", "/ctl/rest", ctl},
{"ALL", "/obj", obj},
{"GET", "/obj/my-show", obj, "Show"},
{"REST", "/obj/rest", obj},
})
s.SetPort(8199)
s.SetDumpRouteMap(false)
go s.Run()
defer s.Shutdown()
time.Sleep(time.Second)
gtest.Case(func() {
gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/handler"), "Handler")
gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/ctl/my-show"), "Controller Show")
gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/ctl/post"), "Controller REST Post")
gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/ctl/show"), "Controller Show")
gtest.Assert(ghttp.PostContent("http://127.0.0.1:8199/api/ctl/rest"), "Controller REST Post")
gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/obj/delete"), "Object REST Delete")
gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/obj/my-show"), "Object Show")
gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/obj/show"), "Object Show")
gtest.Assert(ghttp.DeleteContent("http://127.0.0.1:8199/api/obj/rest"), "Object REST Delete")
})
}

View File

@ -5,7 +5,7 @@
// You can obtain one at https://gitee.com/johng/gf. // You can obtain one at https://gitee.com/johng/gf.
// Package gtimew provides Time Wheel for interval jobs running management/时间轮. // Package gtimew provides Time Wheel for interval jobs running management/时间轮.
// 高效的时间轮任务执行管理,用于管理异步的间隔运行任务,或者异步延迟只运行一次的任务(最小时间粒度为秒)。 // 高效的时间轮任务执行管理,用于管理异步的间隔运行任务,或者异步只运行一次的任务(最小时间粒度为秒)。
// 与其他定时任务管理模块的区别是,时间轮模块只管理间隔执行任务,并且更注重执行效率(纳秒级别)。 // 与其他定时任务管理模块的区别是,时间轮模块只管理间隔执行任务,并且更注重执行效率(纳秒级别)。
package gtimew package gtimew
@ -61,6 +61,11 @@ func Entries() []*Entry {
return defaultWheel.Entries() return defaultWheel.Entries()
} }
// 当前时间轮已注册的任务数
func Size() int {
return defaultWheel.Size()
}
// 在Job方法中调用停止当前运行的Job // 在Job方法中调用停止当前运行的Job
func ExitJob() { func ExitJob() {
panic(gPANIC_EXIT) panic(gPANIC_EXIT)

View File

@ -32,7 +32,7 @@ func TestWheel_Add_Close(t *testing.T) {
gtest.AssertNE(entry1, nil) gtest.AssertNE(entry1, nil)
gtest.AssertNE(entry2, nil) gtest.AssertNE(entry2, nil)
gtest.AssertNE(entry3, nil) gtest.AssertNE(entry3, nil)
gtest.Assert(len(wheel.Entries()), 3) gtest.Assert(wheel.Size(), 3)
time.Sleep(1100*time.Millisecond) time.Sleep(1100*time.Millisecond)
gtest.Assert(array.Len(), 2) gtest.Assert(array.Len(), 2)
time.Sleep(1100*time.Millisecond) time.Sleep(1100*time.Millisecond)
@ -54,7 +54,7 @@ func TestWheel_Singlton(t *testing.T) {
time.Sleep(10*time.Second) time.Sleep(10*time.Second)
}) })
gtest.AssertNE(entry, nil) gtest.AssertNE(entry, nil)
gtest.Assert(len(wheel.Entries()), 1) gtest.Assert(wheel.Size(), 1)
time.Sleep(1100*time.Millisecond) time.Sleep(1100*time.Millisecond)
gtest.Assert(array.Len(), 1) gtest.Assert(array.Len(), 1)
@ -91,9 +91,9 @@ func TestWheel_DelayAdd(t *testing.T) {
gtest.Case(func() { gtest.Case(func() {
wheel := gtimew.New() wheel := gtimew.New()
wheel.DelayAdd(1, 1, func() {}) wheel.DelayAdd(1, 1, func() {})
gtest.Assert(len(wheel.Entries()), 0) gtest.Assert(wheel.Size(), 0)
time.Sleep(1100*time.Millisecond) time.Sleep(1100*time.Millisecond)
gtest.Assert(len(wheel.Entries()), 1) gtest.Assert(wheel.Size(), 1)
}) })
} }
@ -105,9 +105,9 @@ func TestWheel_DelayAdd_Singleton(t *testing.T) {
array.Append(1) array.Append(1)
time.Sleep(10*time.Second) time.Sleep(10*time.Second)
}) })
gtest.Assert(len(wheel.Entries()), 0) gtest.Assert(wheel.Size(), 0)
time.Sleep(1100*time.Millisecond) time.Sleep(1100*time.Millisecond)
gtest.Assert(len(wheel.Entries()), 1) gtest.Assert(wheel.Size(), 1)
gtest.Assert(array.Len(), 0) gtest.Assert(array.Len(), 0)
time.Sleep(1100*time.Millisecond) time.Sleep(1100*time.Millisecond)
@ -122,9 +122,9 @@ func TestWheel_DelayAdd_Once(t *testing.T) {
wheel.DelayAddOnce(1, 1, func() { wheel.DelayAddOnce(1, 1, func() {
array.Append(1) array.Append(1)
}) })
gtest.Assert(len(wheel.Entries()), 0) gtest.Assert(wheel.Size(), 0)
time.Sleep(1100*time.Millisecond) time.Sleep(1100*time.Millisecond)
gtest.Assert(len(wheel.Entries()), 1) gtest.Assert(wheel.Size(), 1)
gtest.Assert(array.Len(), 0) gtest.Assert(array.Len(), 0)
time.Sleep(1100*time.Millisecond) time.Sleep(1100*time.Millisecond)
@ -145,6 +145,6 @@ func TestWheel_ExitJob(t *testing.T) {
}) })
time.Sleep(1100*time.Millisecond) time.Sleep(1100*time.Millisecond)
gtest.Assert(array.Len(), 1) gtest.Assert(array.Len(), 1)
gtest.Assert(len(wheel.Entries()), 0) gtest.Assert(wheel.Size(), 0)
}) })
} }

View File

@ -23,7 +23,7 @@ func TestWheel_Entry_Operation(t *testing.T) {
array.Append(1) array.Append(1)
}) })
gtest.AssertNE(entry, nil) gtest.AssertNE(entry, nil)
gtest.Assert(len(wheel.Entries()), 1) gtest.Assert(wheel.Size(), 1)
time.Sleep(1100*time.Millisecond) time.Sleep(1100*time.Millisecond)
gtest.Assert(array.Len(), 1) gtest.Assert(array.Len(), 1)
entry.Stop() entry.Stop()
@ -44,7 +44,7 @@ func TestWheel_Entry_Singlton(t *testing.T) {
entry.SetMode(gtimew.MODE_SINGLETON) entry.SetMode(gtimew.MODE_SINGLETON)
gtest.AssertNE(entry, nil) gtest.AssertNE(entry, nil)
gtest.Assert(len(wheel.Entries()), 1) gtest.Assert(wheel.Size(), 1)
time.Sleep(1100*time.Millisecond) time.Sleep(1100*time.Millisecond)
gtest.Assert(array.Len(), 1) gtest.Assert(array.Len(), 1)
@ -61,8 +61,8 @@ func TestWheel_Entry_Once(t *testing.T) {
entry.SetMode(gtimew.MODE_ONCE) entry.SetMode(gtimew.MODE_ONCE)
gtest.AssertNE(entry, nil) gtest.AssertNE(entry, nil)
gtest.Assert(len(wheel.Entries()), 1) gtest.Assert(wheel.Size(), 1)
time.Sleep(1100*time.Millisecond) time.Sleep(1100*time.Millisecond)
gtest.Assert(array.Len(), 1) gtest.Assert(array.Len(), 1)
gtest.Assert(len(wheel.Entries()), 0) gtest.Assert(wheel.Size(), 0)
} }

View File

@ -75,6 +75,11 @@ func (w *Wheel) DelayAddOnce(delay int, interval int, job JobFunc) {
}() }()
} }
// 当前时间轮已注册的任务数
func (w *Wheel) Size() int {
return w.entries.Len()
}
// 关闭循环任务 // 关闭循环任务
func (w *Wheel) Close() { func (w *Wheel) Close() {
w.status.Set(STATUS_CLOSED) w.status.Set(STATUS_CLOSED)