Exemple #1
0
def calculate_proper_timeframe(low_value,
                               high_value,
                               start_time,
                               end_time,
                               aggregation,
                               time_as_ts=False):
    start_time = str_to_timestamp(start_time)
    end_time = str_to_timestamp(end_time)
    interval = end_time - start_time
    start_shift = interval * (float(low_value) / 100.0)
    end_shift = interval * (float(high_value) / 100.0)
    end_time = start_time + end_shift
    start_time += start_shift
    real_interval = end_time - start_time
    seconds = real_interval / MAX_DOTS_ON_CHART
    if seconds > 1:
        seconds = int(seconds)
    else:
        seconds = 1
    if aggregation == 'auto':
        aggregation = f'{seconds}s'
    if time_as_ts:
        return int(start_time), int(end_time), aggregation
    return (datetime.fromtimestamp(
        start_time, tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z"),
            datetime.fromtimestamp(
                end_time, tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z"),
            aggregation)
Exemple #2
0
def calculate_proper_timeframe(build_id,
                               test_name,
                               lg_type,
                               low_value,
                               high_value,
                               start_time,
                               end_time,
                               aggregation,
                               time_as_ts=False):
    start_time = str_to_timestamp(start_time)
    end_time = str_to_timestamp(end_time)
    interval = end_time - start_time
    start_shift = interval * (float(low_value) / 100.0)
    end_shift = interval * (float(high_value) / 100.0)
    end_time = start_time + end_shift
    start_time += start_shift
    if time_as_ts:
        return int(start_time), int(end_time), aggregation
    t_format = "%Y-%m-%dT%H:%M:%S.000Z"
    start_time = datetime.fromtimestamp(start_time,
                                        tz=timezone.utc).strftime(t_format)
    end_time = datetime.fromtimestamp(end_time,
                                      tz=timezone.utc).strftime(t_format)
    if aggregation == 'auto':
        aggregation = calculate_auto_aggregation(build_id, test_name, lg_type,
                                                 start_time, end_time)
    return start_time, end_time, aggregation
Exemple #3
0
def get_test_details(project_id, build_id, test_name, lg_type):
    test = {
        "start_time": 0,
        "name": test_name,
        "environment": "",
        "type": "",
        "end_time": 0,
        "failures": 0,
        "total": 0,
        "thresholds_missed": 0,
        "throughput": 0,
        "vusers": 0,
        "duration": 0,
        "1xx": 0,
        "2xx": 0,
        "3xx": 0,
        "4xx": 0,
        "5xx": 0,
        "build_id": build_id,
        "lg_type": lg_type,
        "requests": []
    }
    q_start_time = f"select time, active from {lg_type}_{project_id}..\"users\" " \
                   f"where build_id='{build_id}' order by time asc limit 1"
    q_end_time = f"select time, active from {lg_type}_{project_id}..\"users\" " \
                 f"where build_id='{build_id}' order by time desc limit 1"
    q_response_codes = f"select \"1xx\", \"2xx\", \"3xx\", \"4xx\", \"5xx\", \"ko\" as KO, " \
                       f"\"total\" as Total, \"throughput\" from comparison_{project_id}..api_comparison " \
                       f"where build_id='{build_id}' and request_name='All'"
    q_total_users = f"show tag values on comparison_{project_id} with key=\"users\" where build_id='{build_id}'"
    q_env = f"show tag values on comparison_{project_id} with key=\"env\" where build_id='{build_id}'"
    q_type = f"show tag values on comparison_{project_id} with key=\"test_type\" where build_id='{build_id}'"
    q_requests_name = f"show tag values on comparison_{project_id} with key=\"request_name\" " \
                      f"where build_id='{build_id}'"
    client = get_client(project_id)
    test["start_time"] = list(client.query(q_start_time)["users"])[0]["time"]
    test["end_time"] = list(client.query(q_end_time)["users"])[0]["time"]
    test["duration"] = round(
        str_to_timestamp(test["end_time"]) -
        str_to_timestamp(test["start_time"]), 1)
    test["vusers"] = list(
        client.query(q_total_users)["api_comparison"])[0]["value"]
    test["environment"] = list(
        client.query(q_env)["api_comparison"])[0]["value"]
    test["type"] = list(client.query(q_type)["api_comparison"])[0]["value"]
    test["requests"] = [
        name["value"]
        for name in client.query(q_requests_name)["api_comparison"]
    ]
    response_data = list(client.query(q_response_codes)['api_comparison'])[0]
    test['total'] = response_data['Total']
    test['failures'] = response_data['KO']
    test['throughput'] = round(response_data['throughput'], 1)
    test['1xx'] = response_data['1xx']
    test['2xx'] = response_data['2xx']
    test['3xx'] = response_data['3xx']
    test['4xx'] = response_data['4xx']
    test['5xx'] = response_data['5xx']
    return test
Exemple #4
0
def get_hits(build_id, test_name, lg_type, start_time, end_time, aggregation, sampler,
             timestamps=None, users=None, scope=None):
    if not (timestamps and users):
        timestamps, users = get_backend_users(build_id, lg_type, start_time, end_time, aggregation)
    scope_addon = ""
    if scope and scope != 'All':
        scope_addon = f"and request_name='{scope}'"
    hits_query = f"select time, response_time from {lg_type}..{test_name} where " \
                 f"time>='{start_time}' and time<='{end_time}' and sampler_type='{sampler}' and" \
                 f" build_id='{build_id}' {scope_addon}"
    results = {"hits": {}}
    for _ in timestamps:
        results['hits'][_] = 0
    res = get_client().query(hits_query)[test_name]
    for _ in res:
        timestamp = str_to_timestamp(_['time'])
        hit_time = datetime.fromtimestamp(timestamp - float(_["response_time"]) / 1000.0, tz=timezone.utc)
        if hit_time.strftime("%Y-%m-%dT%H:%M:%SZ") in results['hits']:
            results['hits'][hit_time.strftime("%Y-%m-%dT%H:%M:%SZ")] += 1
    # aggregation of hits
    _tmp = []
    if 'm' in aggregation:
        aggregation = f"{str(int(aggregation.replace('m', ''))*60)}s"
    _ts = None
    for _ in results['hits']:
        if len(_tmp) == 0:
            _ts = _
        _tmp.append(results['hits'][_])
        results['hits'][_] = None
        if (len(_tmp) % int(aggregation.replace('s', ''))) == 0:
            results['hits'][_ts] = float(sum(_tmp)) / int(aggregation.replace('s', ''))
            _tmp = []
            _ts = None
    return timestamps, results, users
Exemple #5
0
def get_tests_metadata(tests):
    tests_meta = APIReport.query.filter(APIReport.id.in_(tests)).order_by(APIReport.id.asc()).all()
    users_data = {}
    responses_data = {}
    errors_data = {}
    rps_data = {}
    labels = []

    for each in tests_meta:
        ts = datetime.fromtimestamp(str_to_timestamp(each.start_time),
                                    tz=timezone.utc).strftime("%m-%d %H:%M:%S")
        labels.append(ts)
        users_data[ts] = each.vusers
        responses_data[ts] = each.pct95
        errors_data[ts] = each.failures
        rps_data[ts] = each.throughput
    return labels, rps_data, errors_data, users_data, responses_data
Exemple #6
0
def get_test_details(build_id, test_name, lg_type):
    test = {
        "start_time": 0,
        "name": test_name,
        "environment": "",
        "type": "",
        "end_time": 0,
        "failures": 0,
        "total": 0,
        "thresholds_missed": 0,
        "throughput": 0,
        "vusers": 0,
        "pct95": 0,
        "duration": 0,
        "1xx": 0,
        "2xx": 0,
        "3xx": 0,
        "4xx": 0,
        "5xx": 0,
        "build_id": build_id,
        "lg_type": lg_type,
        "requests": []
    }
    q_start_time = f"select time, active from {lg_type}..\"users\" " \
                   f"where build_id='{build_id}' order by time asc limit 1"
    q_end_time = f"select time, active from {lg_type}..\"users\" " \
                 f"where build_id='{build_id}' order by time desc limit 1"
    q_response_codes = f"select sum(\"1xx\") as \"1xx\", sum(\"2xx\") as \"2xx\", sum(\"3xx\") as \"3xx\", " \
                       f"sum(\"4xx\") as \"4xx\", sum(\"5xx\") as \"5xx\", sum(\"ko\") as KO, " \
                       f"sum(\"total\") as Total, sum(throughput) as \"throughput\" " \
                       f"from comparison..api_comparison where build_id='{build_id}'"
    q_total_users = f"show tag values on comparison with key=\"users\" where build_id='{build_id}'"
    q_env = f"show tag values on comparison with key=\"env\" where build_id='{build_id}'"
    q_type = f"show tag values on comparison with key=\"test_type\" where build_id='{build_id}'"
    q_pct95 = f"select percentile(response_time, 95) from {lg_type}..{test_name} " \
              f"where build_id='{build_id}' and status='OK'"
    q_requests_name = f"show tag values on comparison with key=\"request_name\" " \
                      f"where build_id='{build_id}'"
    client = get_client()
    test["start_time"] = list(client.query(q_start_time)["users"])[0]["time"]
    test["end_time"] = list(client.query(q_end_time)["users"])[0]["time"]
    test["duration"] = round(
        str_to_timestamp(test["end_time"]) -
        str_to_timestamp(test["start_time"]), 1)
    test["vusers"] = list(
        client.query(q_total_users)["api_comparison"])[0]["value"]
    test["environment"] = list(
        client.query(q_env)["api_comparison"])[0]["value"]
    test["type"] = list(client.query(q_type)["api_comparison"])[0]["value"]
    pct95 = list(client.query(q_pct95)[test_name])
    test["pct95"] = pct95[0]["percentile"] if pct95 else 0
    test["requests"] = [
        name["value"]
        for name in client.query(q_requests_name)["api_comparison"]
    ]
    response_data = list(client.query(q_response_codes)['api_comparison'])[0]
    test['total'] = response_data['Total']
    test['failures'] = response_data['KO']
    test['throughput'] = round(response_data['throughput'], 1)
    test['1xx'] = response_data['1xx']
    test['2xx'] = response_data['2xx']
    test['3xx'] = response_data['3xx']
    test['4xx'] = response_data['4xx']
    test['5xx'] = response_data['5xx']
    return test
Exemple #7
0
    def get(self):
        args = self._parser_get.parse_args(strict=False)
        project = Project.get_or_404(args["project_id"])
        report = APIReport.query.filter(
            and_(APIReport.id == args['test_id'],
                 APIReport.project_id == project.id)).first()
        start_time = str_to_timestamp(report.start_time)
        if report.end_time:
            current_time = str_to_timestamp(report.end_time)
        else:
            current_time = datetime.utcnow().timestamp()
        str_start_time = datetime.fromtimestamp(
            start_time, tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z")
        str_current_time = datetime.fromtimestamp(
            current_time, tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z")
        duration_till_now = current_time - start_time
        if duration_till_now < args['wait_till']:
            return {"message": "not enough results", "code": 0}
        ts_array, data, users = get_tps(report.build_id,
                                        report.name,
                                        report.lg_type,
                                        str_start_time,
                                        str_current_time,
                                        "1s",
                                        args["sampler"],
                                        scope=args["request"],
                                        status=args["status"])
        users = list(users["users"].values())
        _tmp = []
        tps = list()
        usrs = list()
        errors = list()
        if 'm' in args["aggregation"]:
            ss = int(args["aggregation"].replace('m', '')) * 60
        elif 's' in args["aggregation"]:
            ss = int(args["aggregation"].replace('s', ''))
        else:
            ss = 60
        calculation_mapping = {
            'max': max,
            'min': min,
            'mean': mean,
            'sum': sum
        }
        calculation = args['calculation'] if args['calculation'] in list(
            calculation_mapping.keys()) else 'sum'
        for index, _ in enumerate(data["responses"].values()):
            if isinstance(_, int):
                _tmp.append(_)
            if len(_tmp) and (len(_tmp) % ss) == 0:
                tps.append(round(calculation_mapping[calculation](_tmp)))
                usrs.append(users[index])
                _tmp = []
        if _tmp:
            tps.append(round(calculation_mapping[calculation](_tmp)))
            usrs.append(users[-1])
            _tmp = []
        _, data, _ = get_errors(report.build_id,
                                report.name,
                                report.lg_type,
                                str_start_time,
                                str_current_time,
                                args["aggregation"],
                                args["sampler"],
                                scope=args["request"])
        for each in data['errors'].values():
            if each:
                errors.append(each)
        total = int(
            get_response_time_per_test(report.build_id, report.name,
                                       report.lg_type, args["sampler"],
                                       args["request"], "total"))
        error_rate = float(sum(errors)) / float(total) * 100
        try:
            max_tp, user_index = arrays.non_decreasing(
                tps[:-1], deviation=args["deviation"], val=True)
            max_users = args["u_aggr"] * round(
                usrs[user_index] / args["u_aggr"])
            max_tp = tps[user_index]
            current_users = args["u_aggr"] * round(
                usrs[user_index + 1] / args["u_aggr"])
            if current_users == max_users:
                current_users += args["u_aggr"]
            if current_users == 0:
                current_users = max_users + args["u_aggr"]
            if current_users < max_users:
                current_users = max_users + args["u_aggr"]
        except TypeError:
            return {"message": "not enough results", "code": 0}
        except IndexError:
            if error_rate > args["max_errors"]:
                return {
                    "message":
                    f"error rate reached 100% for {args['request']} transaction",
                    "errors_rate": 100.0,
                    "code": 1
                }
            else:
                return {"message": "not enough results", "code": 0}

        response = {
            "ts": ts_array[-1],
            "max_users": max_users,
            "max_throughput": round(max_tp, 2),
            "current_users": current_users,
            "current_throughput": round(tps[user_index], 2),
            "errors_rate": round(error_rate, 2)
        }
        if args["u"]:
            user_array = args["u"]
            if max_users not in user_array:
                user_array.append(max_users)
            if current_users not in user_array:
                user_array.append(current_users)
            user_array.sort()
            user_array.reverse()
            uber_array = {}
            _, users = get_backend_users(report.build_id, report.lg_type,
                                         str_start_time, str_current_time,
                                         "1s")
            u = user_array.pop()
            start_time = _[0]
            end_time = _[-1]
            response["test_start"] = start_time
            response["test_end"] = end_time
            for key, value in users["users"].items():
                if value > u and max_users >= u:
                    _, data, _ = get_tps(report.build_id,
                                         report.name,
                                         report.lg_type,
                                         start_time,
                                         key,
                                         "1s",
                                         args["sampler"],
                                         scope=args["request"],
                                         status=args["status"])
                    tp = [
                        0 if v is None else v
                        for v in list(data['responses'].values())[:-1]
                    ]
                    array_size = len(tp)
                    tp = calculation_mapping[calculation](
                        tp) if len(tp) != 0 else 0
                    if array_size != ss:
                        coefficient = float(array_size / ss)
                    else:
                        coefficient = 1
                    tp = int(tp / coefficient)
                    if round(
                            tp, 2
                    ) > response["max_throughput"] and u != current_users:
                        response["max_throughput"] = round(tp, 2)
                        response["max_users"] = u
                        current_users = u + args["u_aggr"]
                        response["current_users"] = current_users
                    _, data, _ = get_backend_requests(report.build_id,
                                                      report.name,
                                                      report.lg_type,
                                                      start_time,
                                                      key,
                                                      "1s",
                                                      args["sampler"],
                                                      scope=args["request"],
                                                      status=args["status"])
                    rt = []
                    started = False
                    for v in list(data['response'].values())[:-1]:
                        if v and v > 0:
                            started = True
                        if started and v and v > 0:
                            rt.append(v)
                    rt = self.part(rt, args["u_aggr"]) if rt else 0
                    uber_array[str(u)] = {
                        "throughput": round(tp, 2),
                        "response_time": round(rt, 2)
                    }
                    start_time = key
                    u = user_array.pop()
            if str(response["max_users"]) not in list(uber_array.keys()):
                _, data, _ = get_backend_requests(report.build_id,
                                                  report.name,
                                                  report.lg_type,
                                                  start_time,
                                                  end_time,
                                                  "1s",
                                                  args["sampler"],
                                                  scope=args["request"],
                                                  status=args["status"])
                rt = []
                started = False
                for v in list(data['response'].values())[:-1]:
                    if v and v > 0:
                        started = True
                    if started and v and v > 0:
                        rt.append(v)
                rt = self.part(rt, args["u_aggr"]) if rt else 0
                uber_array[str(max_users)] = {
                    "throughput": response["max_throughput"],
                    "response_time": round(rt, 2)
                }
            else:
                uber_array[str(response["max_users"]
                               )]["throughput"] = response["max_throughput"]
            if str(current_users) not in list(uber_array.keys()):

                uber_array[str(current_users)] = {
                    "throughput":
                    response["current_throughput"],
                    "response_time":
                    uber_array.get(
                        str(max_users),
                        list(uber_array.values())[-1])["response_time"]
                }
            else:
                uber_array[str(current_users)]["throughput"] = response[
                    "current_throughput"]
            response["benchmark"] = uber_array
        if args["extended_output"]:
            response["details"] = {}
            response["tps"] = tps
            for index, value in enumerate(usrs):
                if not response["details"].get(
                        value) or response["details"][value] > tps[index]:
                    response["details"][value] = tps[index]
        if (arrays.non_decreasing(tps[:-1], deviation=args["deviation"])
                and error_rate <= args["max_errors"]
                and response["current_throughput"] *
            (1 + args["max_deviation"]) >= response["max_throughput"]):
            response["message"] = "proceed"
            response["code"] = 0
            return response
        else:
            response["message"] = "saturation"
            response["code"] = 1
            return response