Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ hatch run test:integration
```
Note: integration tests cannot currently be invoked by running `pytest tests/integration` because `PYTHONPATH` is not set correctly in that case.

The integration tests test a live, deployed API and point the API at real web resources that are provisioned for testing purposes. The integration test content is currently hosted on `caatestsuite.com` (maintained by SSLMate) and `integration-testing.open-mpic.org` (maintained by the maintainers of the Open MPIC project). The zone file for `caatestsuite.com` can be found [here](https://github.com/SSLMate/caatestsuite) along with more info about the tests at [caatestsuite.com](https://caatestsuite.com), and the zone file for `integration-testing.open-mpic.org` can be found [here](https://github.com/open-mpic/open-mpic-integration-zone). Both of these services are maintained on a best-effort basis. If there is an issue with integration tests, check the availability of these two services and the responses from the sub-domains used in the integration tests. THESE SERVICES ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. They are not intended for use outside of development integration testing (i.e., no excessive query volume, no use in production systems).

If you encounter issues running integration tests with the above commands, contact the project maintainers.


Expand All @@ -93,9 +95,8 @@ After `tofu destroy`, `./clean.sh` in the root directory also clears generated/z

# Remaining tasks

The Open MPIC project is currently under development. The pre-alpha release includes support for the HTTP and DNS domain validation methods using Amazon Web Services Lambda and API Gateway. The work items remaining to a feature-complete production-level product include the following: (subject to change)
The Open MPIC project is currently under development. The work items remaining to a feature-complete production-level product include the following: (subject to change)

- Full alighnment with API spec v2
- Additional integration testing

Throughout the development process, we will address any GitHub issues raised, and may modify the API accordingly. We also welcome pull requests from the general community.
Expand Down
69 changes: 60 additions & 9 deletions tests/integration/test_deployed_mpic_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
import pytest
from pydantic import TypeAdapter

from open_mpic_core.common_domain.check_parameters import CaaCheckParameters, DcvWebsiteChangeValidationDetails
from open_mpic_core.common_domain.check_parameters import CaaCheckParameters, DcvWebsiteChangeValidationDetails, DcvAcmeDns01ValidationDetails, DcvDnsChangeValidationDetails
from open_mpic_core.common_domain.check_parameters import DcvCheckParameters
from open_mpic_core.common_domain.enum.certificate_type import CertificateType
from open_mpic_core.common_domain.enum.check_type import CheckType
from open_mpic_core.common_domain.enum.dns_record_type import DnsRecordType
from open_mpic_core.mpic_coordinator.domain.mpic_request import MpicCaaRequest
from open_mpic_core.mpic_coordinator.domain.mpic_request import MpicDcvRequest
from open_mpic_core.mpic_coordinator.domain.mpic_orchestration_parameters import MpicRequestOrchestrationParameters
Expand Down Expand Up @@ -141,23 +142,73 @@ def api_should_return_is_valid_false_for_do_not_issue_caa_test_suite_for_rfc_684
mpic_response = self.mpic_response_adapter.validate_json(response.text)
assert mpic_response.is_valid is False

@pytest.mark.skip(reason='Not implemented yet')
def api_should_return_200_given_valid_dcv_validation(self, api_client):
@pytest.mark.parametrize('domain_or_ip_target, purpose_of_test', [
('dns-01.integration-testing.open-mpic.org', 'Standard proper dns-01 test'),
('dns-01-multi.integration-testing.open-mpic.org', 'Proper dns-01 test with multiple TXT records'),
('dns-01-cname.integration-testing.open-mpic.org', 'Proper dns-01 test with CNAME')
])
def api_should_return_200_given_valid_dns_01_validation(self, api_client, domain_or_ip_target, purpose_of_test):
print(f"Running test for {domain_or_ip_target} ({purpose_of_test})")
request = MpicDcvRequest(
domain_or_ip_target='example.com',
domain_or_ip_target=domain_or_ip_target,
orchestration_parameters=MpicRequestOrchestrationParameters(perspective_count=3, quorum_count=2),
dcv_check_parameters=DcvCheckParameters(
validation_details=DcvWebsiteChangeValidationDetails(http_token_path='/',
challenge_value='test')
validation_details=DcvAcmeDns01ValidationDetails(key_authorization="7FwkJPsKf-TH54wu4eiIFA3nhzYaevsL7953ihy-tpo")
)
)

print("\nRequest:\n", json.dumps(request.model_dump(), indent=4)) # pretty print request body
response = api_client.post(MPIC_REQUEST_PATH, json.dumps(request.model_dump()))
assert response.status_code == 200
response_body = json.loads(response.text)
print("\nResponse:\n", json.dumps(response_body, indent=4)) # pretty print response body
# finish test... (and figure out how to actually run it successfully and reliably)
mpic_response = self.mpic_response_adapter.validate_json(response.text)

assert mpic_response.is_valid is True

@pytest.mark.parametrize('domain_or_ip_target, purpose_of_test', [
('dns-01-leading-whitespace.integration-testing.open-mpic.org', 'leading whitespace'),
('dns-01-trailing-whitespace.integration-testing.open-mpic.org', 'trailing'),
('dns-01-nxdomain.integration-testing.open-mpic.org', 'NXDOMAIN')
])
def api_should_return_200_is_valid_false_given_invalid_dns_01_validation(self, api_client, domain_or_ip_target, purpose_of_test):
print(f"Running test for {domain_or_ip_target} ({purpose_of_test})")
request = MpicDcvRequest(
domain_or_ip_target=domain_or_ip_target,
orchestration_parameters=MpicRequestOrchestrationParameters(perspective_count=3, quorum_count=2),
dcv_check_parameters=DcvCheckParameters(
validation_details=DcvAcmeDns01ValidationDetails(key_authorization="7FwkJPsKf-TH54wu4eiIFA3nhzYaevsL7953ihy-tpo")
)
)

print("\nRequest:\n", json.dumps(request.model_dump(), indent=4)) # pretty print request body
response = api_client.post(MPIC_REQUEST_PATH, json.dumps(request.model_dump()))
assert response.status_code == 200
mpic_response = self.mpic_response_adapter.validate_json(response.text)

assert mpic_response.is_valid is False

@pytest.mark.parametrize('domain_or_ip_target, dns_record_type, challenge_value, purpose_of_test', [
('dns-change-txt.integration-testing.open-mpic.org', DnsRecordType.TXT, "1234567890abcdefg.", 'standard TXT dns change'),
('dns-change-cname.integration-testing.open-mpic.org', DnsRecordType.CNAME, "1234567890abcdefg.", 'standard CNAME dns change'),
('dns-change-caa.integration-testing.open-mpic.org', DnsRecordType.CAA, '0 dnschange "1234567890abcdefg."', 'standard CAA dns change'),
])
def api_should_return_200_is_valid_true_given_valid_dns_change_validation(self, api_client, domain_or_ip_target, dns_record_type, challenge_value, purpose_of_test):
print(f"Running test for {domain_or_ip_target} ({purpose_of_test})")
request = MpicDcvRequest(
domain_or_ip_target=domain_or_ip_target,
orchestration_parameters=MpicRequestOrchestrationParameters(perspective_count=3, quorum_count=2),
dcv_check_parameters=DcvCheckParameters(
validation_details=DcvDnsChangeValidationDetails(challenge_value=challenge_value, dns_record_type=dns_record_type, dns_name_prefix="")
)
)

print("\nRequest:\n", json.dumps(request.model_dump(), indent=4)) # pretty print request body
response = api_client.post(MPIC_REQUEST_PATH, json.dumps(request.model_dump()))
assert response.status_code == 200
print("\nResponse:\n", json.dumps(json.loads(response.text), indent=4)) # pretty print request body

mpic_response = self.mpic_response_adapter.validate_json(response.text)

assert mpic_response.is_valid is True

def api_should_return_200_and_failed_corroboration_given_failed_dcv_check(self, api_client):
request = MpicDcvRequest(
Expand Down
Loading