Skip to content

Commit

Permalink
Merge pull request #1237 from France-ioi/resultStart_see_inserted_row
Browse files Browse the repository at this point in the history
Select the newly created/updated result FOR UPDATE in resultStart
  • Loading branch information
zenovich authored Jan 17, 2025
2 parents 49c67f8 + 47d0102 commit 2d9283d
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
11 changes: 11 additions & 0 deletions app/api/items/start_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package items

import (
"net/http"
"sync/atomic"

"github.com/go-chi/render"

"github.com/France-ioi/AlgoreaBackend/v2/app/database"
"github.com/France-ioi/AlgoreaBackend/v2/app/service"
"github.com/France-ioi/AlgoreaBackend/v2/golang"
)

// The request has successfully updated the object
Expand Down Expand Up @@ -101,6 +103,8 @@ func (srv *Service) startResult(w http.ResponseWriter, r *http.Request) service.
return apiError.Error // rollback
}

onBeforeInsertingResultInResultStartHook.Load().(func())()

itemID := ids[len(ids)-1]
var found bool
found, err = store.Items().ByID(itemID).
Expand Down Expand Up @@ -129,6 +133,7 @@ func (srv *Service) startResult(w http.ResponseWriter, r *http.Request) service.

service.MustNotBeError(constructQueryForGettingAttemptsList(store, participantID, itemID, srv.GetUser(r)).
Where("attempts.id = ?", attemptID).
WithCustomWriteLocks(golang.NewSet("attempts"), golang.NewSet("results")).
Scan(&attemptInfo).Error())

if attemptInfo.UserCreator.GroupID == nil {
Expand All @@ -145,3 +150,9 @@ func (srv *Service) startResult(w http.ResponseWriter, r *http.Request) service.
service.MustNotBeError(render.Render(w, r, service.UpdateSuccess(&attemptInfo)))
return service.NoError
}

var onBeforeInsertingResultInResultStartHook atomic.Value

func init() {
onBeforeInsertingResultInResultStartHook.Store(func() {})
}
54 changes: 54 additions & 0 deletions app/api/items/start_result_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//go:build !unit

package items_test

import (
"net/http/httptest"
"sync/atomic"
"testing"
_ "unsafe"

"bou.ke/monkey"

"github.com/France-ioi/AlgoreaBackend/v2/app"
"github.com/France-ioi/AlgoreaBackend/v2/app/database"
"github.com/France-ioi/AlgoreaBackend/v2/app/service"
"github.com/France-ioi/AlgoreaBackend/v2/testhelpers"
)

func TestService_startResult_concurrency(t *testing.T) {
db := testhelpers.SetupDBWithFixtureString(`
items: [{id: 1, type: Task, default_language_tag: 'fr', requires_explicit_entry: 0}]
groups: [{id: 3, type: User, root_activity_id: 1}]
users: [{group_id: 3, login: john}]
permissions_generated: [{group_id: 3, item_id: 1, can_view_generated: content}]
attempts: [{participant_id: 3, id: 0}]
sessions: [{session_id: 3, user_id: 3}]
access_tokens: [{token: 'token_john', session_id: 3, expires_at: '9999-12-31 23:59:59'}]`)
defer func() { _ = db.Close() }()

// app server
application, err := app.New()
if err != nil {
t.Fatalf("Unable to load a hooked app: %v", err)
}
defer func() { _ = application.Database.Close() }()
appServer := httptest.NewServer(application.HTTPHandler)
defer appServer.Close()

monkey.Patch(service.SchedulePropagation, func(*database.DataStore, string, []string) {})
defer monkey.UnpatchAll()

onBeforeInsertingResultInResultStartHook.Store(func() {
onBeforeInsertingResultInResultStartHook.Store(func() {})
testhelpers.VerifyTestHTTPRequestWithToken(t, appServer, "token_john", 200,
"POST", "/items/1/start-result?attempt_id=0", nil, nil)
})
defer onBeforeInsertingResultInResultStartHook.Store(func() {})

testhelpers.VerifyTestHTTPRequestWithToken(t, appServer, "token_john", 200,
"POST", "/items/1/start-result?attempt_id=0", nil, nil)
}

//go:linkname onBeforeInsertingResultInResultStartHook github.com/France-ioi/AlgoreaBackend/v2/app/api/items.onBeforeInsertingResultInResultStartHook
var onBeforeInsertingResultInResultStartHook atomic.Value

0 comments on commit 2d9283d

Please sign in to comment.