mirror of
https://github.com/zeromicro/go-zero.git
synced 2026-05-07 15:10:01 +08:00
chore: add more tests (#4930)
This commit is contained in:
@@ -39,7 +39,7 @@ type (
|
|||||||
Telemetry trace.Config `json:",optional"`
|
Telemetry trace.Config `json:",optional"`
|
||||||
DevServer DevServerConfig `json:",optional"`
|
DevServer DevServerConfig `json:",optional"`
|
||||||
Shutdown proc.ShutdownConf `json:",optional"`
|
Shutdown proc.ShutdownConf `json:",optional"`
|
||||||
// Profiling is the configuration for profiling.
|
// Profiling is the configuration for continuous profiling.
|
||||||
Profiling profiling.Config `json:",optional"`
|
Profiling profiling.Config `json:",optional"`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -73,8 +73,8 @@ func (sc ServiceConf) SetUp() error {
|
|||||||
if len(sc.MetricsUrl) > 0 {
|
if len(sc.MetricsUrl) > 0 {
|
||||||
stat.SetReportWriter(stat.NewRemoteWriter(sc.MetricsUrl))
|
stat.SetReportWriter(stat.NewRemoteWriter(sc.MetricsUrl))
|
||||||
}
|
}
|
||||||
devserver.StartAgent(sc.DevServer)
|
|
||||||
|
|
||||||
|
devserver.StartAgent(sc.DevServer)
|
||||||
profiling.Start(sc.Profiling)
|
profiling.Start(sc.Profiling)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -6,27 +6,32 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/pyroscope-go"
|
"github.com/grafana/pyroscope-go"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"github.com/zeromicro/go-zero/core/proc"
|
"github.com/zeromicro/go-zero/core/proc"
|
||||||
"github.com/zeromicro/go-zero/core/stat"
|
"github.com/zeromicro/go-zero/core/stat"
|
||||||
"github.com/zeromicro/go-zero/core/threading"
|
"github.com/zeromicro/go-zero/core/threading"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultCheckInterval = time.Second * 10
|
||||||
|
defaultProfilingDuration = time.Minute * 2
|
||||||
|
defaultUploadRate = time.Second * 15
|
||||||
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
Config struct {
|
Config struct {
|
||||||
// Name is the name of the application.
|
// Name is the name of the application.
|
||||||
Name string `json:",optional,inherit"`
|
Name string `json:",optional,inherit"`
|
||||||
// ServerAddress is the address of the profiling server.
|
// ServerAddr is the address of the profiling server.
|
||||||
ServerAddress string
|
ServerAddr string
|
||||||
// AuthUser is the username for basic authentication.
|
// AuthUser is the username for basic authentication.
|
||||||
AuthUser string `json:",optional"`
|
AuthUser string `json:",optional"`
|
||||||
// AuthPassword is the password for basic authentication.
|
// AuthPassword is the password for basic authentication.
|
||||||
AuthPassword string `json:",optional"`
|
AuthPassword string `json:",optional"`
|
||||||
// UploadDuration is the duration for which profiling data is uploaded.
|
// UploadRate is the duration for which profiling data is uploaded.
|
||||||
UploadDuration time.Duration `json:",default=15s"`
|
UploadRate time.Duration `json:",default=15s"`
|
||||||
// IntervalDuration is the interval for which profiling data is collected.
|
// CheckInterval is the interval to check if profiling should start.
|
||||||
IntervalDuration time.Duration `json:",default=10s"`
|
CheckInterval time.Duration `json:",default=10s"`
|
||||||
// ProfilingDuration is the duration for which profiling data is collected.
|
// ProfilingDuration is the duration for which profiling data is collected.
|
||||||
ProfilingDuration time.Duration `json:",default=2m"`
|
ProfilingDuration time.Duration `json:",default=2m"`
|
||||||
// CpuThreshold the collection is allowed only when the current service cpu < CpuThreshold
|
// CpuThreshold the collection is allowed only when the current service cpu < CpuThreshold
|
||||||
@@ -56,7 +61,7 @@ type (
|
|||||||
Stop() error
|
Stop() error
|
||||||
}
|
}
|
||||||
|
|
||||||
pyProfiler struct {
|
pyroscopeProfiler struct {
|
||||||
c Config
|
c Config
|
||||||
profiler *pyroscope.Profiler
|
profiler *pyroscope.Profiler
|
||||||
}
|
}
|
||||||
@@ -66,63 +71,58 @@ var (
|
|||||||
once sync.Once
|
once sync.Once
|
||||||
|
|
||||||
newProfiler = func(c Config) profiler {
|
newProfiler = func(c Config) profiler {
|
||||||
return newPyProfiler(c)
|
return newPyroscopeProfiler(c)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Start initializes the pyroscope profiler with the given configuration.
|
// Start initializes the pyroscope profiler with the given configuration.
|
||||||
func Start(c Config) {
|
func Start(c Config) {
|
||||||
// check if the profiling is enabled
|
// check if the profiling is enabled
|
||||||
if c.ServerAddress == "" {
|
if len(c.ServerAddr) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// set default values for the configuration
|
// set default values for the configuration
|
||||||
if c.ProfilingDuration <= 0 {
|
if c.ProfilingDuration <= 0 {
|
||||||
c.ProfilingDuration = time.Minute * 2
|
c.ProfilingDuration = defaultProfilingDuration
|
||||||
}
|
}
|
||||||
|
|
||||||
// set default values for the configuration
|
// set default values for the configuration
|
||||||
if c.IntervalDuration <= 0 {
|
if c.CheckInterval <= 0 {
|
||||||
c.IntervalDuration = time.Second * 10
|
c.CheckInterval = defaultCheckInterval
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.UploadDuration <= 0 {
|
if c.UploadRate <= 0 {
|
||||||
c.UploadDuration = time.Second * 15
|
c.UploadRate = defaultUploadRate
|
||||||
}
|
}
|
||||||
|
|
||||||
once.Do(func() {
|
once.Do(func() {
|
||||||
logx.Info("continuous profiling started")
|
logx.Info("continuous profiling started")
|
||||||
|
|
||||||
var done = make(chan struct{})
|
|
||||||
proc.AddShutdownListener(func() {
|
|
||||||
done <- struct{}{}
|
|
||||||
close(done)
|
|
||||||
})
|
|
||||||
|
|
||||||
threading.GoSafe(func() {
|
threading.GoSafe(func() {
|
||||||
startPyroScope(c, done)
|
startPyroscope(c, proc.Done())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// startPyroScope starts the pyroscope profiler with the given configuration.
|
// startPyroscope starts the pyroscope profiler with the given configuration.
|
||||||
func startPyroScope(c Config, done <-chan struct{}) {
|
func startPyroscope(c Config, done <-chan struct{}) {
|
||||||
var (
|
var (
|
||||||
intervalTicker = time.NewTicker(c.IntervalDuration)
|
pr profiler
|
||||||
profilingTicker = time.NewTicker(c.ProfilingDuration)
|
err error
|
||||||
|
|
||||||
pr profiler
|
|
||||||
err error
|
|
||||||
|
|
||||||
latestProfilingTime time.Time
|
latestProfilingTime time.Time
|
||||||
|
intervalTicker = time.NewTicker(c.CheckInterval)
|
||||||
|
profilingTicker = time.NewTicker(c.ProfilingDuration)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
defer profilingTicker.Stop()
|
||||||
|
defer intervalTicker.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-intervalTicker.C:
|
case <-intervalTicker.C:
|
||||||
// Check if the machine is overloaded and if the profiler is not running
|
// Check if the machine is overloaded and if the profiler is not running
|
||||||
if pr == nil && checkMachinePerformance(c) {
|
if pr == nil && isCpuOverloaded(c) {
|
||||||
pr = newProfiler(c)
|
pr = newProfiler(c)
|
||||||
if err := pr.Start(); err != nil {
|
if err := pr.Start(); err != nil {
|
||||||
logx.Errorf("failed to start profiler: %v", err)
|
logx.Errorf("failed to start profiler: %v", err)
|
||||||
@@ -131,7 +131,7 @@ func startPyroScope(c Config, done <-chan struct{}) {
|
|||||||
|
|
||||||
// record the latest profiling time
|
// record the latest profiling time
|
||||||
latestProfilingTime = time.Now()
|
latestProfilingTime = time.Now()
|
||||||
logx.Infof("pyroScope profiler started.")
|
logx.Infof("pyroscope profiler started.")
|
||||||
}
|
}
|
||||||
case <-profilingTicker.C:
|
case <-profilingTicker.C:
|
||||||
// check if the profiling duration has passed
|
// check if the profiling duration has passed
|
||||||
@@ -144,30 +144,26 @@ func startPyroScope(c Config, done <-chan struct{}) {
|
|||||||
if err = pr.Stop(); err != nil {
|
if err = pr.Stop(); err != nil {
|
||||||
logx.Errorf("failed to stop profiler: %v", err)
|
logx.Errorf("failed to stop profiler: %v", err)
|
||||||
}
|
}
|
||||||
logx.Infof("pyroScope profiler stopped.")
|
logx.Infof("pyroscope profiler stopped.")
|
||||||
pr = nil
|
pr = nil
|
||||||
}
|
}
|
||||||
case <-done:
|
case <-done:
|
||||||
logx.Infof("continuous profiling stopped.")
|
logx.Infof("continuous profiling stopped.")
|
||||||
intervalTicker.Stop()
|
|
||||||
profilingTicker.Stop()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// genPyroScopeConf generates the pyroscope configuration based on the given config.
|
// genPyroscopeConf generates the pyroscope configuration based on the given config.
|
||||||
func genPyroScopeConf(c Config) pyroscope.Config {
|
func genPyroscopeConf(c Config) pyroscope.Config {
|
||||||
pConf := pyroscope.Config{
|
pConf := pyroscope.Config{
|
||||||
UploadRate: c.UploadDuration,
|
UploadRate: c.UploadRate,
|
||||||
ApplicationName: c.Name,
|
ApplicationName: c.Name,
|
||||||
BasicAuthUser: c.AuthUser, // http basic auth user
|
BasicAuthUser: c.AuthUser, // http basic auth user
|
||||||
BasicAuthPassword: c.AuthPassword, // http basic auth password
|
BasicAuthPassword: c.AuthPassword, // http basic auth password
|
||||||
ServerAddress: c.ServerAddress,
|
ServerAddress: c.ServerAddr,
|
||||||
Logger: nil,
|
Logger: nil,
|
||||||
|
HTTPHeaders: map[string]string{},
|
||||||
HTTPHeaders: map[string]string{},
|
|
||||||
|
|
||||||
// you can provide static tags via a map:
|
// you can provide static tags via a map:
|
||||||
Tags: map[string]string{
|
Tags: map[string]string{
|
||||||
"name": c.Name,
|
"name": c.Name,
|
||||||
@@ -200,46 +196,46 @@ func genPyroScopeConf(c Config) pyroscope.Config {
|
|||||||
return pConf
|
return pConf
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkMachinePerformance checks the machine performance based on the given configuration.
|
// isCpuOverloaded checks the machine performance based on the given configuration.
|
||||||
func checkMachinePerformance(c Config) bool {
|
func isCpuOverloaded(c Config) bool {
|
||||||
currentValue := stat.CpuUsage()
|
currentValue := stat.CpuUsage()
|
||||||
if currentValue >= c.CpuThreshold {
|
if currentValue >= c.CpuThreshold {
|
||||||
logx.Infof("continuous profiling cpu overload, cpu:%d", currentValue)
|
logx.Infof("continuous profiling cpu overload, cpu: %d", currentValue)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPyProfiler(c Config) profiler {
|
func newPyroscopeProfiler(c Config) profiler {
|
||||||
return &pyProfiler{
|
return &pyroscopeProfiler{
|
||||||
c: c,
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pyProfiler) Start() error {
|
func (p *pyroscopeProfiler) Start() error {
|
||||||
pConf := genPyroScopeConf(p.c)
|
pConf := genPyroscopeConf(p.c)
|
||||||
// set mutex and block profile rate
|
// set mutex and block profile rate
|
||||||
setFraction(p.c)
|
setFraction(p.c)
|
||||||
profiler, err := pyroscope.Start(pConf)
|
prof, err := pyroscope.Start(pConf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resetFraction(p.c)
|
resetFraction(p.c)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.profiler = profiler
|
p.profiler = prof
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pyProfiler) Stop() error {
|
func (p *pyroscopeProfiler) Stop() error {
|
||||||
if p.profiler == nil {
|
if p.profiler == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err := p.profiler.Stop()
|
if err := p.profiler.Stop(); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
resetFraction(p.c)
|
resetFraction(p.c)
|
||||||
p.profiler = nil
|
p.profiler = nil
|
||||||
|
|
||||||
|
|||||||
@@ -7,77 +7,111 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/pyroscope-go"
|
"github.com/grafana/pyroscope-go"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/zeromicro/go-zero/core/conf"
|
||||||
|
"github.com/zeromicro/go-zero/core/syncx"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestStart(t *testing.T) {
|
func TestStart(t *testing.T) {
|
||||||
|
t.Run("profiling", func(t *testing.T) {
|
||||||
|
var c Config
|
||||||
|
assert.NoError(t, conf.FillDefault(&c))
|
||||||
|
c.Name = "test"
|
||||||
|
p := newProfiler(c)
|
||||||
|
assert.NotNil(t, p)
|
||||||
|
assert.NoError(t, p.Start())
|
||||||
|
assert.NoError(t, p.Stop())
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("invalid config", func(t *testing.T) {
|
t.Run("invalid config", func(t *testing.T) {
|
||||||
var mockProfiler = &mockProfiler{}
|
mp := &mockProfiler{}
|
||||||
newProfiler = func(c Config) profiler {
|
newProfiler = func(c Config) profiler {
|
||||||
return mockProfiler
|
return mp
|
||||||
}
|
}
|
||||||
|
|
||||||
Start(Config{})
|
Start(Config{})
|
||||||
|
|
||||||
Start(Config{
|
Start(Config{
|
||||||
ServerAddress: "localhost:4040",
|
ServerAddr: "localhost:4040",
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("test start profiler", func(t *testing.T) {
|
t.Run("test start profiler", func(t *testing.T) {
|
||||||
var mockProfiler = &mockProfiler{}
|
mp := &mockProfiler{}
|
||||||
newProfiler = func(c Config) profiler {
|
newProfiler = func(c Config) profiler {
|
||||||
return mockProfiler
|
return mp
|
||||||
}
|
}
|
||||||
|
|
||||||
c := Config{
|
c := Config{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
ServerAddress: "localhost:4040",
|
ServerAddr: "localhost:4040",
|
||||||
IntervalDuration: time.Millisecond,
|
CheckInterval: time.Millisecond,
|
||||||
ProfilingDuration: time.Millisecond * 10,
|
ProfilingDuration: time.Millisecond * 10,
|
||||||
CpuThreshold: 0,
|
CpuThreshold: 0,
|
||||||
}
|
}
|
||||||
var done = make(chan struct{})
|
var done = make(chan struct{})
|
||||||
go startPyroScope(c, done)
|
go startPyroscope(c, done)
|
||||||
|
|
||||||
time.Sleep(time.Millisecond * 50)
|
time.Sleep(time.Millisecond * 50)
|
||||||
done <- struct{}{}
|
close(done)
|
||||||
|
|
||||||
assert.True(t, mockProfiler.started)
|
assert.True(t, mp.started.True())
|
||||||
assert.True(t, mockProfiler.stopped)
|
assert.True(t, mp.stopped.True())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test start profiler with cpu overloaded", func(t *testing.T) {
|
||||||
|
mp := &mockProfiler{}
|
||||||
|
newProfiler = func(c Config) profiler {
|
||||||
|
return mp
|
||||||
|
}
|
||||||
|
|
||||||
|
c := Config{
|
||||||
|
Name: "test",
|
||||||
|
ServerAddr: "localhost:4040",
|
||||||
|
CheckInterval: time.Millisecond,
|
||||||
|
ProfilingDuration: time.Millisecond * 10,
|
||||||
|
CpuThreshold: 900,
|
||||||
|
}
|
||||||
|
var done = make(chan struct{})
|
||||||
|
go startPyroscope(c, done)
|
||||||
|
|
||||||
|
time.Sleep(time.Millisecond * 50)
|
||||||
|
close(done)
|
||||||
|
|
||||||
|
assert.False(t, mp.started.True())
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("start/stop err", func(t *testing.T) {
|
t.Run("start/stop err", func(t *testing.T) {
|
||||||
var mockProfiler = &mockProfiler{
|
mp := &mockProfiler{
|
||||||
err: assert.AnError,
|
err: assert.AnError,
|
||||||
}
|
}
|
||||||
newProfiler = func(c Config) profiler {
|
newProfiler = func(c Config) profiler {
|
||||||
return mockProfiler
|
return mp
|
||||||
}
|
}
|
||||||
|
|
||||||
c := Config{
|
c := Config{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
ServerAddress: "localhost:4040",
|
ServerAddr: "localhost:4040",
|
||||||
IntervalDuration: time.Millisecond,
|
CheckInterval: time.Millisecond,
|
||||||
ProfilingDuration: time.Millisecond * 10,
|
ProfilingDuration: time.Millisecond * 10,
|
||||||
CpuThreshold: 0,
|
CpuThreshold: 0,
|
||||||
}
|
}
|
||||||
var done = make(chan struct{})
|
var done = make(chan struct{})
|
||||||
go startPyroScope(c, done)
|
go startPyroscope(c, done)
|
||||||
|
|
||||||
time.Sleep(time.Millisecond * 50)
|
time.Sleep(time.Millisecond * 50)
|
||||||
done <- struct{}{}
|
close(done)
|
||||||
|
|
||||||
assert.False(t, mockProfiler.started)
|
assert.False(t, mp.started.True())
|
||||||
assert.False(t, mockProfiler.stopped)
|
assert.False(t, mp.stopped.True())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenPyroScopeConf(t *testing.T) {
|
func TestGenPyroscopeConf(t *testing.T) {
|
||||||
c := Config{
|
c := Config{
|
||||||
Name: "",
|
Name: "",
|
||||||
ServerAddress: "localhost:4040",
|
ServerAddr: "localhost:4040",
|
||||||
AuthUser: "user",
|
AuthUser: "user",
|
||||||
AuthPassword: "password",
|
AuthPassword: "password",
|
||||||
ProfileType: ProfileType{
|
ProfileType: ProfileType{
|
||||||
Logger: true,
|
Logger: true,
|
||||||
CPU: true,
|
CPU: true,
|
||||||
@@ -88,30 +122,30 @@ func TestGenPyroScopeConf(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
conf := genPyroScopeConf(c)
|
pyroscopeConf := genPyroscopeConf(c)
|
||||||
assert.Equal(t, c.ServerAddress, conf.ServerAddress)
|
assert.Equal(t, c.ServerAddr, pyroscopeConf.ServerAddress)
|
||||||
assert.Equal(t, c.AuthUser, conf.BasicAuthUser)
|
assert.Equal(t, c.AuthUser, pyroscopeConf.BasicAuthUser)
|
||||||
assert.Equal(t, c.AuthPassword, conf.BasicAuthPassword)
|
assert.Equal(t, c.AuthPassword, pyroscopeConf.BasicAuthPassword)
|
||||||
assert.Equal(t, c.Name, conf.ApplicationName)
|
assert.Equal(t, c.Name, pyroscopeConf.ApplicationName)
|
||||||
assert.Contains(t, conf.ProfileTypes, pyroscope.ProfileCPU)
|
assert.Contains(t, pyroscopeConf.ProfileTypes, pyroscope.ProfileCPU)
|
||||||
assert.Contains(t, conf.ProfileTypes, pyroscope.ProfileGoroutines)
|
assert.Contains(t, pyroscopeConf.ProfileTypes, pyroscope.ProfileGoroutines)
|
||||||
assert.Contains(t, conf.ProfileTypes, pyroscope.ProfileAllocObjects)
|
assert.Contains(t, pyroscopeConf.ProfileTypes, pyroscope.ProfileAllocObjects)
|
||||||
assert.Contains(t, conf.ProfileTypes, pyroscope.ProfileAllocSpace)
|
assert.Contains(t, pyroscopeConf.ProfileTypes, pyroscope.ProfileAllocSpace)
|
||||||
assert.Contains(t, conf.ProfileTypes, pyroscope.ProfileInuseObjects)
|
assert.Contains(t, pyroscopeConf.ProfileTypes, pyroscope.ProfileInuseObjects)
|
||||||
assert.Contains(t, conf.ProfileTypes, pyroscope.ProfileInuseSpace)
|
assert.Contains(t, pyroscopeConf.ProfileTypes, pyroscope.ProfileInuseSpace)
|
||||||
assert.Contains(t, conf.ProfileTypes, pyroscope.ProfileMutexCount)
|
assert.Contains(t, pyroscopeConf.ProfileTypes, pyroscope.ProfileMutexCount)
|
||||||
assert.Contains(t, conf.ProfileTypes, pyroscope.ProfileMutexDuration)
|
assert.Contains(t, pyroscopeConf.ProfileTypes, pyroscope.ProfileMutexDuration)
|
||||||
assert.Contains(t, conf.ProfileTypes, pyroscope.ProfileBlockCount)
|
assert.Contains(t, pyroscopeConf.ProfileTypes, pyroscope.ProfileBlockCount)
|
||||||
assert.Contains(t, conf.ProfileTypes, pyroscope.ProfileBlockDuration)
|
assert.Contains(t, pyroscopeConf.ProfileTypes, pyroscope.ProfileBlockDuration)
|
||||||
|
|
||||||
setFraction(c)
|
setFraction(c)
|
||||||
resetFraction(c)
|
resetFraction(c)
|
||||||
|
|
||||||
newPyProfiler(c)
|
newPyroscopeProfiler(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewPyProfiler(t *testing.T) {
|
func TestNewPyroscopeProfiler(t *testing.T) {
|
||||||
p := newPyProfiler(Config{})
|
p := newPyroscopeProfiler(Config{})
|
||||||
|
|
||||||
assert.Error(t, p.Start())
|
assert.Error(t, p.Start())
|
||||||
assert.NoError(t, p.Stop())
|
assert.NoError(t, p.Stop())
|
||||||
@@ -119,15 +153,15 @@ func TestNewPyProfiler(t *testing.T) {
|
|||||||
|
|
||||||
type mockProfiler struct {
|
type mockProfiler struct {
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
started bool
|
started syncx.AtomicBool
|
||||||
stopped bool
|
stopped syncx.AtomicBool
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockProfiler) Start() error {
|
func (m *mockProfiler) Start() error {
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
if m.err == nil {
|
if m.err == nil {
|
||||||
m.started = true
|
m.started.Set(true)
|
||||||
}
|
}
|
||||||
m.mutex.Unlock()
|
m.mutex.Unlock()
|
||||||
return m.err
|
return m.err
|
||||||
@@ -136,7 +170,7 @@ func (m *mockProfiler) Start() error {
|
|||||||
func (m *mockProfiler) Stop() error {
|
func (m *mockProfiler) Stop() error {
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
if m.err == nil {
|
if m.err == nil {
|
||||||
m.stopped = true
|
m.stopped.Set(true)
|
||||||
}
|
}
|
||||||
m.mutex.Unlock()
|
m.mutex.Unlock()
|
||||||
return m.err
|
return m.err
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-openapi/spec"
|
"github.com/go-openapi/spec"
|
||||||
|
|
||||||
apiSpec "github.com/zeromicro/go-zero/tools/goctl/api/spec"
|
apiSpec "github.com/zeromicro/go-zero/tools/goctl/api/spec"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/internal/version"
|
"github.com/zeromicro/go-zero/tools/goctl/internal/version"
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user