vitess.io/vitess@v0.16.2/go/mysql/collations/golden_test.go (about) 1 /* 2 Copyright 2021 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package collations 18 19 import ( 20 "bytes" 21 "fmt" 22 "os" 23 "path/filepath" 24 "sort" 25 "strings" 26 "testing" 27 28 "github.com/stretchr/testify/assert" 29 "github.com/stretchr/testify/require" 30 31 "vitess.io/vitess/go/mysql/collations/internal/charset" 32 "vitess.io/vitess/go/mysql/collations/internal/testutil" 33 ) 34 35 func TestGoldenWeights(t *testing.T) { 36 gllGoldenTests, err := filepath.Glob("testdata/wiki_*.gob.gz") 37 if err != nil { 38 t.Fatal(err) 39 } 40 41 for _, goldenPath := range gllGoldenTests { 42 golden := &testutil.GoldenTest{} 43 if err := golden.DecodeFromFile(goldenPath); err != nil { 44 t.Fatal(err) 45 } 46 47 for _, goldenCase := range golden.Cases { 48 t.Run(fmt.Sprintf("%s (%s)", golden.Name, goldenCase.Lang), func(t *testing.T) { 49 for coll, expected := range goldenCase.Weights { 50 coll := testcollation(t, coll) 51 52 input, err := charset.ConvertFromUTF8(nil, coll.Charset(), goldenCase.Text) 53 if err != nil { 54 t.Fatal(err) 55 } 56 57 result := coll.WeightString(nil, input, 0) 58 assert.True(t, bytes.Equal(expected, result), "mismatch for collation=%s\noriginal: %s\ninput: %#v\nexpected: %v\nactual: %v", coll.Name(), string(goldenCase.Text), input, expected, result) 59 60 } 61 }) 62 } 63 } 64 } 65 66 func TestCollationsForLanguage(t *testing.T) { 67 allCollations := testall() 68 langCounts := make(map[testutil.Lang][]string) 69 70 for lang := range testutil.KnownLanguages { 71 var matched []string 72 for _, coll := range allCollations { 73 name := coll.Name() 74 if lang.MatchesCollation(name) { 75 matched = append(matched, name) 76 } 77 } 78 langCounts[lang] = matched 79 } 80 81 for lang := range testutil.KnownLanguages { 82 assert.NotEqual(t, 0, len(langCounts[lang]), "no collations found for %q", lang) 83 84 t.Logf("%s: %v", lang, langCounts[lang]) 85 } 86 } 87 88 // XTestSupportTables should not run by default; it is used to generate a Markdown 89 // table with Collation support information for the current build of Vitess. 90 func XTestSupportTables(t *testing.T) { 91 var versions = []collver{ 92 collverMySQL80, 93 collverMySQL57, 94 collverMySQL56, 95 collverMariaDB103, 96 collverMariaDB102, 97 collverMariaDB101, 98 collverMariaDB100, 99 } 100 101 var envs []*Environment 102 for _, v := range versions { 103 envs = append(envs, makeEnv(v)) 104 } 105 106 var all []ID 107 for id := range globalVersionInfo { 108 all = append(all, id) 109 } 110 sort.Slice(all, func(i, j int) bool { 111 return all[i] < all[j] 112 }) 113 114 var out = os.Stdout 115 116 fmt.Fprintf(out, "| Collation | Charset") 117 for _, env := range envs { 118 fmt.Fprintf(out, " | %s", env.version.String()) 119 } 120 fmt.Fprintf(out, " |\n|%s\n", strings.Repeat("---|", len(envs)+2)) 121 122 for _, id := range all { 123 coll := globalAllCollations[id] 124 if coll == nil { 125 vdata := globalVersionInfo[id] 126 127 var collnames []string 128 for _, alias := range vdata.alias { 129 collnames = append(collnames, alias.name) 130 break 131 } 132 collname := strings.Join(collnames, ",") 133 parts := strings.Split(collname, "_") 134 135 fmt.Fprintf(out, "| %s | %s", collname, parts[0]) 136 for _, env := range envs { 137 var supported bool 138 for _, alias := range vdata.alias { 139 if alias.mask&env.version != 0 { 140 supported = true 141 break 142 } 143 } 144 if supported { 145 fmt.Fprintf(out, " | ⚠️") 146 } else { 147 fmt.Fprintf(out, " | ❌") 148 } 149 } 150 } else { 151 fmt.Fprintf(out, "| %s | %s", coll.Name(), coll.Charset().Name()) 152 for _, env := range envs { 153 _, supported := env.byID[coll.ID()] 154 if supported { 155 fmt.Fprintf(out, " | ✅") 156 } else { 157 fmt.Fprintf(out, " | ❌") 158 } 159 } 160 } 161 162 fmt.Fprintf(out, " |\n") 163 } 164 } 165 166 func TestAllCollationsByCharset(t *testing.T) { 167 var defaults1 = map[string][2]string{ 168 "utf8mb4": {"utf8mb4_general_ci", "utf8mb4_bin"}, 169 } 170 var defaults2 = map[string][2]string{ 171 "utf8mb4": {"utf8mb4_0900_ai_ci", "utf8mb4_0900_bin"}, 172 } 173 174 for _, tc := range []struct { 175 version collver 176 defaults map[string][2]string 177 }{ 178 {collverMariaDB100, defaults1}, 179 {collverMariaDB101, defaults1}, 180 {collverMariaDB102, defaults1}, 181 {collverMariaDB103, defaults1}, 182 {collverMySQL56, defaults1}, 183 {collverMySQL57, defaults1}, 184 {collverMySQL80, defaults2}, 185 } { 186 t.Run(tc.version.String(), func(t *testing.T) { 187 env := makeEnv(tc.version) 188 for csname, cset := range env.byCharset { 189 switch csname { 190 case "gb18030": 191 // this doesn't work yet 192 continue 193 } 194 require.NotNil(t, cset.Default, "charset %s has no default", csname) 195 require.NotNil(t, cset.Binary, "charset %s has no binary", csname) 196 197 } 198 199 for charset, expected := range tc.defaults { 200 expectedDefault, expectedBinary := expected[0], expected[1] 201 if def := env.DefaultCollationForCharset(charset); def.Name() != expectedDefault { 202 t.Fatalf("bad default for utf8mb4: %s (expected %s)", def.Name(), expectedDefault) 203 } 204 if def := env.BinaryCollationForCharset(charset); def.Name() != expectedBinary { 205 t.Fatalf("bad binary for utf8mb4: %s (expected %s)", def.Name(), expectedBinary) 206 } 207 } 208 }) 209 } 210 }