@@ -0,0 +1,78 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func countLifecycleWinners(instanceID string, workers int) int {
|
||||
start := make(chan struct{})
|
||||
results := make(chan bool, workers)
|
||||
var wg sync.WaitGroup
|
||||
for range workers {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
<-start
|
||||
results <- beginInstanceLifecycleOperation(instanceID)
|
||||
}()
|
||||
}
|
||||
close(start)
|
||||
wg.Wait()
|
||||
close(results)
|
||||
winners := 0
|
||||
for won := range results {
|
||||
if won {
|
||||
winners++
|
||||
}
|
||||
}
|
||||
return winners
|
||||
}
|
||||
|
||||
func TestBeginInstanceLifecycleOperationSingleFlight(t *testing.T) {
|
||||
instanceID := "ocid1.instance.oc1..single-flight"
|
||||
instanceLifecycleGuard.Delete(instanceID)
|
||||
t.Cleanup(func() { instanceLifecycleGuard.Delete(instanceID) })
|
||||
if got, want := countLifecycleWinners(instanceID, 16), 1; got != want {
|
||||
t.Errorf("winners = %d, want %d", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func instanceOperationRouter() *gin.Engine {
|
||||
h := &ociConfigHandler{}
|
||||
r := gin.New()
|
||||
r.DELETE("/oci-configs/:id/instances/:instanceId", h.terminateInstance)
|
||||
r.POST("/oci-configs/:id/instances/:instanceId/action", h.instanceAction)
|
||||
return r
|
||||
}
|
||||
|
||||
func TestInstanceLifecycleOperationRejectsLaterRequest(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
instanceID := "ocid1.instance.oc1..same-physical-instance"
|
||||
instanceLifecycleGuard.Store(instanceID, struct{}{})
|
||||
t.Cleanup(func() { instanceLifecycleGuard.Delete(instanceID) })
|
||||
r := instanceOperationRouter()
|
||||
tests := []struct {
|
||||
name, method, path, body string
|
||||
}{
|
||||
{"action先占位时跨配置terminate被拒", http.MethodDelete, "/oci-configs/2/instances/" + instanceID, ""},
|
||||
{"terminate先占位时action被拒", http.MethodPost, "/oci-configs/1/instances/" + instanceID + "/action", `{"action":"STOP"}`},
|
||||
{"action先占位时第二个action被拒", http.MethodPost, "/oci-configs/3/instances/" + instanceID + "/action", `{"action":"RESET"}`},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
req := httptest.NewRequest(tt.method, tt.path, strings.NewReader(tt.body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
w := httptest.NewRecorder()
|
||||
r.ServeHTTP(w, req)
|
||||
if got, want := w.Code, http.StatusConflict; got != want {
|
||||
t.Errorf("status = %d, want %d, body %s", got, want, w.Body.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user