import math import pytest import requests_mock from rpcq.core_messages import BinaryExecutableResponse from pyquil import Program from pyquil.api._base_connection import get_session from pyquil.api._compiler import QPUCompiler from pyquil.api._config import PyquilConfig from pyquil.api._errors import UserMessageError from pyquil.device import Device from pyquil.gates import RX, MEASURE from pyquil.tests.utils import api_fixture_path def simple_program(): program = Program() readout = program.declare("ro", "BIT", 3) program += RX(math.pi / 2, 0) program += MEASURE(0, readout[0]) return program SIMPLE_RESPONSE = { "program": "bAsE64==", "memory_descriptors": {}, "ro_sources": [], "_type": "BinaryExecutableResponse", } DUMMY_ISA_DICT = {"1Q": {"0": {}, "1": {}}, "2Q": {"0-1": {}}} TEST_CONFIG_PATHS = { "QCS_CONFIG": api_fixture_path("qcs_config.ini"), "FOREST_CONFIG": api_fixture_path("forest_config.ini"), } def test_http_compilation(compiler): device_name = "test_device" mock_url = "http://mock-qpu-compiler" config = PyquilConfig(TEST_CONFIG_PATHS) session = get_session(config=config) mock_adapter = requests_mock.Adapter() session.mount("http://", mock_adapter) headers = { # access token from ./data/user_auth_token_valid.json. "Authorization": "Bearer secret" } mock_adapter.register_uri( "POST", f"{mock_url}/devices/{device_name}/get_version_info", status_code=200, json={}, headers=headers, ) mock_adapter.register_uri( "POST", f"{mock_url}/devices/{device_name}/native_quil_to_binary", status_code=200, json=SIMPLE_RESPONSE, headers=headers, ) device = Device( name="not_actually_device_name", raw={"device_name": device_name, "isa": DUMMY_ISA_DICT} ) compiler = QPUCompiler( quilc_endpoint=session.config.quilc_url, qpu_compiler_endpoint=mock_url, device=device, session=session, ) compilation_result = compiler.native_quil_to_executable( compiler.quil_to_native_quil(simple_program()) ) assert isinstance(compilation_result, BinaryExecutableResponse) assert compilation_result.program == SIMPLE_RESPONSE["program"] def test_http_compilation_failure(compiler): device_name = "test_device" mock_url = "http://mock-qpu-compiler" config = PyquilConfig(TEST_CONFIG_PATHS) session = get_session(config=config) mock_adapter = requests_mock.Adapter() session.mount("http://", mock_adapter) headers = { # access token from ./data/user_auth_token_valid.json. "Authorization": "Bearer secret" } mock_adapter.register_uri( "POST", f"{mock_url}/devices/{device_name}/get_version_info", status_code=200, json={}, headers=headers, ) mock_adapter.register_uri( "POST", f"{mock_url}/devices/{device_name}/native_quil_to_binary", status_code=500, json={"message": "test compilation failed"}, headers=headers, ) device = Device( name="not_actually_device_name", raw={"device_name": device_name, "isa": DUMMY_ISA_DICT} ) compiler = QPUCompiler( quilc_endpoint=session.config.quilc_url, qpu_compiler_endpoint=mock_url, device=device, session=session, ) native_quil = compiler.quil_to_native_quil(simple_program()) with pytest.raises(UserMessageError) as excinfo: compiler.native_quil_to_executable(native_quil) assert "test compilation failed" in str(excinfo.value) def test_invalid_protocol(): device_name = "test_device" mock_url = "not-http-or-tcp://mock-qpu-compiler" config = PyquilConfig(TEST_CONFIG_PATHS) session = get_session(config=config) mock_adapter = requests_mock.Adapter() session.mount("", mock_adapter) device = Device( name="not_actually_device_name", raw={"device_name": device_name, "isa": DUMMY_ISA_DICT} ) with pytest.raises(UserMessageError): QPUCompiler( quilc_endpoint=session.config.quilc_url, qpu_compiler_endpoint=mock_url, device=device, session=session, )