github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/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 "flag" 23 "fmt" 24 "io" 25 "io/ioutil" 26 "math/big" 27 "os" 28 "testing" 29 30 "github.com/PlatONnetwork/PlatON-Go/common" 31 "github.com/PlatONnetwork/PlatON-Go/core/types" 32 "github.com/PlatONnetwork/PlatON-Go/log" 33 "github.com/PlatONnetwork/PlatON-Go/swarm/sctx" 34 "github.com/PlatONnetwork/PlatON-Go/swarm/storage" 35 ) 36 37 func init() { 38 loglevel := flag.Int("loglevel", 2, "loglevel") 39 flag.Parse() 40 log.Root().SetHandler(log.CallerFileHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(os.Stderr, log.TerminalFormat(true))))) 41 } 42 43 func testAPI(t *testing.T, f func(*API, bool)) { 44 datadir, err := ioutil.TempDir("", "bzz-test") 45 if err != nil { 46 t.Fatalf("unable to create temp dir: %v", err) 47 } 48 defer os.RemoveAll(datadir) 49 fileStore, err := storage.NewLocalFileStore(datadir, make([]byte, 32)) 50 if err != nil { 51 return 52 } 53 api := NewAPI(fileStore, nil, nil, nil) 54 f(api, false) 55 f(api, true) 56 } 57 58 type testResponse struct { 59 reader storage.LazySectionReader 60 *Response 61 } 62 63 func checkResponse(t *testing.T, resp *testResponse, exp *Response) { 64 65 if resp.MimeType != exp.MimeType { 66 t.Errorf("incorrect mimeType. expected '%s', got '%s'", exp.MimeType, resp.MimeType) 67 } 68 if resp.Status != exp.Status { 69 t.Errorf("incorrect status. expected '%d', got '%d'", exp.Status, resp.Status) 70 } 71 if resp.Size != exp.Size { 72 t.Errorf("incorrect size. expected '%d', got '%d'", exp.Size, resp.Size) 73 } 74 if resp.reader != nil { 75 content := make([]byte, resp.Size) 76 read, _ := resp.reader.Read(content) 77 if int64(read) != exp.Size { 78 t.Errorf("incorrect content length. expected '%d...', got '%d...'", read, exp.Size) 79 } 80 resp.Content = string(content) 81 } 82 if resp.Content != exp.Content { 83 // if !bytes.Equal(resp.Content, exp.Content) 84 t.Errorf("incorrect content. expected '%s...', got '%s...'", string(exp.Content), string(resp.Content)) 85 } 86 } 87 88 // func expResponse(content []byte, mimeType string, status int) *Response { 89 func expResponse(content string, mimeType string, status int) *Response { 90 log.Trace(fmt.Sprintf("expected content (%v): %v ", len(content), content)) 91 return &Response{mimeType, status, int64(len(content)), content} 92 } 93 94 func testGet(t *testing.T, api *API, bzzhash, path string) *testResponse { 95 addr := storage.Address(common.Hex2Bytes(bzzhash)) 96 reader, mimeType, status, _, err := api.Get(context.TODO(), NOOPDecrypt, addr, path) 97 if err != nil { 98 t.Fatalf("unexpected error: %v", err) 99 } 100 quitC := make(chan bool) 101 size, err := reader.Size(context.TODO(), quitC) 102 if err != nil { 103 t.Fatalf("unexpected error: %v", err) 104 } 105 log.Trace(fmt.Sprintf("reader size: %v ", size)) 106 s := make([]byte, size) 107 _, err = reader.Read(s) 108 if err != io.EOF { 109 t.Fatalf("unexpected error: %v", err) 110 } 111 reader.Seek(0, 0) 112 return &testResponse{reader, &Response{mimeType, status, size, string(s)}} 113 // return &testResponse{reader, &Response{mimeType, status, reader.Size(), nil}} 114 } 115 116 func TestApiPut(t *testing.T) { 117 testAPI(t, func(api *API, toEncrypt bool) { 118 content := "hello" 119 exp := expResponse(content, "text/plain", 0) 120 ctx := context.TODO() 121 addr, wait, err := api.Put(ctx, content, exp.MimeType, toEncrypt) 122 if err != nil { 123 t.Fatalf("unexpected error: %v", err) 124 } 125 err = wait(ctx) 126 if err != nil { 127 t.Fatalf("unexpected error: %v", err) 128 } 129 resp := testGet(t, api, addr.Hex(), "") 130 checkResponse(t, resp, exp) 131 }) 132 } 133 134 // testResolver implements the Resolver interface and either returns the given 135 // hash if it is set, or returns a "name not found" error 136 type testResolveValidator struct { 137 hash *common.Hash 138 } 139 140 func newTestResolveValidator(addr string) *testResolveValidator { 141 r := &testResolveValidator{} 142 if addr != "" { 143 hash := common.HexToHash(addr) 144 r.hash = &hash 145 } 146 return r 147 } 148 149 func (t *testResolveValidator) Resolve(addr string) (common.Hash, error) { 150 if t.hash == nil { 151 return common.Hash{}, fmt.Errorf("DNS name not found: %q", addr) 152 } 153 return *t.hash, nil 154 } 155 156 func (t *testResolveValidator) Owner(node [32]byte) (addr common.Address, err error) { 157 return 158 } 159 func (t *testResolveValidator) HeaderByNumber(context.Context, *big.Int) (header *types.Header, err error) { 160 return 161 } 162 163 // TestAPIResolve tests resolving URIs which can either contain content hashes 164 // or ENS names 165 func TestAPIResolve(t *testing.T) { 166 ensAddr := "swarm.eth" 167 hashAddr := "1111111111111111111111111111111111111111111111111111111111111111" 168 resolvedAddr := "2222222222222222222222222222222222222222222222222222222222222222" 169 doesResolve := newTestResolveValidator(resolvedAddr) 170 doesntResolve := newTestResolveValidator("") 171 172 type test struct { 173 desc string 174 dns Resolver 175 addr string 176 immutable bool 177 result string 178 expectErr error 179 } 180 181 tests := []*test{ 182 { 183 desc: "DNS not configured, hash address, returns hash address", 184 dns: nil, 185 addr: hashAddr, 186 result: hashAddr, 187 }, 188 { 189 desc: "DNS not configured, ENS address, returns error", 190 dns: nil, 191 addr: ensAddr, 192 expectErr: errors.New(`no DNS to resolve name: "swarm.eth"`), 193 }, 194 { 195 desc: "DNS configured, hash address, hash resolves, returns resolved address", 196 dns: doesResolve, 197 addr: hashAddr, 198 result: resolvedAddr, 199 }, 200 { 201 desc: "DNS configured, immutable hash address, hash resolves, returns hash address", 202 dns: doesResolve, 203 addr: hashAddr, 204 immutable: true, 205 result: hashAddr, 206 }, 207 { 208 desc: "DNS configured, hash address, hash doesn't resolve, returns hash address", 209 dns: doesntResolve, 210 addr: hashAddr, 211 result: hashAddr, 212 }, 213 { 214 desc: "DNS configured, ENS address, name resolves, returns resolved address", 215 dns: doesResolve, 216 addr: ensAddr, 217 result: resolvedAddr, 218 }, 219 { 220 desc: "DNS configured, immutable ENS address, name resolves, returns error", 221 dns: doesResolve, 222 addr: ensAddr, 223 immutable: true, 224 expectErr: errors.New(`immutable address not a content hash: "swarm.eth"`), 225 }, 226 { 227 desc: "DNS configured, ENS address, name doesn't resolve, returns error", 228 dns: doesntResolve, 229 addr: ensAddr, 230 expectErr: errors.New(`DNS name not found: "swarm.eth"`), 231 }, 232 } 233 for _, x := range tests { 234 t.Run(x.desc, func(t *testing.T) { 235 api := &API{dns: x.dns} 236 uri := &URI{Addr: x.addr, Scheme: "bzz"} 237 if x.immutable { 238 uri.Scheme = "bzz-immutable" 239 } 240 res, err := api.ResolveURI(context.TODO(), uri, "") 241 if err == nil { 242 if x.expectErr != nil { 243 t.Fatalf("expected error %q, got result %q", x.expectErr, res) 244 } 245 if res.String() != x.result { 246 t.Fatalf("expected result %q, got %q", x.result, res) 247 } 248 } else { 249 if x.expectErr == nil { 250 t.Fatalf("expected no error, got %q", err) 251 } 252 if err.Error() != x.expectErr.Error() { 253 t.Fatalf("expected error %q, got %q", x.expectErr, err) 254 } 255 } 256 }) 257 } 258 } 259 260 func TestMultiResolver(t *testing.T) { 261 doesntResolve := newTestResolveValidator("") 262 263 ethAddr := "swarm.eth" 264 ethHash := "0x2222222222222222222222222222222222222222222222222222222222222222" 265 ethResolve := newTestResolveValidator(ethHash) 266 267 testAddr := "swarm.test" 268 testHash := "0x1111111111111111111111111111111111111111111111111111111111111111" 269 testResolve := newTestResolveValidator(testHash) 270 271 tests := []struct { 272 desc string 273 r Resolver 274 addr string 275 result string 276 err error 277 }{ 278 { 279 desc: "No resolvers, returns error", 280 r: NewMultiResolver(), 281 err: NewNoResolverError(""), 282 }, 283 { 284 desc: "One default resolver, returns resolved address", 285 r: NewMultiResolver(MultiResolverOptionWithResolver(ethResolve, "")), 286 addr: ethAddr, 287 result: ethHash, 288 }, 289 { 290 desc: "Two default resolvers, returns resolved address", 291 r: NewMultiResolver( 292 MultiResolverOptionWithResolver(ethResolve, ""), 293 MultiResolverOptionWithResolver(ethResolve, ""), 294 ), 295 addr: ethAddr, 296 result: ethHash, 297 }, 298 { 299 desc: "Two default resolvers, first doesn't resolve, returns resolved address", 300 r: NewMultiResolver( 301 MultiResolverOptionWithResolver(doesntResolve, ""), 302 MultiResolverOptionWithResolver(ethResolve, ""), 303 ), 304 addr: ethAddr, 305 result: ethHash, 306 }, 307 { 308 desc: "Default resolver doesn't resolve, tld resolver resolve, returns resolved address", 309 r: NewMultiResolver( 310 MultiResolverOptionWithResolver(doesntResolve, ""), 311 MultiResolverOptionWithResolver(ethResolve, "eth"), 312 ), 313 addr: ethAddr, 314 result: ethHash, 315 }, 316 { 317 desc: "Three TLD resolvers, third resolves, returns resolved address", 318 r: NewMultiResolver( 319 MultiResolverOptionWithResolver(doesntResolve, "eth"), 320 MultiResolverOptionWithResolver(doesntResolve, "eth"), 321 MultiResolverOptionWithResolver(ethResolve, "eth"), 322 ), 323 addr: ethAddr, 324 result: ethHash, 325 }, 326 { 327 desc: "One TLD resolver doesn't resolve, returns error", 328 r: NewMultiResolver( 329 MultiResolverOptionWithResolver(doesntResolve, ""), 330 MultiResolverOptionWithResolver(ethResolve, "eth"), 331 ), 332 addr: ethAddr, 333 result: ethHash, 334 }, 335 { 336 desc: "One defautl and one TLD resolver, all doesn't resolve, returns error", 337 r: NewMultiResolver( 338 MultiResolverOptionWithResolver(doesntResolve, ""), 339 MultiResolverOptionWithResolver(doesntResolve, "eth"), 340 ), 341 addr: ethAddr, 342 result: ethHash, 343 err: errors.New(`DNS name not found: "swarm.eth"`), 344 }, 345 { 346 desc: "Two TLD resolvers, both resolve, returns resolved address", 347 r: NewMultiResolver( 348 MultiResolverOptionWithResolver(ethResolve, "eth"), 349 MultiResolverOptionWithResolver(testResolve, "test"), 350 ), 351 addr: testAddr, 352 result: testHash, 353 }, 354 { 355 desc: "One TLD resolver, no default resolver, returns error for different TLD", 356 r: NewMultiResolver( 357 MultiResolverOptionWithResolver(ethResolve, "eth"), 358 ), 359 addr: testAddr, 360 err: NewNoResolverError("test"), 361 }, 362 } 363 for _, x := range tests { 364 t.Run(x.desc, func(t *testing.T) { 365 res, err := x.r.Resolve(x.addr) 366 if err == nil { 367 if x.err != nil { 368 t.Fatalf("expected error %q, got result %q", x.err, res.Hex()) 369 } 370 if res.Hex() != x.result { 371 t.Fatalf("expected result %q, got %q", x.result, res.Hex()) 372 } 373 } else { 374 if x.err == nil { 375 t.Fatalf("expected no error, got %q", err) 376 } 377 if err.Error() != x.err.Error() { 378 t.Fatalf("expected error %q, got %q", x.err, err) 379 } 380 } 381 }) 382 } 383 } 384 385 func TestDecryptOriginForbidden(t *testing.T) { 386 ctx := context.TODO() 387 ctx = sctx.SetHost(ctx, "swarm-gateways.net") 388 389 me := &ManifestEntry{ 390 Access: &AccessEntry{Type: AccessTypePass}, 391 } 392 393 api := NewAPI(nil, nil, nil, nil) 394 395 f := api.Decryptor(ctx, "") 396 err := f(me) 397 if err != ErrDecryptDomainForbidden { 398 t.Fatalf("should fail with ErrDecryptDomainForbidden, got %v", err) 399 } 400 } 401 402 func TestDecryptOrigin(t *testing.T) { 403 for _, v := range []struct { 404 host string 405 expectError error 406 }{ 407 { 408 host: "localhost", 409 expectError: ErrDecrypt, 410 }, 411 { 412 host: "127.0.0.1", 413 expectError: ErrDecrypt, 414 }, 415 { 416 host: "swarm-gateways.net", 417 expectError: ErrDecryptDomainForbidden, 418 }, 419 } { 420 ctx := context.TODO() 421 ctx = sctx.SetHost(ctx, v.host) 422 423 me := &ManifestEntry{ 424 Access: &AccessEntry{Type: AccessTypePass}, 425 } 426 427 api := NewAPI(nil, nil, nil, nil) 428 429 f := api.Decryptor(ctx, "") 430 err := f(me) 431 if err != v.expectError { 432 t.Fatalf("should fail with %v, got %v", v.expectError, err) 433 } 434 } 435 }