Skip to content

Use scripts instead of notebooks for tests #1239

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
16 changes: 11 additions & 5 deletions .github/workflows/docker-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,19 @@ jobs:
python-version: '3.9'
- name: install dependencies
shell: bash
run: pip install client/ && pip install nbmake pytest
- name: Run basic notebooks
run: pip install client/
- name: Run basic tests
shell: bash
run: pytest --nbmake docs/getting_started/basic/
- name: Run experimental notebooks
run: |
cd tests/basic
for f in *.py; do echo "$f" && python "$f"; done
cd -
- name: Run experimental tests
shell: bash
run: pytest --nbmake docs/getting_started/experimental/
run: |
cd tests/experimental
for f in *.py; do echo "$f" && python "$f"; done
cd -
- name: Dump logs on failure
if: ${{ failure() }}
run: |
Expand Down
11 changes: 7 additions & 4 deletions .github/workflows/kubernetes-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,17 @@ jobs:
qiskit-aer>=0.13.3 \
certifi==2023.7.22
pip install nbmake pytest
- name: Run notebooks
- name: Run tests
run: |
kubectl patch svc gateway -p '{"spec": {"type": "LoadBalancer"}}'
export GATEWAY_HOST="http://$(kubectl get svc gateway -o jsonpath="{.status.loadBalancer.ingress[0].ip}"):8000"

echo $GATEWAY_HOST
pytest --nbmake /home/runner/work/quantum-serverless/quantum-serverless/docs/getting_started/basic/
pytest --nbmake /home/runner/work/quantum-serverless/quantum-serverless/docs/getting_started/experimental/
# basic tests
cd /home/runner/work/quantum-serverless/quantum-serverless/tests/basic
for f in *.py; do echo "$f" && python "$f"; done
# experimental tests
cd /home/runner/work/quantum-serverless/quantum-serverless/tests/experimental
for f in *.py; do echo "$f" && python "$f"; done
- name: Echo gateway logs
if: ${{ failure() }}
run: |
Expand Down
25 changes: 11 additions & 14 deletions .github/workflows/notebook-local-verify.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,20 @@ jobs:
- name: patch notebooks
shell: bash
run: |
sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/examples/02_qaoa.ipynb
sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/examples/01_vqe.ipynb
sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/getting_started/experimental/running_programs_using_decorators.ipynb
sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/getting_started/experimental/manage_data_directory.ipynb
sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/getting_started/experimental/file_download.ipynb
sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/getting_started/basic/02_arguments_and_results.ipynb
sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/getting_started/basic/04_distributed_workloads.ipynb
sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/getting_started/basic/05_retrieving_past_results.ipynb
sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/getting_started/basic/03_dependencies.ipynb
sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" docs/getting_started/basic/01_running_program.ipynb
for f in tests/basic/*.py; do sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" "$f"; done
for f in tests/experimental/*.py; do sed -i "s/import ServerlessProvider/import LocalProvider/;s/= ServerlessProvider(/= LocalProvider(/;/token=os\.environ\.get/d;/host=os\.environ\.get/d" "$f"; done
- name: install dependencies
shell: bash
run: pip install client/ && pip install nbmake pytest
run: pip install client/
- name: Run basic notebooks
shell: bash
run: IN_TEST=True pytest --nbmake docs/getting_started/basic/
run: |
cd tests/basic
for f in *.py; do echo "$f" && IN_TEST=True python "$f"; done
cd -
- name: Run experimental notebooks
shell: bash
run: IN_TEST=True pytest --nbmake docs/getting_started/experimental/

run: |
cd tests/experimental
for f in *.py; do echo "$f" && IN_TEST=True python "$f"; done
cd -
24 changes: 24 additions & 0 deletions tests/basic/01_running_program.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env python

from quantum_serverless import ServerlessProvider, QiskitPattern
import os


serverless = ServerlessProvider(
token=os.environ.get("GATEWAY_TOKEN", "awesome_token"),
host=os.environ.get("GATEWAY_HOST", "http://localhost:8000"),
)
print(serverless)

pattern = QiskitPattern(
title="my-first-pattern",
entrypoint="pattern.py",
working_dir="./source_files/",
)
serverless.upload(pattern)
job = serverless.run("my-first-pattern")
print(job)

print(job.result())
print(job.status())
print(job.logs())
31 changes: 31 additions & 0 deletions tests/basic/02_arguments_and_results.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env python

from qiskit import QuantumCircuit

circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
circuit.draw()

from quantum_serverless import ServerlessProvider, QiskitPattern
import os

serverless = ServerlessProvider(
token=os.environ.get("GATEWAY_TOKEN", "awesome_token"),
host=os.environ.get("GATEWAY_HOST", "http://localhost:8000"),
)
print(serverless)

pattern = QiskitPattern(
title="pattern-with-arguments",
entrypoint="pattern_with_arguments.py",
working_dir="./source_files/",
)
serverless.upload(pattern)
job = serverless.run("pattern-with-arguments", arguments={"circuit": circuit})
print(job)

print(job.result())
print(job.status())
print(job.logs())
33 changes: 33 additions & 0 deletions tests/basic/03_dependencies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env python

from quantum_serverless import QiskitPattern

pattern = QiskitPattern(
title="pattern-with-dependencies",
entrypoint="pattern_with_dependencies.py",
working_dir="./source_files/",
dependencies=["qiskit-experiments==0.6.0"],
)

from quantum_serverless import ServerlessProvider
import os

serverless = ServerlessProvider(
token=os.environ.get("GATEWAY_TOKEN", "awesome_token"),
host=os.environ.get("GATEWAY_HOST", "http://localhost:8000"),
)
print(serverless)

from qiskit.circuit.random import random_circuit

circuit = random_circuit(2, 2)


serverless.upload(pattern)

job = serverless.run("pattern-with-dependencies", arguments={"circuit": circuit})
print(job)

print(job.result())
print(job.status())
print(job.logs())
35 changes: 35 additions & 0 deletions tests/basic/04_distributed_workloads.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env python

from quantum_serverless import ServerlessProvider
import os

serverless = ServerlessProvider(
token=os.environ.get("GATEWAY_TOKEN", "awesome_token"),
host=os.environ.get("GATEWAY_HOST", "http://localhost:8000"),
)
print(serverless)


from qiskit.circuit.random import random_circuit

circuits = [random_circuit(2, 2) for _ in range(3)]
[circuit.measure_all() for circuit in circuits]
print(circuits)


from quantum_serverless import QiskitPattern

pattern = QiskitPattern(
title="pattern-with-parallel-workflow",
entrypoint="pattern_with_parallel_workflow.py",
working_dir="./source_files/",
)

serverless.upload(pattern)

job = serverless.run("pattern-with-parallel-workflow", arguments={"circuits": circuits})
print(job)

print(job.result())
print(job.status())
print(job.logs())
40 changes: 40 additions & 0 deletions tests/basic/05_retrieving_past_results.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env python

from quantum_serverless import ServerlessProvider
import os

serverless = ServerlessProvider(
token=os.environ.get("GATEWAY_TOKEN", "awesome_token"),
host=os.environ.get("GATEWAY_HOST", "http://localhost:8000"),
)
print(serverless)

from quantum_serverless import QiskitPattern

pattern = QiskitPattern(
title="pattern-to-fetch-results", entrypoint="pattern.py", working_dir="./source_files/"
)
serverless.upload(pattern)

job1 = serverless.run("pattern-to-fetch-results")
job2 = serverless.run("pattern-to-fetch-results")
print(job1)
print(job2)

job_id1 = job1.job_id
job_id2 = job2.job_id

print(job1.result())
print(job2.result())


retrieved_job1 = serverless.get_job_by_id(job_id1)
retrieved_job2 = serverless.get_job_by_id(job_id2)


print(f"Job 1 results: {retrieved_job1.result()}")
print(f"Job 2 results: {retrieved_job2.result()}")

print(f"Job 1 logs: {retrieved_job1.logs()}")

print(serverless.get_jobs(limit=2, offset=1))
9 changes: 9 additions & 0 deletions tests/basic/source_files/circuit_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from qiskit import QuantumCircuit


def create_hello_world_circuit() -> QuantumCircuit:
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
return circuit
22 changes: 22 additions & 0 deletions tests/basic/source_files/pattern.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from qiskit import QuantumCircuit
from qiskit.primitives import Sampler

from quantum_serverless import save_result

# all print statement will be available in job logs
print("Running pattern...")

# creating circuit
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()

# running Sampler primitive
sampler = Sampler()
quasi_dists = sampler.run(circuit).result().quasi_dists

# saves results of program execution,
# which will be accessible by calling `.result()`
save_result(quasi_dists)
print("Completed running pattern.")
20 changes: 20 additions & 0 deletions tests/basic/source_files/pattern_with_arguments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# source_files/program_3.py

from quantum_serverless import get_arguments, save_result

from qiskit.primitives import Sampler

# get all arguments passed to this program
arguments = get_arguments()

# get specific argument that we are interested in
circuit = arguments.get("circuit")

sampler = Sampler()

quasi_dists = sampler.run(circuit).result().quasi_dists

print(f"Quasi distribution: {quasi_dists[0]}")

# saving results of a program
save_result({"quasi_dists": quasi_dists[0]})
23 changes: 23 additions & 0 deletions tests/basic/source_files/pattern_with_dependencies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# source_files/program_4.py

from quantum_serverless import get_arguments, save_result

from qiskit.primitives import Sampler
from qiskit_experiments.library import StandardRB


arguments = get_arguments()

circuit = arguments.get("circuit")

rb = StandardRB(physical_qubits=(1,), lengths=list(range(1, 300, 30)), seed=42)
composed = circuit.compose(rb.circuits()[0])

sampler = Sampler()

quasi_dists = sampler.run(composed).result().quasi_dists

print(f"Quasi distribution: {quasi_dists[0]}")

# saving results of a program
save_result({"quasi_dists": quasi_dists[0]})
26 changes: 26 additions & 0 deletions tests/basic/source_files/pattern_with_parallel_workflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# source_files/program_with_parallel_workflow.py

from quantum_serverless import get_arguments, save_result, distribute_task, get

from qiskit import QuantumCircuit
from qiskit.primitives import Sampler
from qiskit.circuit.random import random_circuit


@distribute_task()
def distributed_sample(circuit: QuantumCircuit):
"""Distributed task that returns quasi distribution for given circuit."""
return Sampler().run(circuit).result().quasi_dists[0]


arguments = get_arguments()
circuits = arguments.get("circuits")

# run distributed tasks as async function
# we get task references as a return type
sample_task_references = [distributed_sample(circuit) for circuit in circuits]

# now we need to collect results from task references
results = get(sample_task_references)

save_result({"results": results})
29 changes: 29 additions & 0 deletions tests/experimental/file_download.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env python

import os
from quantum_serverless import ServerlessProvider, QiskitPattern

serverless = ServerlessProvider(
token=os.environ.get("GATEWAY_TOKEN", "awesome_token"),
host=os.environ.get("GATEWAY_HOST", "http://localhost:8000"),
)
print(serverless)

pattern = QiskitPattern(
title="file-producer", entrypoint="produce_files.py", working_dir="./source_files/"
)
serverless.upload(pattern)

job = serverless.run("file-producer")
print(job)

print(job.result())
print(job.status())
print(job.logs())

available_files = serverless.files()
print(available_files)

if len(available_files) > 0:
serverless.file_download(available_files[0])
print("Download complete")
Loading
Loading