From ef600ce859d0801afe1b145523b85a7bc674ebc1 Mon Sep 17 00:00:00 2001 From: Jason Yellick Date: Thu, 19 Apr 2018 15:17:15 -0400 Subject: [PATCH] FAB-9604 Move container/vm.go to car test The container/vm.go file is only used by the car platform test. There is no reason to export it in the production code. Change-Id: I519c75fe09bba51b165694e329241fee23f4268c Signed-off-by: Jason Yellick --- core/chaincode/platforms/car/platform_test.go | 3 +- .../chaincode/platforms/car/vm_helper_test.go | 60 +++++++++ core/container/controller.go | 14 ++ core/container/controller_test.go | 60 ++++----- core/container/vm.go | 101 --------------- core/container/vm_test.go | 120 ------------------ 6 files changed, 100 insertions(+), 258 deletions(-) create mode 100644 core/chaincode/platforms/car/vm_helper_test.go delete mode 100644 core/container/vm.go delete mode 100644 core/container/vm_test.go diff --git a/core/chaincode/platforms/car/platform_test.go b/core/chaincode/platforms/car/platform_test.go index 5e477c220ae..2c28faee426 100644 --- a/core/chaincode/platforms/car/platform_test.go +++ b/core/chaincode/platforms/car/platform_test.go @@ -22,7 +22,6 @@ import ( "testing" "github.com/hyperledger/fabric/common/util" - "github.com/hyperledger/fabric/core/container" "github.com/hyperledger/fabric/core/testutil" pb "github.com/hyperledger/fabric/protos/peer" ) @@ -33,7 +32,7 @@ func TestMain(m *testing.M) { } func TestCar_BuildImage(t *testing.T) { - vm, err := container.NewVM() + vm, err := NewVM() if err != nil { t.Errorf("Error getting VM: %s", err) return diff --git a/core/chaincode/platforms/car/vm_helper_test.go b/core/chaincode/platforms/car/vm_helper_test.go new file mode 100644 index 00000000000..1519082c9f7 --- /dev/null +++ b/core/chaincode/platforms/car/vm_helper_test.go @@ -0,0 +1,60 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package car_test + +import ( + "bytes" + "fmt" + + "github.com/fsouza/go-dockerclient" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/container" + cutil "github.com/hyperledger/fabric/core/container/util" + pb "github.com/hyperledger/fabric/protos/peer" +) + +// VM implementation of VM management functionality. +type VM struct { + Client *docker.Client +} + +// NewVM creates a new VM instance. +func NewVM() (*VM, error) { + client, err := cutil.NewDockerClient() + if err != nil { + return nil, err + } + VM := &VM{Client: client} + return VM, nil +} + +// BuildChaincodeContainer builds the container for the supplied chaincode specification +func (vm *VM) BuildChaincodeContainer(spec *pb.ChaincodeSpec) error { + codePackage, err := container.GetChaincodePackageBytes(spec) + if err != nil { + return fmt.Errorf("Error getting chaincode package bytes: %s", err) + } + + cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackage} + dockerSpec, err := platforms.GenerateDockerBuild(cds) + if err != nil { + return fmt.Errorf("Error getting chaincode docker image: %s", err) + } + + output := bytes.NewBuffer(nil) + + err = vm.Client.BuildImage(docker.BuildImageOptions{ + Name: spec.ChaincodeId.Name, + InputStream: dockerSpec, + OutputStream: output, + }) + if err != nil { + return fmt.Errorf("Error building docker: %s (output = %s)", err, output.String()) + } + + return nil +} diff --git a/core/container/controller.go b/core/container/controller.go index 5c6450344ad..de7b0a7e01f 100644 --- a/core/container/controller.go +++ b/core/container/controller.go @@ -12,10 +12,13 @@ import ( "golang.org/x/net/context" + "github.com/hyperledger/fabric/common/flogging" + "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/container/api" "github.com/hyperledger/fabric/core/container/ccintf" "github.com/hyperledger/fabric/core/container/dockercontroller" "github.com/hyperledger/fabric/core/container/inproccontroller" + pb "github.com/hyperledger/fabric/protos/peer" ) type refCountedLock struct { @@ -33,6 +36,8 @@ type VMController struct { containerLocks map[string]*refCountedLock } +var vmLogger = flogging.MustGetLogger("container") + var vmcontroller = &VMController{ containerLocks: make(map[string]*refCountedLock), } @@ -198,3 +203,12 @@ func VMCProcess(ctxt context.Context, vmtype string, req VMCReqIntf) (VMCResp, e return VMCResp{}, ctxt.Err() } } + +// GetChaincodePackageBytes creates bytes for docker container generation using the supplied chaincode specification +func GetChaincodePackageBytes(spec *pb.ChaincodeSpec) ([]byte, error) { + if spec == nil || spec.ChaincodeId == nil { + return nil, fmt.Errorf("invalid chaincode spec") + } + + return platforms.GetDeploymentPayload(spec) +} diff --git a/core/container/controller_test.go b/core/container/controller_test.go index 0a8a76962d2..097068b8afb 100644 --- a/core/container/controller_test.go +++ b/core/container/controller_test.go @@ -1,17 +1,7 @@ /* -Copyright IBM Corp. 2016 All Rights Reserved. +Copyright IBM Corp. All Rights Reserved. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. +SPDX-License-Identifier: Apache-2.0 */ package container @@ -23,13 +13,16 @@ import ( "fmt" "io" "io/ioutil" + "os" "testing" "time" + "github.com/hyperledger/fabric/common/util" "github.com/hyperledger/fabric/core/container/api" "github.com/hyperledger/fabric/core/container/ccintf" "github.com/hyperledger/fabric/core/container/dockercontroller" "github.com/hyperledger/fabric/core/container/inproccontroller" + "github.com/hyperledger/fabric/core/testutil" pb "github.com/hyperledger/fabric/protos/peer" "github.com/stretchr/testify/assert" "golang.org/x/net/context" @@ -164,26 +157,13 @@ func createImage() { } } -//set to true by providing "-run-controller-tests" command line option... Tests will create a docker image called "simple" -var runTests bool - -// tests will fail if we don't build an image to start and stop, so check to see if this has been done -var imageCreated bool - -func testForSkip(t *testing.T) { - if !imageCreated { - createImage() - } - - //run tests - if !runTests { - t.SkipNow() - } +func TestMain(m *testing.M) { + testutil.SetupTestConfig() + createImage() + os.Exit(m.Run()) } func TestVMCStartContainer(t *testing.T) { - testForSkip(t) - var ctxt = context.Background() c := make(chan struct{}) @@ -208,8 +188,6 @@ func TestVMCStartContainer(t *testing.T) { } func TestVMCCreateAndStartContainer(t *testing.T) { - testForSkip(t) - var ctxt = context.Background() c := make(chan struct{}) @@ -244,8 +222,6 @@ func TestVMCCreateAndStartContainer(t *testing.T) { } func TestVMCSyncStartContainer(t *testing.T) { - testForSkip(t) - var ctxt = context.Background() //creat a StartImageReq obj and send it to VMCProcess @@ -261,8 +237,6 @@ func TestVMCSyncStartContainer(t *testing.T) { } func TestVMCStopContainer(t *testing.T) { - testForSkip(t) - var ctxt = context.Background() c := make(chan struct{}) @@ -295,3 +269,19 @@ func TestNewVM(t *testing.T) { assert.Panics(t, func() { vmcontroller.newVM("") }, "Requested unknown VM but did not panic") } + +func TestVM_GetChaincodePackageBytes(t *testing.T) { + _, err := GetChaincodePackageBytes(nil) + assert.Error(t, err, + "GetChaincodePackageBytes did not return error when chaincode spec is nil") + spec := &pb.ChaincodeSpec{ChaincodeId: nil} + _, err = GetChaincodePackageBytes(spec) + assert.Error(t, err, "Error expected when GetChaincodePackageBytes is called with nil chaincode ID") + assert.Contains(t, err.Error(), "invalid chaincode spec") + spec = &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, + ChaincodeId: nil, + Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs("f")}} + _, err = GetChaincodePackageBytes(spec) + assert.Error(t, err, + "GetChaincodePackageBytes did not return error when chaincode ID is nil") +} diff --git a/core/container/vm.go b/core/container/vm.go deleted file mode 100644 index a4067bd8b80..00000000000 --- a/core/container/vm.go +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package container - -import ( - "bytes" - "fmt" - - "golang.org/x/net/context" - - "github.com/fsouza/go-dockerclient" - "github.com/hyperledger/fabric/common/flogging" - "github.com/hyperledger/fabric/core/chaincode/platforms" - cutil "github.com/hyperledger/fabric/core/container/util" - pb "github.com/hyperledger/fabric/protos/peer" -) - -// VM implementation of VM management functionality. -type VM struct { - Client *docker.Client -} - -// NewVM creates a new VM instance. -func NewVM() (*VM, error) { - client, err := cutil.NewDockerClient() - if err != nil { - return nil, err - } - VM := &VM{Client: client} - return VM, nil -} - -var vmLogger = flogging.MustGetLogger("container") - -// ListImages list the images available -func (vm *VM) ListImages(context context.Context) error { - imgs, err := vm.Client.ListImages(docker.ListImagesOptions{All: false}) - if err != nil { - return err - } - for _, img := range imgs { - fmt.Println("ID: ", img.ID) - fmt.Println("RepoTags: ", img.RepoTags) - fmt.Println("Created: ", img.Created) - fmt.Println("Size: ", img.Size) - fmt.Println("VirtualSize: ", img.VirtualSize) - fmt.Println("ParentId: ", img.ParentID) - } - - return nil -} - -// BuildChaincodeContainer builds the container for the supplied chaincode specification -func (vm *VM) BuildChaincodeContainer(spec *pb.ChaincodeSpec) error { - codePackage, err := GetChaincodePackageBytes(spec) - if err != nil { - return fmt.Errorf("Error getting chaincode package bytes: %s", err) - } - - cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackage} - dockerSpec, err := platforms.GenerateDockerBuild(cds) - if err != nil { - return fmt.Errorf("Error getting chaincode docker image: %s", err) - } - - output := bytes.NewBuffer(nil) - - err = vm.Client.BuildImage(docker.BuildImageOptions{ - Name: spec.ChaincodeId.Name, - InputStream: dockerSpec, - OutputStream: output, - }) - if err != nil { - return fmt.Errorf("Error building docker: %s (output = %s)", err, output.String()) - } - - return nil -} - -// GetChaincodePackageBytes creates bytes for docker container generation using the supplied chaincode specification -func GetChaincodePackageBytes(spec *pb.ChaincodeSpec) ([]byte, error) { - if spec == nil || spec.ChaincodeId == nil { - return nil, fmt.Errorf("invalid chaincode spec") - } - - return platforms.GetDeploymentPayload(spec) -} diff --git a/core/container/vm_test.go b/core/container/vm_test.go deleted file mode 100644 index 09581580ae2..00000000000 --- a/core/container/vm_test.go +++ /dev/null @@ -1,120 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package container - -import ( - "flag" - "os" - "testing" - - "github.com/hyperledger/fabric/common/util" - "github.com/hyperledger/fabric/core/testutil" - pb "github.com/hyperledger/fabric/protos/peer" - "github.com/stretchr/testify/assert" - "golang.org/x/net/context" -) - -func TestMain(m *testing.M) { - flag.BoolVar(&runTests, "run-controller-tests", true, "run tests") - flag.Parse() - testutil.SetupTestConfig() - os.Exit(m.Run()) -} - -func TestVM_ListImages(t *testing.T) { - vm, err := NewVM() - if err != nil { - t.Fail() - t.Logf("Error getting VM: %s", err) - } - err = vm.ListImages(context.TODO()) - assert.NoError(t, err, "Error listing images") -} - -func TestVM_BuildImage_ChaincodeLocal(t *testing.T) { - vm, err := NewVM() - if err != nil { - t.Fail() - t.Logf("Error getting VM: %s", err) - return - } - // Build the spec - chaincodePath := "github.com/hyperledger/fabric/examples/chaincode/go/example01/cmd" - spec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, - ChaincodeId: &pb.ChaincodeID{Name: "ex01", Path: chaincodePath}, - Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs("f")}} - err = vm.BuildChaincodeContainer(spec) - assert.NoError(t, err) -} - -func TestVM_BuildImage_ChaincodeRemote(t *testing.T) { - t.Skip("Works but needs user credentials. Not suitable for automated unit tests as is") - vm, err := NewVM() - if err != nil { - t.Fail() - t.Logf("Error getting VM: %s", err) - return - } - // Build the spec - chaincodePath := "https://github.com/prjayach/chaincode_examples/chaincode_example02" - spec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, - ChaincodeId: &pb.ChaincodeID{Name: "ex02", Path: chaincodePath}, - Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs("f")}} - err = vm.BuildChaincodeContainer(spec) - assert.NoError(t, err) -} - -func TestVM_GetChaincodePackageBytes(t *testing.T) { - _, err := GetChaincodePackageBytes(nil) - assert.Error(t, err, - "GetChaincodePackageBytes did not return error when chaincode spec is nil") - - spec := &pb.ChaincodeSpec{ChaincodeId: nil} - _, err = GetChaincodePackageBytes(spec) - assert.Error(t, err, "Error expected when GetChaincodePackageBytes is called with nil chaincode ID") - assert.Contains(t, err.Error(), "invalid chaincode spec") - - spec = &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, - ChaincodeId: nil, - Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs("f")}} - _, err = GetChaincodePackageBytes(spec) - assert.Error(t, err, - "GetChaincodePackageBytes did not return error when chaincode ID is nil") -} - -func TestVM_BuildChaincodeContainer(t *testing.T) { - vm, err := NewVM() - assert.NoError(t, err) - err = vm.BuildChaincodeContainer(nil) - assert.Error(t, err) - assert.Contains(t, err.Error(), "Error getting chaincode package bytes") -} - -func TestVM_Chaincode_Compile(t *testing.T) { - // vm, err := NewVM() - // if err != nil { - // t.Fail() - // t.Logf("Error getting VM: %s", err) - // return - // } - - // if err := vm.BuildPeerContainer(); err != nil { - // t.Fail() - // t.Log(err) - // } - t.Skip("NOT IMPLEMENTED") -}