Skip to content

Commit 5e515ff

Browse files
phlogistonjohnbehrmann
authored andcommitted
tests: add a test case for custom server json encoding class
Add a new test file to verify that the json_encoder_cls argument can be given to the Service to specify a custom encoder. Signed-off-by: John Mulligan <jmulligan@redhat.com>
1 parent 2332b34 commit 5e515ff

File tree

2 files changed

+151
-0
lines changed

2 files changed

+151
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Example Varlink service
2+
interface org.example.encoding
3+
4+
type State (
5+
start: ?bool,
6+
progress: ?int,
7+
end: ?bool
8+
)
9+
10+
type Shipment (
11+
name: string,
12+
description: string,
13+
size: int,
14+
weight: ?int
15+
)
16+
17+
type Order (
18+
shipments: []Shipment,
19+
order_num: int,
20+
customer: string
21+
)
22+
23+
# Returns the same string
24+
method Ping(ping: string) -> (pong: string)
25+
26+
# Returns a fake order given an order number
27+
method GetOrder(num: int) -> (order: Order)
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#!/usr/bin/env python
2+
3+
"""Test custom JSON encoding by subclassing VarlinkEncoder and
4+
passing it to a server Service.
5+
"""
6+
7+
import dataclasses
8+
import os
9+
import threading
10+
import time
11+
import typing
12+
import unittest
13+
14+
import varlink
15+
import varlink.error
16+
17+
18+
@dataclasses.dataclass
19+
class Shipment:
20+
name: str
21+
description: str
22+
size: int
23+
weight: typing.Optional[int] = None
24+
25+
26+
@dataclasses.dataclass
27+
class Order:
28+
shipments: list[Shipment]
29+
order_num: int
30+
customer: str
31+
32+
33+
@dataclasses.dataclass
34+
class GetOrderResult:
35+
order: Order
36+
37+
38+
class VDCEncoder(varlink.error.VarlinkEncoder):
39+
def default(self, obj):
40+
if dataclasses.is_dataclass(obj):
41+
return dataclasses.asdict(obj)
42+
return super().default(obj)
43+
44+
45+
service = varlink.Service(
46+
vendor="Varlink",
47+
product="Varlink Encoding Example",
48+
version="1",
49+
url="http://varlink.org",
50+
interface_dir=os.path.dirname(__file__),
51+
json_encoder_cls=VDCEncoder,
52+
)
53+
54+
55+
class ServiceRequestHandler(varlink.RequestHandler):
56+
service = service
57+
58+
59+
@service.interface("org.example.encoding")
60+
class EncodingExample:
61+
sleep_duration = 1
62+
63+
def Ping(self, ping):
64+
return {"pong": ping}
65+
66+
def GetOrder(self, num):
67+
order = Order(
68+
shipments=[
69+
Shipment(
70+
name="Furniture",
71+
description="Furniture by Ferb",
72+
size=1000,
73+
weight=400,
74+
),
75+
Shipment(
76+
name="Electronics",
77+
description="Electronics by Earl",
78+
size=588,
79+
),
80+
],
81+
order_num=num,
82+
customer="Joe's Discount Store",
83+
)
84+
return GetOrderResult(order=order)
85+
86+
87+
class TestService(unittest.TestCase):
88+
address = "tcp:127.0.0.1:23451"
89+
90+
@classmethod
91+
def setUpClass(cls):
92+
cls._server = varlink.ThreadingServer(cls.address, ServiceRequestHandler)
93+
cls._server_thread = threading.Thread(target=cls._server.serve_forever)
94+
cls._server_thread.start()
95+
time.sleep(0.1)
96+
97+
@classmethod
98+
def tearDownClass(cls):
99+
cls._server.shutdown()
100+
cls._server.server_close()
101+
cls._server_thread.join()
102+
103+
def test_ping(self):
104+
client = varlink.Client.new_with_address(self.address)
105+
with client.open("org.example.encoding") as conn:
106+
response = conn.Ping("Foo")
107+
self.assertEqual(response["pong"], "Foo")
108+
109+
def test_get_order(self):
110+
client = varlink.Client.new_with_address(self.address)
111+
with client.open("org.example.encoding") as conn:
112+
response = conn.GetOrder(4638547)
113+
# response will be a dict represenation of GetOrderResult
114+
self.assertIn("order", response)
115+
order = response["order"]
116+
self.assertEqual(order.get("order_num"), 4638547)
117+
self.assertEqual(order.get("customer"), "Joe's Discount Store")
118+
self.assertEqual(len(order.get("shipments", [])), 2)
119+
shipment1 = order["shipments"][0]
120+
self.assertEqual(shipment1.get("name"), "Furniture")
121+
self.assertIsNotNone(shipment1.get("weight"))
122+
shipment2 = order["shipments"][1]
123+
self.assertEqual(shipment2.get("name"), "Electronics")
124+
self.assertIsNone(shipment2.get("weight"))

0 commit comments

Comments
 (0)