diff --git a/core/chaincode/platforms/golang/platform_test.go b/core/chaincode/platforms/golang/platform_test.go index cdbe254063c..30be9f4233e 100644 --- a/core/chaincode/platforms/golang/platform_test.go +++ b/core/chaincode/platforms/golang/platform_test.go @@ -34,9 +34,9 @@ import ( func testerr(err error, succ bool) error { if succ && err != nil { - return fmt.Errorf("Expected success but got %s", err) + return fmt.Errorf("Expected success but got error %s", err) } else if !succ && err == nil { - return fmt.Errorf("Expected failer but succeeded") + return fmt.Errorf("Expected failure but succeeded") } return nil } @@ -210,7 +210,7 @@ func TestGetDeploymentPayload(t *testing.T) { for _, tst := range tests { _, err := platform.GetDeploymentPayload(tst.spec) if err = testerr(err, tst.succ); err != nil { - t.Errorf("Error to validating chaincode spec: %s, %s", tst.spec.ChaincodeId.Path, err) + t.Errorf("Error validating chaincode spec: %s, %s", tst.spec.ChaincodeId.Path, err) } } } @@ -255,7 +255,7 @@ func TestGenerateDockerBuild(t *testing.T) { } err = platform.GenerateDockerBuild(cds, tw) if err = testerr(err, tst.SuccessExpected); err != nil { - t.Errorf("Error to validating chaincode spec: %s, %s", cds.ChaincodeSpec.ChaincodeId.Path, err) + t.Errorf("Error validating chaincode spec: %s, %s", cds.ChaincodeSpec.ChaincodeId.Path, err) } } } diff --git a/core/chaincode/platforms/util/utils.go b/core/chaincode/platforms/util/utils.go index 6e3cf69697e..6c3c4cad16f 100644 --- a/core/chaincode/platforms/util/utils.go +++ b/core/chaincode/platforms/util/utils.go @@ -20,13 +20,12 @@ import ( "archive/tar" "bytes" "fmt" + "io" "io/ioutil" "os" "path/filepath" - "io" - - "github.com/fsouza/go-dockerclient" + docker "github.com/fsouza/go-dockerclient" "github.com/hyperledger/fabric/common/flogging" "github.com/hyperledger/fabric/common/util" cutil "github.com/hyperledger/fabric/core/container/util" @@ -147,7 +146,6 @@ func DockerBuild(opts DockerBuildOptions) error { if err != nil { return fmt.Errorf("Error creating docker client: %s", err) } - if opts.Image == "" { opts.Image = cutil.GetDockerfileFromConfig("chaincode.builder") if opts.Image == "" { diff --git a/core/chaincode/platforms/util/utils_test.go b/core/chaincode/platforms/util/utils_test.go index df57a1bcbf0..1a682f81047 100644 --- a/core/chaincode/platforms/util/utils_test.go +++ b/core/chaincode/platforms/util/utils_test.go @@ -17,22 +17,24 @@ limitations under the License. package util import ( + "archive/tar" "bytes" + "compress/gzip" "encoding/hex" - "math/rand" - "testing" - "time" - - "archive/tar" "fmt" "io" + "io/ioutil" + "math/rand" "os" "strings" + "testing" + "time" "github.com/hyperledger/fabric/common/util" "github.com/hyperledger/fabric/core/config" cutil "github.com/hyperledger/fabric/core/container/util" "github.com/spf13/viper" + "github.com/stretchr/testify/assert" ) // TestHashContentChange changes a random byte in a content and checks for hash change @@ -178,23 +180,139 @@ func TestHashDiffDir(t *testing.T) { if bytes.Compare(hash1, hash2) == 0 { t.Error("Hash should be different for 2 different remote repos") } - } + func TestHashSameDir(t *testing.T) { + assert := assert.New(t) + b := []byte("firstcontent") hash := util.ComputeSHA256(b) - hash1, err := HashFilesInDir(".", "hashtestfiles1", hash, nil) + assert.NoError(err, "Error getting code") + + fname := os.TempDir() + "/hash.tar" + w, err := os.Create(fname) if err != nil { - t.Errorf("Error getting code %s", err) + t.Fatal(err) } - hash2, err := HashFilesInDir(".", "hashtestfiles1", hash, nil) + defer os.Remove(fname) + tw := tar.NewWriter(w) + defer w.Close() + defer tw.Close() + hash2, err := HashFilesInDir(".", "hashtestfiles1", hash, tw) + assert.NoError(err, "Error getting code") + + assert.Equal(bytes.Compare(hash1, hash2), 0, + "Hash should be same across multiple downloads") +} + +func TestHashBadWriter(t *testing.T) { + b := []byte("firstcontent") + hash := util.ComputeSHA256(b) + + fname := os.TempDir() + "/hash.tar" + w, err := os.Create(fname) if err != nil { - t.Errorf("Error getting code %s", err) + t.Fatal(err) + } + defer os.Remove(fname) + tw := tar.NewWriter(w) + defer w.Close() + tw.Close() + + _, err = HashFilesInDir(".", "hashtestfiles1", hash, tw) + assert.Error(t, err, + "HashFilesInDir invoked with closed writer, should have failed") +} + +// TestHashNonExistentDir tests HashFilesInDir with non existant directory +func TestHashNonExistentDir(t *testing.T) { + b := []byte("firstcontent") + hash := util.ComputeSHA256(b) + _, err := HashFilesInDir(".", "idontexist", hash, nil) + assert.Error(t, err, "Expected an error for non existent directory %s", "idontexist") +} + +// TestIsCodeExist tests isCodeExist function +func TestIsCodeExist(t *testing.T) { + assert := assert.New(t) + path := os.TempDir() + err := IsCodeExist(path) + assert.NoError(err, + "%s directory exists, IsCodeExist should not have returned error: %v", + path, err) + + dir, err := ioutil.TempDir(os.TempDir(), "iscodeexist") + assert.NoError(err) + defer os.RemoveAll(dir) + path = dir + "/blah" + err = IsCodeExist(path) + assert.Error(err, + "%s directory does not exist, IsCodeExist should have returned error", path) + + f := createTempFile(t) + defer os.Remove(f) + err = IsCodeExist(f) + assert.Error(err, "%s is a file, IsCodeExist should have returned error", f) +} + +// TestDockerBuild tests DockerBuild function +func TestDockerBuild(t *testing.T) { + assert := assert.New(t) + var err error + + ldflags := "-linkmode external -extldflags '-static'" + codepackage := bytes.NewReader(getDeploymentPayload()) + binpackage := bytes.NewBuffer(nil) + if err != nil { + t.Fatal(err) + } + err = DockerBuild(DockerBuildOptions{ + Cmd: fmt.Sprintf("GOPATH=/chaincode/input:$GOPATH go build -ldflags \"%s\" -o /chaincode/output/chaincode helloworld", + ldflags), + InputStream: codepackage, + OutputStream: binpackage, + }) + assert.NoError(err, "DockerBuild failed") +} + +func getDeploymentPayload() []byte { + var goprog = ` + package main + import "fmt" + func main() { + fmt.Println("Hello World") + } + ` + var zeroTime time.Time + payload := bytes.NewBufferString(goprog).Bytes() + inputbuf := bytes.NewBuffer(nil) + gw := gzip.NewWriter(inputbuf) + tw := tar.NewWriter(gw) + tw.WriteHeader(&tar.Header{ + Name: "src/helloworld/helloworld.go", + Size: int64(len(payload)), + Mode: 0600, + ModTime: zeroTime, + AccessTime: zeroTime, + ChangeTime: zeroTime, + }) + tw.Write(payload) + tw.Close() + gw.Close() + return inputbuf.Bytes() +} + +func createTempFile(t *testing.T) string { + tmpfile, err := ioutil.TempFile("", "test") + if err != nil { + t.Fatal(err) + return "" } - if bytes.Compare(hash1, hash2) != 0 { - t.Error("Hash should be same across multiple downloads") + if err := tmpfile.Close(); err != nil { + t.Fatal(err) } + return tmpfile.Name() } func TestDockerPull(t *testing.T) {