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