예제 #1
0
def get_case_strategy(
        endpoint: Endpoint,
        hooks: Optional[Dict[str, Hook]] = None) -> st.SearchStrategy:
    """Create a strategy for a complete test case.

    Path & endpoint are static, the others are JSON schemas.
    """
    strategies = {}
    static_kwargs: Dict[str, Any] = {"endpoint": endpoint}
    try:
        for parameter in PARAMETERS:
            value = getattr(endpoint, parameter)
            if value is not None:
                if parameter == "path_parameters":
                    strategies[parameter] = (
                        from_schema(value).filter(filter_path_parameters).map(
                            quote_all)  # type: ignore
                    )
                elif parameter in ("headers", "cookies"):
                    strategies[parameter] = from_schema(value).filter(
                        is_valid_header)  # type: ignore
                elif parameter == "query":
                    strategies[parameter] = from_schema(value).filter(
                        is_valid_query)  # type: ignore
                else:
                    strategies[parameter] = from_schema(value)  # type: ignore
            else:
                static_kwargs[parameter] = None
        return _get_case_strategy(endpoint, static_kwargs, strategies, hooks)
    except AssertionError:
        raise InvalidSchema("Invalid schema for this endpoint")
예제 #2
0
def get_case_strategy(endpoint: Endpoint) -> st.SearchStrategy:
    """Create a strategy for a complete test case.

    Path & endpoint are static, the others are JSON schemas.
    """
    strategies = {}
    static_kwargs = {
        "path": endpoint.path,
        "method": endpoint.method,
        "base_url": endpoint.base_url
    }
    try:
        for parameter in PARAMETERS:
            value = getattr(endpoint, parameter)
            if value is not None:
                if parameter == "path_parameters":
                    strategies[parameter] = (
                        from_schema(value).filter(
                            filter_path_parameters)  # type: ignore
                        .map(quote_all)  # type: ignore
                    )
                elif parameter == "headers":
                    strategies[parameter] = from_schema(value).filter(
                        is_valid_header)  # type: ignore
                else:
                    strategies[parameter] = from_schema(value)  # type: ignore
            else:
                static_kwargs[parameter] = None
        return _get_case_strategy(endpoint, static_kwargs, strategies)
    except AssertionError:
        raise InvalidSchema("Invalid schema for this endpoint")
예제 #3
0
def _merge_semantics_helper(data, s1, s2, combined):
    note(combined)
    ic = data.draw(from_schema(combined), label="combined")
    i1 = data.draw(from_schema(s1), label="s1")
    i2 = data.draw(from_schema(s2), label="s2")
    assert is_valid(ic, s1)
    assert is_valid(ic, s2)
    assert is_valid(i1, s2) == is_valid(i1, combined)
    assert is_valid(i2, s1) == is_valid(i2, combined)
예제 #4
0
def prepare_strategy(parameter: str, value: Dict[str,
                                                 Any]) -> st.SearchStrategy:
    if parameter == "path_parameters":
        return from_schema(value).filter(filter_path_parameters).map(
            quote_all)  # type: ignore
    if parameter in ("headers", "cookies"):
        return from_schema(value).filter(is_valid_header)  # type: ignore
    if parameter == "query":
        return from_schema(value).filter(is_valid_query)  # type: ignore
    return from_schema(value)  # type: ignore
예제 #5
0
def get_case_strategy(endpoint: Endpoint) -> st.SearchStrategy:
    return st.builds(
        Case,
        path=st.just(endpoint.path),
        method=st.just(endpoint.method),
        path_parameters=from_schema(endpoint.path_parameters),
        headers=from_schema(endpoint.headers),
        query=from_schema(endpoint.query),
        body=from_schema(endpoint.body),
    )
def test_merge_semantics(data, s1, s2):
    assume(canonicalish(s1) != FALSEY and canonicalish(s2) != FALSEY)
    combined = merged([s1, s2])
    assume(combined is not None)
    assume(combined != FALSEY)
    note(combined)
    ic = data.draw(from_schema(combined), label="combined")
    i1 = data.draw(from_schema(s1), label="s1")
    i2 = data.draw(from_schema(s2), label="s2")
    assert is_valid(ic, s1) and is_valid(ic, s2)
    assert is_valid(i1, s2) == is_valid(i1, combined)
    assert is_valid(i2, s1) == is_valid(i2, combined)
예제 #7
0
def get_case_strategy(endpoint: Endpoint) -> st.SearchStrategy:
    """Create a strategy for a complete test case.

    Path & endpoint are static, the others are JSON schemas.
    """
    return st.builds(
        Case,
        path=st.just(endpoint.path),
        method=st.just(endpoint.method),
        path_parameters=from_schema(endpoint.path_parameters),
        headers=from_schema(endpoint.headers),
        query=from_schema(endpoint.query),
        body=from_schema(endpoint.body),
    )
예제 #8
0
def schema(dataclass):



schema = lambda dataclass: hypothesis_jsonschema.from_schema(dataclass.schema())


def test_get(get_client, tmp_path):
    client = get_client()
    tmp_file = tmp_path / 'test.txt'
    tmp_file.write_text('test')

    response = client.get("/api/contents/test.txt")
    assert response.status_code == 200
    #assert response.json()


@hypothesis.given(body=schema(RenameModel))
def test_rename(get_client, tmp_path, body):
    client = get_client()
    tmp_file = tmp_path / 'test.txt'
    tmp_file.write_text('test')
    
    response = client.patch(
        '/api/contents/test.txt', 
        json=body
    )


    new_name = body['path']
    assert response.json()['path'] == new_name
예제 #9
0
class TestMsgVote:
    def test_schema_valid(self, msg_examples):
        for m in msg_examples[MsgVote]:
            assert_serdes_consistent(MsgVote, m)
            assert_serdes_exact(MsgVote, m)

    @pytest.mark.slow
    @settings(suppress_health_check=[
        HealthCheck.too_slow, HealthCheck.filter_too_much
    ])
    @given(m=from_schema(MsgVote.__schema__))
    def test_serdes_consistent(self, m):
        assert_serdes_consistent(MsgVote, m)

    def test_matches_meta(self):
        assert MsgVote.type == "gov/MsgVote"
        assert MsgVote.action == "vote"

    @given(other=st.text())
    def test_constructor_validates_addresses(self, acc_address, other):
        """MsgVote should validate `voter` to be AccAddress."""
        assume(not is_acc_address(other))
        with pytest.raises(InvalidAccAddress):
            MsgVote(proposal_id=1, voter=other, option="")
        A = MsgVote(proposal_id=1, voter=acc_address, option="")
        assert A.voter == acc_address
예제 #10
0
class TestMsgWithdrawValidatorCommission:
    def test_schema_valid(self, msg_examples):
        for m in msg_examples[MsgWithdrawValidatorCommission]:
            assert_serdes_consistent(MsgWithdrawValidatorCommission, m)
            assert_serdes_exact(MsgWithdrawValidatorCommission, m)

    @pytest.mark.serdes
    @pytest.mark.slow
    @settings(suppress_health_check=[HealthCheck.too_slow, HealthCheck.filter_too_much])
    @given(m=from_schema(MsgWithdrawValidatorCommission.__schema__))
    def test_serdes_consistent(self, m):
        assert_serdes_consistent(MsgWithdrawValidatorCommission, m)

    def test_matches_meta(self):
        assert (
            MsgWithdrawValidatorCommission.type
            == "distribution/MsgWithdrawValidatorCommission"
        )
        assert MsgWithdrawValidatorCommission.action == "withdraw_validator_commission"

    @given(other=st.text())
    def test_constructor_validates_addresses(self, val_address, other):
        """MsgWithdrawValidatorCommission should validate `validator_address` to be ValAddress.
        """

        assume(not is_val_address(other))
        with pytest.raises(InvalidValAddress):
            MsgWithdrawValidatorCommission(validator_address=other)
        A = MsgWithdrawValidatorCommission(validator_address=val_address)
        assert A.validator_address == val_address
예제 #11
0
def test_can_generate_for_test_suite_schema(data, name):
    note(suite[name])
    value = data.draw(from_schema(suite[name]))
    try:
        jsonschema.validate(value, suite[name])
    except jsonschema.exceptions.SchemaError:
        jsonschema.Draft4Validator(suite[name]).validate(value)
예제 #12
0
def test_canonicalises_to_equivalent_fixpoint(schema_strategy, data):
    """Check that an object drawn from an arbitrary schema is valid."""
    schema = data.draw(schema_strategy, label="schema")
    cc = canonicalish(schema)
    assert cc == canonicalish(cc)
    instance = data.draw(JSON_STRATEGY | from_schema(cc), label="instance")
    assert is_valid(instance, schema) == is_valid(instance, cc)
예제 #13
0
class TestMsgSwap:
    def test_schema_valid(self, msg_examples):
        for m in msg_examples[MsgSwap]:
            assert_serdes_consistent(MsgSwap, m)
            assert_serdes_exact(MsgSwap, m)

    @pytest.mark.serdes
    @pytest.mark.slow
    @settings(suppress_health_check=[
        HealthCheck.too_slow, HealthCheck.filter_too_much
    ])
    @given(m=from_schema(MsgSwap.__schema__))
    def test_serdes_consistent(self, m):
        assert_serdes_consistent(MsgSwap, m)

    def test_matches_meta(self):
        assert MsgSwap.type == "market/MsgSwap"
        assert MsgSwap.action == "swap"

    @given(other=st.text())
    def test_constructor_validates_addresses(self, acc_address, other):
        """MsgSwap should validate `trader` to be AccAddress.
        """
        assume(not is_acc_address(other))
        with pytest.raises(InvalidAccAddress):
            MsgSwap(trader=other,
                    offer_coin=Coin("uluna", 100),
                    ask_denom="umnt")
        A = MsgSwap(trader=acc_address,
                    offer_coin=Coin("uluna", 100),
                    ask_denom="umnt")
        assert A.trader == acc_address
예제 #14
0
class TestCoinsSerdes:
    @pytest.mark.serdes
    @pytest.mark.slow
    @settings(suppress_health_check=[HealthCheck.too_slow, HealthCheck.filter_too_much])
    @given(c=from_schema(Coins.__schema__))
    def test_serdes_consistent(self, c):
        assert_serdes_consistent(Coins, c)
예제 #15
0
def generate_experiment_strategy(path, size, level=1, position=[0]):  # pylint: disable=W0102
    """generate strategies from a schema path and current input size"""
    json_schema = read.read_schema(path)

    # pylint: disable=W0102, R1705
    def detect_level_and_position(schema,
                                  level=1,
                                  position=[0],
                                  index_position=0):
        """A dummy function to store the data to file for experiment"""
        if level == 0:
            return schema
        else:
            if isinstance(schema, list):
                subschema = schema[position[index_position]]
            elif isinstance(schema["items"], dict):
                subschema = schema["items"]
            elif isinstance(schema["items"], list):
                subschema = schema["items"][position[index_position]]
            return detect_level_and_position(subschema, level - 1, position,
                                             index_position + 1)

    js = detect_level_and_position(json_schema, level, position)
    double_experiment_size(js, size)
    strategy = []
    for j in json_schema:
        strategy.append(from_schema(j))
    return strategy
예제 #16
0
def test_custom_strategies():
    register_string_format(
        "even_4_digits",
        strategies.from_regex(r"\A[0-9]{4}\Z").filter(
            lambda x: int(x) % 2 == 0))
    endpoint = make_endpoint(
        **{
            "query": {
                "required": ["id"],
                "type": "object",
                "additionalProperties": False,
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "even_4_digits"
                    }
                },
            }
        })
    result = strategies.builds(
        Case,
        path=strategies.just(endpoint.path),
        method=strategies.just(endpoint.method),
        query=from_schema(endpoint.query),
    ).example()
    assert len(result.query["id"]) == 4
    assert int(result.query["id"]) % 2 == 0
예제 #17
0
class TestMsgDelegateFeedConsent:
    def test_schema_valid(self, msg_examples):
        for m in msg_examples[MsgDelegateFeedConsent]:
            assert_serdes_consistent(MsgDelegateFeedConsent, m)
            assert_serdes_exact(MsgDelegateFeedConsent, m)

    @pytest.mark.slow
    @settings(suppress_health_check=[
        HealthCheck.too_slow, HealthCheck.filter_too_much
    ])
    @given(m=from_schema(MsgDelegateFeedConsent.__schema__))
    def test_schema(self, m):
        assert_serdes_consistent(MsgDelegateFeedConsent, m)

    def test_matches_meta(self):
        assert MsgDelegateFeedConsent.type == "oracle/MsgDelegateFeedConsent"
        assert MsgDelegateFeedConsent.action == "delegatefeeder"

    @given(other=st.text())
    def test_constructor_validates_addresses(self, acc_address, val_address,
                                             other):
        """MsgDelegateFeedConsent should validate `operator` to be ValAddress and `delegate`
        to be AccAddress.
        """
        assume(not is_val_address(other) and not is_acc_address(other))
        with pytest.raises(InvalidValAddress):
            MsgDelegateFeedConsent(operator=other, delegate=acc_address)
        with pytest.raises(InvalidAccAddress):
            MsgDelegateFeedConsent(operator=val_address, delegate=other)
        A = MsgDelegateFeedConsent(operator=val_address, delegate=acc_address)
        assert A.operator == val_address
        assert A.delegate == acc_address
예제 #18
0
class TestStdFeeSerdes:
    @pytest.mark.slow
    @settings(suppress_health_check=[HealthCheck.too_slow, HealthCheck.filter_too_much])
    @given(fee=from_schema(StdFee.__schema__))
    def test_schema(self, fee):
        x = StdFee.deserialize(fee)
        y = StdFee.deserialize(json.loads(x.to_json()))
        assert x == y
예제 #19
0
def not_from_schema(draw: Callable, schema: Dict[str, Any]) -> Any:
    """Generate data that does NOT match the given schema."""
    mutations = list(_mutate(schema))
    if not mutations:
        raise Unsatisfiable
    mutation_strategies = st.sampled_from(mutations)
    mutated_strategy = draw(mutation_strategies)
    schema_strategy = from_schema(mutated_strategy)
    return draw(schema_strategy)
예제 #20
0
class TestMsgBeginRedelegate:
    def test_schema_valid(self, msg_examples):
        for m in msg_examples[MsgBeginRedelegate]:
            assert_serdes_consistent(MsgBeginRedelegate, m)
            assert_serdes_exact(MsgBeginRedelegate, m)

    @pytest.mark.serdes
    @pytest.mark.slow
    @settings(suppress_health_check=[
        HealthCheck.too_slow, HealthCheck.filter_too_much
    ])
    @given(m=from_schema(MsgBeginRedelegate.__schema__))
    def test_serdes_consistent(self, m):
        assert_serdes_consistent(MsgBeginRedelegate, m)

    def test_matches_meta(self):
        assert MsgBeginRedelegate.type == "staking/MsgBeginRedelegate"
        assert MsgBeginRedelegate.action == "begin_redelegate"

    @given(other=st.text())
    def test_constructor_validates_addresses(self, acc_address, val_address,
                                             other):
        """MsgBeginRedelegate should validate `delegator` to be AccAddress, and both
        `validator_src_address` and `validator_dst_address` to be ValAddress.
        """
        assume(not is_acc_address(other) and not is_val_address(other))
        with pytest.raises(InvalidAccAddress):
            MsgBeginRedelegate(
                delegator_address=other,
                validator_src_address=val_address,
                validator_dst_address=val_address,
                amount=None,
            )
        with pytest.raises(InvalidValAddress):
            MsgBeginRedelegate(
                delegator_address=acc_address,
                validator_src_address=other,
                validator_dst_address=val_address,
                amount=None,
            )
        with pytest.raises(InvalidValAddress):
            MsgBeginRedelegate(
                delegator_address=acc_address,
                validator_src_address=val_address,
                validator_dst_address=other,
                amount=None,
            )
        A = MsgBeginRedelegate(
            delegator_address=acc_address,
            validator_src_address=val_address,
            validator_dst_address=val_address,
            amount=None,
        )
        assert A.delegator_address == acc_address
        assert A.validator_src_address == val_address
        assert A.validator_dst_address == val_address
예제 #21
0
def test_generated_data_matches_schema(schema_strategy, data):
    """Check that an object drawn from an arbitrary schema is valid."""
    schema = data.draw(schema_strategy)
    try:
        value = data.draw(from_schema(schema), "value from schema")
    except InvalidArgument:
        reject()
    jsonschema.validate(value, schema)
    # This checks that our canonicalisation is semantically equivalent.
    jsonschema.validate(value, canonicalish(schema))
예제 #22
0
def test_generate_func_from_single_st():
    """Checks that generate function from single strategy works"""
    # pylint: disable=blacklisted-name
    def foo(a):
        """A sample function"""
        type(a)

    schema = {"type": "array", "items": {"type": "number"}}
    strategy = from_schema(schema)
    function = generate.generate_func_from_single_st(foo, strategy)
    assert str(type(function)) == "<class 'function'>"
예제 #23
0
class TestRedelegationSerdes:
    def test_schema_valid(self, rdelgn_examples):
        for d in rdelgn_examples:
            assert_serdes_consistent(Redelegation, d)
            assert_serdes_exact(Redelegation, d)

    @pytest.mark.slow
    @settings(suppress_health_check=[HealthCheck.too_slow, HealthCheck.filter_too_much])
    @given(d=from_schema(Redelegation.__schema__))
    def test_schema(self, d):
        assert_serdes_consistent(Redelegation, d)
예제 #24
0
def make_positive_strategy(schema: Dict[str, Any], operation_name: str,
                           location: str,
                           media_type: Optional[str]) -> st.SearchStrategy:
    """Strategy for generating values that fit the schema."""
    if is_header_location(location):
        # We try to enforce the right header values via "format"
        # This way, only allowed values will be used during data generation, which reduces the amount of filtering later
        # If a property schema contains `pattern` it leads to heavy filtering and worse performance - therefore, skip it
        for sub_schema in schema.get("properties", {}).values():
            if list(sub_schema) == ["type"]:
                sub_schema.setdefault("format", HEADER_FORMAT)
    return from_schema(schema, custom_formats=STRING_FORMATS)
예제 #25
0
def get_examples(endpoint: Endpoint) -> Generator[Case, None, None]:
    for name in PARAMETERS:
        parameter = getattr(endpoint, name)
        if "example" in parameter:
            with handle_warnings():
                strategies = {
                    other: from_schema(getattr(endpoint, other))
                    for other in PARAMETERS - {name}
                }
                static_parameters = {name: parameter["example"]}
                yield _get_case_strategy(endpoint, static_parameters,
                                         strategies).example()
예제 #26
0
def prepare_strategy(parameter: str, value: Dict[str, Any], map_func: Optional[Callable]) -> st.SearchStrategy:
    """Create a strategy for a schema and add location-specific filters & maps."""
    strategy = from_schema(value)
    if map_func is not None:
        strategy = strategy.map(map_func)
    if parameter == "path_parameters":
        strategy = strategy.filter(filter_path_parameters).map(quote_all)  # type: ignore
    elif parameter in ("headers", "cookies"):
        strategy = strategy.filter(is_valid_header)  # type: ignore
    elif parameter == "query":
        strategy = strategy.filter(is_valid_query)  # type: ignore
    return strategy
예제 #27
0
class TestExchangeRatePrevoteSerdes:
    def test_schema_valid(self, examples):
        for x in examples:
            assert_serdes_consistent(ExchangeRatePrevote, x)
            assert_serdes_exact(ExchangeRatePrevote, x)

    @pytest.mark.serdes
    @pytest.mark.slow
    @settings(suppress_health_check=[HealthCheck.too_slow])
    @given(x=from_schema(ExchangeRatePrevote.__schema__))
    def test_serdes_consistent(self, x):
        assert_serdes_consistent(ExchangeRatePrevote, x)
예제 #28
0
def test_canonicalises_to_equivalent_fixpoint(schema_strategy, data):
    """Check that an object drawn from an arbitrary schema is valid."""
    schema = data.draw(schema_strategy, label="schema")
    cc = canonicalish(schema)
    assert cc == canonicalish(cc)
    try:
        strat = from_schema(cc)
    except InvalidArgument:
        # e.g. array of unique {type: integers}, with too few allowed integers
        assume(False)
    instance = data.draw(JSON_STRATEGY | strat, label="instance")
    assert is_valid(instance, schema) == is_valid(instance, cc)
    jsonschema.validators.validator_for(schema).check_schema(schema)
예제 #29
0
def test_successful_mutations(data, mutation, schema):
    validate_schema(schema)
    validator = Draft4Validator(schema)
    schema = deepcopy(schema)
    # When mutation can be applied
    # Then it returns "success"
    assert mutation(MutationContext(schema, "body", "application/json"),
                    data.draw, schema) == MutationResult.SUCCESS
    # And the mutated schema is a valid JSON Schema
    validate_schema(schema)
    # And instances valid for this schema are not valid for the original one
    new_instance = data.draw(from_schema(schema))
    assert not validator.is_valid(new_instance)
예제 #30
0
class TestVestingAccountSerdes:
    def test_schema_valid(self, examples):
        for acc in examples:
            assert_serdes_consistent(LazyGradedVestingAccount, acc)
            assert_serdes_exact(LazyGradedVestingAccount, acc)

    @pytest.mark.slow
    @settings(suppress_health_check=[
        HealthCheck.too_slow, HealthCheck.filter_too_much
    ])
    @given(acc=from_schema(LazyGradedVestingAccount.__schema__))
    def test_schema(self, acc):
        assert_serdes_consistent(LazyGradedVestingAccount, acc)