def begin_client_registration(self): """Begins the client registration phase.""" sprint(self.name, 'Beginning client registration...') self.phase = Constants.REGISTRATION_PHASE # update servers and neighbors self.broadcast_neighbors()
def replace_stp(self, msg_args): """Handles setting the short-term pseudonyms. stp_list: The list of short-term pseudonyms. generator: Generator for the server to use. init_id: The id of the server that was the first in the ring. """ stp_list, generator, init_id = msg_args self.generator = generator # tell coordinator that announcement phase is finished if init_id == self.server_id: send(config.COORDINATOR_ADDR, [Constants.END_ANNOUNCEMENT_PHASE]) return if init_id == Constants.INIT_ID: init_id = self.server_id # add announcement list to current server sprint(self.name, 'Announcement phase finished. Updated short-term pseudonyms.') self.stp_list = {k: v for (k, v) in stp_list} self.stp_array = [k for (k, v) in stp_list] # modify for printing purposes stp_list_print = {} for k, v in stp_list: stp_list_print[k % Constants.MOD] = v print('stp list: ' + str(stp_list_print)) # update next server send(self.next_addr, [Constants.REPLACE_STP, stp_list, generator, init_id])
def begin_announcement_phase(self): """Begins the announcement phase.""" sprint(self.name, 'Beginning announcement phase...') self.phase = Constants.ANNOUNCEMENT_PHASE # shuffle list of servers random.shuffle(self.servers) # update servers and neighbors self.servers_ready = 0 self.broadcast_neighbors() # pause before beginning announcement phase while self.servers_ready != self.num_servers: time.sleep(0.01) server_addr = self.servers[0] # get ciphertexts (secret, encrypted reputation) secret, reputation = sendrecv(server_addr, [Constants.GET_CIPHERTEXTS]) clients = [] for server_addr in self.servers: clients.extend(sendrecv(server_addr, [Constants.GET_CLIENTS])) for server_addr in self.servers: sendrecv(server_addr, [Constants.UPDATE_CLIENTS, secret, reputation, clients]) send(self.servers[0], [Constants.NEW_ANNOUNCEMENT, Constants.G, [], [], 0, 0, Constants.INIT_ID])
def _print_grader_activity(short_name, dropbox): import os import pwd import datetime found_grader_subs = [] for hash_dir in os.listdir(dropbox): if hash_dir[0] == '.': continue dirpath = dropbox + os.sep + hash_dir dir_st = os.stat(dirpath) dir_ctime = dir_st.st_mtime grader_pw = pwd.getpwuid(dir_st.st_uid) grader_name = grader_pw.pw_name grader_fullname = grader_pw.pw_gecos group = os.listdir(dirpath)[0] t = (grader_name, grader_fullname, group, dir_ctime) found_grader_subs.append(t) util.sprint("grader submission activity:") for name, fullname, group, time in found_grader_subs: on = datetime.datetime.fromtimestamp(time) util.sprint("{} ({}) submitted group {} on {}".format( fullname, name, group, on))
def assertion(self, name, truth, message): # When testing is off this function becomes trivial if not util.config.mode['testing']: return self.run += 1 #Increment Tests Run util.sprint("Running Test: " + name) try: assert truth except AssertionError: self.failed += 1 #Increment Tests failed self.failed_tests += [name + ": " + message] util.sprint( " ERROR in " + name + ": " + message )
def test_maps(): import mapClass as m util.sprint("\n#!# LOCAL TESTS: mapClass.py:") # Creating Testing Resources test = Tester() root = m.Tk() # Attempt to create Map Class try: test_map = m.Map() except Exception as err: util.sprint("Failed to Initialize map::Terminating") return # Attempt to make that Map class realize it's potential try: test_map.__create__(util.local_path("rsc/basicMap.gif"), '__temp__', (10, 5)) except Exception as err: util.sprint("Failed to Create Map::Terminating") return #Test creation test.assertion("Directory creation test", path.exists(temp_path), "Failed to create directory") test.assertion("Background creation test", path.exists(temp_path + '/background.gif'), "Failed to create Background image") test.assertion("Config creation test", path.exists(temp_path + '/config'), "Failed to create Config File") # Rearrange testing resources: for i in range(10): test_map.walls[randint(0,9)][randint(0,4)] = i try: test_map.__save__('__temp2__') temp_map = m.Map('__temp2__') except Exception as err: util.sprint("Failed during Load/Save") # Continue testing: test.assertion("Save/Load test", test_map.walls == temp_map.walls, "Grid comparison failed, ") # Cleanup testing resources: clean_map(file_name) clean_map('__temp2__') root.destroy() # End Message util.sprint("Map Class testing Complete! Failed: [" + str(test.failed) + "/" + str(test.run) + "]") # Return Testing Object return test
def intercept_stacksize_change(new_val): sprint("intercepting call to sys.setrecursionlimit()") old_val = sys.getrecursionlimit() if new_val < old_val: sprint("keeping stack size at " + str(old_val)) return if new_val > 30000: sprint("code wants to set stack size too large") sprint("keeping stack size at " + str(old_val)) return else: sprint("growing stack size to " + str(new_val)) actual_setrecursionlimit(new_val)
def error_assertion(self, name, function, error, message): # When testing is off this function becomes trivial if not util.config.mode['testing']: return self.run += 1 #Increment Tests Run util.sprint("Running Test: " + name) try: function() except Exception as err: try: assert type(err) == type(error) assert err.message == error.message except AssertionError: self.failed += 1 #Increment Tests failed self.failed_tests += [name + ": " + message] util.sprint( " ERROR in " + name + ": " + message )
def __output_matches(self, out_string): """Given a string obtained from the running of a function or module, determine whether the output matches the expected output. This method handles the case where the criteria file specified exact output or a regular expression. """ if type(self.output) is str: return self.output == out_string if 'match' in self.output: import re return self.output['match'].match(out_string) # TODO this might be a bad idea if 'prompt' in self.output: sprint("deduction description: {}".format(self.description)) sprint("deduction value: {}".format(self.deduction)) ans = input("should this deduction be taken? (y/yes/n/no) ") if ans in ['y', 'yes']: return {'deduction': self.deduction, 'description': self.description, 'notes': ["failed human review"]} else: sprint("taking no deduction")
def run(self, path): import os from functools import reduce import prompt _print_file(path) sprint("reviewing '{}' (in directory '{}')".format( path, os.getcwd())) sprint("description: " + self.description) if type(self.deduction) is int: choices = ["do not take this deduction", "take this deduction (-{} points)".format( self.deduction)] got = prompt.prompt(choices, '1') if got == [1]: return {'deduction': self.deduction, 'description': self.description} else: sprint("taking no points") return None elif type(self.deduction) is list: choices = ["{} (-{} {})".format(y, x, plural("point", x)) for x, y in self.deduction] got = prompt.prompt(choices, self.deduction_mode) if sum(map(lambda x: self.deduction[x][0], got)) > 0: deductions = [] for s in got: if self.deduction[s][0] > 0: d = {'deduction': self.deduction[s][0], 'description': self.deduction[s][1]} deductions.append(d) return deductions else: sprint("taking no points") return None
def run_tests(self): import sys import io import os results = dict() results[self] = [] actual_setrecursionlimit = sys.setrecursionlimit def intercept_stacksize_change(new_val): sprint("intercepting call to sys.setrecursionlimit()") old_val = sys.getrecursionlimit() if new_val < old_val: sprint("keeping stack size at " + str(old_val)) return if new_val > 30000: sprint("code wants to set stack size too large") sprint("keeping stack size at " + str(old_val)) return else: sprint("growing stack size to " + str(new_val)) actual_setrecursionlimit(new_val) sys.setrecursionlimit = intercept_stacksize_change try: directory, name = os.path.split(self.path) mod_name = name[:name.index('.py')] if '.py' in name else name sys.path.append(directory) sprint(COLOR_GREEN + "importing module '{}'".format(mod_name) + \ COLOR_RESET) # redirect standard out to empty buffer to "mute" the program #sys.stdout = io.StringIO() module_context = __import__(mod_name) #sys.stdout = sys.__stdout__ sprint(COLOR_GREEN + "finished importing " "module".format(mod_name) + COLOR_RESET) except: # "un-mute" the program and give socrates access to stdout #sys.stdout = sys.__stdout__ import traceback err = sys.exc_info() sprint("encountered an error importing " "'{}' module ({})".format(mod_name, err[0].__name__)) traceback.print_exc() if self.error_deduction: deduction = self.error_deduction else: deduction = self.point_value sprint(COLOR_YELLOW + "deducting {} points for error during " "import".format(deduction) + COLOR_RESET) return [{'deduction': deduction, 'description': "error importing '{}'".format(self.path), 'notes': ["encountered {}".format(err[0].__name__)]}] found_functions = self.__get_members(module_context, 'functions') found_variables = self.__get_members(module_context, 'variables') for test in self.tests: result = test.run(module_context) if result is not None: add_to(result, results[self]) for func in self.functions: results[func] = [] if func not in found_functions: results[func].append({'deduction': func.point_value, 'description': "missing function " "'{}'".format(func)}) continue for test in func.tests: # TODO fix this hacky thing if type(test) is TestSet: for m in test.members: m.target = func result = test.run(module_context) if result is not None: add_to(result, results[func]) for var in self.variables: results[var] = [] if var not in found_variables: results[var].append({'deduction': var.point_value, 'description': "missing variable " "'{}'".format(var)}) continue for test in var.tests: # TODO fix this hacky thing if type(test) is TestSet: for m in test.members: m.target = var result = test.run(module_context) if result is not None: add_to(result, results[var]) for target, failures in results.items(): sum = 0 for f in failures: sum += f['deduction'] if sum > target.point_value: f['deduction'] = 0 return [item for subl in results.values() for item in subl]
def update_id(self, msg_args): """Handle request to update the server id.""" self.server_id = msg_args[0] sprint(self.name, 'Server id: {}'.format(self.server_id))
def begin_feedback_phase(self): """Begins the feedback phase.""" sprint(self.name, 'Beginning feedback phase...') self.phase = Constants.FEEDBACK_PHASE
def test_util(): util.sprint("\n#!# LOCAL TESTS: util.py:") # Creating Testing Resources test = Tester() iList = [ 4, "hi", [1], (2, 3), False, list ] tList = [ type(i) for i in iList ] tFileName = util.local_path('temp_config') tFile = open(tFileName, 'w') tFile.write("# Graphics Options:\n Test Setting : 123\n Other:(12,foo)\n" + "#### Keybinds Options \n #### EOF") tFile.close() tConfig = util.Config(file=tFileName) tPos = util.LoopPos((5,10), (2, 3)) tGrid = util.Grid(5, 5, "Hello") tGrid[1][2] += "!" tBGrid = util.BitGrid() # Run Tests # Testing: type_check: for i in range(len(iList)): test.assertion("type_check test " + str(i), util.type_check(tList[i], iList[i]), "single item check: " + type(iList[i]).__name__) # type_check: Type List Tests for i in range(len(iList)): test.assertion("type_check list test " + str(i), util.type_check(tList, iList[i]), "Type-List input with: " + str(iList[i])) # Multi-Item Test test.assertion("type_check item list test", util.type_check( tList, iList[0], iList[1], iList[2], iList[3] ), "Type-List, Multi-Item Input.") # type_check: Fail Tests for i in range(len(tList)): test.assertion("type_check failure test " + str(i), not util.type_check(tList[:i] + tList[i+1:], iList[i]), "negative test for: " + type(iList[i]).__name__) for i in range(len(tList)): test.assertion("type_check multi-item failure test " + str(i), not util.type_check( tList[:i] + tList[i+1:], iList[0], iList[1], iList[2], iList[3], iList[4], iList[5] ), "negative test excluding: " + type(iList[i]).__name__) # type_check: Exception Test errorMsg = "type_check given int, where it needs type or list of types" test.error_assertion("type_check exception test", lambda: util.type_check(1, int), TypeError(errorMsg), "exception test") # Testing config file reader: test.assertion("Config file test 0", tConfig.settings['Test Setting'] == 123, "Integer setting failed to load" ) test.assertion("Config file test 1", type(tConfig.settings['Other']) is tuple, "Tuple type not discovered" ) test.assertion("Config file test 2", type(tConfig.settings['Other'][0]) is int, "Integer type not discovered" ) test.assertion("Config file test 3", type(tConfig.settings['Other'][1]) is str, "Str type not Discovered" ) # Testing LoopPos: test.assertion("LoopPos Starting Value Test", tPos[0] == 2 and tPos[1] == 3, "Starting values mismatched") tPos[0] += 11 tPos[1] -= 19 test.assertion("LoopPos Addition Test", tPos[0] == 3 and tPos[1] == 4, "Addition didn't loop correctly") # Testing Grid & BitGrid: test.assertion("Grid Default Test", tGrid[0][0] == "Hello", "Default was not loaded into grid") test.assertion("Grid Assignment Test", tGrid[1][2] == "Hello!", "Item did not assign to Grid") test.assertion("BitGrid Default Test", tBGrid[0][0] == [], "BitGrid Default was %s not 0" % (str(tBGrid[0][0]))) tAssignments = [ 'Right', 'Left', 'Down', 'Up'] for i, t in enumerate(tAssignments): tBGrid[0][0] = t test.assertion("BitGrid Directional Assignment Test: %s" % (t), t in tBGrid[0][0], "Directional Assignment Failed for %s" % (t)) tBGrid[0][0] = 1 << i test.assertion("BitGrid Numeric Assignment Test: %s" % (t), t in tBGrid[0][0], "Directional Assignment Failed for %s" % (t)) test.assertion("BitGrid Other Item Test %s" % (t), False not in [ o not in tBGrid[0][0] for o in tAssignments if not o == t], "Directional Assignment Failed for %s" % (t)) # Clean-up testing resources remove(util.local_path('temp_config')) # End Message util.sprint("Util testing Complete! Failed: [" + str(test.failed) + "/" + str(test.run) + "]") # Return testing object return test
def end_announcement_phase(self, msg_args): """Handles end of announcement phase.""" sprint(self.name, 'Beginning message phase...') self.phase = Constants.MESSAGE_PHASE
def __run_function(self, context): import sys import io mod_name = context.__name__ fn_name = self.target.name formatted_args = self.__format_args(context) fn_call = "{}.{}({})".format(mod_name, fn_name, formatted_args) building_desc = False if not self.description: building_desc = True self.description = fn_call + " should " if self.input is not None: in_buf = io.StringIO(self.input) sys.stdin = in_buf if building_desc: self.description = "on input {}, ".format(repr(self.input)) + \ self.description if self.output is not None: out_buf = io.StringIO() sys.stdout = out_buf if building_desc: self.description += "output {} ".format(repr(self.output)) if self.value is not None and building_desc: if self.output: self.description += "and " self.description += "return {}".format(repr(self.value)) if self.random_seed: import random random.seed(self.random_seed) if building_desc: self.description = "with random seed {}, ".format( self.random_seed) + self.description try: return_value = eval(fn_call, globals(), {mod_name:context}) except: import sys err = sys.exc_info() sys.stdin, sys.stdout = sys.__stdin__, sys.__stdout__ sprint(COLOR_YELLOW + "failing a test due to an " "error ({})".format(err[1]) + COLOR_RESET) return {'deduction': self.deduction, 'description': self.description, 'notes': [str(err[1]) + " (" + str(err[0].__name__) + ")"]} # restore default standard in/out sys.stdin, sys.stdout = sys.__stdin__, sys.__stdout__ if self.output is not None: output = out_buf.getvalue() passed = True if self.value is not None: passed = passed and self.value == return_value if self.output is not None: passed = passed and self.__output_matches(output) if passed: return None else: result = {'deduction': self.deduction, 'description': self.description, 'notes': []} if self.value is not None: result['notes'].append("expected value: " + repr(self.value)) result['notes'].append("produced value: " + repr(return_value)) if self.output is not None and type(self.output) is str: import util eo, po = util.escape(self.output), util.escape(output) result['notes'].append("expected output: " + eo) result['notes'].append("produced output: " + po) return result
def test_engine(): import engineClass as e util.sprint("\n#!# LOCAL TESTS: engineClass.py:") # Creating Testing Resources up, down, left, right, select = [lambda: e.Event() for i in range(5)] test = Tester() up.keysym = 'Up' down.keysym = 'Down' left.keysym = 'Left' right.keysym = 'Right' select.keysym = 'Return' # Run a Simulation of the Editor try: util.sprint("Creating Editor Simulation") # Build and Handle Prompt 1 engine = e.Engine(e.ImgFileName, "Testing!") key = e.Event() util.sprint("Simulating Image location prompt") for char in util.local_path("rsc/basicMap.gif"): if char == '.': char = 'period' elif char == '\\': char = 'backslash' elif char == ':': char = 'colon' elif char == '/': char = 'slash' key.keysym = char engine.GUI.mode.__keypress__(key) engine.GUI.mode.__keypress__(select) except: util.sprint("Excepetion raised during prompt simulation 1") test.assertion("ImgFileName completion test", util.type_check(e.NewFileName, engine.GUI.mode), "Prompt failed to advance " + str(type(engine.GUI.mode))) # Handle Prompt 2 try: util.sprint("Simulating new file name prompt") for char in file_name: if char == '_': char = 'underscore' key.keysym = char engine.GUI.mode.__keypress__(key) engine.GUI.mode.__keypress__(select) except: util.sprint("Exception raised during prompt simulation 2") test.assertion("NewFileName completion test", util.type_check(e.TileDimension, engine.GUI.mode), "Prompt failed to advance") # Handle Prompt 3 try: util.sprint("Simulating tile dimension prompt") for char in "10,11": if char == ',': char = 'comma' key.keysym = char engine.GUI.mode.__keypress__(key) engine.GUI.mode.__keypress__(select) except: util.sprint("Exception raised during prompt simulation 3") test.assertion("TileDimension completion test", util.type_check(e.Editor, engine.GUI.mode), "Prompt failed to advance") # Handle Main Editor: try: # Placing a 5 in [9][8] and a 4 in [9][10] util.sprint("Simulating main Editor") engine.GUI.mode.__keypress__(up) engine.GUI.mode.__keypress__(left) engine.GUI.mode.__keypress__(select) # Select Bottom Right Tile engine.GUI.mode.__keypress__(down) engine.GUI.mode.__keypress__(right) key.keysym = 'BackSpace' engine.GUI.mode.__keypress__(key) engine.GUI.mode.__keypress__(up) engine.GUI.mode.__keypress__(up) engine.GUI.mode.__keypress__(select) # Select Tile 2 Up from BotRight engine.GUI.mode.__keypress__(down) engine.GUI.mode.__keypress__(select) engine.GUI.mode.__keypress__(select) # Create New Item except: util.sprint("Exception raised during prompt simulation 3") # Simulate NewItemFile Prompt try: util.sprint("\tSimulating NewItemFile Prompt") for char in util.local_path("rsc/add.gif"): if char == '.': char = 'period' elif char == '\\': char = 'backslash' elif char == ':': char = 'colon' elif char == '/': char = 'slash' key.keysym = char engine.GUI.mode.__keypress__(key) engine.GUI.mode.__keypress__(select) except: util.sprint("Exception Raised during NewItemFile simulation") # Simulate NewItemStats Prompt; then Save and Exit try: util.sprint("\tSimulating NewItemStats Prompt") engine.GUI.mode.__keypress__(down) engine.GUI.mode.__keypress__(select) # Select Name Field key.keysym = 'Z' engine.GUI.mode.__keypress__(key) key.keysym = 'e' engine.GUI.mode.__keypress__(key) key.keysym = 'd' engine.GUI.mode.__keypress__(key) engine.GUI.mode.__keypress__(select) # Progress to Health engine.GUI.mode.__keypress__(select) key.keysym = '1' engine.GUI.mode.__keypress__(key) key.keysym = '0' engine.GUI.mode.__keypress__(key) engine.GUI.mode.__keypress__(select) # Progess to Attack engine.GUI.mode.__keypress__(select) key.keysym = '2' engine.GUI.mode.__keypress__(key) engine.GUI.mode.__keypress__(select) # Progress to Speed engine.GUI.mode.__keypress__(select) key.keysym = '4' engine.GUI.mode.__keypress__(key) engine.GUI.mode.__keypress__(select) # Progress to Range engine.GUI.mode.__keypress__(select) key.keysym = '3' engine.GUI.mode.__keypress__(key) engine.GUI.mode.__keypress__(select) # Progress to Done engine.GUI.mode.__keypress__(select) util.sprint("\tSimulating Save&Exit") key.keysym = 'BackSpace' engine.GUI.mode.__keypress__(key) engine.GUI.mode.__keypress__(down) engine.GUI.mode.__keypress__(down) except: util.sprint("Exception raised during prompt simulation (item creation)") # Save and Exit needs to be outside of 'Try': engine.GUI.mode.__keypress__(select) try: test_file = open( temp_path + '/config' ) except: util.sprint("Exception raised while reading config file") contents = test_file.readlines() test.assertion("config contents test", int(contents[10].split(",")[9]) == 4 and int(contents[12].split(",")[9]) == 5 and int(contents[22].split(",")[9]) == 1 and "ENEMY: Zed" in contents[26] and "10" in contents[27] and "2" in contents[28] and "4" in contents[29] and "3" in contents[30], "bad config file contents") # Clean-up testing resources test_file.close() clean_map(file_name) # End Message util.sprint( "Engine testing Complete! Failed: [" + str(test.failed) + "/" + str(test.run) + "]" ) # Return testing object return test
util.log_file.write(str(now) + '\n') if args.mode == 'config': import inspect for m in inspect.getmembers(config): if m[0][0] != '_' and not inspect.ismodule(m[1]): print("{}: {}".format(m[0], m[1])) sys.exit() if args.mode in ['grade', 'submit']: import grader try: c = criteria.Criteria.from_yaml(args.criteria_file) except FileNotFoundError: util.sprint("criteria file does not exist", error=True) sys.exit(util.ERR_CRITERIA_MISSING) except IsADirectoryError: util.sprint("specified criteria is a directory", error=True) sys.exit(util.ERR_CRITERIA_IMPORT) except: import traceback err = sys.exc_info() util.sprint("error importing criteria: {} (" "{})".format(err[0].__name__, err[1]), error=True) traceback.print_exc() sys.exit(util.ERR_CRITERIA_IMPORT) grade_filename = c.name + (c.group if c.group else "") + "-grade.txt"
def restart_round(self, msg_args): """Handles signal to restart the round.""" sprint(self.name, 'Round has ended. Starting new round...') self.coordinator.phase = Constants.ANNOUNCEMENT_PHASE
def start_coinshuffle(self): """Begins Coinshuffle phase.""" sprint(self.name, 'Beginning CoinShuffle phase...') # Commits all the changes in reputation to the blockchain. promises = [] for i in range(self.message_marker, len(self.board)): addresses = self.board[i][1][Constants.REP] net_fb = (self.board[i][1][Constants.FB][0] + self.board[i][1][Constants.FB][1]) if net_fb > 0: promises.append( self.blockchain.add_reputation(addresses[0], net_fb)) elif net_fb < 0: to_remove = -net_fb for address in addresses: can_remove = min(to_remove, self.blockchain.get_reputation(address)) promises.append( self.blockchain.remove_reputation(address, can_remove)) to_remove -= can_remove if to_remove <= 0: break for promise in promises: promise.resolve() # reset used_wallets self.used_wallets = set() self.coordinator.phase = Constants.COINSHUFFLE_PHASE # contains a list of (wallet, balance_of_wallet) that need to be transfered # to another wallet self.spending_wallets = [] self.spending_wallets_total = 0 # determine which clients should participate in the coinshuffle final_balances = defaultdict(int) for i in range(self.message_marker, len(self.board)): addr = self.msg_id_to_addr[i] # check if this user has > 0 reputation for wallet in self.board[i][1][Constants.REP]: balance = self.blockchain.get_reputation(wallet) final_balances[addr] += balance if balance > 0: self.spending_wallets.append((wallet, balance)) self.spending_wallets_total += balance # let all clients know whether they are participating in the shuffle or not. participants = [] for addr, balance in final_balances.items(): if balance > 0: encryption_key = sendrecv( addr, [Constants.PARTICIPATION_STATUS, balance]) participants.append((addr, encryption_key)) else: send(addr, [Constants.PARTICIPATION_STATUS, balance]) # iterate over participants and send them the encyption keys that # they need, get ack. e_keys = [] for i, (addr, e_key) in enumerate(reversed(participants)): if i == 0: next_addr = self.coordinator.addr else: next_addr = participants[len(participants) - i][0] # send participants encryption keys next hop in the ring sendrecv(addr, [Constants.KEYS, next_addr, e_keys]) e_keys.append(e_key) # start the shuffling if len(participants) == 0: self.coordinator.phase = Constants.COINSHUFFLE_FINISHED_PHASE return sendbytes(participants[0][0], b'')