Crossfire Server, Trunk
check_account.cpp
Go to the documentation of this file.
1 /*
2  * static char *rcsid_check_account_c =
3  * "$Id: check_account.c 11817 2009-06-12 15:46:56Z akirschbaum $";
4  */
5 
6 /*
7  * CrossFire, A Multiplayer game for X-windows
8  *
9  * Copyright (C) 2010 Mark Wedel & Crossfire Development Team
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *
25  * The authors can be reached via e-mail at crossfire-devel@real-time.com
26  */
27 
28 /*
29  * This is the unit tests file for server/account.c
30  */
31 
32 #include <global.h>
33 #include <stdlib.h>
34 #include <check.h>
35 #include <loader.h>
36 #include <toolkit_common.h>
37 #include <sproto.h>
38 #include <unistd.h>
39 #include <toolkit_server.h>
40 
41 static void setup(void) {
42 }
43 
44 static void teardown(void) {
45  /* put any cleanup steps here, they will be run after each testcase */
46 }
47 
48 
49 /* This test makes sure account_check_string() behaves as expected -
50  * rejects strings with bad characters in them, etc.
51  */
52 START_TEST(test_account_check_string) {
53  char longname[MAX_NAME+3];
54  int i;
55 
56  i=account_check_string(" abcd");
57  fail_unless(i != 0, "string started with spaces should not be considered valid");
58  /* We test one string with colon at end, other starting with semicolon -
59  * in that way, we also do some basic testing to make sure entire string is being checked.
60  */
61  i=account_check_string("abcd:");
62  fail_unless(i != 0, "string with colons should not be considered valid");
63  i=account_check_string("a;bcd");
64  fail_unless(i != 0, "string with semicolons should not be considered valid");
65  i=account_check_string("a/bcd");
66  fail_unless(i != 0, "string with slash should not be considered valid");
67  i=account_check_string("a'bcd");
68  fail_unless(i != 0, "string with quote should not be considered valid");
69 
70  i=account_check_string("abc\n\nefg");
71  fail_unless(i != 0, "string with non printable characters should not be considered valid");
72 
73  i=account_check_string("$abc");
74  fail_unless(i != 0, "string starting with non alphanumeric should not be considered valid");
75 
76  i=account_check_string("abc ");
77  fail_unless(i != 0, "string ending in space should not be considered valid");
78 
79  for (i=0; i<=MAX_NAME; i++) {
80  longname[i]='a';
81  }
82  longname[i]='\0';
83  i=account_check_string(longname);
84 
85  fail_unless(i != 0, "Too long string should not be considered valid");
86 
87  i=account_check_string("Some Body");
88  fail_unless(i == 0, "Valid string not considered valid");
89 
90 }
91 END_TEST
92 
93 /* This test tries to add some accounts. As a final action, we try
94  * to save the account file out.
95  */
96 START_TEST(test_account_add_account) {
97  int i,j;
98  char names[50];
99  char **char_names;
100 
101  /* Note that we run explicit checks for valid account names/passwords.
102  * As such, the focus here is not checking valid strings again, but checking
103  * duplicate account names, saving them out, etc.
104  */
105  i=account_new("Some Body", "mypassword");
106  fail_unless(i == 0, "Could not add valid account, got code %d", i);
107 
108  i=account_new("Some Body", "mypassword");
109  fail_unless(i != 0, "Duplicate account successfully added");
110 
111  /* This is mainly here to have 2 valid accounts */
112  i=account_new("No Body", "mypassword");
113  fail_unless(i == 0, "Could not add valid account, got code %d", i);
114 
115  /* This third account is to have one with no players associated to it */
116  i=account_new("Every Body", "hispassword");
117  fail_unless(i == 0, "Could not add valid account");
118 
119  i=account_link("foobar", "foobar");
120  fail_unless(i != 0, "Added player to non existent character name");
121 
122  i=account_link("Some Body", "foobar");
123  fail_unless(i == 0, "Failed to add player to valid account");
124 
125  for (j=0; j<30; j++) {
126  sprintf(names,"char-%02d", j);
127  account_link("No Body", names);
128  }
129 
130  char_names = account_get_players_for_account("foobar");
131  fail_unless(char_names == NULL, "Got non null value for players on account with non existant accoun");
132 
133  char_names = account_get_players_for_account("No Body");
134  fail_unless(char_names != NULL, "Got null value for players on account");
135 
136  /* No return value here */
137  accounts_save();
138 }
139 END_TEST
140 
141 /* This tests the load logic. Since the only data were are loading is the data from above,
142  * we use that knowledge to check for proper existence accounts, etc.
143  */
144 START_TEST(test_account_load_entries) {
145  int i,j;
146  char **char_names;
147  const char *ae;
148 
149  accounts_clear();
150  accounts_load();
151 
152  ae = account_exists("Every Body");
153  fail_unless(ae != NULL, "Could not find valid account");
154  ae = account_exists("Some Body");
155  fail_unless(ae != NULL, "Could not find valid account");
156 
157  char_names = account_get_players_for_account("No Body");
158  fail_unless(char_names != NULL, "Got null value for players on account");
159 
160  /* This is sort of data integrity testing - if char_names is not properly
161  * null terminated, with will fail. if char_names[] is corrupt, it should also
162  * core.
163  */
164  i=0;
165  while (char_names[i] != NULL) {
166  j=strlen(char_names[i]);
167  i++;
168  }
169  char_names = account_get_players_for_account("Some Body");
170  fail_unless(char_names != NULL, "Got null value for players on account");
171  fail_unless(strcmp(char_names[0],"foobar") == 0, "Can not match on name we put in");
172 
173  /* while we do this same check in test_account_add_account, doing it
174  * again here makes sure the code is properly detecting the end of the accounts
175  * list after loading it up.
176  */
177  char_names = account_get_players_for_account("foobar");
178  fail_unless(char_names == NULL, "Got non null value for players on account with non existant account");
179 
180  i = account_remove_player("foobar", "1foobar");
181  fail_unless(i!=0, "Got successsful return code on account_remove_player_from_account with non existent account");
182 
183  i = account_remove_player("No Body", "1foobar");
184  fail_unless(i!=0, "Got successsful return code on account_remove_player_from_account with non existent player");
185 
186  char_names = account_get_players_for_account("No Body");
187  j=0;
188  while (char_names[j] != NULL) {
189  j++;
190  }
191 
192  i = account_remove_player("No Body", "char-01");
193  fail_unless(i==0, "Got error removing player when it should have worked");
194 
195  char_names = account_get_players_for_account("No Body");
196 
197  i=0;
198  while (char_names[i] != NULL) {
199  i++;
200  }
201  fail_unless((i+1) == j, "Player removal get unexpected result - %d != %d", i+1, j);
202 }
203 END_TEST
204 
205 static Suite *account_suite(void) {
206  Suite *s = suite_create("account");
207  TCase *tc_core = tcase_create("Core");
208 
209  /*setup and teardown will be called before each test in testcase 'tc_core' */
210  tcase_add_checked_fixture(tc_core, setup, teardown);
211 
212  suite_add_tcase(s, tc_core);
213  tcase_add_test(tc_core, test_account_check_string);
214  tcase_add_test(tc_core, test_account_add_account);
215  tcase_add_test(tc_core, test_account_load_entries);
216 
217  return s;
218 }
219 
220 int main(void) {
221  int nf;
222  Suite *s = account_suite();
223  SRunner *sr = srunner_create(s);
224 
225  /* If you wish to debug the program, uncomment this line. */
226  /*srunner_set_fork_status (sr, CK_NOFORK);*/
227 
229  /* Not sure if there is a better place to put this file - basically,
230  * the account code usings the localdir to determine where to read/write
231  * the accounts file from - we don't want to be altering the real version of
232  * that file.
233  */
234  settings.localdir = strdup_local("/tmp/");
235  cctk_setdatadir(SOURCE_ROOT "lib");
237  init(0, NULL);
238 
239  srunner_set_xml(sr, LOGDIR "/unit/server/account.xml");
240  srunner_set_log(sr, LOGDIR "/unit/server/account.out");
241  srunner_run_all(sr, CK_ENV); /*verbosity from env variable*/
242  nf = srunner_ntests_failed(sr);
243  srunner_free(sr);
245  return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
246 }
global.h
settings
struct Settings settings
Definition: init.cpp:139
llevError
@ llevError
Definition: logger.h:11
strdup_local
#define strdup_local
Definition: compat.h:29
cctk_setdatadir
void cctk_setdatadir(const char *datadir)
Definition: toolkit_common.cpp:69
account_get_players_for_account
char ** account_get_players_for_account(const char *account_name)
Definition: account.cpp:520
accounts_save
void accounts_save(void)
Definition: account.cpp:256
Settings::debug
LogLevel debug
Definition: global.h:243
Settings::localdir
const char * localdir
Definition: global.h:249
account_link
int account_link(const char *account_name, const char *player_name)
Definition: account.cpp:445
toolkit_server.h
toolkit_common.h
START_TEST
START_TEST(test_account_check_string)
Definition: check_account.cpp:52
teardown
static void teardown(void)
Definition: check_account.cpp:44
account_remove_player
int account_remove_player(const char *account_name, const char *player_name)
Definition: account.cpp:475
clean_test_account_data
void clean_test_account_data(void)
Definition: toolkit_server.cpp:5
init
pluglist shows those as well as a short text describing each the list will simply appear empty The keyword for the Python plugin is Python plugout< keyword > Unloads a given identified by its _keyword_ So if you want to unload the Python you need to do plugout Python plugin< libname > Loads a given whose _filename_ is libname So in the case of you d have to do a plugin cfpython so Note that all filenames are relative to the default plugin it tries to load all available files in the SHARE plugins directory as plugin libraries It first displays the Initializing the plugin has the opportunity to signal itself by a message on the console Then the server displays an informative message containing both the plugin content and its keyword For the Python the standard load process thus GreenGoblin When a plugin has been it can request to be warned whenever a global event and are named freely by the developer If the directory doesn t nothing will happen< event name > can be init
Definition: plugins.txt:54
MAX_NAME
#define MAX_NAME
Definition: define.h:41
account_new
int account_new(const char *account_name, const char *account_password)
Definition: account.cpp:400
sproto.h
accounts_clear
void accounts_clear(void)
Definition: account.cpp:153
accounts_load
void accounts_load(void)
Definition: account.cpp:162
names
const char *const names[]
Definition: AssetOriginAndCreationDialog.cpp:24
setup
static void setup(void)
Definition: check_account.cpp:41
account_suite
static END_TEST Suite * account_suite(void)
Definition: check_account.cpp:205
loader.h
account_check_string
int account_check_string(const char *str)
Definition: account.cpp:361
main
int main(void)
Definition: check_account.cpp:220
account_exists
const char * account_exists(const char *account_name)
Definition: account.cpp:297