github.com/yimialmonte/fabric@v2.1.1+incompatible/core/chaincode/platforms/node/platform_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package node
     8  
     9  import (
    10  	"archive/tar"
    11  	"bytes"
    12  	"compress/gzip"
    13  	"fmt"
    14  	"os"
    15  	"strings"
    16  	"testing"
    17  
    18  	"github.com/hyperledger/fabric/core/chaincode/platforms/util"
    19  	"github.com/hyperledger/fabric/core/config/configtest"
    20  	"github.com/spf13/viper"
    21  	"github.com/stretchr/testify/assert"
    22  )
    23  
    24  var platform = &Platform{}
    25  
    26  type packageFile struct {
    27  	packagePath string
    28  	mode        int64
    29  }
    30  
    31  func TestValidatePath(t *testing.T) {
    32  	err := platform.ValidatePath("there/is/no/way/this/path/exists")
    33  	if err == nil {
    34  		t.Fatalf("should have returned an error on non-existent chaincode path")
    35  	} else if !strings.HasPrefix(err.Error(), "path to chaincode does not exist") {
    36  		t.Fatalf("should have returned an error about chaincode path not existent, but got '%v'", err)
    37  	}
    38  
    39  	err = platform.ValidatePath("http://something bad/because/it/has/the/space")
    40  	if err == nil {
    41  		t.Fatalf("should have returned an error on an empty chaincode path")
    42  	} else if !strings.HasPrefix(err.Error(), "invalid path") {
    43  		t.Fatalf("should have returned an error about parsing the path, but got '%v'", err)
    44  	}
    45  
    46  }
    47  
    48  func TestValidateCodePackage(t *testing.T) {
    49  	err := platform.ValidateCodePackage([]byte("dummy CodePackage content"))
    50  	if err == nil {
    51  		t.Fatalf("should have returned an error on an invalid chaincode package")
    52  	} else if !strings.HasPrefix(err.Error(), "failure opening codepackage gzip stream") {
    53  		t.Fatalf("should have returned an error about opening the invalid archive, but got '%v'", err)
    54  	}
    55  
    56  	cp, err := makeCodePackage([]*packageFile{{"filename.txt", 0100744}})
    57  	if err != nil {
    58  		t.Fatal(err)
    59  	}
    60  
    61  	err = platform.ValidateCodePackage(cp)
    62  	if err == nil {
    63  		t.Fatal("should have failed to validate because file in the archive is in the root folder instead of 'src'")
    64  	} else if !strings.HasPrefix(err.Error(), "illegal file detected in payload") {
    65  		t.Fatalf("should have returned error about illegal file detected, but got '%s'", err)
    66  	}
    67  
    68  	cp, err = makeCodePackage([]*packageFile{{"src/filename.txt", 0100744}})
    69  	if err != nil {
    70  		t.Fatal(err)
    71  	}
    72  
    73  	err = platform.ValidateCodePackage(cp)
    74  	if err == nil {
    75  		t.Fatal("should have failed to validate because file in the archive is executable")
    76  	} else if !strings.HasPrefix(err.Error(), "illegal file mode detected for file") {
    77  		t.Fatalf("should have returned error about illegal file mode detected, but got '%s'", err)
    78  	}
    79  
    80  	cp, err = makeCodePackage([]*packageFile{{"src/filename.txt", 0100666}})
    81  	if err != nil {
    82  		t.Fatal(err)
    83  	}
    84  
    85  	err = platform.ValidateCodePackage(cp)
    86  	if err == nil {
    87  		t.Fatal("should have failed to validate because no 'package.json' found")
    88  	} else if !strings.HasPrefix(err.Error(), "no package.json found at the root of the chaincode package") {
    89  		t.Fatalf("should have returned error about no package.json found, but got '%s'", err)
    90  	}
    91  
    92  	cp, err = makeCodePackage([]*packageFile{{"src/package.json", 0100666}, {"META-INF/path/to/meta", 0100744}})
    93  	if err != nil {
    94  		t.Fatal(err)
    95  	}
    96  
    97  	err = platform.ValidateCodePackage(cp)
    98  	if err == nil {
    99  		t.Fatalf("should have failed to validate because file in the archive is executable")
   100  	} else if !strings.HasPrefix(err.Error(), "illegal file mode detected for file") {
   101  		t.Fatalf("should have returned error about illegal file mode detected, but got '%s'", err)
   102  	}
   103  	cp, err = makeCodePackage([]*packageFile{{"src/package.json", 0100666}, {"META-INF/path/to/meta", 0100666}})
   104  	if err != nil {
   105  		t.Fatal(err)
   106  	}
   107  
   108  	err = platform.ValidateCodePackage(cp)
   109  	if err != nil {
   110  		t.Fatalf("should have returned no errors, but got '%s'", err)
   111  	}
   112  }
   113  
   114  func TestGetDeploymentPayload(t *testing.T) {
   115  	_, err := platform.GetDeploymentPayload("")
   116  	if err == nil {
   117  		t.Fatal("should have failed to product deployment payload due to empty chaincode path")
   118  	} else if !strings.HasPrefix(err.Error(), "ChaincodeSpec's path cannot be empty") {
   119  		t.Fatalf("should have returned error about path being empty, but got '%s'", err)
   120  	}
   121  }
   122  
   123  func TestGenerateDockerfile(t *testing.T) {
   124  	str, _ := platform.GenerateDockerfile()
   125  	if !strings.Contains(str, "/fabric-nodeenv:") {
   126  		t.Fatalf("should have generated a docker file using the fabric-nodeenv, but got %s", str)
   127  	}
   128  
   129  	if !strings.Contains(str, "ADD binpackage.tar /usr/local/src") {
   130  		t.Fatalf("should have generated a docker file that adds code package content to /usr/local/src, but got %s", str)
   131  	}
   132  }
   133  
   134  var expectedBuildScript = `
   135  set -e
   136  if [ -x /chaincode/build.sh ]; then
   137  	/chaincode/build.sh
   138  else
   139  	cp -R /chaincode/input/src/. /chaincode/output && cd /chaincode/output && npm install --production
   140  fi
   141  `
   142  
   143  func TestGenerateBuildOptions(t *testing.T) {
   144  	opts, err := platform.DockerBuildOptions("pathname")
   145  	assert.NoError(t, err)
   146  
   147  	expectedOpts := util.DockerBuildOptions{
   148  		Image: "hyperledger/fabric-nodeenv:latest",
   149  		Cmd:   expectedBuildScript,
   150  	}
   151  	assert.Equal(t, expectedOpts, opts)
   152  }
   153  
   154  func makeCodePackage(pfiles []*packageFile) ([]byte, error) {
   155  	contents := []byte("fake file's content")
   156  
   157  	payload := bytes.NewBuffer(nil)
   158  	gw := gzip.NewWriter(payload)
   159  	tw := tar.NewWriter(gw)
   160  
   161  	for _, f := range pfiles {
   162  		if err := tw.WriteHeader(&tar.Header{
   163  			Name: f.packagePath,
   164  			Mode: f.mode,
   165  			Size: int64(len(contents)),
   166  		}); err != nil {
   167  			return nil, fmt.Errorf("Error write header: %s", err)
   168  		}
   169  
   170  		if _, err := tw.Write(contents); err != nil {
   171  			return nil, fmt.Errorf("Error writing contents: %s", err)
   172  		}
   173  	}
   174  
   175  	// Write the tar file out
   176  	if err := tw.Close(); err != nil {
   177  		return nil, fmt.Errorf("Error writing Chaincode package contents: %s", err)
   178  	}
   179  
   180  	gw.Close()
   181  
   182  	return payload.Bytes(), nil
   183  }
   184  
   185  func TestMain(m *testing.M) {
   186  	viper.SetConfigName("core")
   187  	viper.SetEnvPrefix("CORE")
   188  	configtest.AddDevConfigPath(nil)
   189  	viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
   190  	viper.AutomaticEnv()
   191  	if err := viper.ReadInConfig(); err != nil {
   192  		fmt.Printf("could not read config %s\n", err)
   193  		os.Exit(-1)
   194  	}
   195  	os.Exit(m.Run())
   196  }