@@ -3,6 +3,200 @@ use anyhow::Result;
33
44const WASM_PATH : & str = "../../kcl.wasm" ;
55const BENCH_COUNT : usize = 20 ;
6+ const SOURCES : & [ & str ] = & [
7+ r#"apiVersion = "apps/v1"
8+ kind = "Deployment"
9+ metadata = {
10+ name = "nginx"
11+ labels.app = "nginx"
12+ }
13+ spec = {
14+ replicas = 3
15+ selector.matchLabels = metadata.labels
16+ template.metadata.labels = metadata.labels
17+ template.spec.containers = [
18+ {
19+ name = metadata.name
20+ image = "nginx:1.14.2"
21+ ports = [{ containerPort = 80 }]
22+ }
23+ ]
24+ }"# ,
25+ r#"import manifests
26+
27+ schema App:
28+ """The application model."""
29+ name: str
30+ replicas: int = 1
31+ labels?: {str:str} = {app = name}
32+ service?: Service
33+ containers?: {str:Container}
34+
35+ schema Service:
36+ """The service model."""
37+ $type?: str
38+ ports: [Port]
39+
40+ schema Port:
41+ """The port model."""
42+ port: int
43+ protocol: "TCP" | "UDP" | "SCTP" = "TCP"
44+ targetPort?: int | str
45+
46+ schema Container:
47+ """The container model."""
48+ image: str
49+ command?: [str]
50+ args?: [str]
51+ env?: [Env]
52+ volumes?: [Volume]
53+ resources?: Resource
54+ ports: [ContainerPort]
55+
56+ schema ContainerPort:
57+ """The container port model."""
58+ name?: str
59+ protocol: "TCP" | "UDP" | "SCTP" = "TCP"
60+ containerPort: int
61+
62+ check:
63+ 1 <= containerPort <= 65535, "containerPort must be between 1 and 65535, inclusive"
64+
65+ schema Env:
66+ name: str
67+ value: str
68+
69+ schema Volume:
70+ source: str
71+ path: str
72+ target: str
73+ readOnly?: bool = False
74+
75+ schema Resource:
76+ limits?: {str:}
77+ requests?: {str:}
78+
79+ kubernetesRender = lambda a: App {
80+ # Construct the deployment manifest.
81+ deployment = {
82+ apiVersion = "apps/v1"
83+ kind = "Deployment"
84+ metadata.name = a.name
85+ metadata.labels = a.labels
86+ spec = {
87+ replicas = a.replicas
88+ selector.matchLabels = a.labels
89+ template.metadata.labels = a.labels
90+ template.spec.containers = [{
91+ name = name
92+ image = c.image
93+ command = c.command
94+ args = c.args
95+ env = c.env
96+ volumeMounts = c.volumes
97+ resources: c.resources
98+ ports = c.ports
99+ } for name, c in a.containers]
100+ }
101+ }
102+ # Construct the service manifest.
103+ service = {
104+ apiVersion = "v1"
105+ kind = "Service"
106+ metadata.name = a.name
107+ metadata.labels = a.labels
108+ spec = {
109+ type = a.service?.$type
110+ selector = a.labels
111+ ports = a.service?.ports
112+ }
113+ }
114+ # Returns Kubernetes manifests
115+ [
116+ deployment
117+ if a.service:
118+ service
119+
120+ ]
121+ }
122+
123+ app = App {
124+ name = "app"
125+ containers.nginx = {
126+ image = "nginx"
127+ ports = [{containerPort = 80}]
128+ }
129+ service.ports = [{port = 80}]
130+ }
131+
132+ manifests.yaml_stream(sum([kubernetesRender(a) for a in App.instances()], []))"# ,
133+ r#"import yaml
134+
135+ resource = yaml.decode("""\
136+ apiVersion: apps/v1
137+ kind: Deployment
138+ metadata:
139+ name: nginx-deployment
140+ labels:
141+ app: nginx
142+ spec:
143+ replicas: 3
144+ selector:
145+ matchLabels:
146+ app: nginx
147+ template:
148+ metadata:
149+ labels:
150+ app: nginx
151+ spec:
152+ containers:
153+ - name: nginx
154+ image: nginx:1.14.2
155+ ports:
156+ - containerPort: 80
157+ """)
158+
159+ set_replicas = lambda item: {str:}, replicas: int {
160+ item | {
161+ if item?.kind == "Deployment":
162+ spec.replicas = replicas
163+
164+ }
165+ }
166+
167+ new_resource = set_replicas(resource, 5)"# ,
168+ r#"import yaml
169+ import json
170+
171+ schema Server:
172+ ports: [int]
173+
174+ check:
175+ all p in ports {
176+ 0 < p < 65535
177+ }
178+
179+ server1: Server = yaml.decode("""\
180+ ports:
181+ - 80
182+ - 8080
183+ """)
184+ server2: Server = json.decode("""\
185+ {
186+ "ports": [80, 8000]
187+ }
188+ """)"# ,
189+ r#"x = (10 + 2) * 30 + 5"# ,
190+ r#"print("Output values")"# ,
191+ r#"if True:
192+ print("Hello")
193+ else:
194+ print("unreachable")"# ,
195+ r#"data = ["one", "two", "three"]"# ,
196+ r#"Config = {
197+ key = "value"
198+ }"# ,
199+ ] ;
6200
7201#[ test]
8202fn test_run ( ) -> Result < ( ) > {
@@ -18,6 +212,20 @@ fn test_run() -> Result<()> {
18212 Ok ( ( ) )
19213}
20214
215+ #[ test]
216+ fn test_run_examples ( ) -> Result < ( ) > {
217+ for source in SOURCES {
218+ let opts = RunOptions {
219+ filename : "test.k" . to_string ( ) ,
220+ source : source. to_string ( ) ,
221+ } ;
222+ let mut module = KCLModule :: from_path ( WASM_PATH ) ?;
223+ let result = module. run ( & opts) ?;
224+ assert ! ( !result. starts_with( "ERROR:" ) , "source: {source}. result: {result}" ) ;
225+ }
226+ Ok ( ( ) )
227+ }
228+
21229#[ test]
22230fn test_run_parse_error ( ) -> Result < ( ) > {
23231 let opts = RunOptions {
0 commit comments