github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/deploy/compile/compilers_test.go (about)

     1  package compile
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"os"
     7  	"os/exec"
     8  	"path/filepath"
     9  	"strings"
    10  	"testing"
    11  
    12  	"github.com/stretchr/testify/require"
    13  
    14  	"github.com/hyperledger/burrow/logging"
    15  	"github.com/stretchr/testify/assert"
    16  )
    17  
    18  // full solc response object
    19  // individual contract items
    20  type SolcItem struct {
    21  	Bin string `json:"bin"`
    22  	Abi string `json:"abi"`
    23  }
    24  
    25  type SolcResponse struct {
    26  	Contracts map[string]*SolcItem `mapstructure:"contracts" json:"contracts"`
    27  	Version   string               `mapstructure:"version" json:"version"` // json encoded
    28  }
    29  
    30  func BlankSolcResponse() *SolcResponse {
    31  	return &SolcResponse{
    32  		Version:   "",
    33  		Contracts: make(map[string]*SolcItem),
    34  	}
    35  }
    36  
    37  func TestLocalMulti(t *testing.T) {
    38  	os.Chdir(testContractPath()) // important to maintain relative paths
    39  
    40  	expectedSolcResponse := BlankSolcResponse()
    41  	actualOutput, err := exec.Command("solc", "--combined-json", "bin,abi", "contractImport1.sol").CombinedOutput()
    42  	if err != nil {
    43  		t.Fatalf("solc failed %v: %s", err, actualOutput)
    44  	}
    45  
    46  	warning, responseJSON := extractWarningJSON(strings.TrimSpace(string(actualOutput)))
    47  	err = json.Unmarshal([]byte(responseJSON), expectedSolcResponse)
    48  	require.NoError(t, err)
    49  
    50  	respItemArray := make([]ResponseItem, 0)
    51  
    52  	for contract, item := range expectedSolcResponse.Contracts {
    53  		respItem := ResponseItem{
    54  			Objectname: objectName(strings.TrimSpace(contract)),
    55  		}
    56  		respItem.Contract.Evm.Bytecode.Object = item.Bin
    57  		respItemArray = append(respItemArray, respItem)
    58  	}
    59  	expectedResponse := &Response{
    60  		Objects: respItemArray,
    61  		Warning: warning,
    62  		Version: "",
    63  		Error:   "",
    64  	}
    65  	resp, err := EVM("contractImport1.sol", false, "", make(map[string]string), logging.NewNoopLogger())
    66  	if err != nil {
    67  		t.Fatal(err)
    68  	}
    69  	allClear := true
    70  	for _, object := range expectedResponse.Objects {
    71  		if !contains(resp.Objects, object) {
    72  			allClear = false
    73  		}
    74  	}
    75  	if !allClear {
    76  		t.Errorf("Got incorrect response, expected %v, \n\n got %v", expectedResponse, resp)
    77  	}
    78  }
    79  
    80  func TestLocalSingle(t *testing.T) {
    81  	os.Chdir(testContractPath()) // important to maintain relative paths
    82  
    83  	expectedSolcResponse := BlankSolcResponse()
    84  
    85  	shellCmd := exec.Command("solc", "--combined-json", "bin,abi", "simpleContract.sol")
    86  	actualOutput, err := shellCmd.CombinedOutput()
    87  	if err != nil {
    88  		t.Fatalf("solc failed %v: %s", err, actualOutput)
    89  	}
    90  
    91  	warning, responseJSON := extractWarningJSON(strings.TrimSpace(string(actualOutput)))
    92  	err = json.Unmarshal([]byte(responseJSON), expectedSolcResponse)
    93  	require.NoError(t, err)
    94  
    95  	respItemArray := make([]ResponseItem, 0)
    96  
    97  	for contract, item := range expectedSolcResponse.Contracts {
    98  		respItem := ResponseItem{
    99  			Objectname: objectName(strings.TrimSpace(contract)),
   100  			Filename:   "simpleContract.sol",
   101  		}
   102  		respItem.Contract.Abi = json.RawMessage(item.Abi)
   103  		respItem.Contract.Evm.Bytecode.Object = item.Bin
   104  		respItem.Contract.Evm.Bytecode.LinkReferences = []byte("{}")
   105  		respItemArray = append(respItemArray, respItem)
   106  	}
   107  	expectedResponse := &Response{
   108  		Objects: respItemArray,
   109  		Warning: warning,
   110  		Version: "",
   111  		Error:   "",
   112  	}
   113  	resp, err := EVM("simpleContract.sol", false, "", make(map[string]string), logging.NewNoopLogger())
   114  	if err != nil {
   115  		t.Fatal(err)
   116  	}
   117  	for i := range resp.Objects {
   118  		resp.Objects[i].Contract.Metadata = ""
   119  		resp.Objects[i].Contract.Devdoc = nil
   120  		resp.Objects[i].Contract.MetadataMap = nil
   121  		resp.Objects[i].Contract.Evm.DeployedBytecode.Object = ""
   122  		resp.Objects[i].Contract.Evm.DeployedBytecode.LinkReferences = nil
   123  	}
   124  	assert.Equal(t, expectedResponse, resp)
   125  }
   126  
   127  func TestFaultyContract(t *testing.T) {
   128  	const faultyContractFile = "tests/compilers_fixtures/faultyContract.sol"
   129  	actualOutput, err := exec.Command("solc", "--combined-json", "bin,abi", faultyContractFile).CombinedOutput()
   130  	require.EqualError(t, err, "exit status 1")
   131  	resp, err := EVM(faultyContractFile, false, "", make(map[string]string), logging.NewNoopLogger())
   132  	require.NoError(t, err)
   133  	if err != nil {
   134  		if string(actualOutput) != resp.Error {
   135  			t.Errorf("Expected %v got %v", string(actualOutput), resp.Error)
   136  		}
   137  	}
   138  	output := strings.TrimSpace(string(actualOutput))
   139  	fmt.Println(output)
   140  }
   141  
   142  func testContractPath() string {
   143  	baseDir, _ := os.Getwd()
   144  	return filepath.Join(baseDir, "..", "..", "tests", "compilers_fixtures")
   145  }
   146  
   147  func extractWarningJSON(output string) (warning string, json string) {
   148  	jsonBeginsCertainly := strings.Index(output, `{"contracts":`)
   149  
   150  	if jsonBeginsCertainly > 0 {
   151  		warning = output[:jsonBeginsCertainly]
   152  		json = output[jsonBeginsCertainly:]
   153  	} else {
   154  		json = output
   155  	}
   156  	return
   157  }
   158  
   159  func contains(s []ResponseItem, e ResponseItem) bool {
   160  	for _, a := range s {
   161  		if a.Contract.Evm.Bytecode.Object == e.Contract.Evm.Bytecode.Object {
   162  			return true
   163  		}
   164  	}
   165  	return false
   166  }