| package impl_test |
| |
| import ( |
| "crypto/md5" |
| "encoding/hex" |
| "errors" |
| "io" |
| "io/ioutil" |
| "os" |
| |
| "veyron2/ipc" |
| "veyron2/services/mgmt/application" |
| "veyron2/services/mgmt/binary" |
| "veyron2/services/mgmt/repository" |
| "veyron2/vlog" |
| ) |
| |
| // arInvoker holds the state of an application repository invocation mock. The |
| // mock returns the value of the wrapped envelope, which can be subsequently be |
| // changed at any time. Client is responsible for synchronization if desired. |
| type arInvoker struct { |
| envelope application.Envelope |
| } |
| |
| // startApplicationRepository sets up a server running the application |
| // repository. It returns a pointer to the envelope that the repository returns |
| // to clients (so that it can be changed). It also returns a cleanup function. |
| func startApplicationRepository() (*application.Envelope, func()) { |
| server, _ := newServer() |
| invoker := new(arInvoker) |
| dispatcher := ipc.LeafDispatcher(repository.NewServerApplication(invoker), nil) |
| name := "ar" |
| if err := server.Serve(name, dispatcher); err != nil { |
| vlog.Fatalf("Serve(%v) failed: %v", name, err) |
| } |
| return &invoker.envelope, func() { |
| if err := server.Stop(); err != nil { |
| vlog.Fatalf("Stop() failed: %v", err) |
| } |
| } |
| } |
| |
| // APPLICATION REPOSITORY INTERFACE IMPLEMENTATION |
| func (i *arInvoker) Match(ipc.ServerContext, []string) (application.Envelope, error) { |
| vlog.VI(1).Infof("Match()") |
| return i.envelope, nil |
| } |
| |
| // brInvoker holds the state of a binary repository invocation mock. It always |
| // serves the current running binary. |
| type brInvoker struct{} |
| |
| // startBinaryRepository sets up a server running the binary repository and |
| // returns a cleanup function. |
| func startBinaryRepository() func() { |
| server, _ := newServer() |
| dispatcher := ipc.LeafDispatcher(repository.NewServerBinary(new(brInvoker)), nil) |
| name := "br" |
| if err := server.Serve(name, dispatcher); err != nil { |
| vlog.Fatalf("Serve(%q) failed: %v", name, err) |
| } |
| return func() { |
| if err := server.Stop(); err != nil { |
| vlog.Fatalf("Stop() failed: %v", err) |
| } |
| } |
| } |
| |
| // BINARY REPOSITORY INTERFACE IMPLEMENTATION |
| |
| func (*brInvoker) Create(ipc.ServerContext, int32) error { |
| vlog.VI(1).Infof("Create()") |
| return nil |
| } |
| |
| func (i *brInvoker) Delete(ipc.ServerContext) error { |
| vlog.VI(1).Infof("Delete()") |
| return nil |
| } |
| |
| var errOperationFailed = errors.New("operation failed") |
| |
| func (i *brInvoker) Download(_ ipc.ServerContext, _ int32, stream repository.BinaryServiceDownloadStream) error { |
| vlog.VI(1).Infof("Download()") |
| file, err := os.Open(os.Args[0]) |
| if err != nil { |
| vlog.Errorf("Open() failed: %v", err) |
| return errOperationFailed |
| } |
| defer file.Close() |
| bufferLength := 4096 |
| buffer := make([]byte, bufferLength) |
| sender := stream.SendStream() |
| for { |
| n, err := file.Read(buffer) |
| switch err { |
| case io.EOF: |
| return nil |
| case nil: |
| if err := sender.Send(buffer[:n]); err != nil { |
| vlog.Errorf("Send() failed: %v", err) |
| return errOperationFailed |
| } |
| default: |
| vlog.Errorf("Read() failed: %v", err) |
| return errOperationFailed |
| } |
| } |
| } |
| |
| func (*brInvoker) DownloadURL(ipc.ServerContext) (string, int64, error) { |
| vlog.VI(1).Infof("DownloadURL()") |
| return "", 0, nil |
| } |
| |
| func (*brInvoker) Stat(ipc.ServerContext) ([]binary.PartInfo, error) { |
| vlog.VI(1).Infof("Stat()") |
| h := md5.New() |
| bytes, err := ioutil.ReadFile(os.Args[0]) |
| if err != nil { |
| return []binary.PartInfo{}, errOperationFailed |
| } |
| h.Write(bytes) |
| part := binary.PartInfo{Checksum: hex.EncodeToString(h.Sum(nil)), Size: int64(len(bytes))} |
| return []binary.PartInfo{part}, nil |
| } |
| |
| func (i *brInvoker) Upload(ipc.ServerContext, int32, repository.BinaryServiceUploadStream) error { |
| vlog.VI(1).Infof("Upload()") |
| return nil |
| } |