Add tests for endpoint NewStream.

Rename OpenWithVidPid to OpenWithVIDPID.
This commit is contained in:
Sebastian Zagrodzki
2017-04-29 12:57:55 +02:00
parent 58c1e6ddb4
commit 730c32b9fd
9 changed files with 239 additions and 141 deletions

View File

@@ -34,13 +34,13 @@ func TestClaimAndRelease(t *testing.T) {
)
c := NewContext()
defer c.Close()
dev, err := c.OpenDeviceWithVidPid(0x8888, 0x0002)
dev, err := c.OpenDeviceWithVIDPID(0x8888, 0x0002)
if dev == nil {
t.Fatal("OpenDeviceWithVidPid(0x8888, 0x0002): got nil device, need non-nil")
t.Fatal("OpenDeviceWithVIDPID(0x8888, 0x0002): got nil device, need non-nil")
}
defer dev.Close()
if err != nil {
t.Fatalf("OpenDeviceWithVidPid(0x8888, 0x0002): %v", err)
t.Fatalf("OpenDeviceWithVIDPID(0x8888, 0x0002): %v", err)
}
cfg, err := dev.Config(cfgNum)
if err != nil {

View File

@@ -0,0 +1,81 @@
// Copyright 2017 the gousb Authors. 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 usb
import "testing"
func TestEndpointReadStream(t *testing.T) {
lib, done := newFakeLibusb()
defer done()
goodTransfers := 7
go func() {
var num int
for {
xfr := lib.waitForSubmitted()
if xfr == nil {
return
}
if num < goodTransfers {
xfr.status = TransferCompleted
xfr.length = len(xfr.buf)
} else {
xfr.status = TransferError
xfr.length = 0
}
xfr.done <- struct{}{}
num++
}
}()
ctx := NewContext()
dev, err := ctx.OpenDeviceWithVIDPID(0x9999, 0x0001)
if err != nil {
t.Fatalf("OpenDeviceWithVIDPID(9999, 0001): %v", err)
}
defer dev.Close()
cfg, err := dev.Config(1)
if err != nil {
t.Fatalf("%s.Config(1): %v", dev, err)
}
defer cfg.Close()
intf, err := cfg.Interface(0, 0)
if err != nil {
t.Fatalf("%s.Interface(0, 0): %v", cfg, err)
}
defer intf.Close()
ep, err := intf.InEndpoint(2)
if err != nil {
t.Fatalf("%s.Endpoint(2): %v", intf, err)
}
stream, err := ep.NewStream(1024, 5)
if err != nil {
t.Fatalf("%s.NewStream(1024, 5): %v", ep, err)
}
defer stream.Close()
var got int
want := goodTransfers * 1024
buf := make([]byte, 1024)
for got <= want {
num, err := stream.Read(buf)
if err != nil {
break
}
got += num
}
if got != want {
t.Errorf("%s.Read(): read %d bytes, want %d")
}
}

View File

@@ -163,9 +163,9 @@ func TestEndpointInOut(t *testing.T) {
ctx := NewContext()
defer ctx.Close()
d, err := ctx.OpenDeviceWithVidPid(0x9999, 0x0001)
d, err := ctx.OpenDeviceWithVIDPID(0x9999, 0x0001)
if err != nil {
t.Fatalf("OpenDeviceWithVidPid(0x9999, 0x0001): got error %v, want nil", err)
t.Fatalf("OpenDeviceWithVIDPID(0x9999, 0x0001): got error %v, want nil", err)
}
defer func() {
if err := d.Close(); err != nil {

141
usb/fakelibusb_devices.go Normal file
View File

@@ -0,0 +1,141 @@
// Copyright 2017 the gousb Authors. 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 usb
// fake devices connected through the fakeLibusb stack.
var fakeDevices = []*Descriptor{
// Bus 001 Device 001: ID 9999:0001
// One config, one interface, one setup,
// two endpoints: 0x01 OUT, 0x82 IN.
&Descriptor{
Bus: 1,
Address: 1,
Spec: Version(2, 0),
Device: Version(1, 0),
Vendor: ID(0x9999),
Product: ID(0x0001),
Protocol: 255,
Configs: map[int]ConfigInfo{1: {
Config: 1,
MaxPower: Milliamperes(100),
Interfaces: []InterfaceInfo{{
Number: 0,
AltSettings: []InterfaceSetting{{
Number: 0,
Alternate: 0,
Class: ClassVendorSpec,
Endpoints: map[int]EndpointInfo{
1: {
Number: 1,
Direction: EndpointDirectionOut,
MaxPacketSize: 512,
TransferType: TransferTypeBulk,
},
2: {
Number: 2,
Direction: EndpointDirectionIn,
MaxPacketSize: 512,
TransferType: TransferTypeBulk,
},
},
}},
}},
}},
},
// Bus 001 Device 002: ID 8888:0002
// One config, two interfaces. interface #0 with no endpoints,
// interface #1 with two alt setups with different packet sizes for
// endpoints. Two isochronous endpoints, 0x05 OUT and 0x86 OUT.
&Descriptor{
Bus: 1,
Address: 2,
Spec: Version(2, 0),
Device: Version(1, 3),
Vendor: ID(0x8888),
Product: ID(0x0002),
Protocol: 255,
Configs: map[int]ConfigInfo{1: {
Config: 1,
MaxPower: Milliamperes(100),
Interfaces: []InterfaceInfo{{
Number: 0,
AltSettings: []InterfaceSetting{{
Number: 0,
Alternate: 0,
Class: ClassVendorSpec,
}},
}, {
Number: 1,
AltSettings: []InterfaceSetting{{
Number: 1,
Alternate: 0,
Class: ClassVendorSpec,
Endpoints: map[int]EndpointInfo{
5: {
Number: 5,
Direction: EndpointDirectionOut,
MaxPacketSize: 3 * 1024,
TransferType: TransferTypeIsochronous,
UsageType: IsoUsageTypeData,
},
6: {
Number: 6,
Direction: EndpointDirectionIn,
MaxPacketSize: 3 * 1024,
TransferType: TransferTypeIsochronous,
UsageType: IsoUsageTypeData,
},
},
}, {
Number: 1,
Alternate: 1,
Class: ClassVendorSpec,
Endpoints: map[int]EndpointInfo{
5: {
Number: 5,
Direction: EndpointDirectionOut,
MaxPacketSize: 2 * 1024,
TransferType: TransferTypeIsochronous,
},
6: {
Number: 6,
Direction: EndpointDirectionIn,
MaxPacketSize: 2 * 1024,
TransferType: TransferTypeIsochronous,
},
},
}, {
Number: 1,
Alternate: 2,
Class: ClassVendorSpec,
Endpoints: map[int]EndpointInfo{
5: {
Number: 5,
Direction: EndpointDirectionIn,
MaxPacketSize: 1024,
TransferType: TransferTypeIsochronous,
},
6: {
Number: 6,
Direction: EndpointDirectionIn,
MaxPacketSize: 1024,
TransferType: TransferTypeIsochronous,
},
},
}},
}},
}},
},
}

View File

@@ -21,134 +21,6 @@ import (
"time"
)
var (
// fake devices connected through the fakeLibusb stack.
fakeDevices = []*Descriptor{
// Bus 001 Device 001: ID 9999:0001
// One config, one interface, one setup,
// two endpoints: 0x01 OUT, 0x82 IN.
&Descriptor{
Bus: 1,
Address: 1,
Spec: Version(2, 0),
Device: Version(1, 0),
Vendor: ID(0x9999),
Product: ID(0x0001),
Protocol: 255,
Configs: map[int]ConfigInfo{1: {
Config: 1,
MaxPower: Milliamperes(100),
Interfaces: []InterfaceInfo{{
Number: 0,
AltSettings: []InterfaceSetting{{
Number: 0,
Alternate: 0,
Class: ClassVendorSpec,
Endpoints: map[int]EndpointInfo{
1: {
Number: 1,
Direction: EndpointDirectionOut,
MaxPacketSize: 512,
TransferType: TransferTypeBulk,
},
2: {
Number: 2,
Direction: EndpointDirectionIn,
MaxPacketSize: 512,
TransferType: TransferTypeBulk,
},
},
}},
}},
}},
},
// Bus 001 Device 002: ID 8888:0002
// One config, two interfaces. interface #0 with no endpoints,
// interface #1 with two alt setups with different packet sizes for
// endpoints. Two isochronous endpoints, 0x05 OUT and 0x86 OUT.
&Descriptor{
Bus: 1,
Address: 2,
Spec: Version(2, 0),
Device: Version(1, 3),
Vendor: ID(0x8888),
Product: ID(0x0002),
Protocol: 255,
Configs: map[int]ConfigInfo{1: {
Config: 1,
MaxPower: Milliamperes(100),
Interfaces: []InterfaceInfo{{
Number: 0,
AltSettings: []InterfaceSetting{{
Number: 0,
Alternate: 0,
Class: ClassVendorSpec,
}},
}, {
Number: 1,
AltSettings: []InterfaceSetting{{
Number: 1,
Alternate: 0,
Class: ClassVendorSpec,
Endpoints: map[int]EndpointInfo{
5: {
Number: 5,
Direction: EndpointDirectionOut,
MaxPacketSize: 3 * 1024,
TransferType: TransferTypeIsochronous,
UsageType: IsoUsageTypeData,
},
6: {
Number: 6,
Direction: EndpointDirectionIn,
MaxPacketSize: 3 * 1024,
TransferType: TransferTypeIsochronous,
UsageType: IsoUsageTypeData,
},
},
}, {
Number: 1,
Alternate: 1,
Class: ClassVendorSpec,
Endpoints: map[int]EndpointInfo{
5: {
Number: 5,
Direction: EndpointDirectionOut,
MaxPacketSize: 2 * 1024,
TransferType: TransferTypeIsochronous,
},
6: {
Number: 6,
Direction: EndpointDirectionIn,
MaxPacketSize: 2 * 1024,
TransferType: TransferTypeIsochronous,
},
},
}, {
Number: 1,
Alternate: 2,
Class: ClassVendorSpec,
Endpoints: map[int]EndpointInfo{
5: {
Number: 5,
Direction: EndpointDirectionIn,
MaxPacketSize: 1024,
TransferType: TransferTypeIsochronous,
},
6: {
Number: 6,
Direction: EndpointDirectionIn,
MaxPacketSize: 1024,
TransferType: TransferTypeIsochronous,
},
},
}},
}},
}},
},
}
)
type fakeDevice struct {
desc *Descriptor
alt uint8
@@ -335,6 +207,7 @@ func newFakeLibusb() (*fakeLibusb, func() error) {
libusb = fl
return fl, func() error {
defer func() { libusb = origLibusb }()
close(fl.submitted)
if got := len(fl.ts); got > 0 {
for t := range fl.ts {
fl.free(t)

View File

@@ -120,6 +120,9 @@ func (r ReadStream) Read(p []byte) (int, error) {
// was encountered earlier.
// Close cannot be called concurrently with Read.
func (r ReadStream) Close() error {
if r.s.transfers == nil {
return nil
}
r.s.setDelayedErr(io.EOF)
return nil
}

View File

@@ -105,7 +105,7 @@ func (r readRes) String() string {
return buf.String()
}
func TestReadStream(t *testing.T) {
func TestTransferReadStream(t *testing.T) {
for tcNum, tc := range []struct {
desc string
closeBefore int

View File

@@ -76,13 +76,13 @@ func (c *Context) ListDevices(each func(desc *Descriptor) bool) ([]*Device, erro
return ret, reterr
}
// OpenDeviceWithVidPid opens Device from specific VendorId and ProductId.
// OpenDeviceWithVIDPID opens Device from specific VendorId and ProductId.
// If none is found, it returns nil and nil error. If there are multiple devices
// with the same VID/PID, it will return one of them, picked arbitrarily.
// If there were any errors during device list traversal, it is possible
// it will return a non-nil device and non-nil error. A Device.Close() must
// be called to release the device if the returned device wasn't nil.
func (c *Context) OpenDeviceWithVidPid(vid, pid ID) (*Device, error) {
func (c *Context) OpenDeviceWithVIDPID(vid, pid ID) (*Device, error) {
var found bool
devs, err := c.ListDevices(func(desc *Descriptor) bool {
if found {

View File

@@ -53,7 +53,7 @@ func TestListDevices(t *testing.T) {
}
}
func TestOpenDeviceWithVidPid(t *testing.T) {
func TestOpenDeviceWithVIDPID(t *testing.T) {
_, done := newFakeLibusb()
defer done()
@@ -69,16 +69,16 @@ func TestOpenDeviceWithVidPid(t *testing.T) {
} {
c := NewContext()
defer c.Close()
dev, err := c.OpenDeviceWithVidPid(d.vid, d.pid)
dev, err := c.OpenDeviceWithVIDPID(d.vid, d.pid)
if (dev != nil) != d.exists {
t.Errorf("OpenDeviceWithVidPid(%s/%s): device != nil is %v, want %v", ID(d.vid), ID(d.pid), dev != nil, d.exists)
t.Errorf("OpenDeviceWithVIDPID(%s/%s): device != nil is %v, want %v", ID(d.vid), ID(d.pid), dev != nil, d.exists)
}
if err != nil {
t.Errorf("OpenDeviceWithVidPid(%s/%s): got error %v, want nil", ID(d.vid), ID(d.pid), err)
t.Errorf("OpenDeviceWithVIDPID(%s/%s): got error %v, want nil", ID(d.vid), ID(d.pid), err)
}
if dev != nil {
if dev.Descriptor.Vendor != ID(d.vid) || dev.Descriptor.Product != ID(d.pid) {
t.Errorf("OpenDeviceWithVidPid(%s/%s): the device returned has VID/PID %s/%s, different from specified in the arguments", ID(d.vid), ID(d.pid), dev.Descriptor.Vendor, dev.Descriptor.Product)
t.Errorf("OpenDeviceWithVIDPID(%s/%s): the device returned has VID/PID %s/%s, different from specified in the arguments", ID(d.vid), ID(d.pid), dev.Descriptor.Vendor, dev.Descriptor.Product)
}
dev.Close()
}