Add tests for endpoint NewStream.
Rename OpenWithVidPid to OpenWithVIDPID.
This commit is contained in:
@@ -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 {
|
||||
|
81
usb/endpoint_stream_test.go
Normal file
81
usb/endpoint_stream_test.go
Normal 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")
|
||||
}
|
||||
}
|
@@ -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
141
usb/fakelibusb_devices.go
Normal 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,
|
||||
},
|
||||
},
|
||||
}},
|
||||
}},
|
||||
}},
|
||||
},
|
||||
}
|
@@ -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)
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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 {
|
||||
|
@@ -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()
|
||||
}
|
||||
|
Reference in New Issue
Block a user