Hello,

I wrote this afternoon this small test program.
It does not do all what i would have liked, but it does enough to 
begin to compare libsmbclient releases.

What it tests:
  -listing workgroups
  -listing computers
  -listing shares

With an automated way

What it does not yet:
  -all what remains

I will go on and implement all what is missing if you feel it 
will be useful for you.

Attached is the output generated by various libsmbclient releases 
+ the current program sources.

The first regression is between 2.2.2 and 2.2.3
The second is somewhere i don't know, but is there in 3.0alpha20

Cheers.

Fabien.


PS:
  I can make it to dlopen libsmbclient if you need it ...but I 
use only linux and i have no idea if it will work elsewhere.

PS(2):
  What do you mean, Andrew, by making it "scriptable" ?

--------------------------------------------------------------
Samba v2.2.1

[fabien@tux libsmb]$ lsmbctest
>> Now running test smbc_init...
Calling int smbc_init(mbc_get_auth_data_fn, int debug=<0>)
Result : 0
>> Test <smbc_init> OK
>> Now running test workgroups listing...
Calling int smbc_opendir(const char *durl=<smb://>)
Authentification required for SERVER <CUTBIDISH> SHARE <IPC$> in 
WORKGROUP <WORKGROUP>.
Returning <><>
Result : 11024, errno=0[Success]
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400a6da0, errno=0[Success]
Found entry type <1>, named <MDKGROUP>
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400a6da0, errno=0[Success]
Found entry type <1>, named <REZ>
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400a6da0, errno=0[Success]
Found entry type <1>, named <WORKGROUP>
Calling int smbc_readdir(int dh=<11024>)
Result : (nil), errno=0[Success]
>> Test <workgroups listing> OK
>> Now running test smbc_closedir...
Calling int smbc_closedir(int dh=<11024>)
Result : 0, errno=0[Success]
>> Test <smbc_closedir> OK
>> Now running test machines in workgroup listing...
Calling int smbc_opendir(const char *durl=<smb://MDKGROUP>)
Authentification required for SERVER <SHADOW> SHARE <IPC$> in 
WORKGROUP <WORKGROUP>.
Returning <><>
Result : 11024, errno=0[Success]
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400a6da0, errno=0[Success]
Found entry type <2>, named <SHADOW>
Calling int smbc_readdir(int dh=<11024>)
Result : (nil), errno=0[Success]
>> Test <machines in workgroup listing> OK
Calling int smbc_closedir(int dh=<11024>)
Result : 0, errno=0[Success]
>> Now running test shares on a machine listing...
Calling int smbc_opendir(const char *durl=<smb://SHADOW>)
Authentification required for SERVER <SHADOW> SHARE <IPC$> in 
WORKGROUP <WORKGROUP>.
Returning <><>
Result : 11024, errno=0[Success]
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400a6da0, errno=0[Success]
Found entry type <6>, named <IPC$>
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400a6da0, errno=0[Success]
Found entry type <3>, named <ADMIN$>
Calling int smbc_readdir(int dh=<11024>)
Result : (nil), errno=0[Success]
>> Test <shares on a machine listing> OK
Calling int smbc_closedir(int dh=<11024>)
Result : 0, errno=0[Success]

Test summary:

smbc_init                               Ok
smbc_closedir                           Ok
workgroups listing                              Ok
machines in workgroup listing                           Ok
shares on a machine listing                             Ok

--------------------------------------------------------------
Samba v2.2.2

[fabien@tux libsmb]$ lsmbctest
>> Now running test smbc_init...
Calling int smbc_init(mbc_get_auth_data_fn, int debug=<0>)
Result : 0
>> Test <smbc_init> OK
>> Now running test workgroups listing...
Calling int smbc_opendir(const char *durl=<smb://>)
Authentification required for SERVER <CUTBIDISH> SHARE <IPC$> in 
WORKGROUP <WORKGROUP>.
Returning <><>
Result : 11024, errno=0[Success]
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400a83e0, errno=0[Success]
Found entry type <1>, named <MDKGROUP>
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400a83e0, errno=0[Success]
Found entry type <1>, named <REZ>
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400a83e0, errno=0[Success]
Found entry type <1>, named <WORKGROUP>
Calling int smbc_readdir(int dh=<11024>)
Result : (nil), errno=0[Success]
>> Test <workgroups listing> OK
>> Now running test smbc_closedir...
Calling int smbc_closedir(int dh=<11024>)
Result : 0, errno=0[Success]
>> Test <smbc_closedir> OK
>> Now running test machines in workgroup listing...
Calling int smbc_opendir(const char *durl=<smb://MDKGROUP>)
Authentification required for SERVER <SHADOW> SHARE <IPC$> in 
WORKGROUP <WORKGROUP>.
Returning <><>
Result : 11024, errno=0[Success]
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400a83e0, errno=0[Success]
Found entry type <2>, named <SHADOW>
Calling int smbc_readdir(int dh=<11024>)
Result : (nil), errno=0[Success]
>> Test <machines in workgroup listing> OK
Calling int smbc_closedir(int dh=<11024>)
Result : 0, errno=0[Success]
>> Now running test shares on a machine listing...
Calling int smbc_opendir(const char *durl=<smb://SHADOW>)
Authentification required for SERVER <SHADOW> SHARE <IPC$> in 
WORKGROUP <WORKGROUP>.
Returning <><>
Result : 11024, errno=0[Success]
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400a83e0, errno=0[Success]
Found entry type <6>, named <IPC$>
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400a83e0, errno=0[Success]
Found entry type <3>, named <ADMIN$>
Calling int smbc_readdir(int dh=<11024>)
Result : (nil), errno=0[Success]
>> Test <shares on a machine listing> OK
Calling int smbc_closedir(int dh=<11024>)
Result : 0, errno=0[Success]

Test summary:

smbc_init                               Ok
smbc_closedir                           Ok
workgroups listing                              Ok
machines in workgroup listing                           Ok
shares on a machine listing                             Ok

--------------------------------------------------------------
Samba v2.2.3

[fabien@tux libsmb]$ lsmbctest -W MDKGROUP
>> Now running test smbc_init...
Calling int smbc_init(mbc_get_auth_data_fn, int debug=<0>)
Result : 0
>> Test <smbc_init> OK
>> Now running test workgroups listing...
Calling int smbc_opendir(const char *durl=<smb://>)
Authentification required for SERVER <CUTBIDISH> SHARE <IPC$> in 
WORKGROUP <WORKGROUP>.
Returning <><>
Result : -1, errno=0[Success]
>> Test <workgroups listing> FAILED
>> Now running test machines in workgroup listing...
Calling int smbc_opendir(const char *durl=<smb://MDKGROUP>)
Authentification required for SERVER <SHADOW> SHARE <IPC$> in 
WORKGROUP <WORKGROUP>.
Returning <><>
Result : 11024, errno=0[Success]
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400b04e0, errno=0[Success]
Found entry type <2>, named <SHADOW>
Calling int smbc_readdir(int dh=<11024>)
Result : (nil), errno=0[Success]
>> Test <machines in workgroup listing> OK
>> Now running test smbc_closedir...
Calling int smbc_closedir(int dh=<11024>)
Result : 0, errno=0[Success]
>> Test <smbc_closedir> OK
>> Now running test shares on a machine listing...
Calling int smbc_opendir(const char *durl=<smb://SHADOW>)
Authentification required for SERVER <SHADOW> SHARE <IPC$> in 
WORKGROUP <WORKGROUP>.
Returning <><>
Result : 11024, errno=0[Success]
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400b04e0, errno=0[Success]
Found entry type <6>, named <IPC$>
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400b04e0, errno=0[Success]
Found entry type <3>, named <ADMIN$>
Calling int smbc_readdir(int dh=<11024>)
Result : (nil), errno=0[Success]
>> Test <shares on a machine listing> OK
Calling int smbc_closedir(int dh=<11024>)
Result : 0, errno=0[Success]

Test summary:

smbc_init                               Ok
smbc_closedir                           Ok
workgroups listing                              Failed
machines in workgroup listing                           Ok
shares on a machine listing                             Ok
--------------------------------------------------------------
Samba v2.2.6

[fabien@tux libsmb]$ lsmbctest -W MDKGROUP
>> Now running test smbc_init...
Calling int smbc_init(mbc_get_auth_data_fn, int debug=<0>)
Result : 0
>> Test <smbc_init> OK
>> Now running test workgroups listing...
Calling int smbc_opendir(const char *durl=<smb://>)
Authentification required for SERVER <CUTBIDISH> SHARE <IPC$> in 
WORKGROUP <WORKGROUP>.
Returning <><>
Result : -1, errno=0[Success]
>> Test <workgroups listing> FAILED
>> Now running test machines in workgroup listing...
Calling int smbc_opendir(const char *durl=<smb://MDKGROUP>)
Authentification required for SERVER <SHADOW> SHARE <IPC$> in 
WORKGROUP <WORKGROUP>.
Returning <><>
Result : 11024, errno=0[Success]
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400b3580, errno=0[Success]
Found entry type <2>, named <SHADOW>
Calling int smbc_readdir(int dh=<11024>)
Result : (nil), errno=0[Success]
>> Test <machines in workgroup listing> OK
>> Now running test smbc_closedir...
Calling int smbc_closedir(int dh=<11024>)
Result : 0, errno=0[Success]
>> Test <smbc_closedir> OK
>> Now running test shares on a machine listing...
Calling int smbc_opendir(const char *durl=<smb://SHADOW>)
Authentification required for SERVER <SHADOW> SHARE <IPC$> in 
WORKGROUP <WORKGROUP>.
Returning <><>
Result : 11024, errno=0[Success]
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400b3580, errno=0[Success]
Found entry type <6>, named <IPC$>
Calling int smbc_readdir(int dh=<11024>)
Result : 0x400b3580, errno=0[Success]
Found entry type <3>, named <ADMIN$>
Calling int smbc_readdir(int dh=<11024>)
Result : (nil), errno=0[Success]
>> Test <shares on a machine listing> OK
Calling int smbc_closedir(int dh=<11024>)
Result : 0, errno=0[Success]

Test summary:

smbc_init                               Ok
smbc_closedir                           Ok
workgroups listing                              Failed
machines in workgroup listing                           Ok
shares on a machine listing                             Ok

--------------------------------------------------------------
Samba v3.0 alpha20

[fabien@tux libsmb]$ lsmbctest -W MDKGROUP
>> Now running test smbc_init...
Calling int smbc_init(mbc_get_auth_data_fn, int debug=<0>)
Result : 0
>> Test <smbc_init> OK
>> Now running test workgroups listing...
Calling int smbc_opendir(const char *durl=<smb://>)
Authentification required for SERVER <CUTBIDISH> SHARE <IPC$> in 
WORKGROUP <WORKGROUP>.
Returning <><>
Result : -1, errno=0[Success]
>> Test <workgroups listing> FAILED
>> Now running test machines in workgroup listing...
Calling int smbc_opendir(const char *durl=<smb://MDKGROUP>)
Authentification required for SERVER <SHADOW> SHARE <IPC$> in 
WORKGROUP <WORKGROUP>.
Returning <><>
Result : 10000, errno=0[Success]
Calling int smbc_readdir(int dh=<10000>)
Result : 0x804aedc, errno=0[Success]
Found entry type <2>, named <SHADOW>
Calling int smbc_readdir(int dh=<10000>)
Result : (nil), errno=0[Success]
>> Test <machines in workgroup listing> OK
>> Now running test smbc_closedir...
Calling int smbc_closedir(int dh=<10000>)
Result : 0, errno=0[Success]
>> Test <smbc_closedir> OK
>> Now running test shares on a machine listing...
Calling int smbc_opendir(const char *durl=<smb://SHADOW>)
Authentification required for SERVER <SHADOW> SHARE <IPC$> in 
WORKGROUP <WORKGROUP>.
Returning <><>
Result : 10001, errno=0[Success]
Calling int smbc_readdir(int dh=<10001>)
Result : (nil), errno=2[No such file or directory]
>> Test <shares on a machine listing> FAILED
Calling int smbc_closedir(int dh=<10001>)
Result : 0, errno=2[No such file or directory]

Test summary:

smbc_init                               Ok
smbc_closedir                           Ok
workgroups listing                              Failed
machines in workgroup listing                           Ok
shares on a machine listing                             Failed
#Simple makefile for lsmbctest

all: lsmbctest

lsmbctest: lsmbctest.c
	$(CC) -lsmbclient -Wall -O0 -g3 lsmbctest.c -o lsmbctest

clean:
	rm -f lsmbctest


/* 
   This program is used to test the libsmbclient library.
   It's designed to perform easy to use non regression testing.
   
   Copyright (C) Fabien Chevalier 2002
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <libsmbclient.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#define VERSION_STRING "0.1"

#define STRING_SIZE 255

char username[STRING_SIZE];
char passwd[STRING_SIZE];
char workgroup[STRING_SIZE];
char machine[STRING_SIZE];
char share[STRING_SIZE];
char directory[STRING_SIZE];

int only_result = 0;

typedef struct {
    /* S = Skipped */
    /* O = ok */
    /* F = Failed */
    /* R = removed */
    /* 0 = end of list*/
  char result;
    /* description */
  char desc[STRING_SIZE];
} struct_test;

#define SMBC_INIT 0
#define SMBC_CLOSEDIR 1
#define SMBC_WORKGROUP_LIST 2
#define SMBC_MACHINE_LIST 3
#define SMBC_SHARE_LIST 4

struct_test Test[] = {{'S', "smbc_init"},
                      {'S', "smbc_closedir"},
                      {'S', "workgroups listing"},
                      {'S', "machines in workgroup listing"},
                      {'S', "shares on a machine listing"},
                      { 0, ""}
                      };

void usage()
{
  printf("\nThis piece of program is used to test the libsmbclient library.\n");
  printf("Version %s\n\n", VERSION_STRING);
  
  printf("Usage: lsmbctest [-W Workgroup] [-M Machine] [-S Share] [-U Username] [-P password] [-R] [-h]\n\n");

  printf("\t-W Workgroup          Workgroup to be used to perform machines listing\n");
  printf("\t                      Defaults to the last workgroup found\n");
  printf("\t                      Use this in order to force a workgroup if the workgroup listing failed\n");
  printf("\t-M Machine            Machine to be used to perform shares listing\n");
  printf("\t                      Defaults to the last machine found over the workgroup\n");
  printf("\t                      Use this in order to force a machine if the machine listing failed\n");
  printf("\t-M Share              Share to be used to perform all file the testing operations\n");
  printf("\t                      Defaults to the last share found.\n");
  printf("\t                      Use this in order to force a share if the share listing failed.\n");
  printf("\t-U Username           Username to be used when accessing the share to perform file operations\n");
  printf("\t                      Defaults to empty string\n");
  printf("\t-P password           Password to be used when accessing the share to perform file operations\n");
  printf("\t                      Defaults to empty string\n");
  /* not for today */
  /* printf("\t-R                    Prints only the result of the tests, without all the output before\n"); */
  printf("\t-h                    Prints this help\n");
}

void test_print_info(int test_id)
{
  printf(">> Now running test %s...\n", Test[test_id].desc);
}

void test_set_failed(int test_id)
{
  Test[test_id].result = 'F';
  printf(">> Test <%s> FAILED\n", Test[test_id].desc);
}

void test_set_ok(int test_id)
{
  Test[test_id].result = 'O';
  printf(">> Test <%s> OK\n", Test[test_id].desc);
}

                      

void auth_data_fn(const char *srv, 
                                      const char *shr,
                                      char *wg, int wglen, 
                                      char *un, int unlen,
                                      char *pw, int pwlen);

int run_smbc_init(smbc_get_auth_data_fn fn, int debug) 
{
  int result;
  
  if(!only_result)
    printf("Calling int smbc_init(mbc_get_auth_data_fn, int debug=<%d>)\n", debug);
  
  result = smbc_init(fn, debug);
  
  if(!only_result)
    printf("Result : %d\n", result);
    
  return result;
}
                                      
int run_smbc_opendir(const char *durl)
{
  int result;
  int error;
  if(!only_result)
    printf("Calling int smbc_opendir(const char *durl=<%s>)\n", durl);
  result = smbc_opendir(durl);
  error = errno;
  if(!only_result)
    printf("Result : %d, errno=%d[%s]\n", result, error, strerror(error));
  
  return result;
}
                                      
int run_smbc_closedir(int dh)
{
  int result;
  int error;
  if(!only_result)
    printf("Calling int smbc_closedir(int dh=<%d>)\n", dh);
  result = smbc_closedir(dh);
  error = errno;
  if(!only_result)
    printf("Result : %d, errno=%d[%s]\n", result, error, strerror(error));
  
  return result;
}
                                      
struct smbc_dirent * run_smbc_readdir(int dh)
{
  int error;
  if(!only_result)
    printf("Calling int smbc_readdir(int dh=<%d>)\n", dh);
  struct smbc_dirent * dirp = smbc_readdir(dh);
  error = errno;
  if(!only_result)
    printf("Result : %p, errno=%d[%s]\n", dirp, error, strerror(error));
  
  return dirp;
}
                                      
                                      
int main(int argc, char **argv)
{
  int opt;
  int result;
  char s[STRING_SIZE];
  int dh;
  int i;
  
  strcpy(username, "");
  strcpy(passwd, "");
  strcpy(workgroup, "");
  strcpy(share, "");
  strcpy(directory, "");

  while ((opt = 
    getopt(argc, argv,"W:M:S:R:U:P:h")) != EOF) {
    switch (opt) {
    case 'U':
      strcpy(username, optarg);
      break;
    case 'P':
      strcpy(passwd, optarg);
      break;  
    case 'W':
      strcpy(workgroup, optarg);
      break;
    case 'M':
      strcpy(machine, optarg);
      break;
    case 'S':
      strcpy(share, optarg);
      break;
    case 'R':
      only_result = 1;
      break;
    case 'h':
      usage();
      exit(0);
      break;
    default:
      usage();
      exit(1);
     }
  }
    
  
  test_print_info(SMBC_INIT);
  
  result = run_smbc_init(auth_data_fn, 0);
  if(result < 0){
    test_set_failed(SMBC_INIT);
  }
  else {
    test_set_ok(SMBC_INIT);
    
    test_print_info(SMBC_WORKGROUP_LIST);
    dh = run_smbc_opendir("smb://");
    
    if(dh < 0){
      test_set_failed(SMBC_WORKGROUP_LIST);
    }
    else {
      struct smbc_dirent *pdirent;
      int found = 0;
      
      while((pdirent = run_smbc_readdir(dh)) != 0) {
        found = 1;
        printf("Found entry type <%d>, named <%s>\n", pdirent->smbc_type, pdirent->name);
        
        /* filling workgroup if not given */
        if(strlen(workgroup) == 0)
          strncpy(workgroup, pdirent->name, STRING_SIZE);
      }
      
      if(found)
        test_set_ok(SMBC_WORKGROUP_LIST);
      else
        test_set_failed(SMBC_WORKGROUP_LIST);

      
      test_print_info(SMBC_CLOSEDIR);
      result = run_smbc_closedir(dh);
      if(result < 0) {
        test_set_failed(SMBC_CLOSEDIR);   
      }
      else {
        test_set_ok(SMBC_CLOSEDIR);   
      }
    }
    
    if(strlen(workgroup) == 0)
      printf("\nSkipping machines listing as we do not have any workgroup to list from. Use switch -W WORKGROUP to enable this test.\n");
    else {
      test_print_info(SMBC_MACHINE_LIST);
      strcpy(s, "smb://");
      strcat(s, workgroup);
      
      dh = run_smbc_opendir(s);

      if(dh < 0){
        test_set_failed(SMBC_MACHINE_LIST);
      }
      else {
        struct smbc_dirent *pdirent;
        int found = 0;

        while((pdirent = run_smbc_readdir(dh)) != 0) {
          found = 1;
          printf("Found entry type <%d>, named <%s>\n", pdirent->smbc_type, pdirent->name);

          /* filling workgroup if not given */
          if(strlen(machine) == 0)
            strncpy(machine, pdirent->name, STRING_SIZE);
        }

        if(found)
          test_set_ok(SMBC_MACHINE_LIST);
        else
          test_set_failed(SMBC_MACHINE_LIST);


        if(Test[SMBC_CLOSEDIR].result != 'O') {
          /* in case workgroup listing failed, we didn't had to close
          the handle. So we try it now */
          
          test_print_info(SMBC_CLOSEDIR);
          result = run_smbc_closedir(dh);
          if(result < 0) {
            test_set_failed(SMBC_CLOSEDIR);   
          }
          else {
            test_set_ok(SMBC_CLOSEDIR);   
          }
        }
        else {
          run_smbc_closedir(dh);
        }
      
      }
    }
    
    if(strlen(machine) == 0)
      printf("\nSkipping shares listing as we do not have any workgroup to list from. Use switch -M MACHINE to enable this test.\n");
    else {
      test_print_info(SMBC_SHARE_LIST);
      strcpy(s, "smb://");
      strcat(s, machine);
      
      dh = run_smbc_opendir(s);

      if(dh < 0){
        test_set_failed(SMBC_SHARE_LIST);
      }
      else {
        struct smbc_dirent *pdirent;
        int found = 0;

        while((pdirent = run_smbc_readdir(dh)) != 0) {
          found = 1;
          printf("Found entry type <%d>, named <%s>\n", pdirent->smbc_type, pdirent->name);
        }

        if(found)
          test_set_ok(SMBC_SHARE_LIST);
        else
          test_set_failed(SMBC_SHARE_LIST);


        if(Test[SMBC_CLOSEDIR].result != 'O') {
          /* in case workgroup & share listing failed, we didn't had to close
          the handle. So we try it now */
          
          test_print_info(SMBC_CLOSEDIR);
          result = run_smbc_closedir(dh);
          if(result < 0) {
            test_set_failed(SMBC_CLOSEDIR);   
          }
          else {
            test_set_ok(SMBC_CLOSEDIR);   
          }
        }
        else {
          run_smbc_closedir(dh);
        }
      
      }
    }

  }
  
  /* printing summary */
  
  printf("\nTest summary:\n\n");
  
  for(i = 0; Test[i].result != 0; i++) {
    switch(Test[i].result) {
    case 'O':
      printf("%s\t\t\t\tOk\n", Test[i].desc);
      break;
    case 'F':
      printf("%s\t\t\t\tFailed\n", Test[i].desc);
      break;
    case 'S':
      printf("%s\t\t\t\tSkipped\n", Test[i].desc);
      break;
    
    }
  }
  
  return 0;
}

void auth_data_fn(const char *srv, 
                                      const char *shr,
                                      char *wg, int wglen, 
                                      char *un, int unlen,
                                      char *pw, int pwlen)
{
  printf("Authentification required for SERVER <%s> SHARE <%s> in WORKGROUP <%s>.\n", srv, shr, wg);
  //strncpy(wg, workgroup, wglen);
  strncpy(un, username, unlen);
  strncpy(pw, passwd, pwlen);
  printf("Returning <%s><%s>\n", un, pw);
}

Reply via email to