func TestReadWriteFile(t *testing.T) { // standard os.MkdirAll(build.TempDir("encoding"), 0777) path := build.TempDir("encoding", "TestReadWriteFile") err := WriteFile(path, testStructs[3]) if err != nil { t.Fatal(err) } var obj test4 err = ReadFile(path, &obj) if err != nil { t.Error(err) } // bad paths err = WriteFile("/foo/bar", "baz") if err == nil { t.Error("expected error, got nil") } err = ReadFile("/foo/bar", nil) if err == nil { t.Error("expected error, got nil") } }
// TestRelativePathSafeFile tests creating and committing safe files with // relative paths. Specifically, we test that calling os.Chdir between creating // and committing a safe file doesn't affect the safe file's final path. The // relative path tested is relative to the working directory. func TestRelativePathSafeFile(t *testing.T) { tmpDir := build.TempDir(persistDir, "TestRelativePathSafeFile") err := os.MkdirAll(tmpDir, 0700) if err != nil { t.Fatal(err) } absPath := filepath.Join(tmpDir, "test") wd, err := os.Getwd() if err != nil { t.Fatal(err) } relPath, err := filepath.Rel(wd, absPath) // Create safe file. sf, err := NewSafeFile(relPath) defer sf.Close() if err != nil { t.Fatal(err) } // Check that the path of the file is not equal to the final path of the // file. if sf.Name() == absPath { t.Errorf("safeFile created with filename: %s has temporary filename that is equivalent to finalName: %s\n", absPath, sf.Name()) } // Write random data to the file. data := make([]byte, 10) rand.Read(data) _, err = sf.Write(data) if err != nil { t.Fatal(err) } // Change directories and commit. tmpChdir := build.TempDir(persistDir, "TestRelativePathSafeFileTmpChdir") err = os.MkdirAll(tmpChdir, 0700) if err != nil { t.Fatal(err) } os.Chdir(tmpChdir) defer os.Chdir(wd) err = sf.CommitSync() if err != nil { t.Fatal(err) } // Check that the file exists and has same data that was written to it. dataRead, err := ioutil.ReadFile(absPath) if err != nil { t.Fatal(err) } if !bytes.Equal(data, dataRead) { t.Fatalf("Committed file has different data than was written to it: expected %v, got %v\n", data, dataRead) } }
// TestSaveLoad tests that the contractor can save and load itself. func TestSaveLoad(t *testing.T) { // create contractor with mocked persist dependency c := &Contractor{ contracts: make(map[types.FileContractID]modules.RenterContract), } c.persist = new(memPersist) // add some fake contracts c.contracts = map[types.FileContractID]modules.RenterContract{ {0}: {NetAddress: "foo"}, {1}: {NetAddress: "bar"}, {2}: {NetAddress: "baz"}, } // save and reload err := c.save() if err != nil { t.Fatal(err) } err = c.load() if err != nil { t.Fatal(err) } // check that contracts were restored _, ok0 := c.contracts[types.FileContractID{0}] _, ok1 := c.contracts[types.FileContractID{1}] _, ok2 := c.contracts[types.FileContractID{2}] if !ok0 || !ok1 || !ok2 { t.Fatal("contracts were not restored properly:", c.contracts) } // use stdPersist instead of mock c.persist = newPersist(build.TempDir("contractor", "TestSaveLoad")) os.MkdirAll(build.TempDir("contractor", "TestSaveLoad"), 0700) // save and reload err = c.save() if err != nil { t.Fatal(err) } err = c.load() if err != nil { t.Fatal(err) } // check that contracts were restored _, ok0 = c.contracts[types.FileContractID{0}] _, ok1 = c.contracts[types.FileContractID{1}] _, ok2 = c.contracts[types.FileContractID{2}] if !ok0 || !ok1 || !ok2 { t.Fatal("contracts were not restored properly:", c.contracts) } }
// TestSaveLoad tests that the hostdb can save and load itself. func TestSaveLoad(t *testing.T) { // create hostdb with mocked persist dependency hdb := bareHostDB() hdb.persist = new(memPersist) // add some fake contracts hdb.contracts = map[types.FileContractID]hostContract{ {0}: {IP: "foo"}, {1}: {IP: "bar"}, {2}: {IP: "baz"}, } // save and reload err := hdb.save() if err != nil { t.Fatal(err) } err = hdb.load() if err != nil { t.Fatal(err) } // check that contracts were restored _, ok0 := hdb.contracts[types.FileContractID{0}] _, ok1 := hdb.contracts[types.FileContractID{1}] _, ok2 := hdb.contracts[types.FileContractID{2}] if !ok0 || !ok1 || !ok2 { t.Fatal("contracts were not restored properly:", hdb.contracts) } // use stdPersist instead of mock hdb.persist = newPersist(build.TempDir("hostdb", "TestSaveLoad")) os.MkdirAll(build.TempDir("hostdb", "TestSaveLoad"), 0700) // save and reload err = hdb.save() if err != nil { t.Fatal(err) } err = hdb.load() if err != nil { t.Fatal(err) } // check that contracts were restored _, ok0 = hdb.contracts[types.FileContractID{0}] _, ok1 = hdb.contracts[types.FileContractID{1}] _, ok2 = hdb.contracts[types.FileContractID{2}] if !ok0 || !ok1 || !ok2 { t.Fatal("contracts were not restored properly:", hdb.contracts) } }
// TestErrIntegratedCheckMetadata checks that checkMetadata returns an error // within OpenDatabase when OpenDatabase is called on a BoltDatabase that has // already been set up with different metadata. func TestErrIntegratedCheckMetadata(t *testing.T) { if testing.Short() { t.SkipNow() } testDir := build.TempDir(persistDir, "TestErrIntegratedCheckMetadata") err := os.MkdirAll(testDir, 0700) if err != nil { t.Fatal(err) } for i, in := range testInputs { dbFilename := testFilenames[i%len(testFilenames)] dbFilepath := filepath.Join(testDir, dbFilename) boltDB, err := OpenDatabase(in.md, dbFilepath) if err != nil { t.Errorf("OpenDatabase failed on input %v, filename %v; error was %v", in, dbFilename, err) continue } err = boltDB.Close() if err != nil { t.Fatal(err) } // Should return an error because boltDB was set up with metadata in.md, not in.newMd boltDB, err = OpenDatabase(in.newMd, dbFilepath) if err != in.err { t.Errorf("expected error %v for input %v and filename %v; got %v instead", in.err, in, dbFilename, err) } err = os.Remove(dbFilepath) if err != nil { t.Fatal(err) } } }
// createExplorerTester creates a tester object for the explorer module. func createExplorerTester(name string) (*explorerTester, error) { // Create and assemble the dependencies. testdir := build.TempDir(modules.HostDir, name) g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := transactionpool.New(cs, g) if err != nil { return nil, err } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } key, err := crypto.GenerateTwofishKey() if err != nil { return nil, err } _, err = w.Encrypt(key) if err != nil { return nil, err } err = w.Unlock(key) if err != nil { return nil, err } m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.RenterDir)) if err != nil { return nil, err } e, err := New(cs, filepath.Join(testdir, modules.ExplorerDir)) if err != nil { return nil, err } et := &explorerTester{ cs: cs, gateway: g, miner: m, tpool: tp, wallet: w, walletKey: key, explorer: e, } // Mine until the wallet has money. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { b, _ := et.miner.FindBlock() err = et.cs.AcceptBlock(b) if err != nil { return nil, err } } return et, nil }
// createAuthenticatedServerTester creates an authenticated server tester // object that is ready for testing, including money in the wallet and all // modules initalized. func createAuthenticatedServerTester(name string, password string) (*serverTester, error) { // createAuthenticatedServerTester should not get called during short // tests, as it takes a long time to run. if testing.Short() { panic("assembleServerTester called during short tests") } // Create the testing directory. testdir := build.TempDir("authenticated-api", name) key, err := crypto.GenerateTwofishKey() if err != nil { return nil, err } st, err := assembleAuthenticatedServerTester(password, key, testdir) if err != nil { return nil, err } // Mine blocks until the wallet has confirmed money. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { _, err := st.miner.AddBlock() if err != nil { return nil, err } } return st, nil }
// TestIntegrationNewNilInputs tries to trigger a panic with nil inputs. func TestIntegrationNewNilInputs(t *testing.T) { // Create a gateway and consensus set. testdir := build.TempDir(modules.TransactionPoolDir, "TestNewNilInputs") g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { t.Fatal(err) } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { t.Fatal(err) } // Try all combinations of nil inputs. _, err = New(nil, nil) if err == nil { t.Error(err) } _, err = New(nil, g) if err != errNilCS { t.Error(err) } _, err = New(cs, nil) if err != errNilGateway { t.Error(err) } _, err = New(cs, g) if err != nil { t.Error(err) } }
// TestStartDaemon probes the startDaemon function. func TestStartDaemon(t *testing.T) { testDir := build.TempDir("siad", "TestStartDaemon") config.Siad.NoBootstrap = false config.Siad.APIaddr = "localhost:45170" config.Siad.RPCaddr = ":45171" config.Siad.HostAddr = ":45172" config.Siad.SiaDir = testDir go func() { err := startDaemon() if err != nil { t.Error(err) } }() // Wait until the server has started, and then send a kill command to the // daemon. <-started time.Sleep(250 * time.Millisecond) resp, err := http.Get("http://localhost:45170/daemon/stop") if err != nil { t.Fatal(err) } if resp.StatusCode != http.StatusOK { t.Fatal(resp.StatusCode) } resp.Body.Close() }
// createConsensusSetTester creates a consensusSetTester that's ready for use. func createConsensusSetTester(name string) (*consensusSetTester, error) { testdir := build.TempDir(modules.ConsensusDir, name) // Create modules. g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := transactionpool.New(cs, g) if err != nil { return nil, err } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } key, err := crypto.GenerateTwofishKey() if err != nil { return nil, err } _, err = w.Encrypt(key) if err != nil { return nil, err } err = w.Unlock(key) if err != nil { return nil, err } m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.MinerDir)) if err != nil { return nil, err } // Assemble all objects into a consensusSetTester. cst := &consensusSetTester{ gateway: g, miner: m, tpool: tp, wallet: w, walletKey: key, cs: cs, persistDir: testdir, } // Mine until the wallet has money. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { b, _ := cst.miner.FindBlock() err = cst.cs.AcceptBlock(b) if err != nil { return nil, err } } return cst, nil }
// newHostDBTester creates a ready-to-use hostdb tester with money in the // wallet. func newHostDBTester(name string) (*hostdbTester, error) { // Create the modules. testdir := build.TempDir("hostdb", name) g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := transactionpool.New(cs, g) if err != nil { return nil, err } w, err := modWallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } key, err := crypto.GenerateTwofishKey() if err != nil { return nil, err } _, err = w.Encrypt(key) if err != nil { return nil, err } err = w.Unlock(key) if err != nil { return nil, err } hdb, err := New(cs, w, tp, filepath.Join(testdir, modules.RenterDir)) if err != nil { return nil, err } m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.MinerDir)) if err != nil { return nil, err } // Assemble all pieces into a hostdb tester. ht := &hostdbTester{ cs: cs, gateway: g, miner: m, tpool: tp, wallet: w, hostdb: hdb, } // Mine blocks until there is money in the wallet. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { _, err := ht.miner.AddBlock() if err != nil { return nil, err } } return ht, nil }
// TestCloseWallet tries to close the wallet. func TestCloseWallet(t *testing.T) { if testing.Short() { t.Skip() } testdir := build.TempDir(modules.WalletDir, "TestCloseWallet") g, err := gateway.New("localhost:0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { t.Fatal(err) } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { t.Fatal(err) } tp, err := transactionpool.New(cs, g, filepath.Join(testdir, modules.TransactionPoolDir)) if err != nil { t.Fatal(err) } wdir := filepath.Join(testdir, modules.WalletDir) w, err := New(cs, tp, wdir) if err != nil { t.Fatal(err) } if err := w.Close(); err != nil { t.Fatal(err) } }
// TestLoggerCritical prints a critical message from the logger. func TestLoggerCritical(t *testing.T) { // Create a folder for the log file. testdir := build.TempDir(persistDir, "TestLogger") err := os.MkdirAll(testdir, 0700) if err != nil { t.Fatal(err) } // Create the logger. logFilename := filepath.Join(testdir, "test.log") fl, err := NewLogger(logFilename) if err != nil { t.Fatal(err) } // Write a catch for a panic that should trigger when logger.Critical is // called. defer func() { r := recover() if r == nil { t.Error("critical message was not thrown in a panic") } // Close the file logger to clean up the test. err = fl.Close() if err != nil { t.Fatal(err) } }() fl.Critical("a critical message") }
func TestGatewayPeerRemove(t *testing.T) { if testing.Short() { t.SkipNow() } st, err := createServerTester("TestGatewayPeerRemove") if err != nil { t.Fatal(err) } peer, err := gateway.New(":0", build.TempDir("api", "TestGatewayPeerRemove", "gateway")) if err != nil { t.Fatal(err) } st.stdGetAPI("/gateway/peers/add?address=" + string(peer.Address())) var info GatewayInfo st.getAPI("/gateway/status", &info) if len(info.Peers) != 1 || info.Peers[0] != peer.Address() { t.Fatal("/gateway/peers/add did not add peer", peer.Address()) } st.stdGetAPI("/gateway/peers/remove?address=" + string(peer.Address())) st.getAPI("/gateway/status", &info) if len(info.Peers) != 0 { t.Fatal("/gateway/peer/add did not add peer", peer.Address()) } }
// createTpoolTester returns a ready-to-use tpool tester, with all modules // initialized. func createTpoolTester(name string) (*tpoolTester, error) { // Initialize the modules. testdir := build.TempDir(modules.TransactionPoolDir, name) g, err := gateway.New("localhost:0", false, filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := consensus.New(g, false, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := New(cs, g, filepath.Join(testdir, modules.TransactionPoolDir)) if err != nil { return nil, err } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } var key crypto.TwofishKey _, err = rand.Read(key[:]) if err != nil { return nil, err } _, err = w.Encrypt(key) if err != nil { return nil, err } err = w.Unlock(key) if err != nil { return nil, err } m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.MinerDir)) if err != nil { return nil, err } // Assemble all of the objects into a tpoolTester tpt := &tpoolTester{ cs: cs, gateway: g, tpool: tp, miner: m, wallet: w, walletKey: key, persistDir: testdir, } // Mine blocks until there is money in the wallet. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { b, _ := tpt.miner.FindBlock() err = tpt.cs.AcceptBlock(b) if err != nil { return nil, err } } return tpt, nil }
// TestNilInputs tries starting the wallet using nil inputs. func TestNilInputs(t *testing.T) { testdir := build.TempDir(modules.WalletDir, "TestNilInputs") g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { t.Fatal(err) } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { t.Fatal(err) } tp, err := transactionpool.New(cs, g) if err != nil { t.Fatal(err) } wdir := filepath.Join(testdir, modules.WalletDir) _, err = New(cs, nil, wdir) if err != errNilTpool { t.Error(err) } _, err = New(nil, tp, wdir) if err != errNilConsensusSet { t.Error(err) } _, err = New(nil, nil, wdir) if err != errNilConsensusSet { t.Error(err) } }
// TestExplorerGenesisHeight checks that when the explorer is initialized and given the // genesis block, the result has the correct height. func TestExplorerGenesisHeight(t *testing.T) { // Create the dependencies. testdir := build.TempDir(modules.HostDir, "TestExplorerGenesisHeight") g, err := gateway.New("localhost:0", false, filepath.Join(testdir, modules.GatewayDir)) if err != nil { t.Fatal(err) } cs, err := consensus.New(g, false, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { t.Fatal(err) } // Create the explorer - from the subscription only the genesis block will // be received. e, err := New(cs, testdir) if err != nil { t.Fatal(err) } block, height, exists := e.Block(types.GenesisID) if !exists { t.Error("explorer missing genesis block after initialization") } if block.ID() != types.GenesisID { t.Error("explorer returned wrong genesis block") } if height != 0 { t.Errorf("genesis block hash wrong height: expected 0, got %v", height) } }
// createWalletTester takes a testing.T and creates a WalletTester. func createWalletTester(name string) (*walletTester, error) { // Create the modules testdir := build.TempDir(modules.WalletDir, name) g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := transactionpool.New(cs, g) if err != nil { return nil, err } w, err := New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } var masterKey crypto.TwofishKey _, err = rand.Read(masterKey[:]) if err != nil { return nil, err } _, err = w.Encrypt(masterKey) if err != nil { return nil, err } err = w.Unlock(masterKey) if err != nil { return nil, err } m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } // Assemble all componenets into a wallet tester. wt := &walletTester{ cs: cs, gateway: g, tpool: tp, miner: m, wallet: w, walletMasterKey: masterKey, persistDir: testdir, } // Mine blocks until there is money in the wallet. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { b, _ := wt.miner.FindBlock() err := wt.cs.AcceptBlock(b) if err != nil { return nil, err } } return wt, nil }
// TestGenerateKeys probes the generateKeys function. func TestGenerateKeys(t *testing.T) { testDir := build.TempDir("siag", "TestGenerateKeys") // Try to create an anyone-can-spend set of keys. _, err := generateKeys(0, 0, testDir, "anyoneCanSpend") if err != ErrInsecureAddress { t.Error("Expecting ErrInsecureAddress:", err) } // Try to create an unspendable address. _, err = generateKeys(1, 0, testDir, "unspendable") if err != ErrUnspendableAddress { t.Error("Expecting ErrUnspendableAddress:", err) } // Create a legitimate set of keys. _, err = generateKeys(1, 1, testDir, "genuine") if err != nil { t.Error(err) } // Check that the file was created. _, err = os.Stat(filepath.Join(testDir, "genuine_Key0"+FileExtension)) if err != nil { t.Error(err) } // Try to overwrite the file that was created. _, err = generateKeys(1, 1, testDir, "genuine") if err != ErrOverwrite { t.Error("Expecting ErrOverwrite:", err) } }
func TestGatewayPeerRemove(t *testing.T) { if testing.Short() { t.SkipNow() } st, err := createServerTester("TestGatewayPeerRemove") if err != nil { t.Fatal(err) } defer st.server.Close() peer, err := gateway.New(":0", build.TempDir("api", "TestGatewayPeerRemove", "gateway")) if err != nil { t.Fatal(err) } st.stdPostAPI("/gateway/add/"+string(peer.Address()), nil) var info GatewayInfo st.getAPI("/gateway", &info) if len(info.Peers) != 1 || info.Peers[0] != peer.Address() { t.Fatal("/gateway/add did not add peer", peer.Address()) } st.stdPostAPI("/gateway/remove/"+string(peer.Address()), nil) st.getAPI("/gateway", &info) if len(info.Peers) != 0 { t.Fatal("/gateway/remove did not remove peer", peer.Address()) } }
// TestIntegrationWalletBlankEncrypt tries to encrypt and unlock the wallet // through the api using a blank encryption key - meaning that the wallet seed // returned by the encryption call can be used as the encryption key. func TestIntegrationWalletBlankEncrypt(t *testing.T) { if testing.Short() { t.SkipNow() } // Create a server object without encrypting or unlocking the wallet. testdir := build.TempDir("api", "TestIntegrationWalletBlankEncrypt") g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { t.Fatal(err) } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { t.Fatal(err) } tp, err := transactionpool.New(cs, g) if err != nil { t.Fatal(err) } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { t.Fatal(err) } srv, err := NewServer(":0", cs, g, nil, nil, nil, nil, tp, w, nil) if err != nil { t.Fatal(err) } // Assemble the serverTester. st := &serverTester{ cs: cs, gateway: g, tpool: tp, wallet: w, server: srv, } go func() { listenErr := srv.Serve() if listenErr != nil { panic(listenErr) } }() // Make a call to /wallet/encrypt and get the seed. Provide no encryption // key so that the encryption key is the seed that gets returned. var wep WalletEncryptPOST err = st.postAPI("/wallet/encrypt", url.Values{}, &wep) if err != nil { t.Fatal(err) } // Use the seed to call /wallet/unlock. unlockValues := url.Values{} unlockValues.Set("encryptionpassword", wep.PrimarySeed) err = st.stdPostAPI("/wallet/unlock", unlockValues) if err != nil { t.Fatal(err) } // Check that the wallet actually unlocked. if !w.Unlocked() { t.Error("wallet is not unlocked") } }
// createMinerTester creates a minerTester that's ready for use. func createMinerTester(name string) (*minerTester, error) { testdir := build.TempDir(modules.MinerDir, name) // Create the modules. g, err := gateway.New(":0", filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := consensus.New(g, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := transactionpool.New(cs, g) if err != nil { return nil, err } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } var key crypto.TwofishKey _, err = rand.Read(key[:]) if err != nil { return nil, err } _, err = w.Encrypt(key) if err != nil { return nil, err } err = w.Unlock(key) if err != nil { return nil, err } m, err := New(cs, tp, w, filepath.Join(testdir, modules.MinerDir)) if err != nil { return nil, err } // Assemble the minerTester. mt := &minerTester{ gateway: g, cs: cs, tpool: tp, wallet: w, walletKey: key, miner: m, } // Mine until the wallet has money. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { b, _ := m.FindBlock() err = cs.AcceptBlock(b) if err != nil { return nil, err } } return mt, nil }
// createServerTester creates a server tester object that is ready for testing, // including money in the wallet and all modules initialized. func createServerTester(name string) (*serverTester, error) { // createServerTester is expensive, and therefore should not be called // during short tests. if testing.Short() { panic("createServerTester called during short tests") } // Create the testing directory. testdir := build.TempDir("api", name) key, err := crypto.GenerateTwofishKey() if err != nil { return nil, err } st, err := assembleServerTester(key, testdir) if err != nil { return nil, err } // Mine blocks until the wallet has confirmed money. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { _, err := st.miner.AddBlock() if err != nil { return nil, err } } return st, nil }
// TestSaveLoad populates a blockchain, saves it, loads it, and checks // the consensus set hash before and after func TestSaveLoad(t *testing.T) { if testing.Short() { t.SkipNow() } t.Parallel() cst, err := createConsensusSetTester("TestSaveLoad") if err != nil { t.Fatal(err) } defer cst.Close() cst.testBlockSuite() oldHash := cst.cs.dbConsensusChecksum() cst.cs.Close() // Reassigning this will lose subscribers and such, but we // just want to call load and get a hash g, err := gateway.New("localhost:0", false, build.TempDir(modules.ConsensusDir, "TestSaveLoad", modules.GatewayDir)) if err != nil { t.Fatal(err) } d := filepath.Join(build.SiaTestingDir, modules.ConsensusDir, "TestSaveLoad", modules.ConsensusDir) cst.cs, err = New(g, false, d) if err != nil { t.Fatal(err) } newHash := cst.cs.dbConsensusChecksum() if oldHash != newHash { t.Fatal("consensus set hash changed after load") } }
// TestGatewayPeerConnect checks that /gateway/connect is adding a peer to the // gateway's peerlist. func TestGatewayPeerConnect(t *testing.T) { if testing.Short() { t.SkipNow() } st, err := createServerTester("TestGatewayPeerConnect1") if err != nil { t.Fatal(err) } defer st.server.Close() peer, err := gateway.New("localhost:0", build.TempDir("api", "TestGatewayPeerConnect2", "gateway")) if err != nil { t.Fatal(err) } err = st.stdPostAPI("/gateway/connect/"+string(peer.Address()), nil) if err != nil { t.Fatal(err) } var info GatewayInfo err = st.getAPI("/gateway", &info) if err != nil { t.Fatal(err) } if len(info.Peers) != 1 || info.Peers[0].NetAddress != peer.Address() { t.Fatal("/gateway/connect did not connect to peer", peer.Address()) } }
// TestErrDatabaseNotOpen tests that checkMetadata returns an error when called // on a BoltDatabase that is closed. func TestErrDatabaseNotOpen(t *testing.T) { if testing.Short() { t.SkipNow() } testDir := build.TempDir(persistDir, "TestErrDatabaseNotOpen") err := os.MkdirAll(testDir, 0700) if err != nil { t.Fatal(err) } dbFilepath := filepath.Join(testDir, "fake_filename") md := Metadata{"Fake Header", "Fake Version"} db, err := bolt.Open(dbFilepath, 0600, &bolt.Options{Timeout: 3 * time.Second}) if err != nil { t.Fatal(err) } boltDB := &BoltDatabase{ Metadata: md, DB: db, } err = boltDB.Close() if err != nil { t.Fatal(err) } // Should return an error since boltDB is closed. err = boltDB.checkMetadata(md) if err != bolt.ErrDatabaseNotOpen { t.Errorf("expected database not open, got %v", err) } err = os.Remove(dbFilepath) if err != nil { t.Error(err) } }
// TestNilInputs tries to create new consensus set modules using nil inputs. func TestNilInputs(t *testing.T) { testdir := build.TempDir(modules.ConsensusDir, "TestNilInputs") _, err := New(nil, testdir) if err != ErrNilGateway { t.Fatal(err) } }
// newRenterTester creates a ready-to-use renter tester with money in the // wallet. func newRenterTester(name string) (*renterTester, error) { // Create the modules. testdir := build.TempDir("renter", name) g, err := gateway.New("localhost:0", false, filepath.Join(testdir, modules.GatewayDir)) if err != nil { return nil, err } cs, err := consensus.New(g, false, filepath.Join(testdir, modules.ConsensusDir)) if err != nil { return nil, err } tp, err := transactionpool.New(cs, g, filepath.Join(testdir, modules.TransactionPoolDir)) if err != nil { return nil, err } w, err := wallet.New(cs, tp, filepath.Join(testdir, modules.WalletDir)) if err != nil { return nil, err } key, err := crypto.GenerateTwofishKey() if err != nil { return nil, err } _, err = w.Encrypt(key) if err != nil { return nil, err } err = w.Unlock(key) if err != nil { return nil, err } r, err := New(cs, w, tp, filepath.Join(testdir, modules.RenterDir)) if err != nil { return nil, err } m, err := miner.New(cs, tp, w, filepath.Join(testdir, modules.MinerDir)) if err != nil { return nil, err } // Assemble all pieces into a renter tester. rt := &renterTester{ cs: cs, gateway: g, miner: m, tpool: tp, wallet: w, renter: r, } // Mine blocks until there is money in the wallet. for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ { _, err := rt.miner.AddBlock() if err != nil { return nil, err } } return rt, nil }
// createExplorerServerTester creates a server tester object contianing only // the explorer and some presets that match standard explorer setups. func createExplorerServerTester(name string) (*serverTester, error) { testdir := build.TempDir("api", name) st, err := assembleExplorerServerTester(testdir) if err != nil { return nil, err } return st, nil }
// TestUploadAndDownload creates a network with a host and then uploads a file // from the renter to the host, and then downloads it. func TestUploadAndDownload(t *testing.T) { t.Skip("broken -- fix when host/renter are revamped") // Create a server and add a host to the network. st := newServerTester("TestUploadAndDownload", t) err := st.announceHost() if err != nil { t.Fatal(err) } for len(st.server.hostdb.ActiveHosts()) == 0 { time.Sleep(time.Millisecond) } // Upload to the host. uploadName := "api.go" st.callAPI("/renter/files/upload?pieces=1&nickname=api.go&source=" + uploadName) // Wait for the upload to finish - this is necessary due to the // fact that zero-conf transactions aren't actually propagated properly. // // TODO: There should be some way to just spinblock until the download // completes. Except there's no exported function in the renter that will // indicate if a download has completed or not. time.Sleep(types.RenterZeroConfDelay + time.Second*10) files := st.server.renter.FileList() if len(files) != 1 || !files[0].Available() { t.Fatal("file is not uploaded") } // Try to download the file. downloadName := build.TempDir("api", "TestUploadAndDownload", "downloadTestData") st.callAPI("/renter/files/download?nickname=api.go&destination=" + downloadName) time.Sleep(time.Second * 2) // Check that the downloaded file is equal to the uploaded file. upFile, err := os.Open(uploadName) if err != nil { t.Fatal(err) } defer upFile.Close() downFile, err := os.Open(downloadName) if err != nil { t.Fatal(err) } defer upFile.Close() upRoot, err := crypto.ReaderMerkleRoot(upFile) if err != nil { t.Fatal(err) } downRoot, err := crypto.ReaderMerkleRoot(downFile) if err != nil { t.Fatal(err) } if upRoot != downRoot { t.Error("uploaded and downloaded file have a hash mismatch") } }