feat: update JSON object returned by blocking strategy

Closes #68
This commit is contained in:
Alexis Couvreur
2022-11-03 19:04:29 +00:00
parent 007f2ae071
commit 8a85a32561
4 changed files with 112 additions and 20 deletions

View File

@@ -41,26 +41,29 @@ docker run -v /var/run/docker.sock:/var/run/docker.sock -p 10000:10000 ghcr.io/a
# Start the containers, the request will hang until both containers are up and running
curl 'http://localhost:10000/api/strategies/blocking?names=nginx&names=whoami&session_duration=1m'
[
{
"session": {
"instances": [
{
"Instance": {
"Name": "whoami",
"CurrentReplicas": 1,
"Status": "ready",
"Message": ""
"instance": {
"name": "nginx",
"currentReplicas": 1,
"status": "ready"
},
"Error": null
"error": null
},
{
"Instance": {
"Name": "nginx",
"CurrentReplicas": 1,
"Status": "ready",
"Message": ""
"instance": {
"name": "nginx",
"currentReplicas": 1,
"status": "ready"
},
"Error": null
"error": null
}
]
],
"status":"ready"
}
}
```
## ⚙️ Configuration

View File

@@ -128,7 +128,7 @@ func (s *ServeStrategy) ServeBlocking(c *gin.Context) {
c.Header("X-Sablier-Session-Status", "not-ready")
}
c.JSON(http.StatusOK, sessionState)
c.JSON(http.StatusOK, map[string]interface{}{"session": sessionState})
}
func sessionStateToRenderOptionsInstanceState(sessionState *sessions.SessionState) (instances []pages.RenderOptionsInstanceState) {

View File

@@ -53,7 +53,7 @@ func TestServeStrategy_ServeDynamic(t *testing.T) {
expectedHeaderValue string
}{
{
name: "return HTML Theme",
name: "header has not ready value when not ready",
arg: arg{
body: models.DynamicRequest{
Names: []string{"nginx"},
@@ -71,7 +71,7 @@ func TestServeStrategy_ServeDynamic(t *testing.T) {
expectedHeaderValue: "not-ready",
},
{
name: "temporary redirect when session is ready",
name: "header has ready value when session is ready",
arg: arg{
body: models.DynamicRequest{
Names: []string{"nginx"},
@@ -112,6 +112,84 @@ func TestServeStrategy_ServeDynamic(t *testing.T) {
}
}
func TestServeStrategy_ServeBlocking(t *testing.T) {
type arg struct {
body models.BlockingRequest
session sessions.SessionState
}
tests := []struct {
name string
arg arg
expectedBody string
expectedHeaderKey string
expectedHeaderValue string
}{
{
name: "not ready returns session status not ready",
arg: arg{
body: models.BlockingRequest{
Names: []string{"nginx"},
Timeout: 10 * time.Second,
SessionDuration: 1 * time.Minute,
},
session: sessions.SessionState{
Instances: createMap([]*instance.State{
{Name: "nginx", Status: instance.NotReady, CurrentReplicas: 0},
}),
},
},
expectedBody: `{"session":{"instances":[{"instance":{"name":"nginx","currentReplicas":0,"status":"not-ready"},"error":null}],"status":"not-ready"}}`,
expectedHeaderKey: "X-Sablier-Session-Status",
expectedHeaderValue: "not-ready",
},
{
name: "ready returns session status ready",
arg: arg{
body: models.BlockingRequest{
Names: []string{"nginx"},
SessionDuration: 1 * time.Minute,
},
session: sessions.SessionState{
Instances: createMap([]*instance.State{
{Name: "nginx", Status: instance.Ready, CurrentReplicas: 1},
}),
},
},
expectedBody: `{"session":{"instances":[{"instance":{"name":"nginx","currentReplicas":1,"status":"ready"},"error":null}],"status":"ready"}}`,
expectedHeaderKey: "X-Sablier-Session-Status",
expectedHeaderValue: "ready",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &ServeStrategy{
SessionsManager: &SessionsManagerMock{
SessionState: tt.arg.session,
},
StrategyConfig: config.NewStrategyConfig(),
}
recorder := httptest.NewRecorder()
c := GetTestGinContext(recorder)
MockJsonPost(c, tt.arg.body)
s.ServeBlocking(c)
res := recorder.Result()
defer res.Body.Close()
bytes, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
assert.Equal(t, c.Writer.Header().Get(tt.expectedHeaderKey), tt.expectedHeaderValue)
assert.Equal(t, string(bytes), tt.expectedBody)
})
}
}
// mock gin context
func GetTestGinContext(w *httptest.ResponseRecorder) *gin.Context {
gin.SetMode(gin.TestMode)

View File

@@ -49,8 +49,8 @@ func (sm *SessionsManager) SaveSessions(writer io.WriteCloser) error {
}
type InstanceState struct {
Instance *instance.State
Error error
Instance *instance.State `json:"instance"`
Error error `json:"error"`
}
type SessionState struct {
@@ -72,6 +72,14 @@ func (s *SessionState) IsReady() bool {
return ready
}
func (s *SessionState) Status() string {
if s.IsReady() {
return "ready"
}
return "not-ready"
}
func (s *SessionsManager) RequestSession(names []string, duration time.Duration) (sessionState *SessionState) {
if len(names) == 0 {
@@ -194,5 +202,8 @@ func (s *SessionState) MarshalJSON() ([]byte, error) {
return true
})
return json.Marshal(instances)
return json.Marshal(map[string]any{
"instances": instances,
"status": s.Status(),
})
}