diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bf225d42..1191a8ea 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -41,7 +41,7 @@ jobs: mysql: strategy: matrix: - dbversion: ['mysql:latest', 'mysql:5.7', 'mariadb:latest'] + dbversion: ['mysql:latest', 'mysql:5.7'] go: ['1.19', '1.18'] platform: [ubuntu-latest] runs-on: ${{ matrix.platform }} @@ -72,7 +72,6 @@ jobs: - name: Check out code into the Go module directory uses: actions/checkout@v3 - - name: go mod package cache uses: actions/cache@v3 with: @@ -82,6 +81,49 @@ jobs: - name: Tests run: GITHUB_ACTION=true GORM_DIALECT=mysql GORM_DSN="gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True" ./tests/tests_all.sh + mariadb: + strategy: + matrix: + dbversion: [ 'mariadb:latest' ] + go: [ '1.19', '1.18' ] + platform: [ ubuntu-latest ] + runs-on: ${{ matrix.platform }} + + services: + mysql: + image: ${{ matrix.dbversion }} + env: + MYSQL_DATABASE: gorm + MYSQL_USER: gorm + MYSQL_PASSWORD: gorm + MYSQL_RANDOM_ROOT_PASSWORD: "yes" + ports: + - 9910:3306 + options: >- + --health-cmd "mariadb-admin ping -ugorm -pgorm" + --health-interval 10s + --health-start-period 10s + --health-timeout 5s + --health-retries 10 + + steps: + - name: Set up Go 1.x + uses: actions/setup-go@v4 + with: + go-version: ${{ matrix.go }} + + - name: Check out code into the Go module directory + uses: actions/checkout@v3 + + - name: go mod package cache + uses: actions/cache@v3 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ matrix.go }}-${{ hashFiles('tests/go.mod') }} + + - name: Tests + run: GITHUB_ACTION=true GORM_DIALECT=mysql GORM_DSN="gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True" ./tests/tests_all.sh + postgres: strategy: matrix: diff --git a/tests/associations_many2many_test.go b/tests/associations_many2many_test.go index b69d668a..39410aed 100644 --- a/tests/associations_many2many_test.go +++ b/tests/associations_many2many_test.go @@ -358,7 +358,7 @@ func TestDuplicateMany2ManyAssociation(t *testing.T) { } func TestConcurrentMany2ManyAssociation(t *testing.T) { - db, err := OpenTestConnection() + db, err := OpenTestConnection(&gorm.Config{}) if err != nil { t.Fatalf("open test connection failed, err: %+v", err) } diff --git a/tests/error_translator_test.go b/tests/error_translator_test.go index ca985a09..f6c70677 100644 --- a/tests/error_translator_test.go +++ b/tests/error_translator_test.go @@ -27,3 +27,34 @@ func TestDialectorWithErrorTranslatorSupport(t *testing.T) { t.Fatalf("expected err: %v got err: %v", translatedErr, err) } } + +func TestSupportedDialectorWithErrDuplicatedKey(t *testing.T) { + type City struct { + gorm.Model + Name string `gorm:"unique"` + } + + db, err := OpenTestConnection(&gorm.Config{TranslateError: true}) + if err != nil { + t.Fatalf("failed to connect database, got error %v", err) + } + + dialectors := map[string]bool{"sqlite": true, "postgres": true, "mysql": true, "sqlserver": true} + if supported, found := dialectors[db.Dialector.Name()]; !(found && supported) { + return + } + + if err = db.AutoMigrate(&City{}); err != nil { + t.Fatalf("failed to migrate cities table, got error: %v", err) + } + + err = db.Create(&City{Name: "Kabul"}).Error + if err != nil { + t.Fatalf("failed to create record: %v", err) + } + + err = db.Create(&City{Name: "Kabul"}).Error + if !errors.Is(err, gorm.ErrDuplicatedKey) { + t.Fatalf("expected err: %v got err: %v", gorm.ErrDuplicatedKey, err) + } +} diff --git a/tests/go.mod b/tests/go.mod index 5c0b142f..fbbee489 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -9,12 +9,11 @@ require ( github.com/lib/pq v1.10.8 github.com/mattn/go-sqlite3 v1.14.16 // indirect github.com/stretchr/testify v1.8.1 - golang.org/x/crypto v0.8.0 // indirect gorm.io/driver/mysql v1.5.0 gorm.io/driver/postgres v1.5.0 gorm.io/driver/sqlite v1.5.0 - gorm.io/driver/sqlserver v1.4.3 - gorm.io/gorm v1.25.0 + gorm.io/driver/sqlserver v1.5.1 + gorm.io/gorm v1.25.1 ) replace gorm.io/gorm => ../ diff --git a/tests/prepared_stmt_test.go b/tests/prepared_stmt_test.go index 64baa01b..b234c8bf 100644 --- a/tests/prepared_stmt_test.go +++ b/tests/prepared_stmt_test.go @@ -92,7 +92,7 @@ func TestPreparedStmtFromTransaction(t *testing.T) { } func TestPreparedStmtDeadlock(t *testing.T) { - tx, err := OpenTestConnection() + tx, err := OpenTestConnection(&gorm.Config{}) AssertEqual(t, err, nil) sqlDB, _ := tx.DB() @@ -127,7 +127,7 @@ func TestPreparedStmtDeadlock(t *testing.T) { } func TestPreparedStmtError(t *testing.T) { - tx, err := OpenTestConnection() + tx, err := OpenTestConnection(&gorm.Config{}) AssertEqual(t, err, nil) sqlDB, _ := tx.DB() diff --git a/tests/scanner_valuer_test.go b/tests/scanner_valuer_test.go index 14121699..472434b4 100644 --- a/tests/scanner_valuer_test.go +++ b/tests/scanner_valuer_test.go @@ -170,10 +170,10 @@ func (data *EncryptedData) Scan(value interface{}) error { return errors.New("Too short") } - *data = b[3:] + *data = append((*data)[0:], b[3:]...) return nil } else if s, ok := value.(string); ok { - *data = []byte(s)[3:] + *data = []byte(s[3:]) return nil } diff --git a/tests/tests_test.go b/tests/tests_test.go index 90eb847f..0167d406 100644 --- a/tests/tests_test.go +++ b/tests/tests_test.go @@ -26,7 +26,7 @@ var ( func init() { var err error - if DB, err = OpenTestConnection(); err != nil { + if DB, err = OpenTestConnection(&gorm.Config{}); err != nil { log.Printf("failed to connect database, got error %v", err) os.Exit(1) } else { @@ -49,7 +49,7 @@ func init() { } } -func OpenTestConnection() (db *gorm.DB, err error) { +func OpenTestConnection(cfg *gorm.Config) (db *gorm.DB, err error) { dbDSN := os.Getenv("GORM_DSN") switch os.Getenv("GORM_DIALECT") { case "mysql": @@ -57,7 +57,7 @@ func OpenTestConnection() (db *gorm.DB, err error) { if dbDSN == "" { dbDSN = mysqlDSN } - db, err = gorm.Open(mysql.Open(dbDSN), &gorm.Config{}) + db, err = gorm.Open(mysql.Open(dbDSN), cfg) case "postgres": log.Println("testing postgres...") if dbDSN == "" { @@ -66,7 +66,7 @@ func OpenTestConnection() (db *gorm.DB, err error) { db, err = gorm.Open(postgres.New(postgres.Config{ DSN: dbDSN, PreferSimpleProtocol: true, - }), &gorm.Config{}) + }), cfg) case "sqlserver": // go install github.com/microsoft/go-sqlcmd/cmd/sqlcmd@latest // SQLCMDPASSWORD=LoremIpsum86 sqlcmd -U sa -S localhost:9930 @@ -80,16 +80,16 @@ func OpenTestConnection() (db *gorm.DB, err error) { if dbDSN == "" { dbDSN = sqlserverDSN } - db, err = gorm.Open(sqlserver.Open(dbDSN), &gorm.Config{}) + db, err = gorm.Open(sqlserver.Open(dbDSN), cfg) case "tidb": log.Println("testing tidb...") if dbDSN == "" { dbDSN = tidbDSN } - db, err = gorm.Open(mysql.Open(dbDSN), &gorm.Config{}) + db, err = gorm.Open(mysql.Open(dbDSN), cfg) default: log.Println("testing sqlite3...") - db, err = gorm.Open(sqlite.Open(filepath.Join(os.TempDir(), "gorm.db")), &gorm.Config{}) + db, err = gorm.Open(sqlite.Open(filepath.Join(os.TempDir(), "gorm.db")), cfg) } if err != nil { diff --git a/tests/transaction_test.go b/tests/transaction_test.go index bfbd8699..126ccb23 100644 --- a/tests/transaction_test.go +++ b/tests/transaction_test.go @@ -361,7 +361,7 @@ func TestDisabledNestedTransaction(t *testing.T) { } func TestTransactionOnClosedConn(t *testing.T) { - DB, err := OpenTestConnection() + DB, err := OpenTestConnection(&gorm.Config{}) if err != nil { t.Fatalf("failed to connect database, got error %v", err) } diff --git a/utils/tests/models.go b/utils/tests/models.go index ec1651a3..a4bad2fc 100644 --- a/utils/tests/models.go +++ b/utils/tests/models.go @@ -11,7 +11,7 @@ import ( // He works in a Company (belongs to), he has a Manager (belongs to - single-table), and also managed a Team (has many - single-table) // He speaks many languages (many to many) and has many friends (many to many - single-table) // His pet also has one Toy (has one - polymorphic) -// NamedPet is a reference to a Named `Pets` (has many) +// NamedPet is a reference to a named `Pet` (has one) type User struct { gorm.Model Name string