ipfs-cluster/test/test_files.go

225 lines
4.8 KiB
Go
Raw Normal View History

package test
import (
"bufio"
"fmt"
"io"
"math/rand"
"os"
"path/filepath"
"github.com/ipfs/go-ipfs-cmdkit/files"
)
const testDirName = "testingData"
const relRootDir = "src/github.com/ipfs/ipfs-cluster/test"
// GetTestingDirSerial returns a cmdkits serial file to the testing directory.
// $GOPATH must be set for this to work
func GetTestingDirSerial() (files.File, error) {
rootPath := filepath.Join(os.Getenv("GOPATH"), relRootDir)
testDir := filepath.Join(rootPath, testDirName)
if _, err := os.Stat(testDir); os.IsNotExist(err) {
err := generateTestDirs(rootPath)
if err != nil {
return nil, err
}
}
stat, err := os.Lstat(testDir)
if err != nil {
return nil, err
}
if !stat.IsDir() {
return nil, fmt.Errorf("testDir should be seen as directory")
}
return files.NewSerialFile(testDirName, testDir, false, stat)
}
// GetTestingDirMultiReader returns a cmdkits multifilereader to the testing
// directory. $GOPATH must be set for this to work
func GetTestingDirMultiReader() (*files.MultiFileReader, error) {
file, err := GetTestingDirSerial()
if err != nil {
return nil, err
}
sliceFile := files.NewSliceFile("", "", []files.File{file})
return files.NewMultiFileReader(sliceFile, true), nil
}
// generateTestDirs creates a testing directory structure on demand for testing
// leveraging random but deterministic strings. Files are the same every run.
// Directory structure:
// - testingData
// - A
// - alpha
// * small_file_0 (< 5 kB)
// - beta
// * small_file_1 (< 5 kB)
// - delta
// - empty
// * small_file_2 (< 5 kB)
// - gamma
// * small_file_3 (< 5 kB)
// - B
// * medium_file (~.3 MB)
// * big_file (3 MB)
//
// Take special care when modifying this function. File data depends on order
// and each file size. If this changes then hashes stored in test/cids.go
// recording the ipfs import hash tree must be updated manually.
func generateTestDirs(path string) error {
// Prepare randomness source for writing files
src := rand.NewSource(int64(1))
ra := rand.New(src)
// Make top level directory
rootPath := filepath.Join(path, testDirName)
err := os.Mkdir(rootPath, os.ModePerm)
if err != nil {
return err
}
// Make subdir A
aPath := filepath.Join(rootPath, "A")
err = os.Mkdir(aPath, os.ModePerm)
if err != nil {
return err
}
alphaPath := filepath.Join(aPath, "alpha")
err = os.Mkdir(alphaPath, os.ModePerm)
if err != nil {
return err
}
sf0Path := filepath.Join(alphaPath, "small_file_0")
f, err := os.Create(sf0Path)
if err != nil {
return err
}
err = writeRandFile(5, ra, f)
if err != nil {
return err
}
if err = f.Close(); err != nil {
return err
}
betaPath := filepath.Join(aPath, "beta")
err = os.Mkdir(betaPath, os.ModePerm)
if err != nil {
return err
}
sf1Path := filepath.Join(betaPath, "small_file_1")
f, err = os.Create(sf1Path)
if err != nil {
return err
}
err = writeRandFile(5, ra, f)
if err != nil {
return err
}
if err = f.Close(); err != nil {
return err
}
deltaPath := filepath.Join(aPath, "delta")
err = os.Mkdir(deltaPath, os.ModePerm)
if err != nil {
return err
}
emptyPath := filepath.Join(deltaPath, "empty")
err = os.Mkdir(emptyPath, os.ModePerm)
if err != nil {
return err
}
sf2Path := filepath.Join(aPath, "small_file_2")
f, err = os.Create(sf2Path)
if err != nil {
return err
}
err = writeRandFile(5, ra, f)
if err != nil {
return err
}
if err = f.Close(); err != nil {
return err
}
gammaPath := filepath.Join(aPath, "gamma")
err = os.Mkdir(gammaPath, os.ModePerm)
if err != nil {
return err
}
sf3Path := filepath.Join(gammaPath, "small_file_3")
f, err = os.Create(sf3Path)
if err != nil {
return err
}
err = writeRandFile(5, ra, f)
if err != nil {
return err
}
if err = f.Close(); err != nil {
return err
}
// Make subdir B
bPath := filepath.Join(rootPath, "B")
err = os.Mkdir(bPath, os.ModePerm)
if err != nil {
return err
}
mfPath := filepath.Join(bPath, "medium_file")
f, err = os.Create(mfPath)
if err != nil {
return err
}
err = writeRandFile(300, ra, f)
if err != nil {
return err
}
if err = f.Close(); err != nil {
return err
}
bfPath := filepath.Join(bPath, "big_file")
f, err = os.Create(bfPath)
if err != nil {
return err
}
err = writeRandFile(3000, ra, f)
if err != nil {
return err
}
if err = f.Close(); err != nil {
return err
}
return nil
}
// writeRandFile takes in a source of randomness, a file, a number of kibibytes
// and a writing buffer and writes a kibibyte at a time from the randomness to
// the file
func writeRandFile(n int, ra *rand.Rand, f io.Writer) error {
w := bufio.NewWriter(f)
buf := make([]byte, 1024)
i := 0
for i < n {
ra.Read(buf)
if _, err := w.Write(buf); err != nil {
return err
}
i++
}
return nil
}