go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/proto/gitiles/gitiles_fake_test.go (about) 1 // Copyright 2020 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package gitiles 16 17 import ( 18 "context" 19 "strconv" 20 "testing" 21 22 . "github.com/smartystreets/goconvey/convey" 23 git "go.chromium.org/luci/common/proto/git" 24 ) 25 26 func TestFake(t *testing.T) { 27 t.Parallel() 28 29 ctx := context.Background() 30 Convey("Edge cases", t, func() { 31 Convey("Empty", func() { 32 fake := Fake{} 33 Convey("Projects", func() { 34 resp, err := fake.Projects(ctx, &ProjectsRequest{}) 35 So(err, ShouldBeNil) 36 So(resp.GetProjects(), ShouldBeEmpty) 37 }) 38 Convey("Revs", func() { 39 in := &RefsRequest{ 40 Project: "foo", 41 } 42 // Repository not found 43 _, err := fake.Refs(ctx, in) 44 So(err, ShouldBeError) 45 }) 46 }) 47 48 Convey("Empty project", func() { 49 fake := Fake{} 50 fake.SetRepository("foo", nil, nil) 51 Convey("Projects", func() { 52 resp, err := fake.Projects(ctx, &ProjectsRequest{}) 53 So(err, ShouldBeNil) 54 So(resp.GetProjects(), ShouldResemble, []string{"foo"}) 55 }) 56 57 Convey("Revs", func() { 58 in := &RefsRequest{ 59 Project: "foo", 60 } 61 // Repository not found 62 out, err := fake.Refs(ctx, in) 63 So(err, ShouldBeNil) 64 So(out.GetRevisions(), ShouldBeEmpty) 65 }) 66 }) 67 68 Convey("Empty repository", func() { 69 fake := Fake{} 70 refs := map[string]string{"refs/heads/main": ""} 71 fake.SetRepository("foo", refs, nil) 72 Convey("Projects", func() { 73 resp, err := fake.Projects(ctx, &ProjectsRequest{}) 74 So(err, ShouldBeNil) 75 So(resp.GetProjects(), ShouldResemble, []string{"foo"}) 76 }) 77 78 Convey("Revs", func() { 79 in := &RefsRequest{ 80 Project: "foo", 81 } 82 // Repository not found 83 out, err := fake.Refs(ctx, in) 84 So(err, ShouldBeNil) 85 So(out.GetRevisions(), ShouldResemble, refs) 86 }) 87 }) 88 89 Convey("Reference points to invalid revision", func() { 90 fake := Fake{} 91 So(func() { 92 fake.SetRepository("foo", map[string]string{"foo": "bar"}, nil) 93 }, ShouldPanic) 94 }) 95 96 Convey("Duplicate commit", func() { 97 fake := Fake{} 98 So(func() { 99 commits := []*git.Commit{ 100 { 101 Id: "bar", 102 }, 103 { 104 Id: "bar", 105 }, 106 } 107 fake.SetRepository("foo", map[string]string{"foo": "bar"}, commits) 108 }, ShouldPanic) 109 }) 110 111 Convey("Broken commit chain", func() { 112 fake := Fake{} 113 commits := []*git.Commit{ 114 { 115 Id: "bar", 116 Parents: []string{"baz"}, 117 }, 118 } 119 fake.SetRepository("foo", map[string]string{"refs/heads/main": "bar"}, commits) 120 So(func() { 121 in := &LogRequest{ 122 Project: "foo", 123 Committish: "refs/heads/main", 124 } 125 fake.Log(ctx, in) 126 }, ShouldPanic) 127 }) 128 }) 129 130 Convey("Linear commits", t, func() { 131 // Commit structure: 9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 132 commits := make([]*git.Commit, 10) 133 for i := 0; i < 10; i++ { 134 commits[i] = &git.Commit{ 135 Id: strconv.Itoa(i), 136 } 137 if i > 0 { 138 commits[i].Parents = []string{commits[i-1].GetId()} 139 } 140 } 141 refs := map[string]string{ 142 "refs/heads/main": "9", 143 "refs/heads/stable": "1", 144 } 145 fake := Fake{} 146 fake.SetRepository("foo", refs, commits) 147 148 Convey("Revs", func() { 149 in := &RefsRequest{ 150 Project: "foo", 151 } 152 out, err := fake.Refs(ctx, in) 153 So(err, ShouldBeNil) 154 So(out.GetRevisions(), ShouldResemble, refs) 155 }) 156 157 Convey("Log pagination main", func() { 158 in := &LogRequest{ 159 Project: "foo", 160 Committish: "refs/heads/main", 161 PageSize: 5, 162 } 163 out, err := fake.Log(ctx, in) 164 So(err, ShouldBeNil) 165 So(len(out.GetLog()), ShouldEqual, 5) 166 // Last element returned is 5, which is the token 167 So(out.GetNextPageToken(), ShouldEqual, "5") 168 169 in.PageToken = out.GetNextPageToken() 170 out, err = fake.Log(ctx, in) 171 So(err, ShouldBeNil) 172 So(len(out.GetLog()), ShouldEqual, 5) 173 // Last element returned is 0, which is the token 174 So(out.GetNextPageToken(), ShouldEqual, "0") 175 176 // We reached the end 177 in.PageToken = out.GetNextPageToken() 178 out, err = fake.Log(ctx, in) 179 So(err, ShouldBeNil) 180 So(len(out.GetLog()), ShouldEqual, 0) 181 So(out.GetNextPageToken(), ShouldEqual, "") 182 }) 183 184 Convey("Log stable branch", func() { 185 in := &LogRequest{ 186 Project: "foo", 187 Committish: "refs/heads/stable", 188 PageSize: 5, 189 } 190 out, err := fake.Log(ctx, in) 191 So(err, ShouldBeNil) 192 So(len(out.GetLog()), ShouldEqual, 2) 193 So(out.GetNextPageToken(), ShouldEqual, "") 194 }) 195 196 Convey("Log Non existing branch", func() { 197 in := &LogRequest{ 198 Project: "foo", 199 Committish: "refs/heads/foo", 200 PageSize: 5, 201 } 202 _, err := fake.Log(ctx, in) 203 So(err, ShouldBeError) 204 }) 205 }) 206 207 Convey("Merge logs", t, func() { 208 // Commit structure: 9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 209 // \_ b2 -> b1 / 210 commits := make([]*git.Commit, 12) 211 for i := 0; i < 10; i++ { 212 commits[i] = &git.Commit{ 213 Id: strconv.Itoa(i), 214 } 215 if i > 0 { 216 commits[i].Parents = []string{commits[i-1].GetId()} 217 } 218 } 219 commits[10] = &git.Commit{ 220 Id: "b1", 221 Parents: []string{"3"}, 222 } 223 commits[11] = &git.Commit{ 224 Id: "b2", 225 Parents: []string{"b1"}, 226 } 227 // Modify commit with ID 8 to merge commit include b2 as parent. 228 commits[8].Parents = []string{"7", "b2"} 229 230 refs := map[string]string{ 231 "refs/heads/main": "9", 232 "refs/heads/feature": "b2", 233 "refs/heads/stable": "7", 234 } 235 fake := Fake{} 236 fake.SetRepository("foo", refs, commits) 237 238 Convey("Entire log", func() { 239 in := &LogRequest{ 240 Project: "foo", 241 Committish: "refs/heads/main", 242 PageSize: 100, 243 } 244 out, err := fake.Log(ctx, in) 245 So(err, ShouldBeNil) 246 So(out.GetNextPageToken(), ShouldBeEmpty) 247 So(len(out.GetLog()), ShouldEqual, 12) 248 }) 249 250 Convey("Partial log, before merge", func() { 251 in := &LogRequest{ 252 Project: "foo", 253 Committish: "refs/heads/stable", 254 PageSize: 100, 255 } 256 out, err := fake.Log(ctx, in) 257 So(err, ShouldBeNil) 258 So(out.GetNextPageToken(), ShouldBeEmpty) 259 So(len(out.GetLog()), ShouldEqual, 8) 260 }) 261 262 Convey("Partial log, before merge (feature branch)", func() { 263 in := &LogRequest{ 264 Project: "foo", 265 Committish: "refs/heads/feature", 266 PageSize: 100, 267 } 268 out, err := fake.Log(ctx, in) 269 So(err, ShouldBeNil) 270 So(out.GetNextPageToken(), ShouldBeEmpty) 271 So(len(out.GetLog()), ShouldEqual, 6) 272 }) 273 274 Convey("Partial log, specific commit", func() { 275 in := &LogRequest{ 276 Project: "foo", 277 Committish: "8", 278 PageSize: 100, 279 } 280 out, err := fake.Log(ctx, in) 281 So(err, ShouldBeNil) 282 So(out.GetNextPageToken(), ShouldBeEmpty) 283 So(len(out.GetLog()), ShouldEqual, 11) 284 }) 285 }) 286 }