github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/transportrequest/gitutils_test.go (about) 1 //go:build unit 2 // +build unit 3 4 package transportrequest 5 6 import ( 7 pipergit "github.com/SAP/jenkins-library/pkg/git" 8 "github.com/go-git/go-billy/v5/memfs" 9 "github.com/go-git/go-git/v5" 10 "github.com/go-git/go-git/v5/plumbing" 11 "github.com/go-git/go-git/v5/plumbing/object" 12 "github.com/go-git/go-git/v5/plumbing/storer" 13 "github.com/go-git/go-git/v5/storage/memory" 14 "github.com/stretchr/testify/assert" 15 "io" 16 "testing" 17 ) 18 19 type commitIteratorMock struct { 20 commits []object.Commit 21 index int 22 } 23 24 func (iter *commitIteratorMock) Next() (*object.Commit, error) { 25 i := iter.index 26 iter.index++ 27 28 if i >= len(iter.commits) { 29 return nil, io.EOF // real iterators also behave like this 30 } 31 return &iter.commits[i], nil 32 } 33 34 func (iter *commitIteratorMock) ForEach(cb func(c *object.Commit) error) error { 35 for { 36 c, err := iter.Next() 37 if err == io.EOF { 38 break 39 } 40 if err != nil { 41 return err 42 } 43 44 err = cb(c) 45 if err == storer.ErrStop { 46 break 47 } 48 if err != nil { 49 return err 50 } 51 } 52 53 return nil 54 } 55 56 func (iter *commitIteratorMock) Close() { 57 58 } 59 60 type TrGitUtilsMock struct { 61 } 62 63 func (m *TrGitUtilsMock) PlainOpen(path string) (*git.Repository, error) { 64 return git.Init(memory.NewStorage(), memfs.New()) 65 } 66 67 func TestRetrieveLabelStraightForward(t *testing.T) { 68 69 t.Run("single commit tests", func(t *testing.T) { 70 71 runTest := func(testConfig []string) { 72 t.Run(testConfig[0], func(t *testing.T) { 73 commitIter := &commitIteratorMock{ 74 commits: []object.Commit{ 75 object.Commit{ 76 Hash: plumbing.NewHash("3434343434343434343434343434343434343434"), 77 Message: testConfig[1], 78 }, 79 }, 80 } 81 labels, err := FindLabelsInCommits(commitIter, "TransportRequest") 82 if assert.NoError(t, err) { 83 expected := testConfig[2:] 84 if assert.Len(t, labels, len(expected)) { 85 assert.Subset(t, expected, labels) 86 } 87 } 88 }) 89 } 90 91 tests := [][]string{ 92 []string{ 93 "straight forward", 94 "this is a commit with TransportRequestId\n\nThis is the first line of the message body\nTransportRequest: 12345678", 95 "12345678", 96 }, 97 []string{ 98 "trailing spaces after our value", 99 "this is a commit with TransportRequestId\n\nThis is the first line of the message body\nTransportRequest: 12345678 ", 100 "12345678", 101 }, 102 []string{ 103 "trailing text after our value", 104 "this is a commit with TransportRequestId\n\nThis is the first line of the message body\nTransportRequest: 12345678 aaa", 105 }, 106 []string{ 107 "leading whitespace before our label", 108 "this is a commit with TransportRequestId\n\nThis is the first line of the message body\n TransportRequest: 12345678", 109 "12345678", 110 }, 111 []string{ 112 "leading text before our label", 113 "this is a commit with TransportRequestId\n\nThis is the first line of the message body\naaa TransportRequest: 12345678", 114 }, 115 []string{ 116 "whitespaces before column", 117 "this is a commit with TransportRequestId\n\nThis is the first line of the message body\nTransportRequest : 12345678", 118 "12345678", 119 }, 120 []string{ 121 "no whitespaces after column", 122 "this is a commit with TransportRequestId\n\nThis is the first line of the message body\nTransportRequest :12345678", 123 "12345678", 124 }, 125 []string{ 126 "two times the same id in the same commit", 127 "this is a commit with TransportRequestId\n\nThis is the first line of the message body\nTransportRequest : 12345678\nTransportRequest : 12345678", 128 "12345678", 129 }, 130 []string{ 131 // we report the ids, this is basically an invalid state, but needs to be filtered out by the caller 132 "two different ids in the same commit", 133 "this is a commit with TransportRequestId\n\nThis is the first line of the message body\nTransportRequest : 12345678\nTransportRequest : 87654321", 134 "12345678", "87654321", 135 }, 136 } 137 138 for _, testConfig := range tests { 139 runTest(testConfig) 140 } 141 }) 142 143 t.Run("multi commit tests", func(t *testing.T) { 144 145 t.Run("two different ids in different commits", func(t *testing.T) { 146 commitIter := &commitIteratorMock{ 147 commits: []object.Commit{ 148 object.Commit{ 149 Hash: plumbing.NewHash("3434343434343434343434343434343434343434"), 150 Message: "this is a commit with TransportRequestId\n\nThis is the first line of the message body\nTransportRequest: 12345678", 151 }, 152 object.Commit{ 153 Hash: plumbing.NewHash("1212121212121212121212121212121212121212"), 154 Message: "this is a commit with TransportRequestId\n\nThis is the first line of the message body\nTransportRequest: 87654321", 155 }, 156 }, 157 } 158 labels, err := FindLabelsInCommits(commitIter, "TransportRequest") 159 if assert.NoError(t, err) { 160 assert.Equal(t, []string{"12345678", "87654321"}, labels) 161 } 162 }) 163 164 t.Run("two different ids in different commits agains, order needs to be the same", func(t *testing.T) { 165 commitIter := &commitIteratorMock{ 166 commits: []object.Commit{ 167 object.Commit{ 168 Hash: plumbing.NewHash("1212121212121212121212121212121212121212"), 169 Message: "this is a commit with TransportRequestId\n\nThis is the first line of the message body\nTransportRequest: 87654321", 170 }, 171 object.Commit{ 172 Hash: plumbing.NewHash("3434343434343434343434343434343434343434"), 173 Message: "this is a commit with TransportRequestId\n\nThis is the first line of the message body\nTransportRequest: 12345678", 174 }, 175 }, 176 } 177 labels, err := FindLabelsInCommits(commitIter, "TransportRequest") 178 if assert.NoError(t, err) { 179 assert.Equal(t, []string{"12345678", "87654321"}, labels) 180 } 181 }) 182 183 t.Run("the same id in different commits", func(t *testing.T) { 184 commitIter := &commitIteratorMock{ 185 commits: []object.Commit{ 186 object.Commit{ 187 Hash: plumbing.NewHash("3434343434343434343434343434343434343434"), 188 Message: "this is a commit with TransportRequestId\n\nThis is the first line of the message body\nTransportRequest: 12345678", 189 }, 190 object.Commit{ 191 Hash: plumbing.NewHash("1212121212121212121212121212121212121212"), 192 Message: "this is a commit with TransportRequestId\n\nThis is the first line of the message body\nTransportRequest: 12345678", 193 }, 194 }, 195 } 196 labels, err := FindLabelsInCommits(commitIter, "TransportRequest") 197 if assert.NoError(t, err) { 198 expected := []string{"12345678"} 199 if assert.Len(t, labels, len(expected)) { 200 assert.Subset(t, expected, labels) 201 } 202 } 203 }) 204 t.Run("default label with default reg ex", func(t *testing.T) { 205 commitIter := &commitIteratorMock{ 206 commits: []object.Commit{ 207 object.Commit{ 208 Hash: plumbing.NewHash("3434343434343434343434343434343434343434"), 209 Message: "TransportRequest: 12345678", 210 }, 211 }, 212 } 213 labels, err := FindLabelsInCommits(commitIter, "TransportRequest\\s?:") 214 if assert.NoError(t, err) { 215 assert.Equal(t, "12345678", labels[0]) 216 } 217 }) 218 }) 219 } 220 221 func TestFinishLabel(t *testing.T) { 222 t.Parallel() 223 t.Run("default label old", func(t *testing.T) { 224 assert.Equal(t, `(?m)^\s*TransportRequest\s?:\s*(\S*)\s*$`, finishLabel("TransportRequest\\s?:")) 225 }) 226 t.Run("default label new", func(t *testing.T) { 227 assert.Equal(t, `(?m)^\s*TransportRequest\s*:\s*(\S*)\s*$`, finishLabel("TransportRequest")) 228 }) 229 230 } 231 232 func TestFindIDInRange(t *testing.T) { 233 234 // For these functions we have already tests. In order to avoid re-testing 235 // we set mocks for these functions. 236 logRange = func(repo *git.Repository, from, to string) (object.CommitIter, error) { 237 return &commitIteratorMock{}, nil 238 } 239 240 defer func() { 241 logRange = pipergit.LogRange 242 findLabelsInCommits = FindLabelsInCommits 243 }() 244 245 t.Run("range is forwarded correctly", func(t *testing.T) { 246 247 var receivedFrom, receivedTo string 248 249 oldLogRangeFunc := logRange 250 logRange = func(repo *git.Repository, from, to string) (object.CommitIter, error) { 251 receivedFrom = from 252 receivedTo = to 253 return &commitIteratorMock{}, nil 254 } 255 defer func() { 256 logRange = oldLogRangeFunc 257 }() 258 259 findIDInRange("TransportRequest", "master", "HEAD", &TrGitUtilsMock{}) 260 261 assert.Equal(t, "master", receivedFrom) 262 assert.Equal(t, "HEAD", receivedTo) 263 }) 264 265 t.Run("no label is found", func(t *testing.T) { 266 267 findLabelsInCommits = func(commits object.CommitIter, label string) ([]string, error) { 268 return []string{}, nil 269 } 270 271 defer func() { 272 findLabelsInCommits = FindLabelsInCommits 273 }() 274 275 _, err := findIDInRange("TransportRequest", "master", "HEAD", &TrGitUtilsMock{}) 276 277 assert.EqualError(t, err, "No values found for 'TransportRequest' in range 'master..HEAD'") 278 }) 279 280 t.Run("one label is found", func(t *testing.T) { 281 282 findLabelsInCommits = func(commits object.CommitIter, label string) ([]string, error) { 283 return []string{"123456789"}, nil 284 } 285 286 defer func() { 287 findLabelsInCommits = FindLabelsInCommits 288 }() 289 290 label, err := findIDInRange("TransportRequest", "master", "HEAD", &TrGitUtilsMock{}) 291 if assert.NoError(t, err) { 292 assert.Equal(t, "123456789", label) 293 } 294 }) 295 296 t.Run("more than one label is found", func(t *testing.T) { 297 298 findLabelsInCommits = func(commits object.CommitIter, label string) ([]string, error) { 299 return []string{"123456789", "987654321"}, nil 300 } 301 302 defer func() { 303 findLabelsInCommits = FindLabelsInCommits 304 }() 305 306 _, err := findIDInRange("TransportRequest", "master", "HEAD", &TrGitUtilsMock{}) 307 if assert.Error(t, err) { 308 // don't want to rely on the order 309 assert.Contains(t, err.Error(), "More than one values found for label 'TransportRequest' in range 'master..HEAD'") 310 assert.Contains(t, err.Error(), "123456789") 311 assert.Contains(t, err.Error(), "987654321") 312 } 313 }) 314 315 }