def test_start_experiment(): counter = { "request": 0, } def check_result(row, result): assert (functools.reduce(lambda x, y: x and y, result.values())) counter["request"] += 1 with common.HTTPServerInstance(): ctx = context.Context(broker.Broker(), traffic.Delimiter("magic")) ctx.broker.subscribe(broker.TOPICS.WARNING, warning_as_error) conf = base.BaseConf() bs = base.Base(ctx, conf) ctx.broker.subscribe(broker.TOPICS.CHECK_RESULT, check_result) traffic.RawRequestCollector(ctx) traffic.RawResponseCollector(ctx) traffic.RealTrafficCollector(ctx) database.Sqlite3DB(ctx) packets_yaml = os.path.join(os.path.dirname(__file__), "data", "packets.yaml") bs._load_yaml_tests(packets_yaml) bs._gen_requests() assert (bs._start_experiment("localhost:" + str(common._PORT)) == 0) bs._report_experiment() assert (counter["request"] == 2)
def test_traffic_extract(): request_buffer = [] response_buffer = [] traffic_buffer = [] def get_request(request): request_buffer.append(request) def get_response(response): response_buffer.append(response) def get_traffic(sql, request, response, duration, id): assert (re.search(r"^GET", request) is not None) assert (re.search(r"^HTTP", response) is not None) assert (re.search(r"^\d+.\d+$", str(duration)) is not None) assert (re.search(r"^\d+$", id) is not None) traffic_buffer.append((request, response)) ctx = context.Context(broker.Broker(), traffic.Delimiter("magic")) ctx.broker.subscribe(broker.TOPICS.RAW_REQUEST, get_request) ctx.broker.subscribe(broker.TOPICS.RAW_RESPONSE, get_response) ctx.broker.subscribe(broker.TOPICS.SQL_COMMAND, get_traffic) traffic.RawRequestCollector(ctx) traffic.RawResponseCollector(ctx) traffic.RealTrafficCollector(ctx) for line in _TEST_PYWB_OUTPUT.splitlines(): ctx.broker.publish(broker.TOPICS.PYWB_OUTPUT, line + "\n") assert (len(request_buffer) == 6) assert (len(response_buffer) == 6) assert (len(traffic_buffer) == 2) for t in traffic_buffer: assert (t[0] in request_buffer and t[1] in response_buffer)
def test_commands_dispatch(): class Trigger(object): def __init__(self): self.count = 0 def expect(self, expected): self.expected = expected def __call__(self, target): assert (target == self.expected) self.count += 1 ctx = context.Context(broker.Broker()) ctx.broker.subscribe(broker.TOPICS.WARNING, warning_as_error) t = Trigger() conf = base.BaseConf(functions={ "test_func1": t, "test_func2": t, }) bs = base.Base(ctx, conf) t.expect(1) bs._command("test_func1", 1) t.expect(2) bs._command("test_func2", 2) assert (t.count == 2)
def test_import_log(): class LogCheck(object): def __init__(self, expected_log): if os.path.exists(expected_log): with open(expected_log, "r") as fd: self.expected_log = iter(fd.readlines()) else: self.expected_log = iter([expected_log]) def __call__(self, line): assert (line == next(self.expected_log)) def finish(self): try: next(self.expected_log) return False except StopIteration: return True ctx = context.Context(broker.Broker()) ctx.broker.subscribe(broker.TOPICS.WARNING, warning_as_error) conf = base.BaseConf() bs = base.Base(ctx, conf) lc = LogCheck("test log") ctx.broker.subscribe(broker.TOPICS.RAW_LOG, lc) bs._import_log("test log") ctx.broker.unsubscribe(broker.TOPICS.RAW_LOG, lc) assert (lc.finish()) lc = LogCheck(__file__) ctx.broker.subscribe(broker.TOPICS.RAW_LOG, lc) bs._import_log(__file__) ctx.broker.unsubscribe(broker.TOPICS.RAW_LOG, lc) assert (lc.finish())
def test_database_create(): ctx = context.Context(broker.Broker()) db = database.Sqlite3DB(ctx) r = db.query(_SQL_GET_ALL_DATA) expect_titles = ("traffic_id", "test_title", "meta", "file", "input", "output", "request", "raw_request", "raw_response", "raw_log", "testing_result", "duration_time") assert (len(expect_titles) == len(r.title())) for title in expect_titles: assert (title in r.title())
def test_log_extract(): counter = { "log" : 0, } def get_log(*args): counter["log"] += 1 ctx = context.Context(broker.Broker(), traffic.Delimiter("magic")) ctx.broker.subscribe(broker.TOPICS.SQL_COMMAND, get_log) collector = log.LogCollector(ctx) for line in _TEST_MODSECURITY_LOG.splitlines(): ctx.broker.publish(broker.TOPICS.RAW_LOG, line + "\n") assert(counter["log"] == 2)
def test_sql(): ctx = context.Context(broker.Broker()) db = database.Sqlite3DB(ctx) # insert request args = ("id_1", "test_title", "meta_data", "file_path", "input_data", "output_data", "request_data") db.query(sql.SQL_INSERT_REQUEST, *args) check_insert(db, args) # query request result = db.query(sql.SQL_QUERY_REQUEST) data = collections.OrderedDict(zip(result.title(), next(iter(result)))) assert (len(data) == 2) assert (data["traffic_id"] == "id_1") assert (data["request"] == "request_data") # insert raw traffic args = ("raw_request", "raw_response", "duration_time", "id_1") db.query(sql.SQL_INSERT_RAW_TRAFFIC, *args) check_insert(db, args) # insert raw log args = ("raw_log", "id_1") db.query(sql.SQL_INSERT_LOG, *args) check_insert(db, args) # insert raw log args = ("True", "id_1") db.query(sql.SQL_UPDATE_TESTING_RESULT, *args) check_insert(db, args) # query result result = db.query(sql.SQL_QUERY_RESULT) data = collections.OrderedDict(zip(result.title(), next(iter(result)))) assert (len(data) == 6) assert (data["traffic_id"] == "id_1") assert (data["test_title"] == "test_title") assert (data["output"] == "output_data") assert (data["raw_request"] == "raw_request") assert (data["raw_response"] == "raw_response") assert (data["raw_log"] == "raw_log") # clean raw data db.query(sql.SQL_CLEAN_RAW_DATA) result = db.query(_SQL_GET_ALL_DATA) data = collections.OrderedDict(zip(result.title(), next(iter(result)))) assert (data["raw_request"] == None) assert (data["raw_response"] == None) assert (data["raw_log"] == None) assert (data["testing_result"] == None)
def test_publish(): brk = broker.Broker() brk.subscribe("test_title", receive_func) brk.subscribe("test_title", receive_class()) brk.publish("test_title", lambda x: x, True) brk.publish("empty_title", lambda x: x, False) # strict publish brk.subscribe("strict_title", receive_func, {"arg": str}) brk.publish("strict_title", lambda x: x, "OK") brk.subscribe("strict_title", receive_class(), {"arg": str}) brk.publish("strict_title", lambda x: x, "OK") brk.publish("strict_title", lambda x: x, arg="OK") try: brk.publish("strict_title", lambda x: x, arg=0) assert (False) except ValueError: assert (True)
def test_multiple_subscribe(): # only get a message although multiple subscribe brk = broker.Broker() brk.subscribe("test_title", receive_func) brk.subscribe("test_title", receive_func) brk.subscribe("test_title", receive_func) brk.subscribe("test_title", receive_func) triggle_time = [0] def inc(x): triggle_time[0] += 1 return True brk.publish("test_title", inc, 1) assert (triggle_time[0] == 1) # unsubscribe brk.unsubscribe("test_title", receive_func) brk.publish("test_title", inc, 1) assert (triggle_time[0] == 1)
def test_subscribe(): brk = broker.Broker() # normal subscribe brk.subscribe("test_title", receive_func) try: brk.subscribe("test_title", 0) assert (False) except ValueError as e: assert (str(e) == "subscriber<0> is not callable") # strict subscribe brk.subscribe("test_title2", lambda x: x, {"x": str}) try: brk.subscribe("test_title", lambda x: x, {"x": str}) assert (False) except ValueError as e: assert ( str(e) == "type limit<{'x': <type 'str'>}> is not compatible with previous<{}>" ) # callable object subscribe brk.subscribe("test_title", receive_class())
def test_load_and_gen_packets(): class FixUUID(object): def __init__(self): self.number = 0 def __call__(self): self.number += 1 return uuid.UUID(int=self.number - 1) old_uuid1 = uuid.uuid1 uuid.uuid1 = FixUUID() ctx = context.Context(broker.Broker(), traffic.Delimiter("magic")) ctx.broker.subscribe(broker.TOPICS.WARNING, warning_as_error) conf = base.BaseConf() bs = base.Base(ctx, conf) database.Sqlite3DB(ctx) packets_yaml = os.path.join(os.path.dirname(__file__), "data", "packets.yaml") bs._load_yaml_tests(packets_yaml) bs._gen_requests() packets_pkt = conf.pkt_path expect_pkt = os.path.join(os.path.dirname(__file__), "data", "packets.pkt") assert (filecmp.cmp(packets_pkt, expect_pkt)) uuid.uuid1 = old_uuid1
def test_result_report(): class FakeQueryResult(object): def __init__(self, data): self.data = iter(data) def __iter__(self): for i in self.data: yield i def title(self): return ("traffic_id", "test_title", "output", "raw_request", "raw_response", "raw_log") class ResultChecker(object): def __init__(self, brk, test_data, expected): self.test_data = iter(test_data) self.expected = iter(expected) brk.subscribe(broker.TOPICS.SQL_COMMAND, self.publish_data) brk.subscribe(broker.TOPICS.CHECK_RESULT, self.check) def publish_data(self, *args, **kwargs): if "callback" in kwargs: kwargs["callback"](FakeQueryResult(self.test_data)) def check(self, row, result): assert (result == next(self.expected)) def finish(self): try: next(self.expected) return False except StopIteration: return True ctx = context.Context(broker.Broker()) # ctx.broker.subscribe(broker.TOPICS.WARNING, warning_as_error) conf = base.BaseConf() bs = base.Base(ctx, conf) test_data = ( (("", "", "", "", "", ""), {}), (("1", "1", "{'status' : 403}", "", "HTTP1.1 403", ""), { "status": True }), (("1", "1", "{'status' : 403}", "", "HTTP1.1 200", ""), { "status": False }), (("1", "1", "{'status' : [200, 404]}", "", "HTTP1.1 200", ""), { "status": True }), (("1", "1", "{'log_contains' : 'a\da'}", "", "", "abcde"), { "log_contains": False }), (("1", "1", "{'log_contains' : 'a\da'}", "", "", "ab[a1a]cde"), { "log_contains": True }), (("1", "1", "{'no_log_contains' : 'a\da'}", "", "", "ab[a1a]cde"), { "no_log_contains": False }), (("1", "1", "{'no_log_contains' : 'a\da'}", "", "", "abcdef"), { "no_log_contains": True }), (("1", "1", "{'response_contains' : 'a\da'}", "", "abcdef", ""), { "response_contains": False }), (("1", "1", "{'response_contains' : 'a\da'}", "", "ab[a1a]cde", ""), { "response_contains": True }), (("1", "1", "{'expect_error' : True}", "", "abcdef", ""), { "expect_error": False }), (("1", "1", "{'expect_error' : True}", "", "", ""), { "expect_error": True }), ) rc = ResultChecker(ctx.broker, [v[0] for v in test_data], [v[1] for v in test_data]) bs._report_experiment() assert (rc.finish())
def test_unit_regression_test(): brk = broker.Broker() brk.subscribe(broker.TOPICS.WARNING, warning_as_error) test_case = os.path.join(os.path.dirname(os.path.dirname(__file__)), "util", "regression-test") main.execute(["-x", "load " + test_case + ""], brk=brk)