github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/swarm/api/manifest_test.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package api 13 14 import ( 15 "bytes" 16 "encoding/json" 17 "fmt" 18 "io" 19 "net/http" 20 "strings" 21 "testing" 22 23 "github.com/Sberex/go-sberex/swarm/storage" 24 ) 25 26 func manifest(paths ...string) (manifestReader storage.LazySectionReader) { 27 var entries []string 28 for _, path := range paths { 29 entry := fmt.Sprintf(`{"path":"%s"}`, path) 30 entries = append(entries, entry) 31 } 32 manifest := fmt.Sprintf(`{"entries":[%s]}`, strings.Join(entries, ",")) 33 return &storage.LazyTestSectionReader{ 34 SectionReader: io.NewSectionReader(strings.NewReader(manifest), 0, int64(len(manifest))), 35 } 36 } 37 38 func testGetEntry(t *testing.T, path, match string, multiple bool, paths ...string) *manifestTrie { 39 quitC := make(chan bool) 40 trie, err := readManifest(manifest(paths...), nil, nil, quitC) 41 if err != nil { 42 t.Errorf("unexpected error making manifest: %v", err) 43 } 44 checkEntry(t, path, match, multiple, trie) 45 return trie 46 } 47 48 func checkEntry(t *testing.T, path, match string, multiple bool, trie *manifestTrie) { 49 entry, fullpath := trie.getEntry(path) 50 if match == "-" && entry != nil { 51 t.Errorf("expected no match for '%s', got '%s'", path, fullpath) 52 } else if entry == nil { 53 if match != "-" { 54 t.Errorf("expected entry '%s' to match '%s', got no match", match, path) 55 } 56 } else if fullpath != match { 57 t.Errorf("incorrect entry retrieved for '%s'. expected path '%v', got '%s'", path, match, fullpath) 58 } 59 60 if multiple && entry.Status != http.StatusMultipleChoices { 61 t.Errorf("Expected %d Multiple Choices Status for path %s, match %s, got %d", http.StatusMultipleChoices, path, match, entry.Status) 62 } else if !multiple && entry != nil && entry.Status == http.StatusMultipleChoices { 63 t.Errorf("Were not expecting %d Multiple Choices Status for path %s, match %s, but got it", http.StatusMultipleChoices, path, match) 64 } 65 } 66 67 func TestGetEntry(t *testing.T) { 68 // file system manifest always contains regularized paths 69 testGetEntry(t, "a", "a", false, "a") 70 testGetEntry(t, "b", "-", false, "a") 71 testGetEntry(t, "/a//", "a", false, "a") 72 // fallback 73 testGetEntry(t, "/a", "", false, "") 74 testGetEntry(t, "/a/b", "a/b", false, "a/b") 75 // longest/deepest math 76 testGetEntry(t, "read", "read", true, "readme.md", "readit.md") 77 testGetEntry(t, "rf", "-", false, "readme.md", "readit.md") 78 testGetEntry(t, "readme", "readme", false, "readme.md") 79 testGetEntry(t, "readme", "-", false, "readit.md") 80 testGetEntry(t, "readme.md", "readme.md", false, "readme.md") 81 testGetEntry(t, "readme.md", "-", false, "readit.md") 82 testGetEntry(t, "readmeAmd", "-", false, "readit.md") 83 testGetEntry(t, "readme.mdffff", "-", false, "readme.md") 84 testGetEntry(t, "ab", "ab", true, "ab/cefg", "ab/cedh", "ab/kkkkkk") 85 testGetEntry(t, "ab/ce", "ab/ce", true, "ab/cefg", "ab/cedh", "ab/ceuuuuuuuuuu") 86 testGetEntry(t, "abc", "abc", true, "abcd", "abczzzzef", "abc/def", "abc/e/g") 87 testGetEntry(t, "a/b", "a/b", true, "a", "a/bc", "a/ba", "a/b/c") 88 testGetEntry(t, "a/b", "a/b", false, "a", "a/b", "a/bb", "a/b/c") 89 testGetEntry(t, "//a//b//", "a/b", false, "a", "a/b", "a/bb", "a/b/c") 90 } 91 92 func TestExactMatch(t *testing.T) { 93 quitC := make(chan bool) 94 mf := manifest("shouldBeExactMatch.css", "shouldBeExactMatch.css.map") 95 trie, err := readManifest(mf, nil, nil, quitC) 96 if err != nil { 97 t.Errorf("unexpected error making manifest: %v", err) 98 } 99 entry, _ := trie.getEntry("shouldBeExactMatch.css") 100 if entry.Path != "" { 101 t.Errorf("Expected entry to match %s, got: %s", "shouldBeExactMatch.css", entry.Path) 102 } 103 if entry.Status == http.StatusMultipleChoices { 104 t.Errorf("Got status %d, which is unexepcted", http.StatusMultipleChoices) 105 } 106 } 107 108 func TestDeleteEntry(t *testing.T) { 109 110 } 111 112 // TestAddFileWithManifestPath tests that adding an entry at a path which 113 // already exists as a manifest just adds the entry to the manifest rather 114 // than replacing the manifest with the entry 115 func TestAddFileWithManifestPath(t *testing.T) { 116 // create a manifest containing "ab" and "ac" 117 manifest, _ := json.Marshal(&Manifest{ 118 Entries: []ManifestEntry{ 119 {Path: "ab", Hash: "ab"}, 120 {Path: "ac", Hash: "ac"}, 121 }, 122 }) 123 reader := &storage.LazyTestSectionReader{ 124 SectionReader: io.NewSectionReader(bytes.NewReader(manifest), 0, int64(len(manifest))), 125 } 126 trie, err := readManifest(reader, nil, nil, nil) 127 if err != nil { 128 t.Fatal(err) 129 } 130 checkEntry(t, "ab", "ab", false, trie) 131 checkEntry(t, "ac", "ac", false, trie) 132 133 // now add path "a" and check we can still get "ab" and "ac" 134 entry := &manifestTrieEntry{} 135 entry.Path = "a" 136 entry.Hash = "a" 137 trie.addEntry(entry, nil) 138 checkEntry(t, "ab", "ab", false, trie) 139 checkEntry(t, "ac", "ac", false, trie) 140 checkEntry(t, "a", "a", false, trie) 141 }