github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/swarm/api/api_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 "errors" 16 "fmt" 17 "io" 18 "io/ioutil" 19 "os" 20 "testing" 21 22 "github.com/Sberex/go-sberex/common" 23 "github.com/Sberex/go-sberex/log" 24 "github.com/Sberex/go-sberex/swarm/storage" 25 ) 26 27 func testApi(t *testing.T, f func(*Api)) { 28 datadir, err := ioutil.TempDir("", "bzz-test") 29 if err != nil { 30 t.Fatalf("unable to create temp dir: %v", err) 31 } 32 os.RemoveAll(datadir) 33 defer os.RemoveAll(datadir) 34 dpa, err := storage.NewLocalDPA(datadir) 35 if err != nil { 36 return 37 } 38 api := NewApi(dpa, nil) 39 dpa.Start() 40 f(api) 41 dpa.Stop() 42 } 43 44 type testResponse struct { 45 reader storage.LazySectionReader 46 *Response 47 } 48 49 func checkResponse(t *testing.T, resp *testResponse, exp *Response) { 50 51 if resp.MimeType != exp.MimeType { 52 t.Errorf("incorrect mimeType. expected '%s', got '%s'", exp.MimeType, resp.MimeType) 53 } 54 if resp.Status != exp.Status { 55 t.Errorf("incorrect status. expected '%d', got '%d'", exp.Status, resp.Status) 56 } 57 if resp.Size != exp.Size { 58 t.Errorf("incorrect size. expected '%d', got '%d'", exp.Size, resp.Size) 59 } 60 if resp.reader != nil { 61 content := make([]byte, resp.Size) 62 read, _ := resp.reader.Read(content) 63 if int64(read) != exp.Size { 64 t.Errorf("incorrect content length. expected '%d...', got '%d...'", read, exp.Size) 65 } 66 resp.Content = string(content) 67 } 68 if resp.Content != exp.Content { 69 // if !bytes.Equal(resp.Content, exp.Content) 70 t.Errorf("incorrect content. expected '%s...', got '%s...'", string(exp.Content), string(resp.Content)) 71 } 72 } 73 74 // func expResponse(content []byte, mimeType string, status int) *Response { 75 func expResponse(content string, mimeType string, status int) *Response { 76 log.Trace(fmt.Sprintf("expected content (%v): %v ", len(content), content)) 77 return &Response{mimeType, status, int64(len(content)), content} 78 } 79 80 // func testGet(t *testing.T, api *Api, bzzhash string) *testResponse { 81 func testGet(t *testing.T, api *Api, bzzhash, path string) *testResponse { 82 key := storage.Key(common.Hex2Bytes(bzzhash)) 83 reader, mimeType, status, err := api.Get(key, path) 84 if err != nil { 85 t.Fatalf("unexpected error: %v", err) 86 } 87 quitC := make(chan bool) 88 size, err := reader.Size(quitC) 89 if err != nil { 90 t.Fatalf("unexpected error: %v", err) 91 } 92 log.Trace(fmt.Sprintf("reader size: %v ", size)) 93 s := make([]byte, size) 94 _, err = reader.Read(s) 95 if err != io.EOF { 96 t.Fatalf("unexpected error: %v", err) 97 } 98 reader.Seek(0, 0) 99 return &testResponse{reader, &Response{mimeType, status, size, string(s)}} 100 // return &testResponse{reader, &Response{mimeType, status, reader.Size(), nil}} 101 } 102 103 func TestApiPut(t *testing.T) { 104 testApi(t, func(api *Api) { 105 content := "hello" 106 exp := expResponse(content, "text/plain", 0) 107 // exp := expResponse([]byte(content), "text/plain", 0) 108 key, err := api.Put(content, exp.MimeType) 109 if err != nil { 110 t.Fatalf("unexpected error: %v", err) 111 } 112 resp := testGet(t, api, key.String(), "") 113 checkResponse(t, resp, exp) 114 }) 115 } 116 117 // testResolver implements the Resolver interface and either returns the given 118 // hash if it is set, or returns a "name not found" error 119 type testResolver struct { 120 hash *common.Hash 121 } 122 123 func newTestResolver(addr string) *testResolver { 124 r := &testResolver{} 125 if addr != "" { 126 hash := common.HexToHash(addr) 127 r.hash = &hash 128 } 129 return r 130 } 131 132 func (t *testResolver) Resolve(addr string) (common.Hash, error) { 133 if t.hash == nil { 134 return common.Hash{}, fmt.Errorf("DNS name not found: %q", addr) 135 } 136 return *t.hash, nil 137 } 138 139 // TestAPIResolve tests resolving URIs which can either contain content hashes 140 // or ENS names 141 func TestAPIResolve(t *testing.T) { 142 ensAddr := "swarm.eth" 143 hashAddr := "1111111111111111111111111111111111111111111111111111111111111111" 144 resolvedAddr := "2222222222222222222222222222222222222222222222222222222222222222" 145 doesResolve := newTestResolver(resolvedAddr) 146 doesntResolve := newTestResolver("") 147 148 type test struct { 149 desc string 150 dns Resolver 151 addr string 152 immutable bool 153 result string 154 expectErr error 155 } 156 157 tests := []*test{ 158 { 159 desc: "DNS not configured, hash address, returns hash address", 160 dns: nil, 161 addr: hashAddr, 162 result: hashAddr, 163 }, 164 { 165 desc: "DNS not configured, ENS address, returns error", 166 dns: nil, 167 addr: ensAddr, 168 expectErr: errors.New(`no DNS to resolve name: "swarm.eth"`), 169 }, 170 { 171 desc: "DNS configured, hash address, hash resolves, returns resolved address", 172 dns: doesResolve, 173 addr: hashAddr, 174 result: resolvedAddr, 175 }, 176 { 177 desc: "DNS configured, immutable hash address, hash resolves, returns hash address", 178 dns: doesResolve, 179 addr: hashAddr, 180 immutable: true, 181 result: hashAddr, 182 }, 183 { 184 desc: "DNS configured, hash address, hash doesn't resolve, returns hash address", 185 dns: doesntResolve, 186 addr: hashAddr, 187 result: hashAddr, 188 }, 189 { 190 desc: "DNS configured, ENS address, name resolves, returns resolved address", 191 dns: doesResolve, 192 addr: ensAddr, 193 result: resolvedAddr, 194 }, 195 { 196 desc: "DNS configured, immutable ENS address, name resolves, returns error", 197 dns: doesResolve, 198 addr: ensAddr, 199 immutable: true, 200 expectErr: errors.New(`immutable address not a content hash: "swarm.eth"`), 201 }, 202 { 203 desc: "DNS configured, ENS address, name doesn't resolve, returns error", 204 dns: doesntResolve, 205 addr: ensAddr, 206 expectErr: errors.New(`DNS name not found: "swarm.eth"`), 207 }, 208 } 209 for _, x := range tests { 210 t.Run(x.desc, func(t *testing.T) { 211 api := &Api{dns: x.dns} 212 uri := &URI{Addr: x.addr, Scheme: "bzz"} 213 if x.immutable { 214 uri.Scheme = "bzz-immutable" 215 } 216 res, err := api.Resolve(uri) 217 if err == nil { 218 if x.expectErr != nil { 219 t.Fatalf("expected error %q, got result %q", x.expectErr, res) 220 } 221 if res.String() != x.result { 222 t.Fatalf("expected result %q, got %q", x.result, res) 223 } 224 } else { 225 if x.expectErr == nil { 226 t.Fatalf("expected no error, got %q", err) 227 } 228 if err.Error() != x.expectErr.Error() { 229 t.Fatalf("expected error %q, got %q", x.expectErr, err) 230 } 231 } 232 }) 233 } 234 } 235 236 func TestMultiResolver(t *testing.T) { 237 doesntResolve := newTestResolver("") 238 239 ethAddr := "swarm.eth" 240 ethHash := "0x2222222222222222222222222222222222222222222222222222222222222222" 241 ethResolve := newTestResolver(ethHash) 242 243 testAddr := "swarm.test" 244 testHash := "0x1111111111111111111111111111111111111111111111111111111111111111" 245 testResolve := newTestResolver(testHash) 246 247 tests := []struct { 248 desc string 249 r Resolver 250 addr string 251 result string 252 err error 253 }{ 254 { 255 desc: "No resolvers, returns error", 256 r: NewMultiResolver(), 257 err: NewNoResolverError(""), 258 }, 259 { 260 desc: "One default resolver, returns resolved address", 261 r: NewMultiResolver(MultiResolverOptionWithResolver(ethResolve, "")), 262 addr: ethAddr, 263 result: ethHash, 264 }, 265 { 266 desc: "Two default resolvers, returns resolved address", 267 r: NewMultiResolver( 268 MultiResolverOptionWithResolver(ethResolve, ""), 269 MultiResolverOptionWithResolver(ethResolve, ""), 270 ), 271 addr: ethAddr, 272 result: ethHash, 273 }, 274 { 275 desc: "Two default resolvers, first doesn't resolve, returns resolved address", 276 r: NewMultiResolver( 277 MultiResolverOptionWithResolver(doesntResolve, ""), 278 MultiResolverOptionWithResolver(ethResolve, ""), 279 ), 280 addr: ethAddr, 281 result: ethHash, 282 }, 283 { 284 desc: "Default resolver doesn't resolve, tld resolver resolve, returns resolved address", 285 r: NewMultiResolver( 286 MultiResolverOptionWithResolver(doesntResolve, ""), 287 MultiResolverOptionWithResolver(ethResolve, "eth"), 288 ), 289 addr: ethAddr, 290 result: ethHash, 291 }, 292 { 293 desc: "Three TLD resolvers, third resolves, returns resolved address", 294 r: NewMultiResolver( 295 MultiResolverOptionWithResolver(doesntResolve, "eth"), 296 MultiResolverOptionWithResolver(doesntResolve, "eth"), 297 MultiResolverOptionWithResolver(ethResolve, "eth"), 298 ), 299 addr: ethAddr, 300 result: ethHash, 301 }, 302 { 303 desc: "One TLD resolver doesn't resolve, returns error", 304 r: NewMultiResolver( 305 MultiResolverOptionWithResolver(doesntResolve, ""), 306 MultiResolverOptionWithResolver(ethResolve, "eth"), 307 ), 308 addr: ethAddr, 309 result: ethHash, 310 }, 311 { 312 desc: "One defautl and one TLD resolver, all doesn't resolve, returns error", 313 r: NewMultiResolver( 314 MultiResolverOptionWithResolver(doesntResolve, ""), 315 MultiResolverOptionWithResolver(doesntResolve, "eth"), 316 ), 317 addr: ethAddr, 318 result: ethHash, 319 err: errors.New(`DNS name not found: "swarm.eth"`), 320 }, 321 { 322 desc: "Two TLD resolvers, both resolve, returns resolved address", 323 r: NewMultiResolver( 324 MultiResolverOptionWithResolver(ethResolve, "eth"), 325 MultiResolverOptionWithResolver(testResolve, "test"), 326 ), 327 addr: testAddr, 328 result: testHash, 329 }, 330 { 331 desc: "One TLD resolver, no default resolver, returns error for different TLD", 332 r: NewMultiResolver( 333 MultiResolverOptionWithResolver(ethResolve, "eth"), 334 ), 335 addr: testAddr, 336 err: NewNoResolverError("test"), 337 }, 338 } 339 for _, x := range tests { 340 t.Run(x.desc, func(t *testing.T) { 341 res, err := x.r.Resolve(x.addr) 342 if err == nil { 343 if x.err != nil { 344 t.Fatalf("expected error %q, got result %q", x.err, res.Hex()) 345 } 346 if res.Hex() != x.result { 347 t.Fatalf("expected result %q, got %q", x.result, res.Hex()) 348 } 349 } else { 350 if x.err == nil { 351 t.Fatalf("expected no error, got %q", err) 352 } 353 if err.Error() != x.err.Error() { 354 t.Fatalf("expected error %q, got %q", x.err, err) 355 } 356 } 357 }) 358 } 359 }