github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/core/chaincode/platforms/golang/platform_test.go (about)

     1  package golang
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strings"
     7  	"testing"
     8  
     9  	"archive/tar"
    10  	"bytes"
    11  	"compress/gzip"
    12  	"time"
    13  
    14  	"github.com/spf13/viper"
    15  
    16  	"github.com/hyperledger/fabric/core/config"
    17  	pb "github.com/hyperledger/fabric/protos/peer"
    18  )
    19  
    20  func testerr(err error, succ bool) error {
    21  	if succ && err != nil {
    22  		return fmt.Errorf("Expected success but got %s", err)
    23  	} else if !succ && err == nil {
    24  		return fmt.Errorf("Expected failer but succeeded")
    25  	}
    26  	return nil
    27  }
    28  
    29  func writeBytesToPackage(name string, payload []byte, mode int64, tw *tar.Writer) error {
    30  	//Make headers identical by using zero time
    31  	var zeroTime time.Time
    32  	tw.WriteHeader(&tar.Header{Name: name, Size: int64(len(payload)), ModTime: zeroTime, AccessTime: zeroTime, ChangeTime: zeroTime, Mode: mode})
    33  	tw.Write(payload)
    34  
    35  	return nil
    36  }
    37  
    38  func generateFakeCDS(ccname, path, file string, mode int64) (*pb.ChaincodeDeploymentSpec, error) {
    39  	codePackage := bytes.NewBuffer(nil)
    40  	gw := gzip.NewWriter(codePackage)
    41  	tw := tar.NewWriter(gw)
    42  
    43  	payload := make([]byte, 25, 25)
    44  	err := writeBytesToPackage(file, payload, mode, tw)
    45  	if err != nil {
    46  		return nil, err
    47  	}
    48  
    49  	tw.Close()
    50  	gw.Close()
    51  
    52  	cds := &pb.ChaincodeDeploymentSpec{
    53  		ChaincodeSpec: &pb.ChaincodeSpec{
    54  			ChaincodeId: &pb.ChaincodeID{
    55  				Name: ccname,
    56  				Path: path,
    57  			},
    58  		},
    59  		CodePackage: codePackage.Bytes(),
    60  	}
    61  
    62  	return cds, nil
    63  }
    64  
    65  type spec struct {
    66  	CCName          string
    67  	Path, File      string
    68  	Mode            int64
    69  	SuccessExpected bool
    70  	RealGen         bool
    71  }
    72  
    73  func TestValidateCDS(t *testing.T) {
    74  	platform := &Platform{}
    75  
    76  	specs := make([]spec, 0)
    77  	specs = append(specs, spec{CCName: "NoCode", Path: "path/to/nowhere", File: "/bin/warez", Mode: 0100400, SuccessExpected: false})
    78  	specs = append(specs, spec{CCName: "NoCode", Path: "path/to/somewhere", File: "/src/path/to/somewhere/main.go", Mode: 0100400, SuccessExpected: true})
    79  	specs = append(specs, spec{CCName: "NoCode", Path: "path/to/somewhere", File: "/src/path/to/somewhere/warez", Mode: 0100555, SuccessExpected: false})
    80  
    81  	for _, s := range specs {
    82  		cds, err := generateFakeCDS(s.CCName, s.Path, s.File, s.Mode)
    83  
    84  		err = platform.ValidateDeploymentSpec(cds)
    85  		if s.SuccessExpected == true && err != nil {
    86  			t.Errorf("Unexpected failure: %s", err)
    87  		}
    88  		if s.SuccessExpected == false && err == nil {
    89  			t.Log("Expected validation failure")
    90  			t.Fail()
    91  		}
    92  	}
    93  }
    94  
    95  func Test_writeGopathSrc(t *testing.T) {
    96  
    97  	inputbuf := bytes.NewBuffer(nil)
    98  	tw := tar.NewWriter(inputbuf)
    99  
   100  	err := writeGopathSrc(tw, "")
   101  	if err != nil {
   102  		t.Fail()
   103  		t.Logf("Error writing gopath src: %s", err)
   104  	}
   105  	//ioutil.WriteFile("/tmp/chaincode_deployment.tar", inputbuf.Bytes(), 0644)
   106  
   107  }
   108  
   109  func Test_decodeUrl(t *testing.T) {
   110  	cs := &pb.ChaincodeSpec{
   111  		ChaincodeId: &pb.ChaincodeID{
   112  			Name: "Test Chaincode",
   113  			Path: "http://github.com/hyperledger/fabric/examples/chaincode/go/map",
   114  		},
   115  	}
   116  
   117  	if _, err := decodeUrl(cs); err != nil {
   118  		t.Fail()
   119  		t.Logf("Error to decodeUrl unsuccessfully with valid path: %s, %s", cs.ChaincodeId.Path, err)
   120  	}
   121  
   122  	cs.ChaincodeId.Path = ""
   123  
   124  	if _, err := decodeUrl(cs); err == nil {
   125  		t.Fail()
   126  		t.Logf("Error to decodeUrl successfully with invalid path: %s", cs.ChaincodeId.Path)
   127  	}
   128  
   129  	cs.ChaincodeId.Path = "/"
   130  
   131  	if _, err := decodeUrl(cs); err == nil {
   132  		t.Fail()
   133  		t.Logf("Error to decodeUrl successfully with invalid path: %s", cs.ChaincodeId.Path)
   134  	}
   135  
   136  	cs.ChaincodeId.Path = "http:///"
   137  
   138  	if _, err := decodeUrl(cs); err == nil {
   139  		t.Fail()
   140  		t.Logf("Error to decodeUrl successfully with invalid path: %s", cs.ChaincodeId.Path)
   141  	}
   142  }
   143  
   144  func TestValidChaincodeSpec(t *testing.T) {
   145  	platform := &Platform{}
   146  
   147  	var tests = []struct {
   148  		spec *pb.ChaincodeSpec
   149  		succ bool
   150  	}{
   151  		{spec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "Test Chaincode", Path: "http://github.com/hyperledger/fabric/examples/chaincode/go/map"}}, succ: true},
   152  		{spec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "Test Chaincode", Path: "https://github.com/hyperledger/fabric/examples/chaincode/go/map"}}, succ: true},
   153  		{spec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "Test Chaincode", Path: "github.com/hyperledger/fabric/examples/chaincode/go/map"}}, succ: true},
   154  		{spec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "Test Chaincode", Path: "github.com/hyperledger/fabric/bad/chaincode/go/map"}}, succ: false},
   155  	}
   156  
   157  	for _, tst := range tests {
   158  		err := platform.ValidateSpec(tst.spec)
   159  		if err = testerr(err, tst.succ); err != nil {
   160  			t.Errorf("Error to validating chaincode spec: %s, %s", tst.spec.ChaincodeId.Path, err)
   161  		}
   162  	}
   163  }
   164  
   165  func TestGetDeploymentPayload(t *testing.T) {
   166  	platform := &Platform{}
   167  
   168  	var tests = []struct {
   169  		spec *pb.ChaincodeSpec
   170  		succ bool
   171  	}{
   172  		{spec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "Test Chaincode", Path: "github.com/hyperledger/fabric/examples/chaincode/go/map"}}, succ: true},
   173  		{spec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "Test Chaincode", Path: "github.com/hyperledger/fabric/examples/bad/go/map"}}, succ: false},
   174  	}
   175  
   176  	for _, tst := range tests {
   177  		_, err := platform.GetDeploymentPayload(tst.spec)
   178  		if err = testerr(err, tst.succ); err != nil {
   179  			t.Errorf("Error to validating chaincode spec: %s, %s", tst.spec.ChaincodeId.Path, err)
   180  		}
   181  	}
   182  }
   183  
   184  //TestGenerateDockerBuild goes through the functions needed to do docker build
   185  func TestGenerateDockerBuild(t *testing.T) {
   186  	platform := &Platform{}
   187  
   188  	specs := make([]spec, 0)
   189  	specs = append(specs, spec{CCName: "NoCode", Path: "path/to/nowhere", File: "/bin/warez", Mode: 0100400, SuccessExpected: false})
   190  	specs = append(specs, spec{CCName: "invalidhttp", Path: "https://not/a/valid/path", File: "/src/github.com/hyperledger/fabric/examples/chaincode/go/map/map.go", Mode: 0100400, SuccessExpected: false, RealGen: true})
   191  	specs = append(specs, spec{CCName: "map", Path: "github.com/hyperledger/fabric/examples/chaincode/go/map", File: "/src/github.com/hyperledger/fabric/examples/chaincode/go/map/map.go", Mode: 0100400, SuccessExpected: true, RealGen: true})
   192  	specs = append(specs, spec{CCName: "mapBadPath", Path: "github.com/hyperledger/fabric/examples/chaincode/go/map", File: "/src/github.com/hyperledger/fabric/examples/bad/path/to/map.go", Mode: 0100400, SuccessExpected: false})
   193  	specs = append(specs, spec{CCName: "mapBadMode", Path: "github.com/hyperledger/fabric/examples/chaincode/go/map", File: "/src/github.com/hyperledger/fabric/examples/chaincode/go/map/map.go", Mode: 0100555, SuccessExpected: false})
   194  
   195  	var err error
   196  	for _, tst := range specs {
   197  		inputbuf := bytes.NewBuffer(nil)
   198  		tw := tar.NewWriter(inputbuf)
   199  
   200  		var cds *pb.ChaincodeDeploymentSpec
   201  		if tst.RealGen {
   202  			cds = &pb.ChaincodeDeploymentSpec{
   203  				ChaincodeSpec: &pb.ChaincodeSpec{
   204  					ChaincodeId: &pb.ChaincodeID{
   205  						Name:    tst.CCName,
   206  						Path:    tst.Path,
   207  						Version: "0",
   208  					},
   209  				},
   210  			}
   211  			cds.CodePackage, err = platform.GetDeploymentPayload(cds.ChaincodeSpec)
   212  			if err = testerr(err, tst.SuccessExpected); err != nil {
   213  				t.Errorf("test failed in GetDeploymentPayload: %s, %s", cds.ChaincodeSpec.ChaincodeId.Path, err)
   214  			}
   215  		} else {
   216  			cds, err = generateFakeCDS(tst.CCName, tst.Path, tst.File, tst.Mode)
   217  		}
   218  
   219  		if _, err = platform.GenerateDockerfile(cds); err != nil {
   220  			t.Errorf("could not generate docker file for a valid spec: %s, %s", cds.ChaincodeSpec.ChaincodeId.Path, err)
   221  		}
   222  		err = platform.GenerateDockerBuild(cds, tw)
   223  		if err = testerr(err, tst.SuccessExpected); err != nil {
   224  			t.Errorf("Error to validating chaincode spec: %s, %s", cds.ChaincodeSpec.ChaincodeId.Path, err)
   225  		}
   226  	}
   227  }
   228  
   229  func TestMain(m *testing.M) {
   230  	viper.SetConfigName("core")
   231  	viper.SetEnvPrefix("CORE")
   232  	config.AddDevConfigPath(nil)
   233  	viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
   234  	viper.AutomaticEnv()
   235  	if err := viper.ReadInConfig(); err != nil {
   236  		fmt.Printf("could not read config %s\n", err)
   237  		os.Exit(-1)
   238  	}
   239  	os.Exit(m.Run())
   240  }