feeds_test.go 5.48 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
// Copyright 2017 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"
	"encoding/json"
	"io/ioutil"
	"os"
	"testing"

	"github.com/ethereum/go-ethereum/common/hexutil"
27
	"github.com/ethereum/go-ethereum/crypto"
28
	"github.com/ethereum/go-ethereum/log"
29
	"github.com/ethereum/go-ethereum/swarm/api"
30 31
	swarm "github.com/ethereum/go-ethereum/swarm/api/client"
	swarmhttp "github.com/ethereum/go-ethereum/swarm/api/http"
32 33 34
	"github.com/ethereum/go-ethereum/swarm/storage/feed"
	"github.com/ethereum/go-ethereum/swarm/storage/feed/lookup"
	"github.com/ethereum/go-ethereum/swarm/testutil"
35 36
)

37
func TestCLIFeedUpdate(t *testing.T) {
38
	srv := swarmhttp.NewTestSwarmServer(t, func(api *api.API) swarmhttp.TestServer {
39 40
		return swarmhttp.NewServer(api, "")
	}, nil)
41
	log.Info("starting a test swarm server")
42 43 44 45 46 47 48
	defer srv.Close()

	// create a private key file for signing
	privkeyHex := "0000000000000000000000000000000000000000000000000000000000001979"
	privKey, _ := crypto.HexToECDSA(privkeyHex)
	address := crypto.PubkeyToAddress(privKey.PublicKey)

49 50
	pkFileName := testutil.TempFileWithContent(t, privkeyHex)
	defer os.Remove(pkFileName)
51 52

	// compose a topic. We'll be doing quotes about Miguel de Cervantes
53
	var topic feed.Topic
54 55 56 57 58 59 60 61 62 63
	subject := []byte("Miguel de Cervantes")
	copy(topic[:], subject[:])
	name := "quotes"

	// prepare some data for the update
	data := []byte("En boca cerrada no entran moscas")
	hexData := hexutil.Encode(data)

	flags := []string{
		"--bzzapi", srv.URL,
64
		"--bzzaccount", pkFileName,
65
		"feed", "update",
66 67 68 69 70
		"--topic", topic.Hex(),
		"--name", name,
		hexData}

	// create an update and expect an exit without errors
71
	log.Info("updating a feed with 'swarm feed update'")
72 73 74 75 76 77 78 79
	cmd := runSwarm(t, flags...)
	cmd.ExpectExit()

	// now try to get the update using the client
	client := swarm.NewClient(srv.URL)

	// build the same topic as before, this time
	// we use NewTopic to create a topic automatically.
80
	topic, err := feed.NewTopic(name, subject)
81 82 83 84
	if err != nil {
		t.Fatal(err)
	}

85
	// Feed configures whose updates we will be looking up.
86
	fd := feed.Feed{
87 88 89 90 91
		Topic: topic,
		User:  address,
	}

	// Build a query to get the latest update
92
	query := feed.NewQueryLatest(&fd, lookup.NoClue)
93 94

	// retrieve content!
95
	reader, err := client.QueryFeed(query, "")
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
	if err != nil {
		t.Fatal(err)
	}

	retrieved, err := ioutil.ReadAll(reader)
	if err != nil {
		t.Fatal(err)
	}

	// check we retrieved the sent information
	if !bytes.Equal(data, retrieved) {
		t.Fatalf("Received %s, expected %s", retrieved, data)
	}

	// Now retrieve info for the next update
	flags = []string{
		"--bzzapi", srv.URL,
113
		"feed", "info",
114 115 116 117
		"--topic", topic.Hex(),
		"--user", address.Hex(),
	}

118
	log.Info("getting feed info with 'swarm feed info'")
119 120 121 122 123
	cmd = runSwarm(t, flags...)
	_, matches := cmd.ExpectRegexp(`.*`) // regex hack to extract stdout
	cmd.ExpectExit()

	// verify we can deserialize the result as a valid JSON
124
	var request feed.Request
125 126 127 128 129
	err = json.Unmarshal([]byte(matches[0]), &request)
	if err != nil {
		t.Fatal(err)
	}

130
	// make sure the retrieved feed is the same
131 132
	if request.Feed != fd {
		t.Fatalf("Expected feed to be: %s, got %s", fd, request.Feed)
133 134 135 136 137
	}

	// test publishing a manifest
	flags = []string{
		"--bzzapi", srv.URL,
138
		"--bzzaccount", pkFileName,
139
		"feed", "create",
140 141 142
		"--topic", topic.Hex(),
	}

143
	log.Info("Publishing manifest with 'swarm feed create'")
144
	cmd = runSwarm(t, flags...)
145
	_, matches = cmd.ExpectRegexp(`[a-f\d]{64}`)
146 147
	cmd.ExpectExit()

148
	manifestAddress := matches[0] // read the received feed manifest
149 150

	// now attempt to lookup the latest update using a manifest instead
151
	reader, err = client.QueryFeed(nil, manifestAddress)
152 153 154 155 156 157 158 159 160 161 162 163
	if err != nil {
		t.Fatal(err)
	}

	retrieved, err = ioutil.ReadAll(reader)
	if err != nil {
		t.Fatal(err)
	}

	if !bytes.Equal(data, retrieved) {
		t.Fatalf("Received %s, expected %s", retrieved, data)
	}
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195

	// test publishing a manifest for a different user
	flags = []string{
		"--bzzapi", srv.URL,
		"feed", "create",
		"--topic", topic.Hex(),
		"--user", "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", // different user
	}

	log.Info("Publishing manifest with 'swarm feed create' for a different user")
	cmd = runSwarm(t, flags...)
	_, matches = cmd.ExpectRegexp(`[a-f\d]{64}`)
	cmd.ExpectExit()

	manifestAddress = matches[0] // read the received feed manifest

	// now let's try to update that user's manifest which we don't have the private key for
	flags = []string{
		"--bzzapi", srv.URL,
		"--bzzaccount", pkFileName,
		"feed", "update",
		"--manifest", manifestAddress,
		hexData}

	// create an update and expect an error given there is a user mismatch
	log.Info("updating a feed with 'swarm feed update'")
	cmd = runSwarm(t, flags...)
	cmd.ExpectRegexp("Fatal:.*") // best way so far to detect a failure.
	cmd.ExpectExit()
	if cmd.ExitStatus() == 0 {
		t.Fatal("Expected nonzero exit code when updating a manifest with the wrong user. Got 0.")
	}
196
}