github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/go-ethereum-master/swarm/api/api_test.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package api 18 19 import ( 20 "context" 21 "errors" 22 "fmt" 23 "io" 24 "io/ioutil" 25 "math/big" 26 "os" 27 "testing" 28 29 "github.com/ethereum/go-ethereum/common" 30 "github.com/ethereum/go-ethereum/core/types" 31 "github.com/ethereum/go-ethereum/swarm/log" 32 "github.com/ethereum/go-ethereum/swarm/storage" 33 ) 34 35 func testAPI(t *testing.T, f func(*API, bool)) { 36 datadir, err := ioutil.TempDir("", "bzz-test") 37 if err != nil { 38 t.Fatalf("unable to create temp dir: %v", err) 39 } 40 defer os.RemoveAll(datadir) 41 fileStore, err := storage.NewLocalFileStore(datadir, make([]byte, 32)) 42 if err != nil { 43 return 44 } 45 api := NewAPI(fileStore, nil, nil) 46 f(api, false) 47 f(api, true) 48 } 49 50 type testResponse struct { 51 reader storage.LazySectionReader 52 *Response 53 } 54 55 func checkResponse(t *testing.T, resp *testResponse, exp *Response) { 56 57 if resp.MimeType != exp.MimeType { 58 t.Errorf("incorrect mimeType. expected '%s', got '%s'", exp.MimeType, resp.MimeType) 59 } 60 if resp.Status != exp.Status { 61 t.Errorf("incorrect status. expected '%d', got '%d'", exp.Status, resp.Status) 62 } 63 if resp.Size != exp.Size { 64 t.Errorf("incorrect size. expected '%d', got '%d'", exp.Size, resp.Size) 65 } 66 if resp.reader != nil { 67 content := make([]byte, resp.Size) 68 read, _ := resp.reader.Read(content) 69 if int64(read) != exp.Size { 70 t.Errorf("incorrect content length. expected '%d...', got '%d...'", read, exp.Size) 71 } 72 resp.Content = string(content) 73 } 74 if resp.Content != exp.Content { 75 // if !bytes.Equal(resp.Content, exp.Content) 76 t.Errorf("incorrect content. expected '%s...', got '%s...'", string(exp.Content), string(resp.Content)) 77 } 78 } 79 80 // func expResponse(content []byte, mimeType string, status int) *Response { 81 func expResponse(content string, mimeType string, status int) *Response { 82 log.Trace(fmt.Sprintf("expected content (%v): %v ", len(content), content)) 83 return &Response{mimeType, status, int64(len(content)), content} 84 } 85 86 func testGet(t *testing.T, api *API, bzzhash, path string) *testResponse { 87 addr := storage.Address(common.Hex2Bytes(bzzhash)) 88 reader, mimeType, status, _, err := api.Get(context.TODO(), addr, path) 89 if err != nil { 90 t.Fatalf("unexpected error: %v", err) 91 } 92 quitC := make(chan bool) 93 size, err := reader.Size(quitC) 94 if err != nil { 95 t.Fatalf("unexpected error: %v", err) 96 } 97 log.Trace(fmt.Sprintf("reader size: %v ", size)) 98 s := make([]byte, size) 99 _, err = reader.Read(s) 100 if err != io.EOF { 101 t.Fatalf("unexpected error: %v", err) 102 } 103 reader.Seek(0, 0) 104 return &testResponse{reader, &Response{mimeType, status, size, string(s)}} 105 // return &testResponse{reader, &Response{mimeType, status, reader.Size(), nil}} 106 } 107 108 func TestApiPut(t *testing.T) { 109 testAPI(t, func(api *API, toEncrypt bool) { 110 content := "hello" 111 exp := expResponse(content, "text/plain", 0) 112 ctx := context.TODO() 113 addr, wait, err := api.Put(ctx, content, exp.MimeType, toEncrypt) 114 if err != nil { 115 t.Fatalf("unexpected error: %v", err) 116 } 117 err = wait(ctx) 118 if err != nil { 119 t.Fatalf("unexpected error: %v", err) 120 } 121 resp := testGet(t, api, addr.Hex(), "") 122 checkResponse(t, resp, exp) 123 }) 124 } 125 126 // testResolver implements the Resolver interface and either returns the given 127 // hash if it is set, or returns a "name not found" error 128 type testResolveValidator struct { 129 hash *common.Hash 130 } 131 132 func newTestResolveValidator(addr string) *testResolveValidator { 133 r := &testResolveValidator{} 134 if addr != "" { 135 hash := common.HexToHash(addr) 136 r.hash = &hash 137 } 138 return r 139 } 140 141 func (t *testResolveValidator) Resolve(addr string) (common.Hash, error) { 142 if t.hash == nil { 143 return common.Hash{}, fmt.Errorf("DNS name not found: %q", addr) 144 } 145 return *t.hash, nil 146 } 147 148 func (t *testResolveValidator) Owner(node [32]byte) (addr common.Address, err error) { 149 return 150 } 151 func (t *testResolveValidator) HeaderByNumber(context.Context, *big.Int) (header *types.Header, err error) { 152 return 153 } 154 155 // TestAPIResolve tests resolving URIs which can either contain content hashes 156 // or ENS names 157 func TestAPIResolve(t *testing.T) { 158 ensAddr := "swarm.eth" 159 hashAddr := "1111111111111111111111111111111111111111111111111111111111111111" 160 resolvedAddr := "2222222222222222222222222222222222222222222222222222222222222222" 161 doesResolve := newTestResolveValidator(resolvedAddr) 162 doesntResolve := newTestResolveValidator("") 163 164 type test struct { 165 desc string 166 dns Resolver 167 addr string 168 immutable bool 169 result string 170 expectErr error 171 } 172 173 tests := []*test{ 174 { 175 desc: "DNS not configured, hash address, returns hash address", 176 dns: nil, 177 addr: hashAddr, 178 result: hashAddr, 179 }, 180 { 181 desc: "DNS not configured, ENS address, returns error", 182 dns: nil, 183 addr: ensAddr, 184 expectErr: errors.New(`no DNS to resolve name: "swarm.eth"`), 185 }, 186 { 187 desc: "DNS configured, hash address, hash resolves, returns resolved address", 188 dns: doesResolve, 189 addr: hashAddr, 190 result: resolvedAddr, 191 }, 192 { 193 desc: "DNS configured, immutable hash address, hash resolves, returns hash address", 194 dns: doesResolve, 195 addr: hashAddr, 196 immutable: true, 197 result: hashAddr, 198 }, 199 { 200 desc: "DNS configured, hash address, hash doesn't resolve, returns hash address", 201 dns: doesntResolve, 202 addr: hashAddr, 203 result: hashAddr, 204 }, 205 { 206 desc: "DNS configured, ENS address, name resolves, returns resolved address", 207 dns: doesResolve, 208 addr: ensAddr, 209 result: resolvedAddr, 210 }, 211 { 212 desc: "DNS configured, immutable ENS address, name resolves, returns error", 213 dns: doesResolve, 214 addr: ensAddr, 215 immutable: true, 216 expectErr: errors.New(`immutable address not a content hash: "swarm.eth"`), 217 }, 218 { 219 desc: "DNS configured, ENS address, name doesn't resolve, returns error", 220 dns: doesntResolve, 221 addr: ensAddr, 222 expectErr: errors.New(`DNS name not found: "swarm.eth"`), 223 }, 224 } 225 for _, x := range tests { 226 t.Run(x.desc, func(t *testing.T) { 227 api := &API{dns: x.dns} 228 uri := &URI{Addr: x.addr, Scheme: "bzz"} 229 if x.immutable { 230 uri.Scheme = "bzz-immutable" 231 } 232 res, err := api.Resolve(context.TODO(), uri) 233 if err == nil { 234 if x.expectErr != nil { 235 t.Fatalf("expected error %q, got result %q", x.expectErr, res) 236 } 237 if res.String() != x.result { 238 t.Fatalf("expected result %q, got %q", x.result, res) 239 } 240 } else { 241 if x.expectErr == nil { 242 t.Fatalf("expected no error, got %q", err) 243 } 244 if err.Error() != x.expectErr.Error() { 245 t.Fatalf("expected error %q, got %q", x.expectErr, err) 246 } 247 } 248 }) 249 } 250 } 251 252 func TestMultiResolver(t *testing.T) { 253 doesntResolve := newTestResolveValidator("") 254 255 ethAddr := "swarm.eth" 256 ethHash := "0x2222222222222222222222222222222222222222222222222222222222222222" 257 ethResolve := newTestResolveValidator(ethHash) 258 259 testAddr := "swarm.test" 260 testHash := "0x1111111111111111111111111111111111111111111111111111111111111111" 261 testResolve := newTestResolveValidator(testHash) 262 263 tests := []struct { 264 desc string 265 r Resolver 266 addr string 267 result string 268 err error 269 }{ 270 { 271 desc: "No resolvers, returns error", 272 r: NewMultiResolver(), 273 err: NewNoResolverError(""), 274 }, 275 { 276 desc: "One default resolver, returns resolved address", 277 r: NewMultiResolver(MultiResolverOptionWithResolver(ethResolve, "")), 278 addr: ethAddr, 279 result: ethHash, 280 }, 281 { 282 desc: "Two default resolvers, returns resolved address", 283 r: NewMultiResolver( 284 MultiResolverOptionWithResolver(ethResolve, ""), 285 MultiResolverOptionWithResolver(ethResolve, ""), 286 ), 287 addr: ethAddr, 288 result: ethHash, 289 }, 290 { 291 desc: "Two default resolvers, first doesn't resolve, returns resolved address", 292 r: NewMultiResolver( 293 MultiResolverOptionWithResolver(doesntResolve, ""), 294 MultiResolverOptionWithResolver(ethResolve, ""), 295 ), 296 addr: ethAddr, 297 result: ethHash, 298 }, 299 { 300 desc: "Default resolver doesn't resolve, tld resolver resolve, returns resolved address", 301 r: NewMultiResolver( 302 MultiResolverOptionWithResolver(doesntResolve, ""), 303 MultiResolverOptionWithResolver(ethResolve, "eth"), 304 ), 305 addr: ethAddr, 306 result: ethHash, 307 }, 308 { 309 desc: "Three TLD resolvers, third resolves, returns resolved address", 310 r: NewMultiResolver( 311 MultiResolverOptionWithResolver(doesntResolve, "eth"), 312 MultiResolverOptionWithResolver(doesntResolve, "eth"), 313 MultiResolverOptionWithResolver(ethResolve, "eth"), 314 ), 315 addr: ethAddr, 316 result: ethHash, 317 }, 318 { 319 desc: "One TLD resolver doesn't resolve, returns error", 320 r: NewMultiResolver( 321 MultiResolverOptionWithResolver(doesntResolve, ""), 322 MultiResolverOptionWithResolver(ethResolve, "eth"), 323 ), 324 addr: ethAddr, 325 result: ethHash, 326 }, 327 { 328 desc: "One defautl and one TLD resolver, all doesn't resolve, returns error", 329 r: NewMultiResolver( 330 MultiResolverOptionWithResolver(doesntResolve, ""), 331 MultiResolverOptionWithResolver(doesntResolve, "eth"), 332 ), 333 addr: ethAddr, 334 result: ethHash, 335 err: errors.New(`DNS name not found: "swarm.eth"`), 336 }, 337 { 338 desc: "Two TLD resolvers, both resolve, returns resolved address", 339 r: NewMultiResolver( 340 MultiResolverOptionWithResolver(ethResolve, "eth"), 341 MultiResolverOptionWithResolver(testResolve, "test"), 342 ), 343 addr: testAddr, 344 result: testHash, 345 }, 346 { 347 desc: "One TLD resolver, no default resolver, returns error for different TLD", 348 r: NewMultiResolver( 349 MultiResolverOptionWithResolver(ethResolve, "eth"), 350 ), 351 addr: testAddr, 352 err: NewNoResolverError("test"), 353 }, 354 } 355 for _, x := range tests { 356 t.Run(x.desc, func(t *testing.T) { 357 res, err := x.r.Resolve(x.addr) 358 if err == nil { 359 if x.err != nil { 360 t.Fatalf("expected error %q, got result %q", x.err, res.Hex()) 361 } 362 if res.Hex() != x.result { 363 t.Fatalf("expected result %q, got %q", x.result, res.Hex()) 364 } 365 } else { 366 if x.err == nil { 367 t.Fatalf("expected no error, got %q", err) 368 } 369 if err.Error() != x.err.Error() { 370 t.Fatalf("expected error %q, got %q", x.err, err) 371 } 372 } 373 }) 374 } 375 }