-
Notifications
You must be signed in to change notification settings - Fork 130
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add golintci yaml * add testcontainers --------- Co-authored-by: yiling <yiling@yilingdeMacBook-Air.local>
- Loading branch information
Showing
10 changed files
with
606 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
linters-settings: | ||
staticcheck: | ||
checks: ["all", "-SA1029"] | ||
whitespace: | ||
multi-if: true | ||
multi-func: true | ||
govet: | ||
disable: | ||
- composites |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,128 +1,290 @@ | ||
package database | ||
package database_test | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"testing" | ||
"time" | ||
|
||
"opencsg.com/csghub-server/common/config" | ||
"github.com/stretchr/testify/require" | ||
"opencsg.com/csghub-server/builder/store/database" | ||
"opencsg.com/csghub-server/common/tests" | ||
) | ||
|
||
var ( | ||
TestRepoId int64 = 40 | ||
TestRepoIds []int64 = []int64{40} | ||
TestDSN string = "postgresql://postgres:postgres@localhost:5433/starhub_server?sslmode=disable" | ||
TestNamespace string = "wanghh2003" | ||
TestName string = "gitalyds2" | ||
) | ||
|
||
func InitTestDB(t *testing.T) { | ||
cfg, err := config.LoadConfig() | ||
if err != nil { | ||
t.Fatalf("failed to load config: %v", err) | ||
} | ||
cfg.Database.DSN = TestDSN | ||
dbConfig := DBConfig{ | ||
Dialect: DatabaseDialect(cfg.Database.Driver), | ||
DSN: cfg.Database.DSN, | ||
} | ||
InitDB(dbConfig) | ||
} | ||
func TestPromptStore_Create(t *testing.T) { | ||
db := tests.InitTestDB() | ||
defer db.Close() | ||
|
||
func TestCreate(t *testing.T) { | ||
InitTestDB(t) | ||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) | ||
defer cancel() | ||
|
||
ps := NewPromptStore() | ||
ps := database.NewPromptStoreWithDB(db) | ||
|
||
p := Prompt{ | ||
RepositoryID: TestRepoId, | ||
p := database.Prompt{ | ||
RepositoryID: 1234, | ||
} | ||
|
||
res, err := ps.Create(ctx, p) | ||
_, err := ps.Create(ctx, p) | ||
require.Nil(t, err) | ||
|
||
_, err = ps.ByRepoID(ctx, 1234) | ||
require.Nil(t, err) | ||
|
||
if err != nil { | ||
t.Fatalf("failed to create prompt: %v", err) | ||
} | ||
t.Logf("created prompt: %d", res.ID) | ||
} | ||
|
||
func TestUpdate(t *testing.T) { | ||
InitTestDB(t) | ||
func TestPromptStore_Update(t *testing.T) { | ||
db := tests.InitTestDB() | ||
defer db.Close() | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) | ||
defer cancel() | ||
|
||
ps := NewPromptStore() | ||
ps := database.NewPromptStoreWithDB(db) | ||
|
||
p, err := ps.ByRepoID(ctx, TestRepoId) | ||
_, err := ps.Create(ctx, database.Prompt{ | ||
RepositoryID: 1234, | ||
}) | ||
require.Nil(t, err) | ||
|
||
ps.Update(ctx, *p) | ||
p, err := ps.ByRepoID(ctx, 1234) | ||
require.Nil(t, err) | ||
p.RepositoryID = 3456 | ||
err = ps.Update(ctx, *p) | ||
require.Nil(t, err) | ||
|
||
_, err = ps.ByRepoID(ctx, 1234) | ||
require.NotNil(t, err) | ||
|
||
_, err = ps.ByRepoID(ctx, 3456) | ||
require.Nil(t, err) | ||
|
||
if err != nil { | ||
t.Fatalf("failed to update prompt: %v", err) | ||
} | ||
} | ||
|
||
func TestByRepoID(t *testing.T) { | ||
InitTestDB(t) | ||
func TestPromptStore_ByRepoID(t *testing.T) { | ||
db := tests.InitTestDB() | ||
defer db.Close() | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) | ||
defer cancel() | ||
|
||
ps := NewPromptStore() | ||
ps := database.NewPromptStoreWithDB(db) | ||
|
||
_, err := ps.ByRepoID(ctx, TestRepoId) | ||
|
||
if err != nil { | ||
t.Fatalf("failed to get prompt by repo id: %v", err) | ||
p := database.Prompt{ | ||
RepositoryID: 1234, | ||
} | ||
|
||
_, err := ps.Create(ctx, p) | ||
require.Nil(t, err) | ||
|
||
_, err = ps.ByRepoID(ctx, 1234) | ||
require.Nil(t, err) | ||
} | ||
|
||
func TestByRepoIDs(t *testing.T) { | ||
InitTestDB(t) | ||
func TestPromptStore_ByRepoIDs(t *testing.T) { | ||
db := tests.InitTestDB() | ||
defer db.Close() | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) | ||
defer cancel() | ||
|
||
ps := NewPromptStore() | ||
ps := database.NewPromptStoreWithDB(db) | ||
rs := database.NewRepoStoreWithDB(db) | ||
us := database.NewUserStoreWithDB(db) | ||
|
||
err := us.Create(ctx, &database.User{ | ||
Username: "foo", | ||
}, &database.Namespace{}) | ||
require.Nil(t, err) | ||
user, err := us.FindByUsername(ctx, "foo") | ||
require.Nil(t, err) | ||
|
||
repoIds := []int64{} | ||
for _, r := range []string{"a", "b", "c"} { | ||
|
||
repo, err := rs.CreateRepo(ctx, database.Repository{ | ||
UserID: user.ID, | ||
Name: r, | ||
Path: r, | ||
GitPath: r, | ||
}) | ||
require.Nil(t, err) | ||
repoIds = append(repoIds, repo.ID) | ||
|
||
_, err = ps.Create(ctx, database.Prompt{ | ||
RepositoryID: repo.ID, | ||
}) | ||
|
||
require.Nil(t, err) | ||
} | ||
|
||
_, err := ps.ByRepoIDs(ctx, TestRepoIds) | ||
prompts, err := ps.ByRepoIDs(ctx, repoIds) | ||
require.Nil(t, err) | ||
|
||
if err != nil { | ||
t.Fatalf("failed to get prompt by repo ids: %v", err) | ||
require.Equal(t, 3, len(prompts)) | ||
names := []string{} | ||
for _, p := range prompts { | ||
require.Equal(t, "foo", p.Repository.User.Username) | ||
names = append(names, p.Repository.Name) | ||
} | ||
require.ElementsMatch(t, []string{"a", "b", "c"}, names) | ||
} | ||
|
||
func TestFindByPath(t *testing.T) { | ||
InitTestDB(t) | ||
func TestPromptStore_FindByPath(t *testing.T) { | ||
db := tests.InitTestDB() | ||
defer db.Close() | ||
// db.BunDB.AddQueryHook(bundebug.NewQueryHook(bundebug.WithVerbose(true))) | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) | ||
defer cancel() | ||
|
||
ps := NewPromptStore() | ||
rs := database.NewRepoStoreWithDB(db) | ||
ts := database.NewTagStoreWithDB(db) | ||
|
||
repo, err := rs.CreateRepo(ctx, database.Repository{ | ||
Path: "a/b/c", | ||
GitPath: "abc", | ||
}) | ||
require.Nil(t, err) | ||
|
||
tags := []database.RepositoryTag{} | ||
// tab a,c count -1, tag b count 1 | ||
for _, n := range []string{"a", "b", "c"} { | ||
var c int32 = -1 | ||
if n == "b" { | ||
c = 1 | ||
} | ||
tag, err := ts.CreateTag(ctx, "foo", n, n, database.DatasetTagScope) | ||
require.Nil(t, err) | ||
tags = append(tags, database.RepositoryTag{ | ||
RepositoryID: repo.ID, | ||
TagID: tag.ID, | ||
Count: c, | ||
}) | ||
} | ||
|
||
_, err := ps.FindByPath(ctx, TestNamespace, TestName) | ||
err = rs.BatchCreateRepoTags(ctx, tags) | ||
require.Nil(t, err) | ||
|
||
ps := database.NewPromptStoreWithDB(db) | ||
_, err = ps.Create(ctx, database.Prompt{ | ||
RepositoryID: repo.ID, | ||
}) | ||
require.Nil(t, err) | ||
|
||
prompt, err := ps.FindByPath(ctx, "a", "b/c") | ||
require.Nil(t, err) | ||
require.Equal(t, "", prompt.Repository.Name, "abc") | ||
// FindByPath only get tags with count > 0 (tag b) | ||
require.Equal(t, 1, len(prompt.Repository.Tags)) | ||
require.Equal(t, prompt.Repository.Tags[0].Name, "b") | ||
|
||
if err != nil { | ||
t.Fatalf("failed to find prompt by repo path: %v", err) | ||
} | ||
} | ||
|
||
func TestDelete(t *testing.T) { | ||
InitTestDB(t) | ||
func TestPromptStore_Delete(t *testing.T) { | ||
db := tests.InitTestDB() | ||
defer db.Close() | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) | ||
defer cancel() | ||
|
||
ps := NewPromptStore() | ||
ps := database.NewPromptStoreWithDB(db) | ||
|
||
err := ps.Delete(ctx, database.Prompt{ID: 123}) | ||
require.NotNil(t, err) | ||
|
||
p, err := ps.Create(ctx, database.Prompt{}) | ||
require.Nil(t, err) | ||
|
||
err = ps.Delete(ctx, *p) | ||
require.Nil(t, err) | ||
|
||
err = ps.Delete(ctx, *p) | ||
require.NotNil(t, err) | ||
|
||
p, err := ps.ByRepoID(ctx, TestRepoId) | ||
} | ||
|
||
func TestPromptStore_ByUserName(t *testing.T) { | ||
db := tests.InitTestDB() | ||
defer db.Close() | ||
ctx := context.TODO() | ||
|
||
us := database.NewUserStoreWithDB(db) | ||
err := us.Create(ctx, &database.User{ | ||
Username: "foo", | ||
}, &database.Namespace{}) | ||
require.Nil(t, err) | ||
user, err := us.FindByUsername(ctx, "foo") | ||
require.Nil(t, err) | ||
|
||
rs := database.NewRepoStoreWithDB(db) | ||
|
||
// order: 4-6-2-1-3-5 | ||
repos := []struct { | ||
Name string | ||
CreatedAt time.Time | ||
Private bool | ||
}{ | ||
{"repo1", time.Unix(1731561102, 0), false}, | ||
{"repo2", time.Unix(1731561302, 0), false}, | ||
{"repo3", time.Unix(1731551102, 0), false}, | ||
{"repo4", time.Unix(1731564132, 0), true}, | ||
{"repo5", time.Unix(1721561102, 0), false}, | ||
{"repo6", time.Unix(1731564102, 0), true}, | ||
} | ||
|
||
ps.Delete(ctx, *p) | ||
ps := database.NewPromptStoreWithDB(db) | ||
for _, repo := range repos { | ||
r := database.Repository{ | ||
UserID: user.ID, | ||
Name: repo.Name, | ||
Path: repo.Name, | ||
GitPath: repo.Name, | ||
Private: repo.Private, | ||
} | ||
|
||
rp, err := rs.CreateRepo(ctx, r) | ||
require.Nil(t, err) | ||
|
||
pm := database.Prompt{ | ||
RepositoryID: rp.ID, | ||
} | ||
pm.CreatedAt = repo.CreatedAt | ||
_, err = ps.Create(ctx, pm) | ||
require.Nil(t, err) | ||
} | ||
|
||
if err != nil { | ||
t.Fatalf("failed to delete prompt: %v", err) | ||
cases := []struct { | ||
per int | ||
page int | ||
total int | ||
onlyPublic bool | ||
expected []int | ||
}{ | ||
{10, 1, 6, false, []int{4, 6, 2, 1, 3, 5}}, | ||
{10, 1, 4, true, []int{2, 1, 3, 5}}, | ||
{2, 1, 6, false, []int{4, 6}}, | ||
{2, 2, 6, false, []int{2, 1}}, | ||
{2, 1, 4, true, []int{2, 1}}, | ||
{2, 2, 4, true, []int{3, 5}}, | ||
} | ||
|
||
for _, c := range cases { | ||
t.Run(fmt.Sprintf("page %d, per %d, public %t", c.page, c.per, c.onlyPublic), func(t *testing.T) { | ||
prompts, total, err := ps.ByUsername(ctx, "foo", c.per, c.page, c.onlyPublic) | ||
require.Nil(t, err) | ||
names := []string{} | ||
for _, pm := range prompts { | ||
names = append(names, pm.Repository.Name) | ||
} | ||
expected := []string{} | ||
for _, i := range c.expected { | ||
expected = append(expected, fmt.Sprintf("repo%d", i)) | ||
} | ||
|
||
require.Equal(t, c.total, total) | ||
require.Equal(t, expected, names) | ||
|
||
}) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.