cmd/swarm: speed up tests - use global cluster (#18129)

This commit is contained in:
Anton Evangelatov 2018-11-19 14:57:22 +01:00 committed by GitHub
parent 3333fe660f
commit 6b6c4d1c27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 106 additions and 97 deletions

@ -14,8 +14,6 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
// +build !windows
package main package main
import ( import (
@ -28,6 +26,7 @@ import (
gorand "math/rand" gorand "math/rand"
"net/http" "net/http"
"os" "os"
"runtime"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -37,8 +36,7 @@ import (
"github.com/ethereum/go-ethereum/crypto/sha3" "github.com/ethereum/go-ethereum/crypto/sha3"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/swarm/api" "github.com/ethereum/go-ethereum/swarm/api"
swarm "github.com/ethereum/go-ethereum/swarm/api/client" swarmapi "github.com/ethereum/go-ethereum/swarm/api/client"
swarmhttp "github.com/ethereum/go-ethereum/swarm/api/http"
"github.com/ethereum/go-ethereum/swarm/testutil" "github.com/ethereum/go-ethereum/swarm/testutil"
) )
@ -49,22 +47,41 @@ const (
var DefaultCurve = crypto.S256() var DefaultCurve = crypto.S256()
// TestAccessPassword tests for the correct creation of an ACT manifest protected by a password. func TestACT(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip()
}
initCluster(t)
cases := []struct {
name string
f func(t *testing.T)
}{
{"Password", testPassword},
{"PK", testPK},
{"ACTWithoutBogus", testACTWithoutBogus},
{"ACTWithBogus", testACTWithBogus},
}
for _, tc := range cases {
t.Run(tc.name, tc.f)
}
}
// testPassword tests for the correct creation of an ACT manifest protected by a password.
// The test creates bogus content, uploads it encrypted, then creates the wrapping manifest with the Access entry // The test creates bogus content, uploads it encrypted, then creates the wrapping manifest with the Access entry
// The parties participating - node (publisher), uploads to second node then disappears. Content which was uploaded // The parties participating - node (publisher), uploads to second node then disappears. Content which was uploaded
// is then fetched through 2nd node. since the tested code is not key-aware - we can just // is then fetched through 2nd node. since the tested code is not key-aware - we can just
// fetch from the 2nd node using HTTP BasicAuth // fetch from the 2nd node using HTTP BasicAuth
func TestAccessPassword(t *testing.T) { func testPassword(t *testing.T) {
srv := swarmhttp.NewTestSwarmServer(t, serverFunc, nil)
defer srv.Close()
dataFilename := testutil.TempFileWithContent(t, data) dataFilename := testutil.TempFileWithContent(t, data)
defer os.RemoveAll(dataFilename) defer os.RemoveAll(dataFilename)
// upload the file with 'swarm up' and expect a hash // upload the file with 'swarm up' and expect a hash
up := runSwarm(t, up := runSwarm(t,
"--bzzapi", "--bzzapi",
srv.URL, //it doesn't matter through which node we upload content cluster.Nodes[0].URL,
"up", "up",
"--encrypt", "--encrypt",
dataFilename) dataFilename)
@ -138,16 +155,17 @@ func TestAccessPassword(t *testing.T) {
if a.Publisher != "" { if a.Publisher != "" {
t.Fatal("should be empty") t.Fatal("should be empty")
} }
client := swarm.NewClient(srv.URL)
client := swarmapi.NewClient(cluster.Nodes[0].URL)
hash, err := client.UploadManifest(&m, false) hash, err := client.UploadManifest(&m, false)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
httpClient := &http.Client{} url := cluster.Nodes[0].URL + "/" + "bzz:/" + hash
url := srv.URL + "/" + "bzz:/" + hash httpClient := &http.Client{}
response, err := httpClient.Get(url) response, err := httpClient.Get(url)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -189,7 +207,7 @@ func TestAccessPassword(t *testing.T) {
//download file with 'swarm down' with wrong password //download file with 'swarm down' with wrong password
up = runSwarm(t, up = runSwarm(t,
"--bzzapi", "--bzzapi",
srv.URL, cluster.Nodes[0].URL,
"down", "down",
"bzz:/"+hash, "bzz:/"+hash,
tmp, tmp,
@ -203,16 +221,12 @@ func TestAccessPassword(t *testing.T) {
up.ExpectExit() up.ExpectExit()
} }
// TestAccessPK tests for the correct creation of an ACT manifest between two parties (publisher and grantee). // testPK tests for the correct creation of an ACT manifest between two parties (publisher and grantee).
// The test creates bogus content, uploads it encrypted, then creates the wrapping manifest with the Access entry // The test creates bogus content, uploads it encrypted, then creates the wrapping manifest with the Access entry
// The parties participating - node (publisher), uploads to second node (which is also the grantee) then disappears. // The parties participating - node (publisher), uploads to second node (which is also the grantee) then disappears.
// Content which was uploaded is then fetched through the grantee's http proxy. Since the tested code is private-key aware, // Content which was uploaded is then fetched through the grantee's http proxy. Since the tested code is private-key aware,
// the test will fail if the proxy's given private key is not granted on the ACT. // the test will fail if the proxy's given private key is not granted on the ACT.
func TestAccessPK(t *testing.T) { func testPK(t *testing.T) {
// Setup Swarm and upload a test file to it
cluster := newTestCluster(t, 2)
defer cluster.Shutdown()
dataFilename := testutil.TempFileWithContent(t, data) dataFilename := testutil.TempFileWithContent(t, data)
defer os.RemoveAll(dataFilename) defer os.RemoveAll(dataFilename)
@ -318,7 +332,7 @@ func TestAccessPK(t *testing.T) {
if a.Publisher != pkComp { if a.Publisher != pkComp {
t.Fatal("publisher key did not match") t.Fatal("publisher key did not match")
} }
client := swarm.NewClient(cluster.Nodes[0].URL) client := swarmapi.NewClient(cluster.Nodes[0].URL)
hash, err := client.UploadManifest(&m, false) hash, err := client.UploadManifest(&m, false)
if err != nil { if err != nil {
@ -344,29 +358,24 @@ func TestAccessPK(t *testing.T) {
} }
} }
// TestAccessACT tests the creation of the ACT manifest end-to-end, without any bogus entries (i.e. default scenario = 3 nodes 1 unauthorized) // testACTWithoutBogus tests the creation of the ACT manifest end-to-end, without any bogus entries (i.e. default scenario = 3 nodes 1 unauthorized)
func TestAccessACT(t *testing.T) { func testACTWithoutBogus(t *testing.T) {
testAccessACT(t, 0) testACT(t, 0)
} }
// TestAccessACTScale tests the creation of the ACT manifest end-to-end, with 1000 bogus entries (i.e. 1000 EC keys + default scenario = 3 nodes 1 unauthorized = 1003 keys in the ACT manifest) // testACTWithBogus tests the creation of the ACT manifest end-to-end, with 100 bogus entries (i.e. 100 EC keys + default scenario = 3 nodes 1 unauthorized = 103 keys in the ACT manifest)
func TestAccessACTScale(t *testing.T) { func testACTWithBogus(t *testing.T) {
testAccessACT(t, 1000) testACT(t, 100)
} }
// TestAccessACT tests the e2e creation, uploading and downloading of an ACT access control with both EC keys AND password protection // testACT tests the e2e creation, uploading and downloading of an ACT access control with both EC keys AND password protection
// the test fires up a 3 node cluster, then randomly picks 2 nodes which will be acting as grantees to the data // the test fires up a 3 node cluster, then randomly picks 2 nodes which will be acting as grantees to the data
// set and also protects the ACT with a password. the third node should fail decoding the reference as it will not be granted access. // set and also protects the ACT with a password. the third node should fail decoding the reference as it will not be granted access.
// the third node then then tries to download using a correct password (and succeeds) then uses a wrong password and fails. // the third node then then tries to download using a correct password (and succeeds) then uses a wrong password and fails.
// the publisher uploads through one of the nodes then disappears. // the publisher uploads through one of the nodes then disappears.
func testAccessACT(t *testing.T, bogusEntries int) { func testACT(t *testing.T, bogusEntries int) {
// Setup Swarm and upload a test file to it
const clusterSize = 3
cluster := newTestCluster(t, clusterSize)
defer cluster.Shutdown()
var uploadThroughNode = cluster.Nodes[0] var uploadThroughNode = cluster.Nodes[0]
client := swarm.NewClient(uploadThroughNode.URL) client := swarmapi.NewClient(uploadThroughNode.URL)
r1 := gorand.New(gorand.NewSource(time.Now().UnixNano())) r1 := gorand.New(gorand.NewSource(time.Now().UnixNano()))
nodeToSkip := r1.Intn(clusterSize) // a number between 0 and 2 (node indices in `cluster`) nodeToSkip := r1.Intn(clusterSize) // a number between 0 and 2 (node indices in `cluster`)

@ -43,8 +43,8 @@ func TestCLISwarmExportImport(t *testing.T) {
} }
cluster := newTestCluster(t, 1) cluster := newTestCluster(t, 1)
// generate random 10mb file // generate random 1mb file
content := testutil.RandomBytes(1, 10000000) content := testutil.RandomBytes(1, 1000000)
fileName := testutil.TempFileWithContent(t, string(content)) fileName := testutil.TempFileWithContent(t, string(content))
defer os.Remove(fileName) defer os.Remove(fileName)

@ -36,7 +36,6 @@ import (
) )
func TestCLIFeedUpdate(t *testing.T) { func TestCLIFeedUpdate(t *testing.T) {
srv := swarmhttp.NewTestSwarmServer(t, func(api *api.API) swarmhttp.TestServer { srv := swarmhttp.NewTestSwarmServer(t, func(api *api.API) swarmhttp.TestServer {
return swarmhttp.NewServer(api, "") return swarmhttp.NewServer(api, "")
}, nil) }, nil)
@ -44,7 +43,6 @@ func TestCLIFeedUpdate(t *testing.T) {
defer srv.Close() defer srv.Close()
// create a private key file for signing // create a private key file for signing
privkeyHex := "0000000000000000000000000000000000000000000000000000000000001979" privkeyHex := "0000000000000000000000000000000000000000000000000000000000001979"
privKey, _ := crypto.HexToECDSA(privkeyHex) privKey, _ := crypto.HexToECDSA(privkeyHex)
address := crypto.PubkeyToAddress(privKey.PublicKey) address := crypto.PubkeyToAddress(privKey.PublicKey)

@ -29,14 +29,8 @@ import (
"time" "time"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
colorable "github.com/mattn/go-colorable"
) )
func init() {
log.PrintOrigins(true)
log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true))))
}
type testFile struct { type testFile struct {
filePath string filePath string
content string content string

@ -57,6 +57,17 @@ func init() {
}) })
} }
const clusterSize = 3
var clusteronce sync.Once
var cluster *testCluster
func initCluster(t *testing.T) {
clusteronce.Do(func() {
cluster = newTestCluster(t, clusterSize)
})
}
func serverFunc(api *api.API) swarmhttp.TestServer { func serverFunc(api *api.API) swarmhttp.TestServer {
return swarmhttp.NewServer(api, "") return swarmhttp.NewServer(api, "")
} }

@ -31,8 +31,7 @@ import (
"time" "time"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
swarm "github.com/ethereum/go-ethereum/swarm/api/client" swarmapi "github.com/ethereum/go-ethereum/swarm/api/client"
swarmhttp "github.com/ethereum/go-ethereum/swarm/api/http"
"github.com/ethereum/go-ethereum/swarm/testutil" "github.com/ethereum/go-ethereum/swarm/testutil"
"github.com/mattn/go-colorable" "github.com/mattn/go-colorable"
) )
@ -42,42 +41,50 @@ func init() {
log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true)))) log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true))))
} }
// TestCLISwarmUp tests that running 'swarm up' makes the resulting file func TestSwarmUp(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip()
}
initCluster(t)
cases := []struct {
name string
f func(t *testing.T)
}{
{"NoEncryption", testNoEncryption},
{"Encrypted", testEncrypted},
{"RecursiveNoEncryption", testRecursiveNoEncryption},
{"RecursiveEncrypted", testRecursiveEncrypted},
{"DefaultPathAll", testDefaultPathAll},
}
for _, tc := range cases {
t.Run(tc.name, tc.f)
}
}
// testNoEncryption tests that running 'swarm up' makes the resulting file
// available from all nodes via the HTTP API // available from all nodes via the HTTP API
func TestCLISwarmUp(t *testing.T) { func testNoEncryption(t *testing.T) {
if runtime.GOOS == "windows" { testDefault(false, t)
t.Skip()
}
testCLISwarmUp(false, t)
}
func TestCLISwarmUpRecursive(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip()
}
testCLISwarmUpRecursive(false, t)
} }
// TestCLISwarmUpEncrypted tests that running 'swarm encrypted-up' makes the resulting file // testEncrypted tests that running 'swarm up --encrypted' makes the resulting file
// available from all nodes via the HTTP API // available from all nodes via the HTTP API
func TestCLISwarmUpEncrypted(t *testing.T) { func testEncrypted(t *testing.T) {
if runtime.GOOS == "windows" { testDefault(true, t)
t.Skip()
}
testCLISwarmUp(true, t)
}
func TestCLISwarmUpEncryptedRecursive(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip()
}
testCLISwarmUpRecursive(true, t)
} }
func testCLISwarmUp(toEncrypt bool, t *testing.T) { func testRecursiveNoEncryption(t *testing.T) {
log.Info("starting 3 node cluster") testRecursive(false, t)
cluster := newTestCluster(t, 3) }
defer cluster.Shutdown()
func testRecursiveEncrypted(t *testing.T) {
testRecursive(true, t)
}
func testDefault(toEncrypt bool, t *testing.T) {
tmpFileName := testutil.TempFileWithContent(t, data) tmpFileName := testutil.TempFileWithContent(t, data)
defer os.Remove(tmpFileName) defer os.Remove(tmpFileName)
@ -182,11 +189,7 @@ func testCLISwarmUp(toEncrypt bool, t *testing.T) {
} }
} }
func testCLISwarmUpRecursive(toEncrypt bool, t *testing.T) { func testRecursive(toEncrypt bool, t *testing.T) {
fmt.Println("starting 3 node cluster")
cluster := newTestCluster(t, 3)
defer cluster.Shutdown()
tmpUploadDir, err := ioutil.TempDir("", "swarm-test") tmpUploadDir, err := ioutil.TempDir("", "swarm-test")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -253,7 +256,7 @@ func testCLISwarmUpRecursive(toEncrypt bool, t *testing.T) {
switch mode := fi.Mode(); { switch mode := fi.Mode(); {
case mode.IsRegular(): case mode.IsRegular():
if file, err := swarm.Open(path.Join(tmpDownload, v.Name())); err != nil { if file, err := swarmapi.Open(path.Join(tmpDownload, v.Name())); err != nil {
t.Fatalf("encountered an error opening the file returned from the CLI: %v", err) t.Fatalf("encountered an error opening the file returned from the CLI: %v", err)
} else { } else {
ff := make([]byte, len(data)) ff := make([]byte, len(data))
@ -274,22 +277,16 @@ func testCLISwarmUpRecursive(toEncrypt bool, t *testing.T) {
} }
} }
// TestCLISwarmUpDefaultPath tests swarm recursive upload with relative and absolute // testDefaultPathAll tests swarm recursive upload with relative and absolute
// default paths and with encryption. // default paths and with encryption.
func TestCLISwarmUpDefaultPath(t *testing.T) { func testDefaultPathAll(t *testing.T) {
if runtime.GOOS == "windows" { testDefaultPath(false, false, t)
t.Skip() testDefaultPath(false, true, t)
} testDefaultPath(true, false, t)
testCLISwarmUpDefaultPath(false, false, t) testDefaultPath(true, true, t)
testCLISwarmUpDefaultPath(false, true, t)
testCLISwarmUpDefaultPath(true, false, t)
testCLISwarmUpDefaultPath(true, true, t)
} }
func testCLISwarmUpDefaultPath(toEncrypt bool, absDefaultPath bool, t *testing.T) { func testDefaultPath(toEncrypt bool, absDefaultPath bool, t *testing.T) {
srv := swarmhttp.NewTestSwarmServer(t, serverFunc, nil)
defer srv.Close()
tmp, err := ioutil.TempDir("", "swarm-defaultpath-test") tmp, err := ioutil.TempDir("", "swarm-defaultpath-test")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -312,7 +309,7 @@ func testCLISwarmUpDefaultPath(toEncrypt bool, absDefaultPath bool, t *testing.T
args := []string{ args := []string{
"--bzzapi", "--bzzapi",
srv.URL, cluster.Nodes[0].URL,
"--recursive", "--recursive",
"--defaultpath", "--defaultpath",
defaultPath, defaultPath,
@ -329,7 +326,7 @@ func testCLISwarmUpDefaultPath(toEncrypt bool, absDefaultPath bool, t *testing.T
up.ExpectExit() up.ExpectExit()
hash := matches[0] hash := matches[0]
client := swarm.NewClient(srv.URL) client := swarmapi.NewClient(cluster.Nodes[0].URL)
m, isEncrypted, err := client.DownloadManifest(hash) m, isEncrypted, err := client.DownloadManifest(hash)
if err != nil { if err != nil {