Odyssey
generate_cu_data.py
1 #!/usr/bin/env python
2 '''Generate SQL statements for CU'''
3 
4 
5 from faker import Faker
6 import bcrypt
7 import random
8 import json
9 import os
10 import sys
11 import tempfile
12 
13 TIMEFORMAT = '%Y-%m-%d %H:%M:%S '
14 
15 
16 def generate_test_data(N=1000):
17  '''Generate test data'''
18  CU = 'gatlingcu'
19  FAKER = Faker()
20  (gatling_data, sql) = generate_profiles(FAKER, CU, N)
21  tmpdir = tempfile.gettempdir()
22  with open(os.path.join(tmpdir, "gatling.users.json"), "w") as users_json:
23  print(json.dumps(gatling_data, indent=4), file=users_json)
24  with open(os.path.join(tmpdir, "gatling.users.sql"), "w") as users_sql:
25  for s in sql:
26  print(s, file=users_sql)
27  print('\n\n\n', file=users_sql)
28 
29 
30 def generate_profiles(faker, cu, N=1000):
31  '''Generate profiles'''
32  USERNAMES = {}
33 
34  def generate():
35  '''do generation'''
36  for i in range(0, N):
37  profile = generate_cuuser(i, faker, cu, USERNAMES)
38  yield (gatling_test_data(profile),
39  generate_profile_sql(profile))
40 
41  profiles = list(generate())
42  return ([x[0] for x in profiles], [x[1] for x in profiles])
43 
44 
45 def generate_profile_sql(profile):
46  '''Generate CU SQL inserts'''
47  sqls = [
48  generate_cuuser_sql(profile),
49  generate_cugroup_sql(profile),
55  ]
56  return '\n'.join(sqls)
57 
58 
59 def bool_to_str(b):
60  '''return Y or N, ugh...'''
61  return 'Y' if b else 'N'
62 
63 
64 def random_bool_to_str(faker):
65  '''return random bool as str'''
66  return bool_to_str(faker.boolean())
67 
68 
69 def generate_cuuser(index, faker, cu, USERNAMES):
70  '''Generate CU user information, return dictionary'''
71  r = random.Random()
72  # Ensure we are generating unique profiles
73  while True:
74  profile = faker.simple_profile(sex=None)
75  if USERNAMES.get(profile['username']) is None:
76  USERNAMES[profile['username']] = 1
77  break
78  uid = index + 1
79  account_balance = r.random() * r.randint(10, 100)
80  return {**profile, **{
81  'cu': cu,
82  'user_id': uid,
83  'account_number': uid,
84  'account_description': faker.sentence(nb_words=3),
85  'account_balance': account_balance,
86  'account_ytdinterest': r.random() * r.randint(1, 12),
87  'account_lastyrinterest': r.random() * r.randint(1, 12),
88  'account_available': account_balance - r.random() * r.randint(1, 3),
89  'group': uid,
90  'password': faker.password(length=10),
91  'primary_accounts': uid,
92  'billpayid': uid + r.randint(1, 20),
93  'estmt_flag': random_bool_to_str(faker),
94  'egenl_flag': 'N',
95  'failedremain': 5,
96  'forcechange': 'N',
97  'forceremain': r.randint(0, 100),
98  'lastlogin': faker.past_datetime().strftime(TIMEFORMAT),
99  'priorlogin': faker.past_datetime().strftime(TIMEFORMAT),
100  'pwchange': faker.past_datetime().strftime(TIMEFORMAT),
101  'msg_tx': 0,
102  'employee': 'N',
103  'userflags': 0,
104  'confidence': faker.text(max_nb_chars=20),
105  'challenge_quest_id': 0,
106  'mfaquest': {
107  'answers': {
108  '54': faker.word(),
109  },
110  'challenge': 0
111  }
112  }}
113 
114 
115 def generate_cuuser_sql(profile):
116  '''Generate statement for cusuer'''
117  TEMPLATE = ('INSERT INTO {cu}user VALUES('
118  '{user_id},'
119  '{group},'
120  "'{username}',"
121  "'{passwd}',"
122  "'{mail}',"
123  '{primary_accounts},'
124  "'{egenl_flag}',"
125  '{failedremain},'
126  "'{forcechange}',"
127  '{forceremain},'
128  'NULL,'
129  'NULL,'
130  'NULL,'
131  "'{pwchange}',"
132  '{msg_tx},'
133  "'{employee}',"
134  '{userflags},'
135  "'{confidence}',"
136  '{challenge_quest_id},'
137  'NULL,'
138  'NULL,'
139  'NULL,'
140  "'{name}',"
141  'NULL,'
142  'NULL,'
143  'NULL,'
144  "'{mfaquest}');")
145  return TEMPLATE.format(**{**profile, **{
146  'passwd': bcrypt.hashpw(profile['password'].encode('utf8'),
147  bcrypt.gensalt()).decode('utf8'),
148  'mfaquest': json.dumps(profile['mfaquest']),
149  }})
150 
151 
152 def generate_cugroup_sql(profile):
153  '''Generate statement for cugroup'''
154  TEMPLATE = ("INSERT INTO {cu}group VALUES ({group}, '{group}', 200, 0);")
155  return TEMPLATE.format(**profile)
156 
157 
159  '''Generate statement for cu member accounts'''
160  TEMPLATE = ('INSERT INTO {cu}memberacct VALUES('
161  '{user_id},'
162  "'{account_number}',"
163  "'{estmt_flag}',"
164  '{billpayid},'
165  '0,'
166  "'L',"
167  'NULL,'
168  'NULL);')
169  return TEMPLATE.format(**profile)
170 
171 
173  '''Generate INSERT statement for cu member account balance'''
174  TEMPLATE = ('INSERT INTO {cu}accountbalance VALUES('
175  "'{account_number}',"
176  "'502',"
177  '0,'
178  "'Y',"
179  "'{account_description}',"
180  '{account_balance},'
181  '{account_ytdinterest},'
182  '{account_lastyrinterest},'
183  '{account_available},'
184  'NULL,'
185  'true,'
186  'true,'
187  'NULL,'
188  'NULL,'
189  "'',"
190  'NULL,'
191  'NULL,'
192  'NULL,'
193  'NULL,'
194  'NULL);')
195  return TEMPLATE.format(**profile)
196 
197 
199  '''Generate SQL insert statements for account history'''
200  FAKER = Faker()
201  r = random.Random()
202  TEMPLATE = ('INSERT INTO {cu}accounthistory VALUES('
203  "'{account_number}',"
204  "'502',"
205  '0,'
206  "'{trace_number}',"
207  "'0',"
208  "'{date}',"
209  '{amount},'
210  "'{description}',"
211  '{balance},'
212  'NULL,'
213  "'{sortkey}');")
214 
215  def generate():
216  '''do generation'''
217  INT_MAX = int((2 ** 32 - 1) / 2)
218  for i in range(1, r.randint(2, 6)):
219  amount = r.random() * r.randint(10, 20)
220  yield TEMPLATE.format(**{**profile, **{
221  'trace_number': str(r.randint(1, INT_MAX)).zfill(20),
222  'date': FAKER.past_datetime().strftime(TIMEFORMAT),
223  'amount': amount,
224  'balance': profile['account_balance'] - amount,
225  'description': FAKER.sentence(nb_words=6),
226  'sortkey': str(r.randint(1, INT_MAX)).zfill(16),
227  }})
228  return '\n'.join(generate())
229 
230 
232  '''Generate statement for cu member account rights'''
233  TEMPLATE = ('INSERT INTO {cu}memberacctrights VALUES('
234  '{user_id},'
235  "'{account_number}',"
236  "'ACCESS',"
237  'true,'
238  'NULL);')
239  return TEMPLATE.format(**profile)
240 
241 
243  '''Generate statement for cu user accounts'''
244  TEMPLATE = ('INSERT INTO {cu}useraccounts VALUES('
245  '{user_id},'
246  "'{account_number}',"
247  "'502',"
248  '0,'
249  "'D',"
250  "'',"
251  'true,'
252  'true,'
253  'true,'
254  'true,'
255  'true,'
256  'true,'
257  '0,'
258  '30,'
259  "'D');")
260  return TEMPLATE.format(**profile)
261 
262 
263 def gatling_test_data(profile):
264  '''filter fields for gatling test harness'''
265  KEYS = {
266  'username': None,
267  'mail': lambda x: ('email', x),
268  'password': None,
269  'cu': lambda x: ('cu', x.upper()),
270  'account_number': lambda x: ('account_id', x),
271  'mfaquest': lambda x: ('mfa', x['answers']['54']),
272  }
273 
274  def filter_keys(profile, keys):
275  '''Filter out keys, based on KEYS dictionary'''
276  for k, f in keys.items():
277  if not f:
278  yield (k, profile[k])
279  else:
280  yield f(profile[k])
281  return dict(filter_keys(profile, KEYS))
282 
283 
284 if __name__ == '__main__':
285  N = 1000
286  if len(sys.argv[1:]) > 0:
287  N = int(sys.argv[1])
def generate_cuaccountbalance_sql(profile)
def generate_cugroup_sql(profile)
def gatling_test_data(profile)
def generate_cumemberacct_sql(profile)
def generate_cuuser_sql(profile)
def generate_cumemberacctrights_sql(profile)
def random_bool_to_str(faker)
def generate_cuuseraccounts_sql(profile)
def generate_cuuser(index, faker, cu, USERNAMES)
def generate_cuaccounthistory_sql(profile)
def generate_profile_sql(profile)
def generate_test_data(N=1000)
def generate_profiles(faker, cu, N=1000)