libusb 0.7.0-x64-mingw-ucrt

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.appveyor.yml +33 -0
  3. data/.github/workflows/ci.yml +185 -0
  4. data/.gitignore +9 -0
  5. data/.travis.yml +26 -0
  6. data/.yardopts +6 -0
  7. data/COPYING +165 -0
  8. data/Gemfile +19 -0
  9. data/History.md +193 -0
  10. data/README.md +184 -0
  11. data/Rakefile +79 -0
  12. data/lib/libusb/bos.rb +362 -0
  13. data/lib/libusb/call.rb +622 -0
  14. data/lib/libusb/compat.rb +376 -0
  15. data/lib/libusb/configuration.rb +154 -0
  16. data/lib/libusb/constants.rb +170 -0
  17. data/lib/libusb/context.rb +576 -0
  18. data/lib/libusb/context_reference.rb +38 -0
  19. data/lib/libusb/dependencies.rb +7 -0
  20. data/lib/libusb/dev_handle.rb +574 -0
  21. data/lib/libusb/device.rb +407 -0
  22. data/lib/libusb/endpoint.rb +195 -0
  23. data/lib/libusb/eventmachine.rb +187 -0
  24. data/lib/libusb/gem_helper.rb +151 -0
  25. data/lib/libusb/interface.rb +60 -0
  26. data/lib/libusb/libusb_recipe.rb +29 -0
  27. data/lib/libusb/setting.rb +132 -0
  28. data/lib/libusb/ss_companion.rb +72 -0
  29. data/lib/libusb/stdio.rb +25 -0
  30. data/lib/libusb/transfer.rb +418 -0
  31. data/lib/libusb/version_gem.rb +19 -0
  32. data/lib/libusb/version_struct.rb +63 -0
  33. data/lib/libusb-1.0.dll +0 -0
  34. data/lib/libusb.rb +146 -0
  35. data/libusb.gemspec +28 -0
  36. data/test/test_libusb.rb +42 -0
  37. data/test/test_libusb_bos.rb +140 -0
  38. data/test/test_libusb_bulk_stream_transfer.rb +61 -0
  39. data/test/test_libusb_compat.rb +78 -0
  40. data/test/test_libusb_compat_mass_storage.rb +81 -0
  41. data/test/test_libusb_context.rb +88 -0
  42. data/test/test_libusb_descriptors.rb +245 -0
  43. data/test/test_libusb_event_machine.rb +118 -0
  44. data/test/test_libusb_gc.rb +52 -0
  45. data/test/test_libusb_hotplug.rb +129 -0
  46. data/test/test_libusb_iso_transfer.rb +56 -0
  47. data/test/test_libusb_mass_storage.rb +268 -0
  48. data/test/test_libusb_mass_storage2.rb +96 -0
  49. data/test/test_libusb_structs.rb +87 -0
  50. data/test/test_libusb_threads.rb +89 -0
  51. data/wireshark-usb-sniffer.png +0 -0
  52. metadata +112 -0
@@ -0,0 +1,42 @@
1
+ # This file is part of Libusb for Ruby.
2
+ #
3
+ # Libusb for Ruby is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Lesser General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # Libusb for Ruby is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public License
14
+ # along with Libusb for Ruby. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "minitest/autorun"
17
+ require "libusb"
18
+
19
+ class TestLibusb < Minitest::Test
20
+ def test_has_capability
21
+ assert LIBUSB.has_capability?(:CAP_HAS_CAPABILITY)
22
+ end
23
+
24
+ def test_version_parts
25
+ v = LIBUSB.version
26
+ assert_operator v.major, :>=, 0
27
+ assert_operator v.minor, :>=, 0
28
+ assert_operator v.micro, :>=, 0
29
+ assert_operator v.nano, :>=, 0
30
+ assert_kind_of String, v.rc
31
+ end
32
+
33
+ def test_version_string
34
+ v = LIBUSB.version
35
+ assert_match(/^\d+\.\d+\.\d+/, v.to_s)
36
+ assert_match(/^#<LIBUSB::Version \d+\.\d+\.\d+/, v.inspect)
37
+ end
38
+
39
+ def test_gem_version_string
40
+ assert_match(/^\d+\.\d+\.\d+/, LIBUSB::VERSION)
41
+ end
42
+ end
@@ -0,0 +1,140 @@
1
+ # This file is part of Libusb for Ruby.
2
+ #
3
+ # Libusb for Ruby is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Lesser General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # Libusb for Ruby is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public License
14
+ # along with Libusb for Ruby. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "minitest/autorun"
17
+ require "libusb"
18
+
19
+ class TestLibusbBos < Minitest::Test
20
+ include LIBUSB
21
+
22
+ attr_accessor :usb
23
+
24
+ def setup
25
+ @usb = Context.new
26
+ @usb.debug = 0
27
+ end
28
+
29
+ def test_bos
30
+ did_bos = false
31
+ did_cap = false
32
+ usb.devices.each do |dev|
33
+ # devices with USB version >= 0x201 could support bos
34
+ # devices with USB version >= 0x210 must support bos
35
+ if dev.bcdUSB >= 0x210
36
+ dev.open do |devh|
37
+ bos = devh.bos
38
+ did_bos = true
39
+
40
+ assert_equal 5, bos.bLength
41
+ assert_equal 0x0f, bos.bDescriptorType
42
+ assert_operator 5, :<=, bos.wTotalLength
43
+ assert_operator 0, :<=, bos.bNumDeviceCaps
44
+
45
+ caps = bos.device_capabilities
46
+ assert_equal bos.bNumDeviceCaps, caps.length
47
+ cap_types = bos.device_capability_types
48
+ assert_equal bos.bNumDeviceCaps, cap_types.length
49
+
50
+ cap_types.each do |cap_type|
51
+ assert_operator [
52
+ :BT_WIRELESS_USB_DEVICE_CAPABILITY,
53
+ :BT_USB_2_0_EXTENSION,
54
+ :BT_SS_USB_DEVICE_CAPABILITY,
55
+ :BT_CONTAINER_ID,
56
+ :BT_WIRELESS_USB_DEVICE_CAPABILITY,
57
+ :BT_USB_2_0_EXTENSION,
58
+ :BT_SS_USB_DEVICE_CAPABILITY,
59
+ :BT_CONTAINER_ID,
60
+ :BT_PLATFORM_DESCRIPTOR,
61
+ :BT_POWER_DELIVERY_CAPABILITY,
62
+ :BT_BATTERY_INFO_CAPABILITY,
63
+ :BT_PD_CONSUMER_PORT_CAPABILITY,
64
+ :BT_PD_PROVIDER_PORT_CAPABILITY,
65
+ :BT_SUPERSPEED_PLUS,
66
+ :BT_PRECISION_TIME_MEASUREMENT,
67
+ :BT_Wireless_USB_Ext,
68
+ :BT_BILLBOARD,
69
+ :BT_AUTHENTICATION,
70
+ :BT_BILLBOARD_EX,
71
+ :BT_CONFIGURATION_SUMMARY,
72
+ :BT_FWStatus_Capability,
73
+ ], :include?, cap_type
74
+ end
75
+
76
+
77
+ caps.each do |cap|
78
+ did_cap = true
79
+
80
+ assert_operator 4, :<=, cap.bLength
81
+ assert_equal LIBUSB::DT_DEVICE_CAPABILITY, cap.bDescriptorType
82
+ assert_kind_of String, cap.dev_capability_data, "should provide binary capability data"
83
+ assert_kind_of String, cap.inspect, "should respond to inspect"
84
+ assert_operator 1, :<=, cap.dev_capability_data.length, "dev_capability_data should be at least one byte"
85
+
86
+ case cap
87
+ when Bos::DeviceCapability
88
+ assert_kind_of Integer, cap.bDevCapabilityType
89
+
90
+ when Bos::Usb20Extension
91
+ assert_equal 2, cap.bDevCapabilityType
92
+ assert_operator 0, :<=, cap.bmAttributes
93
+ assert_operator [true, false], :include?, cap.bm_lpm_support?
94
+
95
+ when Bos::SsUsbDeviceCapability
96
+ assert_equal 3, cap.bDevCapabilityType
97
+ assert_operator 0, :<=, cap.bmAttributes
98
+ assert_operator [true, false], :include?, cap.bm_ltm_support?
99
+ assert_operator 0, :<=, cap.wSpeedSupported
100
+ assert_kind_of Array, cap.supported_speeds
101
+ assert_operator 0, :<=, cap.bFunctionalitySupport
102
+ assert_operator 0, :<=, cap.bU1DevExitLat
103
+ assert_operator 0, :<=, cap.bU2DevExitLat
104
+
105
+ when Bos::ContainerId
106
+ assert_equal 4, cap.bDevCapabilityType
107
+ assert_operator 0, :<=, cap.bReserved
108
+ assert_operator 16, :==, cap.container_id.bytesize, "container_id should be 16 bytes long"
109
+
110
+ when Bos::PlatformDescriptor
111
+ assert_operator 0, :<=, cap.bReserved
112
+ assert_operator 16, :==, cap.platformCapabilityUUID.bytesize, "container_id should be 16 bytes long"
113
+ assert_kind_of String, cap.capabilityData
114
+
115
+ else
116
+ refute true, "invalid device capability class"
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+ skip "no device with BOS available" unless did_bos
123
+ skip "no device with BOS capability available" unless did_cap
124
+ end
125
+
126
+ def test_no_bos
127
+ did_failing_bos = false
128
+
129
+ # devices with USB version < 0x201 shouldn't support bos
130
+ if dev=usb.devices.find{|dev| dev.bcdUSB < 0x201 }
131
+ dev.open do |devh|
132
+ assert_raises LIBUSB::ERROR_PIPE do
133
+ devh.bos
134
+ end
135
+ did_failing_bos = true
136
+ end
137
+ end
138
+ skip "no device without BOS available" unless did_failing_bos
139
+ end
140
+ end
@@ -0,0 +1,61 @@
1
+ # This file is part of Libusb for Ruby.
2
+ #
3
+ # Libusb for Ruby is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Lesser General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # Libusb for Ruby is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public License
14
+ # along with Libusb for Ruby. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "minitest/autorun"
17
+ require "libusb"
18
+
19
+ class TestLibusbBulkStreamTransfer < Minitest::Test
20
+ include LIBUSB
21
+
22
+ def setup
23
+ c = Context.new
24
+ c.devices.each do |dev|
25
+ if [:SPEED_SUPER, :SPEED_SUPER_PLUS].include?(dev.device_speed)
26
+ dev.endpoints.each do |ep|
27
+ if ep.transfer_type == :bulk
28
+ ss = ep.ss_companion
29
+ if ss.bmAttributes & 0x1f > 0
30
+ @dev = dev.open
31
+ break
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ def teardown
40
+ @dev.close if @dev
41
+ end
42
+
43
+ def test_alloc_streams
44
+ skip "no device found with bulk stream support" unless @dev
45
+
46
+ nr_allocated = @dev.alloc_streams( 2, @dev.device.endpoints )
47
+ assert_equal 2, nr_allocated
48
+
49
+ # TODO: test with a OS that supports bulk streams and against a real device
50
+
51
+ @dev.free_streams( [0x01,0x82] )
52
+ end
53
+
54
+ def test_bulk_stream_transfer
55
+ c = Context.new
56
+ dev = c.devices.first.open
57
+ tr = BulkStreamTransfer.new dev_handle: dev, stream_id: 123, buffer: ' '*100
58
+ assert_equal 123, tr.stream_id, "stream_id should match"
59
+ dev.close
60
+ end
61
+ end
@@ -0,0 +1,78 @@
1
+ # This file is part of Libusb for Ruby.
2
+ #
3
+ # Libusb for Ruby is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Lesser General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # Libusb for Ruby is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public License
14
+ # along with Libusb for Ruby. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "minitest/autorun"
17
+ require "libusb/compat"
18
+
19
+ class TestLibusbCompat < Minitest::Test
20
+ include USB
21
+
22
+ attr_accessor :usb
23
+
24
+ def test_find
25
+ devlist = USB.devices
26
+ assert_kind_of Array, devlist, "Bus#find should return an Array"
27
+ assert_kind_of Device, devlist.first, "Bus#find should return Devices"
28
+ devlist.each do |dev|
29
+ assert_match( /Device/, dev.inspect, "Device#inspect should work")
30
+ end
31
+ end
32
+
33
+ def test_constants
34
+ assert_equal 7, USB_CLASS_PRINTER, "Printer class id should be defined"
35
+ assert_equal 32, USB_TYPE_CLASS, "type class should be defined"
36
+ end
37
+
38
+ def test_descriptors
39
+ USB.devices.each do |dev|
40
+ assert_match(/Device/, dev.inspect, "Device#inspect should work")
41
+ dev.configurations.each do |config_desc|
42
+ assert_match(/Configuration/, config_desc.inspect, "Configuration#inspect should work")
43
+ assert dev.configurations.include?(config_desc), "Device#configurations should include this one"
44
+
45
+ config_desc.interfaces.each do |interface|
46
+ assert_match(/Interface/, interface.inspect, "Interface#inspect should work")
47
+
48
+ assert dev.interfaces.include?(interface), "Device#interfaces should include this one"
49
+ assert config_desc.interfaces.include?(interface), "Configuration#interfaces should include this one"
50
+
51
+ interface.settings.each do |if_desc|
52
+ assert_match(/Setting/, if_desc.inspect, "Setting#inspect should work")
53
+
54
+ assert dev.settings.include?(if_desc), "Device#settings should include this one"
55
+ assert config_desc.settings.include?(if_desc), "Configuration#settings should include this one"
56
+ assert interface.settings.include?(if_desc), "Interface#settings should include this one"
57
+
58
+ if_desc.endpoints.each do |ep|
59
+ assert_match(/Endpoint/, ep.inspect, "Endpoint#inspect should work")
60
+
61
+ assert dev.endpoints.include?(ep), "Device#endpoints should include this one"
62
+ assert config_desc.endpoints.include?(ep), "Configuration#endpoints should include this one"
63
+ assert interface.endpoints.include?(ep), "Interface#endpoints should include this one"
64
+ assert if_desc.endpoints.include?(ep), "Setting#endpoints should include this one"
65
+
66
+ assert_equal if_desc, ep.setting, "backref should be correct"
67
+ assert_equal interface, ep.interface, "backref should be correct"
68
+ assert_equal config_desc, ep.configuration, "backref should be correct"
69
+ assert_equal dev, ep.device, "backref should be correct"
70
+
71
+ assert_operator 0, :<=, ep.wMaxPacketSize, "packet size should be > 0"
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,81 @@
1
+ # This file is part of Libusb for Ruby.
2
+ #
3
+ # Libusb for Ruby is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Lesser General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # Libusb for Ruby is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public License
14
+ # along with Libusb for Ruby. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "minitest/autorun"
17
+ require "libusb/compat"
18
+
19
+ class TestLibusbCompatMassStorage < Minitest::Test
20
+ include USB
21
+
22
+ attr_accessor :devh
23
+
24
+ BOMS_RESET = 0xFF
25
+ BOMS_GET_MAX_LUN = 0xFE
26
+
27
+ def setup
28
+ devs = []
29
+ USB.each_device_by_class(USB_CLASS_MASS_STORAGE, 0x01, 0x50){|dev| devs << dev }
30
+ USB.each_device_by_class(USB_CLASS_MASS_STORAGE, 0x06, 0x50){|dev| devs << dev }
31
+
32
+ dev = devs.last
33
+ skip "no mass storage device found" unless dev
34
+ devh = dev.open
35
+ if RUBY_PLATFORM=~/linux/i
36
+ data = " "*1000
37
+ begin
38
+ devh.usb_get_driver_np 0, data
39
+ rescue Errno::ENODATA
40
+ data = "nodata exception".ljust(1000, "\0")
41
+ end
42
+ assert_match(/\w+/, data, "There should be a driver or an exception")
43
+ begin
44
+ # second param is needed because of a bug in ruby-usb
45
+ devh.usb_detach_kernel_driver_np 0, 123
46
+ rescue RuntimeError => e
47
+ assert_match(/ERROR_NOT_FOUND/, e.to_s, "Raise proper exception, if no kernel driver is active")
48
+ end
49
+ end
50
+
51
+ endpoint_in = dev.endpoints.find{|ep| ep.bEndpointAddress&USB_ENDPOINT_IN != 0 }
52
+ endpoint_out = dev.endpoints.find{|ep| ep.bEndpointAddress&USB_ENDPOINT_IN == 0 }
53
+
54
+ devh.set_configuration 1
55
+ devh.set_configuration dev.configurations.first
56
+ devh.claim_interface dev.settings.first
57
+ devh.clear_halt(endpoint_in)
58
+ devh.clear_halt(endpoint_out.bEndpointAddress)
59
+ @devh = devh
60
+ end
61
+
62
+ def teardown
63
+ if devh
64
+ devh.release_interface 0
65
+ devh.usb_close
66
+ end
67
+ end
68
+
69
+ def test_mass_storage_reset
70
+ res = devh.usb_control_msg(USB_ENDPOINT_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE,
71
+ BOMS_RESET, 0, 0, "", 2000)
72
+ assert_equal 0, res, "BOMS_RESET response should be 0 byte"
73
+ end
74
+
75
+ def test_read_max_lun
76
+ bytes = [].pack('x1')
77
+ devh.usb_control_msg(USB_ENDPOINT_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE,
78
+ BOMS_GET_MAX_LUN, 0, 0, bytes, 100)
79
+ assert [0].pack("C")==bytes || [1].pack("C")==bytes, "BOMS_GET_MAX_LUN response is usually 0 or 1"
80
+ end
81
+ end
@@ -0,0 +1,88 @@
1
+ # This file is part of Libusb for Ruby.
2
+ #
3
+ # Libusb for Ruby is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Lesser General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # Libusb for Ruby is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public License
14
+ # along with Libusb for Ruby. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "minitest/autorun"
17
+ require "libusb"
18
+
19
+ class TestLibusbContext < Minitest::Test
20
+ def setup
21
+ @c = LIBUSB::Context.new
22
+ end
23
+
24
+ def teardown
25
+ @c.exit if @c
26
+ end
27
+
28
+ def test_set_option
29
+ @c.set_option LIBUSB::OPTION_LOG_LEVEL, LIBUSB::LOG_LEVEL_NONE
30
+ @c.set_option LIBUSB::OPTION_LOG_LEVEL, LIBUSB::LOG_LEVEL_ERROR
31
+ @c.set_option LIBUSB::OPTION_LOG_LEVEL, LIBUSB::LOG_LEVEL_WARNING
32
+ @c.set_option LIBUSB::OPTION_LOG_LEVEL, LIBUSB::LOG_LEVEL_INFO
33
+ @c.set_option LIBUSB::OPTION_LOG_LEVEL, LIBUSB::LOG_LEVEL_DEBUG
34
+ @c.set_option :OPTION_LOG_LEVEL, :LOG_LEVEL_NONE
35
+ end
36
+
37
+ def test_set_debug
38
+ @c.debug = 4
39
+ @c.debug = 0
40
+ end
41
+
42
+ def test_left_references
43
+ @test_devs = @c.devices
44
+ assert_raises(LIBUSB::RemainingReferencesError) do
45
+ @c.exit
46
+ end
47
+ @c = nil
48
+ end
49
+
50
+ def test_double_exit
51
+ @c.exit
52
+ end
53
+
54
+ def test_log_callback
55
+ skip "only supported on Linux" unless RUBY_PLATFORM=~/linux/
56
+ skip "libusb version older than 1.0.27" if Gem::Version.new(LIBUSB.version) < Gem::Version.new("1.0.27")
57
+
58
+ LIBUSB.set_options OPTION_LOG_CB: [nil], OPTION_LOG_LEVEL: LIBUSB::LOG_LEVEL_NONE
59
+ begin
60
+ called = Hash.new { |h, k| h[k] = [] }
61
+ LIBUSB.set_options OPTION_LOG_CB: proc{|*a| called[:global] << a }, OPTION_LOG_LEVEL: LIBUSB::LOG_LEVEL_DEBUG
62
+
63
+ c = LIBUSB::Context.new OPTION_LOG_CB: proc{|*a| called[:ctx1] << a }, OPTION_NO_DEVICE_DISCOVERY: nil
64
+ c.devices
65
+ c.set_log_cb(LIBUSB::LOG_CB_CONTEXT){|*a| called[:ctx2] << a }
66
+ c.devices
67
+
68
+ #pp called
69
+ assert_nil called[:global][0][0]
70
+ assert_equal :LOG_LEVEL_DEBUG, called[:global][0][1], called[:global][0][2]
71
+ assert_match(/libusb_init_context/, called[:global].join)
72
+ assert_match(/no device discovery/, called[:global].join)
73
+
74
+ assert_operator called[:ctx1].size, :>, called[:ctx2].size
75
+ assert_equal c, called[:ctx1][-1][0]
76
+ assert_equal :LOG_LEVEL_DEBUG, called[:ctx1][-1][1]
77
+ assert_match(/libusb_get_device_list/, called[:ctx1][-1][2])
78
+ assert_match(/no device discovery/, called[:ctx1].join)
79
+
80
+ assert_equal c, called[:ctx2][-1][0]
81
+ assert_equal :LOG_LEVEL_DEBUG, called[:ctx2][-1][1]
82
+ assert_match(/libusb_get_device_list/, called[:ctx2][-1][2])
83
+
84
+ ensure
85
+ LIBUSB.set_options OPTION_LOG_CB: [nil], OPTION_LOG_LEVEL: LIBUSB::LOG_LEVEL_NONE
86
+ end
87
+ end
88
+ end