github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/core/container/controller_test.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package container 18 19 import ( 20 "archive/tar" 21 "bytes" 22 "compress/gzip" 23 "fmt" 24 "io" 25 "io/ioutil" 26 "testing" 27 "time" 28 29 "github.com/hyperledger/fabric/core/container/ccintf" 30 "github.com/hyperledger/fabric/core/container/dockercontroller" 31 "github.com/hyperledger/fabric/core/container/inproccontroller" 32 pb "github.com/hyperledger/fabric/protos/peer" 33 "github.com/stretchr/testify/assert" 34 "golang.org/x/net/context" 35 ) 36 37 /**** not using actual files from file system for testing.... use these funcs if we want to do that 38 func getCodeChainBytes(pathtocodechain string) (io.Reader, error) { 39 inputbuf := bytes.NewBuffer(nil) 40 gw := gzip.NewWriter(inputbuf) 41 tr := tar.NewWriter(gw) 42 // Get the Tar contents for the image 43 err := writeCodeChainTar(pathtocodechain, tr) 44 tr.Close() 45 gw.Close() 46 if err != nil { 47 return nil, errors.New(fmt.Sprintf("Error getting codechain tar: %s", err)) 48 } 49 ioutil.WriteFile("/tmp/chaincode.tar", inputbuf.Bytes(), 0644) 50 return inputbuf, nil 51 } 52 53 func writeCodeChainTar(pathtocodechain string, tw *tar.Writer) error { 54 root_directory := pathtocodechain //use full path 55 fmt.Printf("tar %s start(%s)\n", root_directory, time.Now()) 56 57 walkFn := func(path string, info os.FileInfo, err error) error { 58 fmt.Printf("path %s(%s)\n", path, info.Name()) 59 if info == nil { 60 return errors.New(fmt.Sprintf("Error walking the path: %s", path)) 61 } 62 63 if info.Mode().IsDir() { 64 return nil 65 } 66 // Because of scoping we can reference the external root_directory variable 67 //new_path := fmt.Sprintf("%s", path[len(root_directory):]) 68 new_path := info.Name() 69 70 if len(new_path) == 0 { 71 return nil 72 } 73 74 fr, err := os.Open(path) 75 if err != nil { 76 return err 77 } 78 defer fr.Close() 79 80 if h, err := tar.FileInfoHeader(info, new_path); err != nil { 81 fmt.Printf(fmt.Sprintf("Error getting FileInfoHeader: %s\n", err)) 82 return err 83 } else { 84 h.Name = new_path 85 if err = tw.WriteHeader(h); err != nil { 86 fmt.Printf(fmt.Sprintf("Error writing header: %s\n", err)) 87 return err 88 } 89 } 90 if length, err := io.Copy(tw, fr); err != nil { 91 return err 92 } else { 93 fmt.Printf("Length of entry = %d\n", length) 94 } 95 return nil 96 } 97 98 if err := filepath.Walk(root_directory, walkFn); err != nil { 99 fmt.Printf("Error walking root_directory: %s\n", err) 100 return err 101 } else { 102 // Write the tar file out 103 if err := tw.Close(); err != nil { 104 return err 105 } 106 } 107 fmt.Printf("tar end = %s\n", time.Now()) 108 return nil 109 } 110 *********************/ 111 112 func getCodeChainBytesInMem() (io.Reader, error) { 113 startTime := time.Now() 114 inputbuf := bytes.NewBuffer(nil) 115 gw := gzip.NewWriter(inputbuf) 116 tr := tar.NewWriter(gw) 117 dockerFileContents := []byte("FROM busybox:latest\n\nCMD echo hello") 118 dockerFileSize := int64(len([]byte(dockerFileContents))) 119 120 tr.WriteHeader(&tar.Header{Name: "Dockerfile", Size: dockerFileSize, ModTime: startTime, AccessTime: startTime, ChangeTime: startTime}) 121 tr.Write([]byte(dockerFileContents)) 122 tr.Close() 123 gw.Close() 124 ioutil.WriteFile("/tmp/chaincode.tar", inputbuf.Bytes(), 0644) 125 return inputbuf, nil 126 } 127 128 //set to true by providing "-run-controller-tests" command line option... Tests will create a docker image called "simple" 129 var runTests bool 130 131 func testForSkip(t *testing.T) { 132 //run tests 133 if !runTests { 134 t.SkipNow() 135 } 136 } 137 138 func TestVMCBuildImage(t *testing.T) { 139 testForSkip(t) 140 var ctxt = context.Background() 141 142 //get the tarball for codechain 143 tarRdr, err := getCodeChainBytesInMem() 144 if err != nil { 145 t.Fail() 146 t.Logf("Error reading tar file: %s", err) 147 return 148 } 149 150 c := make(chan struct{}) 151 152 //creat a CreateImageReq obj and send it to VMCProcess 153 go func() { 154 defer close(c) 155 cir := CreateImageReq{CCID: ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "simple"}}}, Reader: tarRdr} 156 _, err := VMCProcess(ctxt, "Docker", cir) 157 if err != nil { 158 t.Fail() 159 t.Logf("Error creating image: %s", err) 160 return 161 } 162 }() 163 164 //wait for VMController to complete. 165 fmt.Println("VMCBuildImage-waiting for response") 166 <-c 167 } 168 169 func TestVMCStartContainer(t *testing.T) { 170 testForSkip(t) 171 172 var ctxt = context.Background() 173 174 c := make(chan struct{}) 175 176 //create a StartImageReq obj and send it to VMCProcess 177 go func() { 178 defer close(c) 179 sir := StartImageReq{CCID: ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "simple"}}}} 180 _, err := VMCProcess(ctxt, "Docker", sir) 181 if err != nil { 182 t.Fail() 183 t.Logf("Error starting container: %s", err) 184 return 185 } 186 }() 187 188 //wait for VMController to complete. 189 fmt.Println("VMCStartContainer-waiting for response") 190 <-c 191 stopr := StopImageReq{CCID: ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "simple"}}}, Timeout: 0, Dontremove: true} 192 VMCProcess(ctxt, "Docker", stopr) 193 } 194 195 func TestVMCCreateAndStartContainer(t *testing.T) { 196 testForSkip(t) 197 198 var ctxt = context.Background() 199 200 c := make(chan struct{}) 201 202 //create a StartImageReq obj and send it to VMCProcess 203 go func() { 204 defer close(c) 205 206 //stop and delete the container first (if it exists) 207 stopir := StopImageReq{CCID: ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "simple"}}}, Timeout: 0} 208 VMCProcess(ctxt, "Docker", stopir) 209 210 startir := StartImageReq{CCID: ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "simple"}}}} 211 r, err := VMCProcess(ctxt, "Docker", startir) 212 if err != nil { 213 t.Fail() 214 t.Logf("Error starting container: %s", err) 215 return 216 } 217 vmcresp, ok := r.(VMCResp) 218 if !ok { 219 t.Fatalf("invalid response from VMCProcess") 220 } 221 if vmcresp.Err != nil { 222 t.Fail() 223 t.Logf("docker error starting container: %s", vmcresp.Err) 224 return 225 } 226 }() 227 228 //wait for VMController to complete. 229 fmt.Println("VMCStartContainer-waiting for response") 230 <-c 231 //stopr := StopImageReq{ID: "simple", Timeout: 0, Dontremove: true} 232 //VMCProcess(ctxt, "Docker", stopr) 233 } 234 235 func TestVMCSyncStartContainer(t *testing.T) { 236 testForSkip(t) 237 238 var ctxt = context.Background() 239 240 //creat a StartImageReq obj and send it to VMCProcess 241 sir := StartImageReq{CCID: ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "simple"}}}} 242 _, err := VMCProcess(ctxt, "Docker", sir) 243 if err != nil { 244 t.Fail() 245 t.Logf("Error starting container: %s", err) 246 return 247 } 248 stopr := StopImageReq{CCID: ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "simple"}}}, Timeout: 0, Dontremove: true} 249 VMCProcess(ctxt, "Docker", stopr) 250 } 251 252 func TestVMCStopContainer(t *testing.T) { 253 testForSkip(t) 254 255 var ctxt = context.Background() 256 257 c := make(chan struct{}) 258 259 //creat a StopImageReq obj and send it to VMCProcess 260 go func() { 261 defer close(c) 262 sir := StopImageReq{CCID: ccintf.CCID{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: "simple"}}}, Timeout: 0} 263 _, err := VMCProcess(ctxt, "Docker", sir) 264 if err != nil { 265 t.Fail() 266 t.Logf("Error stopping container: %s", err) 267 return 268 } 269 }() 270 271 //wait for VMController to complete. 272 fmt.Println("VMCStopContainer-waiting for response") 273 <-c 274 } 275 276 func TestNewVM(t *testing.T) { 277 vm := vmcontroller.newVM("Docker") 278 dvm := vm.(*dockercontroller.DockerVM) 279 assert.NotNil(t, dvm, "Requested Docker VM but newVM did not return dockercontroller.DockerVM") 280 281 vm = vmcontroller.newVM("System") 282 ivm := vm.(*inproccontroller.InprocVM) 283 assert.NotNil(t, ivm, "Requested System VM but newVM did not return inproccontroller.InprocVM") 284 285 vm = vmcontroller.newVM("") 286 dvm = vm.(*dockercontroller.DockerVM) 287 assert.NotNil(t, dvm, "Requested default VM but newVM did not return dockercontroller.DockerVM") 288 }