| package utils_test |
| |
| import ( |
| "github.com/apache/cloudberry-backup/utils" |
| "github.com/apache/cloudberry-go-libs/testhelper" |
| |
| . "github.com/onsi/ginkgo/v2" |
| . "github.com/onsi/gomega" |
| ) |
| |
| var _ = Describe("utils/util tests", func() { |
| Context("DollarQuoteString", func() { |
| It("uses $$ if the string contains no dollar signs", func() { |
| testStr := "message" |
| expected := "$$message$$" |
| actual := utils.DollarQuoteString(testStr) |
| Expect(actual).To(Equal(expected)) |
| }) |
| It("uses $_$ if the string contains $", func() { |
| testStr := "message$text" |
| expected := "$_$message$text$_$" |
| actual := utils.DollarQuoteString(testStr) |
| Expect(actual).To(Equal(expected)) |
| }) |
| It("uses $_X$ if the string contains $_", func() { |
| testStr := "message$_text" |
| expected := "$_X$message$_text$_X$" |
| actual := utils.DollarQuoteString(testStr) |
| Expect(actual).To(Equal(expected)) |
| }) |
| It("uses $_$ if the string contains non-adjacent $ and _", func() { |
| testStr := "message$text_" |
| expected := "$_$message$text_$_$" |
| actual := utils.DollarQuoteString(testStr) |
| Expect(actual).To(Equal(expected)) |
| }) |
| }) |
| Describe("ValidateFQNs", func() { |
| It("validates the following cases correctly", func() { |
| testStrings := []string{ |
| `schemaname.tablename`, // unquoted |
| `"schema,name".tablename`, // quoted schema |
| `schemaname."table,name"`, // quoted table |
| `schema name.tablename"`, // spaces |
| `schema name .tablename"`, //tabs |
| `schemaname.TABLENAME!@#$%^&*()_+={}|[]\';":/,?><"`, // special characters |
| } |
| utils.ValidateFQNs(testStrings) |
| }) |
| It("fails if given a string without a schema", func() { |
| testStrings := []string{`.tablename`} |
| err := utils.ValidateFQNs(testStrings) |
| Expect(err).To(HaveOccurred()) |
| }) |
| It("fails if given a string without a table", func() { |
| testStrings := []string{`schemaname.`} |
| err := utils.ValidateFQNs(testStrings) |
| Expect(err).To(HaveOccurred()) |
| }) |
| It("fails if the schema and table can't be determined", func() { |
| testStrings := []string{`schemanametablename`} |
| err := utils.ValidateFQNs(testStrings) |
| Expect(err).To(HaveOccurred()) |
| }) |
| }) |
| Context("ValidateFullPath", func() { |
| It("does not return error when the flag is not set", func() { |
| path := "" |
| Expect(utils.ValidateFullPath(path)).To(Succeed()) |
| }) |
| It("does not return error when given an absolute path", func() { |
| path := "/this/is/an/absolute/path" |
| Expect(utils.ValidateFullPath(path)).To(Succeed()) |
| }) |
| It("panics when given a relative path", func() { |
| path := "this/is/a/relative/path" |
| err := utils.ValidateFullPath(path) |
| Expect(err).To(MatchError("this/is/a/relative/path is not an absolute path.")) |
| |
| }) |
| }) |
| Describe("ValidateGPDBVersionCompatibility", func() { |
| It("panics if GPDB 5 version is less than 5.1.0", func() { |
| testhelper.SetDBVersion(connectionPool, "5.0.0") |
| defer testhelper.ShouldPanicWithMessage("GPDB version 5.0.0 is not supported. Please upgrade to GPDB 5.1.0 or later.") |
| utils.ValidateGPDBVersionCompatibility(connectionPool) |
| }) |
| It("does not panic if GPDB version is at least 5.1.0", func() { |
| testhelper.SetDBVersion(connectionPool, "5.1.0") |
| utils.ValidateGPDBVersionCompatibility(connectionPool) |
| }) |
| It("does not panic if GPDB version is at least 6.0.0", func() { |
| testhelper.SetDBVersion(connectionPool, "6.0.0") |
| utils.ValidateGPDBVersionCompatibility(connectionPool) |
| }) |
| }) |
| Describe("ValidateCompressionTypeAndLevel", func() { |
| It("validates a compression type 'gzip' and a level between 1 and 9", func() { |
| compressType := "gzip" |
| compressLevel := 5 |
| err := utils.ValidateCompressionTypeAndLevel(compressType, compressLevel) |
| Expect(err).To(Not(HaveOccurred())) |
| }) |
| It("panics if given a compression type 'gzip' and a compression level < 1", func() { |
| compressType := "gzip" |
| compressLevel := 0 |
| err := utils.ValidateCompressionTypeAndLevel(compressType, compressLevel) |
| Expect(err).To(MatchError("compression type 'gzip' only allows compression levels between 1 and 9, but the provided level is 0")) |
| }) |
| It("panics if given a compression type 'gzip' and a compression level > 9", func() { |
| compressType := "gzip" |
| compressLevel := 11 |
| err := utils.ValidateCompressionTypeAndLevel(compressType, compressLevel) |
| Expect(err).To(MatchError("compression type 'gzip' only allows compression levels between 1 and 9, but the provided level is 11")) |
| }) |
| It("panics if given a compression type 'invalid' and a compression level > 0", func() { |
| compressType := "invalid" |
| compressLevel := 1 |
| err := utils.ValidateCompressionTypeAndLevel(compressType, compressLevel) |
| Expect(err).To(MatchError("unknown compression type 'invalid'")) |
| }) |
| It("panics if given a compression type 'invalid' and a compression level < 0", func() { |
| compressType := "invalid" |
| compressLevel := -1 |
| err := utils.ValidateCompressionTypeAndLevel(compressType, compressLevel) |
| Expect(err).To(MatchError("unknown compression type 'invalid'")) |
| }) |
| It("panics if given a compression type '' and a compression level > 0", func() { |
| compressType := "" |
| compressLevel := 1 |
| err := utils.ValidateCompressionTypeAndLevel(compressType, compressLevel) |
| Expect(err).To(MatchError("unknown compression type ''")) |
| }) |
| It("validates a compression type 'zstd' and a level between 1 and 19", func() { |
| compressType := "zstd" |
| compressLevel := 11 |
| err := utils.ValidateCompressionTypeAndLevel(compressType, compressLevel) |
| Expect(err).To(Not(HaveOccurred())) |
| }) |
| It("panics if given a compression type 'zstd' and a compression level < 1", func() { |
| compressType := "zstd" |
| compressLevel := 0 |
| err := utils.ValidateCompressionTypeAndLevel(compressType, compressLevel) |
| Expect(err).To(MatchError("compression type 'zstd' only allows compression levels between 1 and 19, but the provided level is 0")) |
| }) |
| It("panics if given a compression type 'gzip' and a compression level > 19", func() { |
| compressType := "zstd" |
| compressLevel := 20 |
| err := utils.ValidateCompressionTypeAndLevel(compressType, compressLevel) |
| Expect(err).To(MatchError("compression type 'zstd' only allows compression levels between 1 and 19, but the provided level is 20")) |
| }) |
| }) |
| Describe("UnquoteIdent", func() { |
| It("returns unchanged ident when passed a single char", func() { |
| dbname := `a` |
| resultString := utils.UnquoteIdent(dbname) |
| |
| Expect(resultString).To(Equal(`a`)) |
| }) |
| It("returns unchanged ident when passed an unquoted ident", func() { |
| dbname := `test` |
| resultString := utils.UnquoteIdent(dbname) |
| |
| Expect(resultString).To(Equal(`test`)) |
| }) |
| It("returns one double quote when passed a double quote", func() { |
| dbname := `"` |
| resultString := utils.UnquoteIdent(dbname) |
| |
| Expect(resultString).To(Equal(`"`)) |
| }) |
| It("returns empty string when passed an empty string", func() { |
| dbname := "" |
| resultString := utils.UnquoteIdent(dbname) |
| |
| Expect(resultString).To(Equal(``)) |
| }) |
| It("properly unquotes an identfier string and unescapes double quotes", func() { |
| dbname := `"""test"` |
| resultString := utils.UnquoteIdent(dbname) |
| |
| Expect(resultString).To(Equal(`"test`)) |
| }) |
| }) |
| Describe("SliceToQuotedString", func() { |
| It("quotes and joins a slice of strings into a single string", func() { |
| inputStrings := []string{"string1", "string2", "string3"} |
| expectedString := "'string1','string2','string3'" |
| resultString := utils.SliceToQuotedString(inputStrings) |
| Expect(resultString).To(Equal(expectedString)) |
| }) |
| It("returns an empty string when given an empty slice", func() { |
| inputStrings := make([]string, 0) |
| resultString := utils.SliceToQuotedString(inputStrings) |
| Expect(resultString).To(Equal("")) |
| }) |
| }) |
| }) |