def plot_test_timing(plot, stats, marathon_type, test_type, xticks): """ Plots a specific test graph. In addition, it sets the legend title, and flags the highest scale reached. :param plot: The matplotlib subplot object is the object that will be plotted :type plot: matplotlib subplot :param stats: This map contains the data to be plotted :type stats: map :param marathon_type: The type of marathon is part of the map key. For scale tests it is `root` (vs. mom1) :type marathon_type: str :param test_type: Defines the test type, usually {instances, count, group} :type test_type: str :param xticks: An array of scale targets (1, 10, 100) for the x axis of the plot :type xticks: array """ deploy_time = stats.get(get_key(marathon_type, test_type, 'deploy_time')) if deploy_time is None or len(deploy_time) == 0 or deploy_time[0] <= 0.0: return timings = np.array(deploy_time) title = '{} Scale Times'.format(test_type.title()) timings = pad(timings, len(xticks)) timings_handle, = plot.plot(xticks, timings, label=title) fail_index = index_of_first_failure(stats, marathon_type, test_type) if fail_index > 0: scale_at_fail = stats.get(get_key(marathon_type, test_type, 'max'))[fail_index] time_at_fail = stats.get( get_key(marathon_type, test_type, 'human_deploy_time'))[fail_index] text = '{} at {}'.format(scale_at_fail, time_at_fail) plot.text(fail_index, timings[fail_index], text, wrap=True)
def plot_test_timing(plot, stats, marathon_type, test_type, xticks): """ Plots a specific test graph. In addition, it sets the legend title, and flags the highest scale reached. :param plot: The matplotlib subplot object is the object that will be plotted :type plot: matplotlib subplot :param stats: This map contains the data to be plotted :type stats: map :param marathon_type: The type of marathon is part of the map key. For scale tests it is `root` (vs. mom1) :type marathon_type: str :param test_type: Defines the test type, usually {instances, count, group} :type test_type: str :param xticks: An array of scale targets (1, 10, 100) for the x axis of the plot :type xticks: array """ deploy_time = stats.get(get_key(marathon_type, test_type, 'deploy_time')) if deploy_time is None or len(deploy_time) == 0 or deploy_time[0] <= 0.0: return timings = np.array(deploy_time) title = '{} Scale Times'.format(test_type.title()) timings = pad(timings, len(xticks)) timings_handle, = plot.plot(xticks, timings, label=title) fail_index = index_of_first_failure(stats, marathon_type, test_type) if fail_index > 0: scale_at_fail = stats.get(get_key(marathon_type, test_type, 'max'))[fail_index] time_at_fail = stats.get(get_key(marathon_type, test_type, 'human_deploy_time'))[fail_index] text = '{} at {}'.format(scale_at_fail, time_at_fail) plot.text(fail_index, timings[fail_index], text, wrap=True)
def plot_test_errors(plot, stats, marathon_type, test_type, xticks): """ Plots the number of errors for a given test :param plot: The matplotlib subplot object is the object that will be plotted :type plot: matplotlib subplot :param stats: This map contains the data to be plotted :type stats: map :param marathon_type: The type of marathon is part of the map key. For scale tests it is `root` (vs. mom1) :type marathon_type: str :param test_type: Defines the test type, usually {instances, count, group} :type test_type: str :param xticks: An array of scale targets (1, 10, 100) for the x axis of the plot :type xticks: array """ test_errors = stats.get(get_key(marathon_type, test_type, 'errors')) if test_errors is None or len(test_errors) == 0: return 0 plot.set_title("Errors During Test") errors = np.array(test_errors) title = '{} Errors'.format(test_type.title()) errors = pad(errors, len(errors)) errors_handle, = plot.plot(xticks, errors, label=title, marker='o', linestyle='None') return max(test_errors)
def load(csvfile): """ This is suppose to be short-term. Teammates have better ideas on how to structure the data. I would like to not break the ability to call it directly from the test (instead of shelling out). index after table header: 0 - target - expected scale 1 - max - actual scale 2 - deploy_time 3 - human_deploy_time 4 - launch_status 5 - deployment_status 6 - errors """ row_keys = [ 'target', 'max', 'deploy_time', 'human_deploy_time', 'launch_status', 'deployment_status', 'errors' ] stats = empty_stats() current_marathon = None current_test_type = None index_from_header = 0 with open(csvfile, 'r') as f: reader = csv.reader(f, quoting=csv.QUOTE_NONNUMERIC) for i, row in enumerate(reader): if 'Marathon:' in row: current_marathon = row[1] current_test_type = row[2] index_from_header = 0 elif len(row) > 0: key = get_key(current_marathon, current_test_type, row_keys[index_from_header]) stats[key] = row index_from_header += 1 return stats
def load(csvfile): """ This is suppose to be short-term. Teammates have better ideas on how to structure the data. I would like to not break the ability to call it directly from the test (instead of shelling out). index after table header: 0 - target - expected scale 1 - max - actual scale 2 - deploy_time 3 - human_deploy_time 4 - launch_status 5 - deployment_status 6 - errors """ row_keys = ['target', 'max', 'deploy_time', 'human_deploy_time', 'launch_status', 'deployment_status', 'errors'] stats = empty_stats() current_marathon = None current_test_type = None index_from_header = 0 with open(csvfile, 'r') as f: reader = csv.reader(f, quoting=csv.QUOTE_NONNUMERIC) for i, row in enumerate(reader): if 'Marathon:' in row: current_marathon = row[1] current_test_type = row[2] index_from_header = 0 elif len(row) > 0: key = get_key(current_marathon, current_test_type, row_keys[index_from_header]) stats[key] = row index_from_header += 1 return stats
def index_of_first_failure(stats, marathon_type, test_type): """ Finds the first occurance of an error during a deployment """ index = -1 deploy_status = stats.get(get_key(marathon_type, test_type, 'deployment_status')) for status in deploy_status: index += 1 if "f" == status: return index return -1
def get_scale_targets(stats, marathon_type, test_types): """ Returns the scale targets 1, 10, 100, 1000 It is possible that some tests are ignored so we may have to loop to grab the right list. :param stats: This map contains the data to be plotted :type stats: map :param marathon_type: The type of marathon is part of the map key. For scale tests it is `root` (vs. mom1) :type marathon_type: str :param test_types: An array of test types to be graphed, usually {instances, count, group} :type test_types: array """ targets = None for test_type in test_types: targets = stats.get(get_key(marathon_type, test_type, 'target')) if targets and len(targets) > 0: return targets return targets
def error_graph_enabled(stats, marathon_type, test_types): """ Returns true if there is any error data to graph :param stats: This map contains the data to be plotted :type stats: map :param marathon_type: The type of marathon is part of the map key. For scale tests it is `root` (vs. mom1) :type marathon_type: str :param test_types: An array of test types to be graphed, usually {instances, count, group} :type test_types: array """ enabled = False for test_type in test_types: test_errors_key = get_key(marathon_type, test_type, 'errors') if test_errors_key is not None: test_errors = stats.get(test_errors_key) # if there are test errors... graph them if test_errors is not None and len(test_errors) > 0: return True return False