From 996f58505935655758058776b21e340036a0f65a Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Tue, 27 Aug 2019 02:16:42 -0300 Subject: [PATCH 1/5] Re-add test --- models/issue_stress_test.go | 109 ++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 models/issue_stress_test.go diff --git a/models/issue_stress_test.go b/models/issue_stress_test.go new file mode 100644 index 0000000000000..7f3a14f898f90 --- /dev/null +++ b/models/issue_stress_test.go @@ -0,0 +1,109 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package models + +import ( + "fmt" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +// TestIssueNoDupIndex Performs a stress test of the INSERT ... SELECT function of database for inserting issues +func TestIssueNoDupIndex(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + + const initialIssueFill = 1000 // issues inserted prior to stress test + const maxTestDuration = 60 // seconds + const threadCount = 8 // max simultaneous threads + const useTransactions = true // true: wrap attempts with BEGIN TRANSACTION/COMMIT + + var err error + repo := AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository) + doer := AssertExistsAndLoadBean(t, &User{ID: repo.OwnerID}).(*User) + + // Pre-load + for i := 1; i < initialIssueFill; i++ { + issue := &Issue{ + RepoID: repo.ID, + PosterID: repo.OwnerID, + Index: int64(i + 5000), // Avoid clashing with other tests + Title: fmt.Sprintf("NoDup initial %d", i), + } + _, err = x.Insert(issue) + assert.NoError(t, err) + } + + fmt.Printf("TestIssueNoDupIndex(): %d rows created\n", initialIssueFill) + + until := time.Now().Add(time.Second * maxTestDuration) + + var hasErrors int32 + var wg sync.WaitGroup + + f := func(thread int) { + defer wg.Done() + sess := x.NewSession() + defer sess.Close() + i := 1 + for { + if time.Now().After(until) || atomic.LoadInt32(&hasErrors) != 0 { + return + } + issue := &Issue{ + RepoID: repo.ID, + PosterID: repo.OwnerID, + Title: fmt.Sprintf("NoDup stress %d, %d", thread, i), + OriginalAuthor: "TestIssueNoDupIndex()", + Priority: thread, // For statistics + } + if useTransactions { + if err = sess.Begin(); err != nil { + break + } + } + if err = newIssue(sess, doer, NewIssueOptions{ + Repo: repo, + Issue: issue, + }); err != nil { + break + } + if useTransactions { + if err = sess.Commit(); err != nil { + break + } + } + i++ + } + if useTransactions { + _ = sess.Rollback() + } + atomic.StoreInt32(&hasErrors, 1) + t.Logf("newIssue(): %+v", err) + } + + for i := 1; i <= threadCount; i++ { + go f(i) + wg.Add(1) + } + + fmt.Printf("TestIssueNoDupIndex(): %d threads created\n", threadCount) + + wg.Wait() + + for i := 1; i <= threadCount; i++ { + total, err := x.Table("issue"). + Where("original_author = ?", "TestIssueNoDupIndex()"). + And("priority = ?", i). + Count() + assert.NoError(t, err, "Failed counting generated issues count") + fmt.Printf("TestIssueNoDupIndex(): rows created in thread #%d: %d\n", i, total) + } + + assert.Equal(t, int32(0), hasErrors, "Synchronization errors detected.") +} From 45e039810c52e879c5a666e74e948120453a8c47 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Tue, 27 Aug 2019 17:51:30 -0300 Subject: [PATCH 2/5] Refactor test files --- integrations/issue_stress_test.go | 20 +++++++++++++++++++ .../{issue_stress_test.go => issue_stress.go} | 6 ++++-- 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 integrations/issue_stress_test.go rename models/{issue_stress_test.go => issue_stress.go} (93%) diff --git a/integrations/issue_stress_test.go b/integrations/issue_stress_test.go new file mode 100644 index 0000000000000..2dc64fd76724b --- /dev/null +++ b/integrations/issue_stress_test.go @@ -0,0 +1,20 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +// +build stress + + +package integrations + +import ( + "testing" + + "code.gitea.io/gitea/models" +) + +// TestStressCreateIssue do something +func TestStressCreateIssue(t *testing.T) { + // TODO: refactor this to avoid including StressIssueNoDupIndex() in production + models.StressIssueNoDupIndex(t) +} \ No newline at end of file diff --git a/models/issue_stress_test.go b/models/issue_stress.go similarity index 93% rename from models/issue_stress_test.go rename to models/issue_stress.go index 7f3a14f898f90..4b02f1edd688e 100644 --- a/models/issue_stress_test.go +++ b/models/issue_stress.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. +// +build stress + package models import ( @@ -14,8 +16,8 @@ import ( "github.com/stretchr/testify/assert" ) -// TestIssueNoDupIndex Performs a stress test of the INSERT ... SELECT function of database for inserting issues -func TestIssueNoDupIndex(t *testing.T) { +// StressIssueNoDupIndex Performs a stress test of the INSERT ... SELECT function of database for inserting issues +func StressIssueNoDupIndex(t *testing.T) { assert.NoError(t, PrepareTestDatabase()) const initialIssueFill = 1000 // issues inserted prior to stress test From 78d2f4489dbc8ffabb7730ee3bc98dffa9c621d0 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Tue, 27 Aug 2019 17:52:23 -0300 Subject: [PATCH 3/5] make fmt --- integrations/issue_stress_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/integrations/issue_stress_test.go b/integrations/issue_stress_test.go index 2dc64fd76724b..5555dc496d65e 100644 --- a/integrations/issue_stress_test.go +++ b/integrations/issue_stress_test.go @@ -4,7 +4,6 @@ // +build stress - package integrations import ( @@ -17,4 +16,4 @@ import ( func TestStressCreateIssue(t *testing.T) { // TODO: refactor this to avoid including StressIssueNoDupIndex() in production models.StressIssueNoDupIndex(t) -} \ No newline at end of file +} From c48156e67ca5724f2c71ff1b95ff42c3aec6e2d8 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Tue, 27 Aug 2019 17:59:33 -0300 Subject: [PATCH 4/5] Allow test configuration via parameters --- integrations/issue_stress_test.go | 3 ++- models/issue_stress.go | 20 +++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/integrations/issue_stress_test.go b/integrations/issue_stress_test.go index 5555dc496d65e..02fa9d3612090 100644 --- a/integrations/issue_stress_test.go +++ b/integrations/issue_stress_test.go @@ -15,5 +15,6 @@ import ( // TestStressCreateIssue do something func TestStressCreateIssue(t *testing.T) { // TODO: refactor this to avoid including StressIssueNoDupIndex() in production - models.StressIssueNoDupIndex(t) + // func StressIssueNoDupIndex(t *testing.T, useTransactions bool, initialIssueFill int, maxTestDuration int, threadCount int) { + models.StressIssueNoDupIndex(t, true, 0, 0, 0) } diff --git a/models/issue_stress.go b/models/issue_stress.go index 4b02f1edd688e..0c50ce7ffbd48 100644 --- a/models/issue_stress.go +++ b/models/issue_stress.go @@ -17,13 +17,23 @@ import ( ) // StressIssueNoDupIndex Performs a stress test of the INSERT ... SELECT function of database for inserting issues -func StressIssueNoDupIndex(t *testing.T) { +func StressIssueNoDupIndex(t *testing.T, useTransactions bool, initialIssueFill int, maxTestDuration int, threadCount int) { assert.NoError(t, PrepareTestDatabase()) - const initialIssueFill = 1000 // issues inserted prior to stress test - const maxTestDuration = 60 // seconds - const threadCount = 8 // max simultaneous threads - const useTransactions = true // true: wrap attempts with BEGIN TRANSACTION/COMMIT + // Defaults + const defInitialIssueFill = 1000 // issues inserted prior to stress test + const defMaxTestDuration = 60 // seconds + const defThreadCount = 8 // max simultaneous threads + + if initialIssueFill == 0 { + initialIssueFill = defInitialIssueFill + } + if maxTestDuration == 0 { + maxTestDuration = defMaxTestDuration + } + if threadCount == 0 { + threadCount = defThreadCount + } var err error repo := AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository) From 882129f8e77ce0243bb2f199fb1a8ca28df759c0 Mon Sep 17 00:00:00 2001 From: Guillermo Prandi Date: Tue, 27 Aug 2019 20:16:12 -0300 Subject: [PATCH 5/5] Correct time.Duration() --- models/issue_stress.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/issue_stress.go b/models/issue_stress.go index 0c50ce7ffbd48..9157335861810 100644 --- a/models/issue_stress.go +++ b/models/issue_stress.go @@ -53,7 +53,7 @@ func StressIssueNoDupIndex(t *testing.T, useTransactions bool, initialIssueFill fmt.Printf("TestIssueNoDupIndex(): %d rows created\n", initialIssueFill) - until := time.Now().Add(time.Second * maxTestDuration) + until := time.Now().Add(time.Second * time.Duration(maxTestDuration)) var hasErrors int32 var wg sync.WaitGroup