github.com/blend/go-sdk@v1.20220411.3/status/controller_test.go (about) 1 /* 2 3 Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file. 5 6 */ 7 8 package status 9 10 import ( 11 "context" 12 "fmt" 13 "net/http" 14 "sync/atomic" 15 "testing" 16 17 "github.com/blend/go-sdk/assert" 18 "github.com/blend/go-sdk/configmeta" 19 "github.com/blend/go-sdk/web" 20 ) 21 22 func Test_Controller_getStatus(t *testing.T) { 23 t.Parallel() 24 its := assert.New(t) 25 26 statusController := NewController( 27 OptConfig(configmeta.Meta{ 28 ServiceEnv: "test", 29 ServiceName: "test-service", 30 Version: "1.2.3", 31 }), 32 ) 33 app := web.MustNew() 34 app.Register(statusController) 35 36 var res configmeta.Meta 37 meta, err := web.MockGet(app, "/status").JSON(&res) 38 its.Nil(err) 39 its.Equal(http.StatusOK, meta.StatusCode) 40 41 its.Equal("test", res.ServiceEnv) 42 its.Equal("test-service", res.ServiceName) 43 its.Equal("1.2.3", res.Version) 44 } 45 46 func Test_Controller_getStatusSLA(t *testing.T) { 47 t.Parallel() 48 its := assert.New(t) 49 50 var fooCalls, barCalls int32 51 statusController := NewController( 52 OptCheck("foo", CheckerFunc(func(_ context.Context) error { 53 atomic.AddInt32(&fooCalls, 1) 54 return nil 55 })), 56 OptCheck("bar", CheckerFunc(func(_ context.Context) error { 57 atomic.AddInt32(&barCalls, 1) 58 return nil 59 })), 60 ) 61 62 app := web.MustNew() 63 app.Register(statusController) 64 65 var slaOutput FreeformResult 66 meta, err := web.MockGet(app, "/status/sla").JSON(&slaOutput) 67 its.Nil(err) 68 its.Equal(http.StatusOK, meta.StatusCode) 69 its.True(slaOutput["foo"]) 70 its.True(slaOutput["bar"]) 71 72 meta, err = web.MockGet(app, "/status/sla").JSON(&slaOutput) 73 its.Nil(err) 74 its.Equal(http.StatusOK, meta.StatusCode) 75 its.True(slaOutput["foo"]) 76 its.True(slaOutput["bar"]) 77 78 meta, err = web.MockGet(app, "/status/sla").JSON(&slaOutput) 79 its.Nil(err) 80 its.Equal(http.StatusOK, meta.StatusCode) 81 its.True(slaOutput["foo"]) 82 its.True(slaOutput["bar"]) 83 84 its.Equal(3, fooCalls) 85 its.Equal(3, barCalls) 86 } 87 88 func Test_Controller_getStatusSLA_intermittentFailures(t *testing.T) { 89 t.Parallel() 90 its := assert.New(t) 91 92 var successCalls int32 93 var maybeFailureCalls int32 94 shouldFail := true 95 statusController := NewController( 96 OptCheck("success", CheckerFunc(func(_ context.Context) error { 97 atomic.AddInt32(&successCalls, 1) 98 return nil 99 })), 100 OptCheck("maybeFailure", CheckerFunc(func(_ context.Context) error { 101 atomic.AddInt32(&maybeFailureCalls, 1) 102 if shouldFail { 103 return fmt.Errorf("oh noes") 104 } 105 return nil 106 })), 107 ) 108 109 app := web.MustNew() 110 app.Register(statusController) 111 112 var slaOutput FreeformResult 113 meta, err := web.MockGet(app, "/status/sla").JSON(&slaOutput) 114 its.Nil(err) 115 its.Equal(http.StatusServiceUnavailable, meta.StatusCode) 116 its.True(slaOutput["success"]) 117 its.False(slaOutput["maybeFailure"]) 118 119 shouldFail = false 120 meta, err = web.MockGet(app, "/status/sla").JSON(&slaOutput) 121 its.Nil(err) 122 its.Equal(http.StatusOK, meta.StatusCode) 123 its.True(slaOutput["success"]) 124 its.True(slaOutput["maybeFailure"]) 125 126 shouldFail = true 127 meta, err = web.MockGet(app, "/status/sla").JSON(&slaOutput) 128 its.Nil(err) 129 its.Equal(http.StatusServiceUnavailable, meta.StatusCode) 130 its.True(slaOutput["success"]) 131 its.False(slaOutput["maybeFailure"]) 132 133 its.Equal(3, successCalls) 134 its.Equal(3, maybeFailureCalls) 135 } 136 137 func Test_Controller_getStatusDetails(t *testing.T) { 138 t.Parallel() 139 its := assert.New(t) 140 141 statusController := NewController() 142 143 var shouldFail bool 144 interceptor := statusController.Interceptor("test-service") 145 action := interceptor.Intercept(ActionerFunc(func(ctx context.Context, args interface{}) (interface{}, error) { 146 if shouldFail { 147 return nil, fmt.Errorf("oh noes") 148 } 149 return nil, nil 150 })) 151 its.Len(statusController.TrackedActions.TrackedActions, 1) 152 153 app := web.MustNew() 154 app.Register(statusController) 155 156 var res TrackedActionsResult 157 meta, err := web.MockGet(app, "/status/details").JSON(&res) 158 its.Nil(err) 159 its.Equal(http.StatusOK, meta.StatusCode) 160 its.Equal(SignalGreen, res.Status) 161 its.Equal(SignalGreen, res.SubSystems["test-service"].Status) 162 163 _, err = action.Action(context.Background(), nil) 164 its.Nil(err) 165 166 meta, err = web.MockGet(app, "/status/details").JSON(&res) 167 its.Nil(err) 168 its.Equal(http.StatusOK, meta.StatusCode) 169 its.Equal(SignalGreen, res.Status) 170 171 shouldFail = true 172 173 for x := 0; x < DefaultRedRequestCount; x++ { 174 _, err = action.Action(context.Background(), nil) 175 its.NotNil(err) 176 } 177 178 meta, err = web.MockGet(app, "/status/details").JSON(&res) 179 its.Nil(err) 180 its.Equal(http.StatusServiceUnavailable, meta.StatusCode) 181 its.Equal(SignalRed, res.Status) 182 its.Equal(SignalRed, res.SubSystems["test-service"].Status) 183 }