blob: 9086e7ca7482c95398ec9326777c84f2f93b76d7 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//go:build !build_with_native_toolchain
package component_test
import (
"context"
"errors"
"syscall/zx"
"testing"
"go.fuchsia.dev/fuchsia/src/lib/component"
"fidl/fuchsia/io"
"github.com/google/go-cmp/cmp"
)
var _ component.Directory = (*mockDirImpl)(nil)
type mockDirImpl struct{}
func (*mockDirImpl) Get(string) (component.Node, bool) {
return nil, false
}
func (*mockDirImpl) ForEach(func(string, component.Node) error) error {
return nil
}
func TestHandleClosedOnOpenFailure(t *testing.T) {
dir := component.DirectoryWrapper{
Directory: &mockDirImpl{},
}
req, proxy, err := io.NewNodeWithCtxInterfaceRequest()
if err != nil {
t.Fatalf("io.NewNodeWithCtxInterfaceRequest() = %s", err)
}
defer func() {
if err := proxy.Channel.Close(); err != nil {
t.Fatalf("proxy.Channel.Close() = %s", err)
}
}()
if err := dir.GetDirectory().Open(context.Background(), 0, 0, "non-existing node", req); err != nil {
t.Fatalf("dir.GetDirecory.Open(...) = %s", err)
}
if status := zx.Sys_object_wait_one(*proxy.Channel.Handle(), zx.SignalChannelPeerClosed, 0, nil); status != zx.ErrOk {
t.Fatalf("zx.Sys_object_wait_one(_, zx.SignalChannelPeerClosed, 0, _) = %s", status)
}
}
var _ component.File = (*vmoFileImpl)(nil)
type vmoFileImpl struct {
vmo zx.VMO
}
var errUnimplemented = errors.New("unimplemented")
type vmoReader struct {
vmo zx.VMO
}
func (r *vmoReader) Read([]byte) (int, error) {
return 0, errUnimplemented
}
func (r *vmoReader) ReadAt([]byte, int64) (int, error) {
return 0, errUnimplemented
}
func (r *vmoReader) Seek(int64, int) (int64, error) {
return 0, errUnimplemented
}
func (r *vmoReader) Close() error {
return errUnimplemented
}
func (r *vmoReader) GetVMO() *zx.VMO {
return &r.vmo
}
func (i *vmoFileImpl) GetReader() (component.Reader, uint64, error) {
return &vmoReader{vmo: i.vmo}, 0, nil
}
func TestGetBackingMemory(t *testing.T) {
content := []byte{
1, 2, 3, 4, 5, 6,
}
vmo, err := zx.NewVMO(uint64(len(content)), 0)
if err != nil {
t.Fatalf("zx.NewVMO() = %s", err)
}
t.Cleanup(func() {
if err := vmo.Close(); err != nil {
t.Error(err)
}
})
if err := vmo.Write(content, 0); err != nil {
t.Fatalf("vmo.Write() = %s", err)
}
impl := vmoFileImpl{
vmo: vmo,
}
file := component.FileWrapper{
File: &impl,
}
f, err := file.GetFile()
if err != nil {
t.Fatalf("file.GetFile() = %s", err)
}
result, err := f.GetBackingMemory(context.Background(), 0)
if err != nil {
t.Fatalf("f.GetBackingMemory() = %s", err)
}
switch w := result.Which(); w {
case io.FileGetBackingMemoryResultErr:
t.Fatalf("file.GetBackingMemory() = %s", zx.Status(result.Err))
case io.FileGetBackingMemoryResultResponse:
vmo := result.Response.Vmo
b := make([]byte, len(content))
if err := vmo.Read(b, 0); err != nil {
t.Fatalf("vmo.Read() = %s", err)
}
if diff := cmp.Diff(b, content); diff != "" {
t.Errorf("vmo.Read() mismatch (-want +got):\n%s", diff)
}
default:
t.Fatalf("file.GetBackingMemory().Which() = %d", w)
}
}