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);
}