1 #include "../../include/sane/config.h"
2 
3 #include <errno.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <unistd.h>
8 #include <math.h>
9 #include <stddef.h>
10 #ifdef HAVE_SYS_TIME_H
11 #include <sys/time.h>
12 #endif
13 #ifdef HAVE_SYS_TYPES_H
14 #include <sys/types.h>
15 #endif
16 #ifdef HAVE_MKDIR
17 #include <sys/stat.h>
18 #include <sys/types.h>
19 #endif
20 
21 #include <assert.h>
22 
23 #define BACKEND_NAME	sanei_usb
24 
25 #include "../../include/sane/sane.h"
26 #include "../../include/sane/sanei.h"
27 #include "../../include/sane/saneopts.h"
28 
29 #include "../../include/sane/sanei_backend.h"
30 #include "../../include/sane/sanei_usb.h"
31 
32 #include "../../include/_stdint.h"
33 
34 /*
35  * In order to avoid modifying sanei_usb.c to allow for unit tests
36  * we include it so we can use its private variables and structures
37  * and still test the code.
38  */
39 #include "../../sanei/sanei_usb.c"
40 
41 
42 /** test sanei_usb_init()
43  * calls sanei_usb_init
44  * @param expected expected use count
45  * @return 1 on success, else 0
46  */
47 static int
test_init(int expected)48 test_init (int expected)
49 {
50   /* initialize USB */
51   printf ("%s starting ...\n", __func__);
52   sanei_usb_init ();
53   if (initialized == 0)
54     {
55       printf ("ERROR: sanei_usb not initialized!\n");
56       return 0;
57     }
58   if (initialized != expected)
59     {
60       printf ("ERROR: incorrect use count, expected %d, got %d!\n", expected,
61 	      initialized);
62       return 0;
63     }
64 
65   printf ("sanei_usb initialized, use count is %d ...\n", initialized);
66   printf ("%s success\n\n", __func__);
67   return 1;
68 }
69 
70 /** test sanei_usb_exit()
71  * calls sanei_usb_exit
72  * @param expected use count after exit call
73  * @return 1 on success, else 0
74  */
75 static int
test_exit(int expected)76 test_exit (int expected)
77 {
78   printf ("%s starting ...\n", __func__);
79 
80   /* end of USB use test */
81   sanei_usb_exit ();
82   if (initialized != expected)
83     {
84       printf ("ERROR: incorrect use count, expected %d, got %d!\n", expected,
85 	      initialized);
86       return 0;
87     }
88 
89   printf ("%s success\n\n", __func__);
90   return 1;
91 }
92 
93 
94 /** count detected devices
95  * count all detected devices and check it against expected value
96  * @param expected detected count
97  * @return 1 on success, else 0
98  */
99 static int
count_detected(int expected)100 count_detected (int expected)
101 {
102   int num = 0;
103   int i;
104 
105   for (i = 0; i < device_number; i++)
106     {
107       if (devices[i].missing == 0 && devices[i].devname != NULL)
108 	{
109 	  num++;
110 	}
111     }
112   if (num != expected)
113     {
114       printf ("ERROR: %d detected devices, expected %d!\n", num, expected);
115       return 0;
116     }
117   printf ("%d devices still detected.\n", num);
118   return 1;
119 }
120 
121 /** create mock device
122  * create a mock device entry
123  * @param device device pointer to fill with mock data
124  * @return nothing
125  */
126 static void
create_mock_device(char *devname, device_list_type * device)127 create_mock_device (char *devname, device_list_type * device)
128 {
129   memset (device, 0, sizeof (device_list_type));
130   device->devname = strdup (devname);
131   device->vendor = 0xdead;
132   device->product = 0xbeef;
133 #if defined(HAVE_LIBUSB_LEGACY) || defined(HAVE_LIBUSB)
134   device->method = sanei_usb_method_libusb;
135 #endif
136 #ifdef HAVE_USBCALLS
137   device->method = sanei_usb_method_usbcalls;
138 #endif
139 #if !defined(HAVE_LIBUSB_LEGACY) && !defined(HAVE_LIBUSB) && !defined(HAVE_USBCALLS)
140   device->method == sanei_usb_method_scanner_driver;
141 #endif
142 }
143 
144 /** test store_device
145  * test store_device for corner cases not covered by the
146  * other regular use by sanei_usb_scan_devices
147  * the startiing situation is that the mock device has never
148  * put into device list.
149  * @return 1 on success, else 0
150  */
151 static int
test_store_device(void)152 test_store_device (void)
153 {
154   int current_number;
155   int expected;
156   int i;
157   int found;
158   device_list_type mock;
159 
160   create_mock_device ("mock", &mock);
161 
162   /* first test store when there is no more room
163    * to store device */
164   current_number = device_number;
165   device_number = MAX_DEVICES;
166   /* give unused devices a name so strcmp() won't crash. */
167   for (i = current_number; i < MAX_DEVICES; i++)
168     devices[i].devname = "";
169 
170   store_device (mock);
171   /* there should be no more devices */
172   if (device_number > MAX_DEVICES)
173     {
174       printf ("ERROR: store past end of device list!\n");
175       return 0;
176     }
177   /* walk device list to be sure mock device hasn't been stored */
178   for (i = 0; i < MAX_DEVICES; i++)
179     {
180       if (devices[i].devname && !strcmp (devices[i].devname, mock.devname))
181 	{
182 	  printf
183 	    ("ERROR: device stored although there were no place for it!\n");
184 	  return 0;
185 	}
186     }
187 
188   /* restore device_number */
189   device_number = current_number;
190   /* reset unused devnames to NULL */
191   for (i = current_number; i < MAX_DEVICES; i++)
192     devices[i].devname = NULL;
193   expected = device_number + 1;
194 
195   /* store mock device */
196   store_device (mock);
197   found = 0;
198   for (i = 0; i < MAX_DEVICES && !found; i++)
199     {
200       if (devices[i].devname && !strcmp (devices[i].devname, mock.devname))
201 	{
202 	  found = 1;
203 	}
204     }
205   if (device_number != expected || !found)
206     {
207       printf ("ERROR: mock device not stored !\n");
208       return 0;
209     }
210 
211   /* scan devices should mark it as missing, and device_number should decrease */
212   sanei_usb_scan_devices ();
213   found = 0;
214   for (i = 0; i < MAX_DEVICES && !found; i++)
215     {
216       if (devices[i].devname
217 	  && devices[i].missing == 1
218 	  && !strcmp (devices[i].devname, mock.devname))
219 	{
220 	  found = 1;
221 	}
222     }
223   if (device_number != expected || !found)
224     {
225       printf ("ERROR: mock device still present !\n");
226       return 0;
227     }
228 
229   /* second scan devices should mark missing to 2 */
230   sanei_usb_scan_devices ();
231   found = 0;
232   for (i = 0; i < MAX_DEVICES && !found; i++)
233     {
234       if (devices[i].devname
235 	  && devices[i].missing == 2
236 	  && !strcmp (devices[i].devname, mock.devname))
237 	{
238 	  found = 1;
239 	}
240     }
241   if (device_number != expected || !found)
242     {
243       printf ("ERROR: mock device slot not reusable !\n");
244       return 0;
245     }
246 
247   /* store mock device again, slot in devices should be reused
248    * and device_number shouldn't change */
249   create_mock_device ("mock2", &mock);
250   store_device (mock);
251   found = 0;
252   for (i = 0; i < MAX_DEVICES && !found; i++)
253     {
254       if (devices[i].devname && !strcmp (devices[i].devname, mock.devname))
255 	{
256 	  found = 1;
257 	}
258     }
259   if (device_number != expected || !found)
260     {
261       printf ("ERROR: mock device not stored !\n");
262       return 0;
263     }
264 
265   /* last rescan to wipe mock device out */
266   sanei_usb_scan_devices ();
267 
268   return 1;
269 }
270 
271 /** return count of opened devices
272  * @return count of opened devices
273  */
274 static int
get_opened(void)275 get_opened (void)
276 {
277   int num = 0;
278   int i;
279 
280   for (i = 0; i < device_number; i++)
281     {
282       if (devices[i].missing == 0 && devices[i].devname != NULL
283 	  && devices[i].open == SANE_TRUE)
284 	{
285 	  num++;
286 	}
287     }
288   return num;
289 }
290 
291 /** count opened devices
292  * count all opended devices and check it against expected value
293  * @param expected use opened count
294  * @return 1 on success, else 0
295  */
296 static int
count_opened(int expected)297 count_opened (int expected)
298 {
299   int num = get_opened();
300 
301   if (num != expected)
302     {
303       printf ("ERROR: %d opened devices, expected %d!\n", num, expected);
304       return 0;
305     }
306   printf ("%d devices still opened.\n", num);
307   return 1;
308 }
309 
310 /** open all devices
311  * loop on all existing devices and open them
312  * @param dn array to store opened device number
313  * @param expected number of devices to be opened
314  * @return 1 on success, else 0
315  */
316 static int
test_open_all(SANE_Int * dn, int expected)317 test_open_all (SANE_Int * dn, int expected)
318 {
319   int opened = 0;
320   int i;
321   int last;
322   SANE_Status status;
323 
324   /* loop on detected devices and open them */
325   last = -1;
326   for (i = 0; i < device_number; i++)
327     {
328       if (devices[i].missing == 0 && devices[i].devname != NULL)
329 	{
330 	  /* open device */
331 	  status = sanei_usb_open (devices[i].devname, dn + opened);
332 	  if (status == SANE_STATUS_GOOD)
333 	    {
334 	      opened++;
335 	      last = i;
336 	    }
337 	  else
338 	    {
339               if (status == SANE_STATUS_ACCESS_DENIED ||
340                   status == SANE_STATUS_DEVICE_BUSY)
341                 {
342                   expected--;
343                 }
344               else
345                 {
346 	          printf ("ERROR: couldn't open device %s!\n",
347                           devices[i].devname);
348 	          return 0;
349                 }
350 	    }
351 	}
352     }
353   printf ("opened %d devices\n", opened);
354 
355   /* try to reopen an opened device when there is one */
356   if (last >= 0)
357     {
358       status = sanei_usb_open (devices[last].devname, dn + opened);
359       if (status == SANE_STATUS_GOOD)
360 	{
361 	  printf ("ERROR: unexpected success when opening %s twice!\n",
362 		  devices[last].devname);
363 	  return 0;
364 	}
365     }
366 
367   /* there should be as many opened devices than detected devices */
368   return count_opened (expected);
369 }
370 
371 /** test opening invalid device
372  * try to open an non existing device
373  * @return 1 on success, else 0
374  */
375 static int
test_open_invalid(void)376 test_open_invalid (void)
377 {
378   SANE_Status status;
379   SANE_Int dn;
380 
381   status = sanei_usb_open ("invalid device", &dn);
382   if (status == SANE_STATUS_GOOD)
383     {
384       printf ("ERROR: unexpected success opening invalid device!\n");
385       return 0;
386     }
387   return 1;
388 }
389 
390 /** close all devices
391  * loop on all opened devices and close them
392  * @param dn array of opened device number
393  * @param expected number of devices to be closed
394  * @return 1 on success, else 0
395  */
396 static int
test_close_all(SANE_Int * dn, int expected)397 test_close_all (SANE_Int * dn, int expected)
398 {
399   int closed = 0;
400   int i;
401 
402   /* loop on detected devices and open them */
403   for (i = 0; i < expected; i++)
404     {
405       /* close device */
406       sanei_usb_close (dn[i]);
407       closed++;
408     }
409   printf ("closed %d devices\n", closed);
410 
411   /* there should be any more opened devices */
412   return count_opened (0);
413 }
414 
415 
416 /** claim all open devices
417  * loop on all opened devices and claim interface 0
418  * @param dn array of opened device number
419  * @param expected number of devices to be claimed
420  * @return 1 on success, else 0
421  */
422 static int
test_claim_all(SANE_Int * dn, int expected)423 test_claim_all (SANE_Int * dn, int expected)
424 {
425   int claimed = 0;
426   int i;
427   SANE_Status status;
428   device_list_type mock;
429 
430   claimed = 0;
431   for (i = 0; i < expected; i++)
432     {
433       status = sanei_usb_claim_interface (dn[i], devices[dn[i]].interface_nr);
434       if (status != SANE_STATUS_GOOD)
435 	{
436 	  printf ("ERROR: couldn't claim interface 0 on device %d!\n", dn[i]);
437 	}
438       else
439 	{
440 	  claimed++;
441 	}
442     }
443   if (claimed != expected)
444     {
445       printf ("ERROR: expected %d claimed interfaces, got %d!\n", expected,
446 	      claimed);
447       return 0;
448     }
449   printf ("%d devices claimed...\n\n", claimed);
450 
451   /* try to claim invalid device entry */
452   status = sanei_usb_claim_interface (device_number, 0);
453   if (status == SANE_STATUS_GOOD)
454     {
455       printf ("ERROR: could claim interface 0 on invalid device!\n");
456       return 0;
457     }
458 
459   /* create a mock device and make it missing by rescanning */
460   create_mock_device ("mock", &mock);
461   store_device (mock);
462   sanei_usb_scan_devices ();
463 
464   /* try to claim interface on missing device */
465   status = sanei_usb_claim_interface (device_number - 1, 0);
466   if (status == SANE_STATUS_GOOD)
467     {
468       printf ("ERROR: could claim interface 0 on invalid device!\n");
469       return 0;
470     }
471 
472   /* remove mock device */
473   device_number--;
474   free (devices[device_number].devname);
475   devices[device_number].devname = NULL;
476 
477   return 1;
478 }
479 
480 
481 /** release all claimed devices
482  * loop on all opened devices and claim interface 0
483  * @param dn array of opened device number
484  * @param expected number of devices to be claimed
485  * @return 1 on success, else 0
486  */
487 static int
test_release_all(SANE_Int * dn, int expected)488 test_release_all (SANE_Int * dn, int expected)
489 {
490   int released = 0;
491   int i;
492   SANE_Status status;
493   device_list_type mock;
494 
495   released = 0;
496   for (i = 0; i < expected; i++)
497     {
498       status =
499 	sanei_usb_release_interface (dn[i], devices[dn[i]].interface_nr);
500       if (status != SANE_STATUS_GOOD)
501 	{
502 	  printf ("ERROR: couldn't release interface 0 on device %d!\n",
503 		  dn[i]);
504 	}
505       else
506 	{
507 	  released++;
508 	}
509     }
510   if (released != expected)
511     {
512       printf ("ERROR: expected %d released interfaces, got %d!\n", expected,
513 	      released);
514       return 0;
515     }
516   printf ("%d devices released...\n\n", released);
517 
518   /* try to release invalid device entry */
519   status = sanei_usb_release_interface (device_number, 0);
520   if (status == SANE_STATUS_GOOD)
521     {
522       printf ("ERROR: could release interface 0 on invalid device!\n");
523       return 0;
524     }
525 
526   /* create a mock device and make it missing by rescanning */
527   create_mock_device ("mock", &mock);
528   store_device (mock);
529   sanei_usb_scan_devices ();
530 
531   /* try to claim interface on missing device */
532   status = sanei_usb_release_interface (device_number - 1, 0);
533   if (status == SANE_STATUS_GOOD)
534     {
535       printf ("ERROR: could release interface 0 on invalid device!\n");
536       return 0;
537     }
538 
539   /* remove mock device */
540   device_number--;
541   free (devices[device_number].devname);
542   devices[device_number].devname = NULL;
543 
544   return 1;
545 }
546 
547 /** get id for all devices names
548  * loop on all existing devices and get vendor
549  * and product id by name.
550  * @param expected count
551  * @return 1 on success, else 0
552  */
553 static int
test_vendor_by_devname(void)554 test_vendor_by_devname (void)
555 {
556   int i;
557   SANE_Status status;
558   SANE_Word vendor, product;
559   device_list_type mock;
560 
561   /* loop on detected devices and open them */
562   for (i = 0; i < device_number; i++)
563     {
564       if (devices[i].missing == 0 && devices[i].devname != NULL)
565 	{
566 	  /* get device id */
567 	  status = sanei_usb_get_vendor_product_byname (devices[i].devname,
568 							&vendor, &product);
569 	  if (status != SANE_STATUS_GOOD)
570 	    {
571 	      printf ("ERROR: couldn't query device %s!\n",
572 		      devices[i].devname);
573 	      return 0;
574 	    }
575 	  if (vendor == 0 || product == 0)
576 	    {
577 	      printf ("ERROR: incomplete device id for %s!\n",
578 		      devices[i].devname);
579 	      return 0;
580 	    }
581 	  printf ("%s is %04x:%04x\n", devices[i].devname, vendor, product);
582 	}
583     }
584 
585   /* add mock device */
586   create_mock_device ("mock", &mock);
587   store_device (mock);
588   status = sanei_usb_get_vendor_product_byname ("mock", &vendor, &product);
589   if (status != SANE_STATUS_GOOD)
590     {
591       printf ("ERROR: getting vendor for mock devname!\n");
592       return 0;
593     }
594   if (vendor != mock.vendor || product != mock.product)
595     {
596       printf ("ERROR: wrong vendor/product for mock devname!\n");
597       return 0;
598     }
599   /* remove mock device */
600   device_number--;
601   free (devices[device_number].devname);
602   devices[device_number].devname = NULL;
603 
604   /* try go get id for an invalid devname */
605   status = sanei_usb_get_vendor_product_byname ("invalid devname",
606 						&vendor, &product);
607   if (status == SANE_STATUS_GOOD)
608     {
609       printf ("ERROR: unexpected success getting id for invalid devname!\n");
610       return 0;
611     }
612 
613   printf ("\n");
614   return 1;
615 }
616 
617 /** get vendor for all devices id
618  * loop on all existing devices and get vendor
619  * and product id.
620  * @param expected count
621  * @return 1 on success, else 0
622  */
623 static int
test_vendor_by_id(void)624 test_vendor_by_id (void)
625 {
626   int i;
627   SANE_Status status;
628   SANE_Word vendor, product;
629   device_list_type mock;
630 
631   /* loop on detected devices and open them */
632   for (i = 0; i < device_number; i++)
633     {
634       if (devices[i].missing == 0 && devices[i].devname != NULL)
635 	{
636 	  /* get device id */
637 	  status = sanei_usb_get_vendor_product (i, &vendor, &product);
638 	  if (status != SANE_STATUS_GOOD)
639 	    {
640 	      printf ("ERROR: couldn't query device %d!\n", i);
641 	      return 0;
642 	    }
643 	  if (vendor == 0 || product == 0)
644 	    {
645 	      printf ("ERROR: incomplete device id for %d!\n", i);
646 	      return 0;
647 	    }
648 	  printf ("%d is %04x:%04x\n", i, vendor, product);
649 	}
650     }
651 
652   /* add mock device */
653   create_mock_device ("mock", &mock);
654   store_device (mock);
655   status =
656     sanei_usb_get_vendor_product (device_number - 1, &vendor, &product);
657   if (status != SANE_STATUS_GOOD)
658     {
659       printf ("ERROR: getting vendor for mock devname!\n");
660       return 0;
661     }
662   if (vendor != mock.vendor || product != mock.product)
663     {
664       printf ("ERROR: wrong vendor/product for mock devname!\n");
665       return 0;
666     }
667   /* remove mock device */
668   device_number--;
669   free (devices[device_number].devname);
670   devices[device_number].devname = NULL;
671 
672   /* try go get id for an invalid id */
673   status =
674     sanei_usb_get_vendor_product (device_number + 1, &vendor, &product);
675   if (status == SANE_STATUS_GOOD)
676     {
677       printf
678 	("ERROR: unexpected success getting vendor for invalid devname!\n");
679       return 0;
680     }
681 
682   printf ("\n");
683   return 1;
684 }
685 
686 /** test timeout functions : libusb only
687  * @return 1 on success, else 0
688  */
689 static int
test_timeout(void)690 test_timeout (void)
691 {
692 #if defined(HAVE_LIBUSB_LEGACY) || defined(HAVE_LIBUSB)
693   int timeout = libusb_timeout;
694 
695   sanei_usb_set_timeout (5000);
696   if (libusb_timeout != 5000)
697     {
698       printf ("ERROR: failed to set timeout\n");
699       return 1;
700     }
701   sanei_usb_set_timeout (timeout);
702 #endif
703   return 1;
704 }
705 
706 /** test device scanning
707  * call sanei_usb_scan_devices, since it has no return code, no real
708  * assert can be done, but at least we can test it doesn't break
709  * other functions or don't leak memory
710  * @return always 1
711  */
712 static int
test_scan_devices(int detected, int opened)713 test_scan_devices (int detected, int opened)
714 {
715   int rc;
716 
717   printf ("rescanning for devices ...\n");
718   sanei_usb_scan_devices ();
719   rc = count_detected (detected);
720   if (!rc)
721     {
722       printf ("ERROR: scanning devices change detected count!\n");
723       return 0;
724     }
725   rc = count_opened (opened);
726   if (!rc)
727     {
728       printf ("ERROR: scanning devices change opened count!\n");
729       return 0;
730     }
731   printf ("\n");
732   return 1;
733 }
734 
735 
736 /**
737  * flag for dummy attach
738  */
739 static int dummy_flag;
740 
741 /**
742  * expected device name during attach
743  */
744 static char *expected_device;
745 
746 /** dummy attach function
747  * dummy attach function
748  * @return return SANE_STATUS_GOOD
749  */
750 static SANE_Status
dummy_attach(const char *dev)751 dummy_attach (const char *dev)
752 {
753   dummy_flag = (strcmp (expected_device, dev) == 0);
754   if (dummy_flag)
755     {
756       printf ("success attaching to %s...\n", dev);
757     }
758   else
759     {
760       printf ("failed attaching to %s...\n", dev);
761     }
762   return SANE_STATUS_GOOD;
763 }
764 
765 /** test attaching usb device
766  * create a mock device and attach to it, checking
767  * if it is ok
768  * @return 1 on success, else 0
769  */
770 static int
test_attach(void)771 test_attach (void)
772 {
773   device_list_type mock;
774 
775   /* add mock device and try to attach to it */
776   dummy_flag = 0;
777   create_mock_device ("mock", &mock);
778   expected_device = mock.devname;
779   store_device (mock);
780   sanei_usb_attach_matching_devices ("usb 0xdead 0xbeef", dummy_attach);
781 
782   /* flag must be set */
783   if (dummy_flag != 1)
784     {
785       printf ("ERROR: couldn't attach to 'usb xdead 0xbeef' device!\n");
786       return 0;
787     }
788 
789   /* attach by devname */
790   dummy_flag = 0;
791   sanei_usb_attach_matching_devices (mock.devname, dummy_attach);
792   /* flag must be set */
793   if (dummy_flag != 1)
794     {
795       printf ("ERROR: couldn't attach to 'mock' device!\n");
796       return 0;
797     }
798 
799   /* attach to bogus device */
800   dummy_flag = 0;
801   sanei_usb_attach_matching_devices ("usb 0x0001 0x0001", dummy_attach);
802 
803   /* flag must not be set */
804   if (dummy_flag != 0)
805     {
806       printf ("ERROR: shouldn't be attached to bogus device!\n");
807       return 0;
808     }
809 
810   /* attach by bogus devname */
811   sanei_usb_attach_matching_devices ("bogus", dummy_attach);
812 
813   /* flag must not be set */
814   if (dummy_flag != 0)
815     {
816       printf ("ERROR: shouldn't be attached to bogus device!\n");
817       return 0;
818     }
819 
820   /* remove mock device */
821   device_number--;
822   free (devices[device_number].devname);
823   devices[device_number].devname = NULL;
824   dummy_flag = 0;
825 
826   return 1;
827 }
828 
829 int
main(int __sane_unused__ argc, char **argv)830 main (int __sane_unused__ argc, char **argv)
831 {
832   int detected, opened, i;
833   SANE_Int dn[MAX_DEVICES];
834 
835 #ifdef HAVE_LIBUSB_LEGACY
836   printf ("\n%s built with old libusb\n\n", argv[0]);
837 #endif
838 #ifdef HAVE_LIBUSB
839   printf ("\n%s built with libusb-1.0\n\n", argv[0]);
840 #endif
841 #ifdef HAVE_USBCALLS
842   printf ("\n%s built with usbcalls\n\n", argv[0]);
843 #endif
844 #if !defined(HAVE_LIBUSB_LEGACY) && !defined(HAVE_LIBUSB) && !defined(HAVE_USBCALLS)
845   printf ("\n%s relying on deprecated scanner kernel module\n", argv[0]);
846 #endif
847 
848   /* start sanei_usb */
849   assert (test_init (1));
850 
851   /* test timeout function */
852   assert (test_timeout ());
853 
854   /* count available devices */
855   detected = 0;
856   for (i = 0; i < device_number; i++)
857     {
858       if (devices[i].missing == 0 && devices[i].devname != NULL)
859 	{
860 	  detected++;
861 	}
862     }
863   printf ("%d devices found.\n", detected);
864 
865   /* rescan devices : detected count shouldn't change */
866   assert (test_scan_devices (detected, 0));
867 
868   /* test corner cases with mock device */
869   assert (test_store_device ());
870 
871   /* get vendor/product id for all available devices devname */
872   assert (test_vendor_by_devname ());
873 
874   /* get vendor/product id for all available devices id */
875   assert (test_vendor_by_id ());
876 
877   /* open all available devices */
878   assert (test_open_all (dn, detected));
879 
880   opened = get_opened();
881 
882   /* rescan devices : detected and opened count shouldn't change */
883   assert (test_scan_devices (detected, opened));
884 
885   /* try to open an inexisting device */
886   assert (test_open_invalid ());
887 
888   /* increase sanei _sub use count */
889   assert (test_init (2));
890 
891   /* there should be still as many detected devices */
892   assert (count_detected (detected));
893 
894   /* there should be still as many opened devices */
895   assert (count_opened (opened));
896 
897   assert (test_exit (1));
898 
899   /* there should be still as many opened devices */
900   assert (count_opened (opened));
901 
902   /* count devices again , sanei_usb_exit() shouldn't have
903    * change the count */
904   assert (count_detected (detected));
905 
906   /* claim all available devices */
907   assert (test_claim_all (dn, opened));
908 
909   /* then release them all */
910   assert (test_release_all (dn, opened));
911 
912   /* close all opened devices */
913   assert (test_close_all (dn, opened));
914 
915   /* check there is no opened device */
916   assert (count_opened (0));
917 
918   /* finally free resources */
919   assert (test_exit (0));
920 
921   /* check there is no more devices */
922   assert (count_detected (0));
923 
924   /* test attach matching device with a mock */
925   assert (test_attach ());
926 
927   /* try to call sanei_usb_exit() when it not initialized */
928   assert (test_exit (0));
929 
930   /* scan devices when sanei usb is not initialized */
931   assert (test_scan_devices (0, 0));
932 
933   /* we re start use of sanei usb so we check we have left it
934    * it he correct state after "closing" it. */
935   printf ("\n============================================================\n");
936   printf ("restart use of sanei usb after having freed all resources...\n\n");
937   assert (test_init (1));
938 
939   /* we should have the same initial count of detected devices */
940   assert (count_detected (detected));
941 
942   /* finally free resources */
943   assert (test_exit (0));
944 
945   /* all the tests are OK ! */
946   return 0;
947 }
948 
949 /* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */
950