github.com/braveheart12/insolar-09-08-19@v0.8.7/ledger/storage/jet/tree_test.go (about) 1 /* 2 * Copyright 2019 Insolar Technologies 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 jet 18 19 import ( 20 "strings" 21 "testing" 22 23 "github.com/insolar/insolar/core" 24 "github.com/stretchr/testify/assert" 25 "github.com/stretchr/testify/require" 26 ) 27 28 func TestTree_Find(t *testing.T) { 29 tree := Tree{ 30 Head: &jet{ 31 Right: &jet{ 32 Right: &jet{ 33 Left: &jet{ 34 Right: &jet{}, 35 Left: &jet{}, 36 }, 37 Right: &jet{}, 38 }, 39 }, 40 Left: &jet{}, 41 }, 42 } 43 lookup := core.NewRecordID(0, []byte{0xD5}) // 11010101 44 jetLookup := NewID(15, []byte{1, 2, 3}) 45 expectedPrefix := make([]byte, core.RecordIDSize-core.PulseNumberSize-1) 46 expectedPrefix[0] = 0xD0 // 11010000 47 48 id, actual := tree.Find(*lookup) 49 depth, prefix := Jet(*id) 50 assert.Equal(t, depth, uint8(4)) 51 assert.Equal(t, expectedPrefix, prefix) 52 assert.False(t, actual) 53 54 jetID, actual := tree.Find(*jetLookup) 55 assert.Equal(t, jetLookup, jetID) 56 assert.True(t, actual) 57 } 58 59 func TestTree_Update(t *testing.T) { 60 tree := Tree{Head: &jet{}} 61 62 lookup := core.NewRecordID(0, []byte{0xD5}) // 11010101 63 64 id, actual := tree.Find(*lookup) 65 depth, prefix := Jet(*id) 66 assert.Equal(t, depth, uint8(0)) 67 assert.Equal(t, prefix, make([]byte, core.RecordHashSize-1)) 68 assert.Equal(t, false, actual) 69 70 tree.Update(*NewID(1, []byte{1 << 7}), false) 71 id, actual = tree.Find(*lookup) 72 depth, prefix = Jet(*id) 73 expectedPrefix := make([]byte, core.RecordHashSize-1) 74 expectedPrefix[0] = 0x80 75 require.Equal(t, uint8(1), depth) 76 assert.Equal(t, expectedPrefix, prefix) 77 assert.Equal(t, false, actual) 78 79 tree.Update(*NewID(8, lookup.Hash()), false) 80 id, actual = tree.Find(*lookup) 81 depth, prefix = Jet(*id) 82 assert.Equal(t, uint8(8), depth) 83 assert.Equal(t, lookup.Hash()[:core.RecordHashSize-1], prefix) 84 assert.Equal(t, false, actual) 85 86 tree.Update(*NewID(8, lookup.Hash()), true) 87 id, actual = tree.Find(*lookup) 88 depth, prefix = Jet(*id) 89 assert.Equal(t, uint8(8), depth) 90 assert.Equal(t, lookup.Hash()[:core.RecordHashSize-1], prefix) 91 assert.Equal(t, true, actual) 92 } 93 94 func TestTree_Split(t *testing.T) { 95 tree := Tree{ 96 Head: &jet{ 97 Right: &jet{ 98 Right: &jet{}, 99 }, 100 Left: &jet{}, 101 }, 102 } 103 tooDeep := NewID(6, []byte{0xD5}) // 11010101 104 ok := NewID(2, []byte{0xD5}) // 11010101 105 106 t.Run("not existing jet returns error", func(t *testing.T) { 107 _, _, err := tree.Split(*tooDeep) 108 assert.Error(t, err) 109 }) 110 111 t.Run("splits jet", func(t *testing.T) { 112 okDepth, okPrefix := Jet(*ok) 113 lExpectedPrefix := make([]byte, len(okPrefix)) 114 copy(lExpectedPrefix, okPrefix) 115 lExpectedPrefix[0] = 0xC0 // 11000000 116 rExpectedPrefix := make([]byte, len(okPrefix)) 117 copy(rExpectedPrefix, okPrefix) 118 rExpectedPrefix[0] = 0xE0 // 11100000 119 120 left, right, err := tree.Split(*ok) 121 require.NoError(t, err) 122 lDepth, lPrefix := Jet(*left) 123 rDepth, rPrefix := Jet(*right) 124 assert.Equal(t, uint8(okDepth+1), lDepth) 125 assert.Equal(t, uint8(okDepth+1), rDepth) 126 assert.Equal(t, lExpectedPrefix, lPrefix) 127 assert.Equal(t, rExpectedPrefix, rPrefix) 128 }) 129 } 130 131 func TestTree_String(t *testing.T) { 132 tree := Tree{ 133 Head: &jet{ 134 Left: &jet{ 135 Actual: true, 136 Right: &jet{ 137 Actual: true, 138 Left: &jet{Actual: true}, 139 Right: &jet{}, 140 }, 141 }, 142 Right: &jet{ 143 Left: &jet{}, 144 Right: &jet{}, 145 }, 146 }, 147 } 148 treeOut := strings.Join([]string{ 149 "root (level=0 actual=false)", 150 " 0 (level=1 actual=true)", 151 " 01 (level=2 actual=true)", 152 " 010 (level=3 actual=true)", 153 " 011 (level=3 actual=false)", 154 " 1 (level=1 actual=false)", 155 " 10 (level=2 actual=false)", 156 " 11 (level=2 actual=false)", 157 }, "\n") + "\n" 158 assert.Equal(t, treeOut, tree.String()) 159 160 emptyTree := Tree{ 161 Head: &jet{}, 162 } 163 assert.Equal(t, "root (level=0 actual=false)\n", emptyTree.String()) 164 } 165 166 func TestTree_Merge(t *testing.T) { 167 t.Run("One level", func(t *testing.T) { 168 savedTree := Tree{ 169 Head: &jet{ 170 Left: &jet{ 171 Actual: true, 172 }, 173 Right: &jet{ 174 Actual: false, 175 }, 176 Actual: true, 177 }, 178 } 179 180 newTree := Tree{ 181 Head: &jet{ 182 Left: &jet{ 183 Actual: false, 184 }, 185 Right: &jet{ 186 Actual: true, 187 }, 188 Actual: false, 189 }, 190 } 191 192 result := savedTree.Merge(&newTree) 193 194 require.Equal(t, 195 Tree{ 196 Head: &jet{ 197 Left: &jet{ 198 Actual: true, 199 }, 200 Right: &jet{ 201 Actual: true, 202 }, 203 Actual: true, 204 }, 205 }.String(), 206 result.String()) 207 }) 208 209 t.Run("Five levels saved is false active is true", func(t *testing.T) { 210 savedTree := Tree{ 211 Head: &jet{ 212 Left: &jet{ 213 Actual: false, 214 Left: &jet{ 215 Actual: false, 216 }, 217 Right: &jet{ 218 Actual: false, 219 }, 220 }, 221 Right: &jet{ 222 Actual: false, 223 Left: &jet{ 224 Actual: false, 225 Left: &jet{ 226 Actual: false, 227 }, 228 Right: &jet{ 229 Actual: false, 230 Left: &jet{ 231 Actual: false, 232 }, 233 Right: &jet{ 234 Actual: false, 235 }, 236 }, 237 }, 238 Right: &jet{ 239 Actual: false, 240 }, 241 }, 242 Actual: false, 243 }, 244 } 245 246 newTree := Tree{ 247 Head: &jet{ 248 Left: &jet{ 249 Actual: true, 250 Left: &jet{ 251 Actual: true, 252 }, 253 Right: &jet{ 254 Actual: true, 255 }, 256 }, 257 Right: &jet{ 258 Actual: true, 259 Left: &jet{ 260 Actual: true, 261 Left: &jet{ 262 Actual: true, 263 }, 264 Right: &jet{ 265 Actual: true, 266 Left: &jet{ 267 Actual: true, 268 }, 269 Right: &jet{ 270 Actual: true, 271 }, 272 }, 273 }, 274 Right: &jet{ 275 Actual: true, 276 }, 277 }, 278 Actual: true, 279 }, 280 } 281 282 result := savedTree.Merge(&newTree) 283 284 require.Equal(t, newTree.String(), result.String()) 285 }) 286 287 t.Run("Two levels saved is empty", func(t *testing.T) { 288 savedTree := Tree{ 289 Head: &jet{ 290 Actual: false, 291 }, 292 } 293 294 newTree := Tree{ 295 Head: &jet{ 296 Left: &jet{ 297 Actual: true, 298 Left: &jet{ 299 Actual: true, 300 }, 301 Right: &jet{ 302 Actual: true, 303 }, 304 }, 305 Right: &jet{ 306 Actual: true, 307 Left: &jet{ 308 Actual: true, 309 Left: &jet{ 310 Actual: true, 311 }, 312 Right: &jet{ 313 Actual: true, 314 Left: &jet{ 315 Actual: true, 316 }, 317 Right: &jet{ 318 Actual: true, 319 }, 320 }, 321 }, 322 Right: &jet{ 323 Actual: true, 324 }, 325 }, 326 Actual: true, 327 }, 328 } 329 330 result := savedTree.Merge(&newTree) 331 332 require.Equal(t, newTree.String(), result.String()) 333 }) 334 335 t.Run("Three levels saved with left and new with right", func(t *testing.T) { 336 savedTree := Tree{ 337 Head: &jet{ 338 Actual: true, 339 Left: &jet{ 340 Actual: true, 341 Left: &jet{ 342 Actual: true, 343 Left: &jet{ 344 Actual: true, 345 }, 346 }, 347 Right: &jet{ 348 Actual: false, 349 }, 350 }, 351 }, 352 } 353 354 newTree := Tree{ 355 Head: &jet{ 356 Right: &jet{ 357 Right: &jet{ 358 Actual: true, 359 Right: &jet{ 360 Actual: true, 361 Right: &jet{ 362 Actual: false, 363 }, 364 }, 365 }, 366 }, 367 Actual: true, 368 }, 369 } 370 371 expectedTree := Tree{ 372 Head: &jet{ 373 Left: &jet{ 374 Actual: true, 375 Left: &jet{ 376 Actual: true, 377 Left: &jet{ 378 Actual: true, 379 }, 380 }, 381 Right: &jet{ 382 Actual: false, 383 }, 384 }, 385 386 Actual: true, 387 388 Right: &jet{ 389 Right: &jet{ 390 Actual: true, 391 Right: &jet{ 392 Actual: true, 393 Right: &jet{ 394 Actual: false, 395 }, 396 }, 397 }, 398 }, 399 }, 400 } 401 402 result := savedTree.Merge(&newTree) 403 404 require.Equal(t, expectedTree.String(), result.String()) 405 }) 406 407 t.Run("heads saved false new true", func(t *testing.T) { 408 savedTree := Tree{ 409 Head: &jet{ 410 Actual: false, 411 }, 412 } 413 414 newTree := Tree{ 415 Head: &jet{ 416 Actual: true, 417 }, 418 } 419 420 result := savedTree.Merge(&newTree) 421 422 require.Equal(t, newTree.String(), result.String()) 423 }) 424 425 t.Run("heads saved false new true", func(t *testing.T) { 426 savedTree := Tree{ 427 Head: &jet{ 428 Actual: true, 429 }, 430 } 431 432 newTree := Tree{ 433 Head: &jet{ 434 Actual: false, 435 }, 436 } 437 438 result := savedTree.Merge(&newTree) 439 440 require.Equal(t, savedTree.String(), result.String()) 441 }) 442 } 443 444 func TestTree_LeafIDs(t *testing.T) { 445 tree := Tree{ 446 Head: &jet{ 447 Right: &jet{ 448 Right: &jet{ 449 Left: &jet{ 450 Right: &jet{}, 451 Left: &jet{}, 452 }, 453 Right: &jet{}, 454 }, 455 }, 456 Left: &jet{}, 457 }, 458 } 459 460 leafIDs := tree.LeafIDs() 461 462 require.Equal(t, len(leafIDs), 4) 463 assert.Equal(t, leafIDs[0], *NewID(1, nil)) // 0000 464 assert.Equal(t, leafIDs[1], *NewID(4, []byte{0xC0})) // 1100 465 assert.Equal(t, leafIDs[2], *NewID(4, []byte{0xD0})) // 1101 466 assert.Equal(t, leafIDs[3], *NewID(3, []byte{0xE0})) // 1110 467 }