| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | // Copyright 2018 The go-ethereum Authors | 
					
						
							|  |  |  | // This file is part of go-ethereum. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // go-ethereum is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // go-ethereum is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							|  |  |  | // GNU General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package main | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							|  |  |  | 	"io/ioutil" | 
					
						
							|  |  |  | 	"os" | 
					
						
							|  |  |  | 	"path/filepath" | 
					
						
							| 
									
										
										
										
											2018-10-04 09:18:03 +02:00
										 |  |  | 	"runtime" | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/swarm/api" | 
					
						
							|  |  |  | 	swarm "github.com/ethereum/go-ethereum/swarm/api/client" | 
					
						
							| 
									
										
										
										
											2018-11-14 15:21:14 +07:00
										 |  |  | 	swarmhttp "github.com/ethereum/go-ethereum/swarm/api/http" | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TestManifestChange tests manifest add, update and remove | 
					
						
							|  |  |  | // cli commands without encryption. | 
					
						
							|  |  |  | func TestManifestChange(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2018-10-04 09:18:03 +02:00
										 |  |  | 	if runtime.GOOS == "windows" { | 
					
						
							|  |  |  | 		t.Skip() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	testManifestChange(t, false) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TestManifestChange tests manifest add, update and remove | 
					
						
							|  |  |  | // cli commands with encryption enabled. | 
					
						
							|  |  |  | func TestManifestChangeEncrypted(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2018-10-04 09:18:03 +02:00
										 |  |  | 	if runtime.GOOS == "windows" { | 
					
						
							|  |  |  | 		t.Skip() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	testManifestChange(t, true) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // testManifestChange performs cli commands: | 
					
						
							|  |  |  | // - manifest add | 
					
						
							|  |  |  | // - manifest update | 
					
						
							|  |  |  | // - manifest remove | 
					
						
							|  |  |  | // on a manifest, testing the functionality of this | 
					
						
							|  |  |  | // comands on paths that are in root manifest or a nested one. | 
					
						
							|  |  |  | // Argument encrypt controls whether to use encryption or not. | 
					
						
							|  |  |  | func testManifestChange(t *testing.T, encrypt bool) { | 
					
						
							|  |  |  | 	t.Parallel() | 
					
						
							| 
									
										
										
										
											2018-11-14 15:21:14 +07:00
										 |  |  | 	srv := swarmhttp.NewTestSwarmServer(t, serverFunc, nil) | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 	defer srv.Close() | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	tmp, err := ioutil.TempDir("", "swarm-manifest-test") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer os.RemoveAll(tmp) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	origDir := filepath.Join(tmp, "orig") | 
					
						
							|  |  |  | 	if err := os.Mkdir(origDir, 0777); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	indexDataFilename := filepath.Join(origDir, "index.html") | 
					
						
							|  |  |  | 	err = ioutil.WriteFile(indexDataFilename, []byte("<h1>Test</h1>"), 0666) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Files paths robots.txt and robots.html share the same prefix "robots." | 
					
						
							|  |  |  | 	// which will result a manifest with a nested manifest under path "robots.". | 
					
						
							|  |  |  | 	// This will allow testing manifest changes on both root and nested manifest. | 
					
						
							|  |  |  | 	err = ioutil.WriteFile(filepath.Join(origDir, "robots.txt"), []byte("Disallow: /"), 0666) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	err = ioutil.WriteFile(filepath.Join(origDir, "robots.html"), []byte("<strong>No Robots Allowed</strong>"), 0666) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	err = ioutil.WriteFile(filepath.Join(origDir, "mutants.txt"), []byte("Frank\nMarcus"), 0666) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	args := []string{ | 
					
						
							|  |  |  | 		"--bzzapi", | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 		srv.URL, | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 		"--recursive", | 
					
						
							|  |  |  | 		"--defaultpath", | 
					
						
							|  |  |  | 		indexDataFilename, | 
					
						
							|  |  |  | 		"up", | 
					
						
							|  |  |  | 		origDir, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if encrypt { | 
					
						
							|  |  |  | 		args = append(args, "--encrypt") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	origManifestHash := runSwarmExpectHash(t, args...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	checkHashLength(t, origManifestHash, encrypt) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 	client := swarm.NewClient(srv.URL) | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// upload a new file and use its manifest to add it the original manifest. | 
					
						
							|  |  |  | 	t.Run("add", func(t *testing.T) { | 
					
						
							|  |  |  | 		humansData := []byte("Ann\nBob") | 
					
						
							|  |  |  | 		humansDataFilename := filepath.Join(tmp, "humans.txt") | 
					
						
							|  |  |  | 		err = ioutil.WriteFile(humansDataFilename, humansData, 0666) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatal(err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		humansManifestHash := runSwarmExpectHash(t, | 
					
						
							|  |  |  | 			"--bzzapi", | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 			srv.URL, | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 			"up", | 
					
						
							|  |  |  | 			humansDataFilename, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		newManifestHash := runSwarmExpectHash(t, | 
					
						
							|  |  |  | 			"--bzzapi", | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 			srv.URL, | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 			"manifest", | 
					
						
							|  |  |  | 			"add", | 
					
						
							|  |  |  | 			origManifestHash, | 
					
						
							|  |  |  | 			"humans.txt", | 
					
						
							|  |  |  | 			humansManifestHash, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		checkHashLength(t, newManifestHash, encrypt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		newManifest := downloadManifest(t, client, newManifestHash, encrypt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var found bool | 
					
						
							|  |  |  | 		for _, e := range newManifest.Entries { | 
					
						
							|  |  |  | 			if e.Path == "humans.txt" { | 
					
						
							|  |  |  | 				found = true | 
					
						
							|  |  |  | 				if e.Size != int64(len(humansData)) { | 
					
						
							|  |  |  | 					t.Errorf("expected humans.txt size %v, got %v", len(humansData), e.Size) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if e.ModTime.IsZero() { | 
					
						
							|  |  |  | 					t.Errorf("got zero mod time for humans.txt") | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				ct := "text/plain; charset=utf-8" | 
					
						
							|  |  |  | 				if e.ContentType != ct { | 
					
						
							|  |  |  | 					t.Errorf("expected content type %q, got %q", ct, e.ContentType) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				break | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if !found { | 
					
						
							|  |  |  | 			t.Fatal("no humans.txt in new manifest") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		checkFile(t, client, newManifestHash, "humans.txt", humansData) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// upload a new file and use its manifest to add it the original manifest, | 
					
						
							|  |  |  | 	// but ensure that the file will be in the nested manifest of the original one. | 
					
						
							|  |  |  | 	t.Run("add nested", func(t *testing.T) { | 
					
						
							|  |  |  | 		robotsData := []byte(`{"disallow": "/"}`) | 
					
						
							|  |  |  | 		robotsDataFilename := filepath.Join(tmp, "robots.json") | 
					
						
							|  |  |  | 		err = ioutil.WriteFile(robotsDataFilename, robotsData, 0666) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatal(err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		robotsManifestHash := runSwarmExpectHash(t, | 
					
						
							|  |  |  | 			"--bzzapi", | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 			srv.URL, | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 			"up", | 
					
						
							|  |  |  | 			robotsDataFilename, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		newManifestHash := runSwarmExpectHash(t, | 
					
						
							|  |  |  | 			"--bzzapi", | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 			srv.URL, | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 			"manifest", | 
					
						
							|  |  |  | 			"add", | 
					
						
							|  |  |  | 			origManifestHash, | 
					
						
							|  |  |  | 			"robots.json", | 
					
						
							|  |  |  | 			robotsManifestHash, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		checkHashLength(t, newManifestHash, encrypt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		newManifest := downloadManifest(t, client, newManifestHash, encrypt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var found bool | 
					
						
							|  |  |  | 	loop: | 
					
						
							|  |  |  | 		for _, e := range newManifest.Entries { | 
					
						
							|  |  |  | 			if e.Path == "robots." { | 
					
						
							|  |  |  | 				nestedManifest := downloadManifest(t, client, e.Hash, encrypt) | 
					
						
							|  |  |  | 				for _, e := range nestedManifest.Entries { | 
					
						
							|  |  |  | 					if e.Path == "json" { | 
					
						
							|  |  |  | 						found = true | 
					
						
							|  |  |  | 						if e.Size != int64(len(robotsData)) { | 
					
						
							|  |  |  | 							t.Errorf("expected robots.json size %v, got %v", len(robotsData), e.Size) | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						if e.ModTime.IsZero() { | 
					
						
							|  |  |  | 							t.Errorf("got zero mod time for robots.json") | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						ct := "application/json" | 
					
						
							|  |  |  | 						if e.ContentType != ct { | 
					
						
							|  |  |  | 							t.Errorf("expected content type %q, got %q", ct, e.ContentType) | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						break loop | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if !found { | 
					
						
							|  |  |  | 			t.Fatal("no robots.json in new manifest") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		checkFile(t, client, newManifestHash, "robots.json", robotsData) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// upload a new file and use its manifest to change the file it the original manifest. | 
					
						
							|  |  |  | 	t.Run("update", func(t *testing.T) { | 
					
						
							|  |  |  | 		indexData := []byte("<h1>Ethereum Swarm</h1>") | 
					
						
							|  |  |  | 		indexDataFilename := filepath.Join(tmp, "index.html") | 
					
						
							|  |  |  | 		err = ioutil.WriteFile(indexDataFilename, indexData, 0666) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatal(err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		indexManifestHash := runSwarmExpectHash(t, | 
					
						
							|  |  |  | 			"--bzzapi", | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 			srv.URL, | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 			"up", | 
					
						
							|  |  |  | 			indexDataFilename, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		newManifestHash := runSwarmExpectHash(t, | 
					
						
							|  |  |  | 			"--bzzapi", | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 			srv.URL, | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 			"manifest", | 
					
						
							|  |  |  | 			"update", | 
					
						
							|  |  |  | 			origManifestHash, | 
					
						
							|  |  |  | 			"index.html", | 
					
						
							|  |  |  | 			indexManifestHash, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		checkHashLength(t, newManifestHash, encrypt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		newManifest := downloadManifest(t, client, newManifestHash, encrypt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var found bool | 
					
						
							|  |  |  | 		for _, e := range newManifest.Entries { | 
					
						
							|  |  |  | 			if e.Path == "index.html" { | 
					
						
							|  |  |  | 				found = true | 
					
						
							|  |  |  | 				if e.Size != int64(len(indexData)) { | 
					
						
							|  |  |  | 					t.Errorf("expected index.html size %v, got %v", len(indexData), e.Size) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if e.ModTime.IsZero() { | 
					
						
							|  |  |  | 					t.Errorf("got zero mod time for index.html") | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				ct := "text/html; charset=utf-8" | 
					
						
							|  |  |  | 				if e.ContentType != ct { | 
					
						
							|  |  |  | 					t.Errorf("expected content type %q, got %q", ct, e.ContentType) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				break | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if !found { | 
					
						
							|  |  |  | 			t.Fatal("no index.html in new manifest") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		checkFile(t, client, newManifestHash, "index.html", indexData) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// check default entry change | 
					
						
							|  |  |  | 		checkFile(t, client, newManifestHash, "", indexData) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// upload a new file and use its manifest to change the file it the original manifest, | 
					
						
							|  |  |  | 	// but ensure that the file is in the nested manifest of the original one. | 
					
						
							|  |  |  | 	t.Run("update nested", func(t *testing.T) { | 
					
						
							|  |  |  | 		robotsData := []byte(`<string>Only humans allowed!!!</strong>`) | 
					
						
							|  |  |  | 		robotsDataFilename := filepath.Join(tmp, "robots.html") | 
					
						
							|  |  |  | 		err = ioutil.WriteFile(robotsDataFilename, robotsData, 0666) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatal(err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		humansManifestHash := runSwarmExpectHash(t, | 
					
						
							|  |  |  | 			"--bzzapi", | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 			srv.URL, | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 			"up", | 
					
						
							|  |  |  | 			robotsDataFilename, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		newManifestHash := runSwarmExpectHash(t, | 
					
						
							|  |  |  | 			"--bzzapi", | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 			srv.URL, | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 			"manifest", | 
					
						
							|  |  |  | 			"update", | 
					
						
							|  |  |  | 			origManifestHash, | 
					
						
							|  |  |  | 			"robots.html", | 
					
						
							|  |  |  | 			humansManifestHash, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		checkHashLength(t, newManifestHash, encrypt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		newManifest := downloadManifest(t, client, newManifestHash, encrypt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var found bool | 
					
						
							|  |  |  | 	loop: | 
					
						
							|  |  |  | 		for _, e := range newManifest.Entries { | 
					
						
							|  |  |  | 			if e.Path == "robots." { | 
					
						
							|  |  |  | 				nestedManifest := downloadManifest(t, client, e.Hash, encrypt) | 
					
						
							|  |  |  | 				for _, e := range nestedManifest.Entries { | 
					
						
							|  |  |  | 					if e.Path == "html" { | 
					
						
							|  |  |  | 						found = true | 
					
						
							|  |  |  | 						if e.Size != int64(len(robotsData)) { | 
					
						
							|  |  |  | 							t.Errorf("expected robots.html size %v, got %v", len(robotsData), e.Size) | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						if e.ModTime.IsZero() { | 
					
						
							|  |  |  | 							t.Errorf("got zero mod time for robots.html") | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						ct := "text/html; charset=utf-8" | 
					
						
							|  |  |  | 						if e.ContentType != ct { | 
					
						
							|  |  |  | 							t.Errorf("expected content type %q, got %q", ct, e.ContentType) | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						break loop | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if !found { | 
					
						
							|  |  |  | 			t.Fatal("no robots.html in new manifest") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		checkFile(t, client, newManifestHash, "robots.html", robotsData) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// remove a file from the manifest. | 
					
						
							|  |  |  | 	t.Run("remove", func(t *testing.T) { | 
					
						
							|  |  |  | 		newManifestHash := runSwarmExpectHash(t, | 
					
						
							|  |  |  | 			"--bzzapi", | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 			srv.URL, | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 			"manifest", | 
					
						
							|  |  |  | 			"remove", | 
					
						
							|  |  |  | 			origManifestHash, | 
					
						
							|  |  |  | 			"mutants.txt", | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		checkHashLength(t, newManifestHash, encrypt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		newManifest := downloadManifest(t, client, newManifestHash, encrypt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var found bool | 
					
						
							|  |  |  | 		for _, e := range newManifest.Entries { | 
					
						
							|  |  |  | 			if e.Path == "mutants.txt" { | 
					
						
							|  |  |  | 				found = true | 
					
						
							|  |  |  | 				break | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if found { | 
					
						
							|  |  |  | 			t.Fatal("mutants.txt is not removed") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// remove a file from the manifest, but ensure that the file is in | 
					
						
							|  |  |  | 	// the nested manifest of the original one. | 
					
						
							|  |  |  | 	t.Run("remove nested", func(t *testing.T) { | 
					
						
							|  |  |  | 		newManifestHash := runSwarmExpectHash(t, | 
					
						
							|  |  |  | 			"--bzzapi", | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 			srv.URL, | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 			"manifest", | 
					
						
							|  |  |  | 			"remove", | 
					
						
							|  |  |  | 			origManifestHash, | 
					
						
							|  |  |  | 			"robots.html", | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		checkHashLength(t, newManifestHash, encrypt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		newManifest := downloadManifest(t, client, newManifestHash, encrypt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var found bool | 
					
						
							|  |  |  | 	loop: | 
					
						
							|  |  |  | 		for _, e := range newManifest.Entries { | 
					
						
							|  |  |  | 			if e.Path == "robots." { | 
					
						
							|  |  |  | 				nestedManifest := downloadManifest(t, client, e.Hash, encrypt) | 
					
						
							|  |  |  | 				for _, e := range nestedManifest.Entries { | 
					
						
							|  |  |  | 					if e.Path == "html" { | 
					
						
							|  |  |  | 						found = true | 
					
						
							|  |  |  | 						break loop | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if found { | 
					
						
							|  |  |  | 			t.Fatal("robots.html in not removed") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TestNestedDefaultEntryUpdate tests if the default entry is updated | 
					
						
							|  |  |  | // if the file in nested manifest used for it is also updated. | 
					
						
							|  |  |  | func TestNestedDefaultEntryUpdate(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2018-10-04 09:18:03 +02:00
										 |  |  | 	if runtime.GOOS == "windows" { | 
					
						
							|  |  |  | 		t.Skip() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	testNestedDefaultEntryUpdate(t, false) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TestNestedDefaultEntryUpdateEncrypted tests if the default entry | 
					
						
							|  |  |  | // of encrypted upload is updated if the file in nested manifest | 
					
						
							|  |  |  | // used for it is also updated. | 
					
						
							|  |  |  | func TestNestedDefaultEntryUpdateEncrypted(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2018-10-04 09:18:03 +02:00
										 |  |  | 	if runtime.GOOS == "windows" { | 
					
						
							|  |  |  | 		t.Skip() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 	testNestedDefaultEntryUpdate(t, true) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func testNestedDefaultEntryUpdate(t *testing.T, encrypt bool) { | 
					
						
							|  |  |  | 	t.Parallel() | 
					
						
							| 
									
										
										
										
											2018-11-14 15:21:14 +07:00
										 |  |  | 	srv := swarmhttp.NewTestSwarmServer(t, serverFunc, nil) | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 	defer srv.Close() | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	tmp, err := ioutil.TempDir("", "swarm-manifest-test") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer os.RemoveAll(tmp) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	origDir := filepath.Join(tmp, "orig") | 
					
						
							|  |  |  | 	if err := os.Mkdir(origDir, 0777); err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	indexData := []byte("<h1>Test</h1>") | 
					
						
							|  |  |  | 	indexDataFilename := filepath.Join(origDir, "index.html") | 
					
						
							|  |  |  | 	err = ioutil.WriteFile(indexDataFilename, indexData, 0666) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Add another file with common prefix as the default entry to test updates of | 
					
						
							|  |  |  | 	// default entry with nested manifests. | 
					
						
							|  |  |  | 	err = ioutil.WriteFile(filepath.Join(origDir, "index.txt"), []byte("Test"), 0666) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	args := []string{ | 
					
						
							|  |  |  | 		"--bzzapi", | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 		srv.URL, | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 		"--recursive", | 
					
						
							|  |  |  | 		"--defaultpath", | 
					
						
							|  |  |  | 		indexDataFilename, | 
					
						
							|  |  |  | 		"up", | 
					
						
							|  |  |  | 		origDir, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if encrypt { | 
					
						
							|  |  |  | 		args = append(args, "--encrypt") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	origManifestHash := runSwarmExpectHash(t, args...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	checkHashLength(t, origManifestHash, encrypt) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 	client := swarm.NewClient(srv.URL) | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	newIndexData := []byte("<h1>Ethereum Swarm</h1>") | 
					
						
							|  |  |  | 	newIndexDataFilename := filepath.Join(tmp, "index.html") | 
					
						
							|  |  |  | 	err = ioutil.WriteFile(newIndexDataFilename, newIndexData, 0666) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	newIndexManifestHash := runSwarmExpectHash(t, | 
					
						
							|  |  |  | 		"--bzzapi", | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 		srv.URL, | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 		"up", | 
					
						
							|  |  |  | 		newIndexDataFilename, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	newManifestHash := runSwarmExpectHash(t, | 
					
						
							|  |  |  | 		"--bzzapi", | 
					
						
							| 
									
										
										
										
											2018-10-09 14:08:40 +02:00
										 |  |  | 		srv.URL, | 
					
						
							| 
									
										
										
										
											2018-08-10 16:12:55 +02:00
										 |  |  | 		"manifest", | 
					
						
							|  |  |  | 		"update", | 
					
						
							|  |  |  | 		origManifestHash, | 
					
						
							|  |  |  | 		"index.html", | 
					
						
							|  |  |  | 		newIndexManifestHash, | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	checkHashLength(t, newManifestHash, encrypt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	newManifest := downloadManifest(t, client, newManifestHash, encrypt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var found bool | 
					
						
							|  |  |  | 	for _, e := range newManifest.Entries { | 
					
						
							|  |  |  | 		if e.Path == "index." { | 
					
						
							|  |  |  | 			found = true | 
					
						
							|  |  |  | 			newManifest = downloadManifest(t, client, e.Hash, encrypt) | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !found { | 
					
						
							|  |  |  | 		t.Fatal("no index. path in new manifest") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	found = false | 
					
						
							|  |  |  | 	for _, e := range newManifest.Entries { | 
					
						
							|  |  |  | 		if e.Path == "html" { | 
					
						
							|  |  |  | 			found = true | 
					
						
							|  |  |  | 			if e.Size != int64(len(newIndexData)) { | 
					
						
							|  |  |  | 				t.Errorf("expected index.html size %v, got %v", len(newIndexData), e.Size) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if e.ModTime.IsZero() { | 
					
						
							|  |  |  | 				t.Errorf("got zero mod time for index.html") | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			ct := "text/html; charset=utf-8" | 
					
						
							|  |  |  | 			if e.ContentType != ct { | 
					
						
							|  |  |  | 				t.Errorf("expected content type %q, got %q", ct, e.ContentType) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !found { | 
					
						
							|  |  |  | 		t.Fatal("no html in new manifest") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	checkFile(t, client, newManifestHash, "index.html", newIndexData) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// check default entry change | 
					
						
							|  |  |  | 	checkFile(t, client, newManifestHash, "", newIndexData) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func runSwarmExpectHash(t *testing.T, args ...string) (hash string) { | 
					
						
							|  |  |  | 	t.Helper() | 
					
						
							|  |  |  | 	hashRegexp := `[a-f\d]{64,128}` | 
					
						
							|  |  |  | 	up := runSwarm(t, args...) | 
					
						
							|  |  |  | 	_, matches := up.ExpectRegexp(hashRegexp) | 
					
						
							|  |  |  | 	up.ExpectExit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(matches) < 1 { | 
					
						
							|  |  |  | 		t.Fatal("no matches found") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return matches[0] | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func checkHashLength(t *testing.T, hash string, encrypted bool) { | 
					
						
							|  |  |  | 	t.Helper() | 
					
						
							|  |  |  | 	l := len(hash) | 
					
						
							|  |  |  | 	if encrypted && l != 128 { | 
					
						
							|  |  |  | 		t.Errorf("expected hash length 128, got %v", l) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !encrypted && l != 64 { | 
					
						
							|  |  |  | 		t.Errorf("expected hash length 64, got %v", l) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func downloadManifest(t *testing.T, client *swarm.Client, hash string, encrypted bool) (manifest *api.Manifest) { | 
					
						
							|  |  |  | 	t.Helper() | 
					
						
							|  |  |  | 	m, isEncrypted, err := client.DownloadManifest(hash) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if encrypted != isEncrypted { | 
					
						
							|  |  |  | 		t.Error("new manifest encryption flag is not correct") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return m | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func checkFile(t *testing.T, client *swarm.Client, hash, path string, expected []byte) { | 
					
						
							|  |  |  | 	t.Helper() | 
					
						
							|  |  |  | 	f, err := client.Download(hash, path) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	got, err := ioutil.ReadAll(f) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !bytes.Equal(got, expected) { | 
					
						
							|  |  |  | 		t.Errorf("expected file content %q, got %q", expected, got) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |