1 package qapi
2
3 import (
4 "encoding/json"
5 "strings"
6 "testing"
7 )
8
9 func TestEvents(t *testing.T) {
10 tests := []struct {
11 input string
12 name string
13 }{
14 {
15 name: `SHUTDOWN`,
16 input: `{"event":"SHUTDOWN",` +
17 `"timestamp":{"seconds":1267040730,"microseconds":682951},` +
18 `"data":{"guest":true,"reason":"guest-shutdown"}}`,
19 },
20 {
21 name: `POWERDOWN`,
22 input: `{"event":"POWERDOWN",` +
23 `"timestamp":{"seconds":1267040730,"microseconds":682951}}`,
24 },
25 {
26 name: `RESET`,
27 input: `{"event":"RESET",` +
28 `"timestamp":{"seconds":1267041653,"microseconds":9518},` +
29 `"data":{"guest":false,"reason":"guest-reset"}}`,
30 },
31 {
32 name: `STOP`,
33 input: `{"event":"STOP",` +
34 `"timestamp":{"seconds":1267041730,"microseconds":281295}}`,
35 },
36 {
37 name: `RESUME`,
38 input: `{"event":"RESUME",` +
39 `"timestamp":{"seconds":1271770767,"microseconds":582542}}`,
40 },
41 {
42 name: `SUSPEND`,
43 input: `{"event":"SUSPEND",` +
44 `"timestamp":{"seconds":1344456160,"microseconds":309119}}`,
45 },
46 {
47 name: `SUSPEND_DISK`,
48 input: `{"event":"SUSPEND_DISK",` +
49 `"timestamp":{"seconds":1344456160,"microseconds":309119}}`,
50 },
51 {
52 name: `WAKEUP`,
53 input: `{"event":"WAKEUP",` +
54 `"timestamp":{"seconds":1344522075,"microseconds":745528}}`,
55 },
56 {
57 name: `WATCHDOG`,
58 input: `{"event":"WATCHDOG",` +
59 `"timestamp":{"seconds":1267061043,"microseconds":959568},` +
60 `"data":{"action":"reset"}}`,
61 },
62 {
63 name: `GUEST_PANICKED`,
64 input: `{"event":"GUEST_PANICKED",` +
65 `"timestamp":{"seconds":1267061043,"microseconds":959568},` +
66 `"data":{"action":"pause"}}`,
67 },
68 {
69 name: `GUEST_CRASHLOADED`,
70 input: `{"event":"GUEST_CRASHLOADED",` +
71 `"timestamp":{"seconds":1267061043,"microseconds":959568},` +
72 `"data":{"action":"run"}}`,
73 },
74 {
75 name: `MEMORY_FAILURE`,
76 input: `{"event":"MEMORY_FAILURE",` +
77 `"timestamp":{"seconds":1267061043,"microseconds":959568},` +
78 `"data":{"recipient":"hypervisor","action":"fatal","flags":{"action-required":false,"recursive":false}}}`,
79 },
80 {
81 name: `DEVICE_TRAY_MOVED`,
82 input: `{"event":"DEVICE_TRAY_MOVED",` +
83 `"timestamp":{"seconds":1265044230,"microseconds":450486},` +
84 `"data":{"device":"ide1-cd0","id":"/machine/unattached/device[22]","tray-open":true}}`,
85 },
86 {
87 name: `PR_MANAGER_STATUS_CHANGED`,
88 input: `{"event":"PR_MANAGER_STATUS_CHANGED",` +
89 `"timestamp":{"seconds":1519840375,"microseconds":450486},` +
90 `"data":{"id":"pr-helper0","connected":true}}`,
91 },
92 {
93 name: `BLOCK_IMAGE_CORRUPTED`,
94 input: `{"event":"BLOCK_IMAGE_CORRUPTED",` +
95 `"timestamp":{"seconds":1378126126,"microseconds":966463},` +
96 `"data":{"device":"","node-name":"drive","msg":"L2 table offset 0x2a2a2a00 unaligned (L1 index: 0)","fatal":false}}`,
97 },
98 {
99 name: `BLOCK_IO_ERROR`,
100 input: `{"event":"BLOCK_IO_ERROR",` +
101 `"timestamp":{"seconds":1265044230,"microseconds":450486},` +
102 `"data":{"device":"ide0-hd1","node-name":"#block212","operation":"write","action":"stop","reason":"Driver requires too large request alignment"}}`,
103 },
104 {
105 name: `BLOCK_JOB_COMPLETED`,
106 input: `{"event":"BLOCK_JOB_COMPLETED",` +
107 `"timestamp":{"seconds":1267061043,"microseconds":959568},` +
108 `"data":{"type":"stream","device":"virtio-disk0","len":10737418240,"offset":10737418240,"speed":0}}`,
109 },
110 {
111 name: `BLOCK_JOB_CANCELLED`,
112 input: `{"event":"BLOCK_JOB_CANCELLED",` +
113 `"timestamp":{"seconds":1267061043,"microseconds":959568},` +
114 `"data":{"type":"stream","device":"virtio-disk0","len":10737418240,"offset":134217728,"speed":0}}`,
115 },
116 {
117 name: `BLOCK_JOB_ERROR`,
118 input: `{"event":"BLOCK_JOB_ERROR",` +
119 `"timestamp":{"seconds":1265044230,"microseconds":450486},` +
120 `"data":{"device":"ide0-hd1","operation":"write","action":"stop"}}`,
121 },
122 {
123 name: `BLOCK_JOB_READY`,
124 input: `{"event":"BLOCK_JOB_READY",` +
125 `"timestamp":{"seconds":1265044230,"microseconds":450486},` +
126 `"data":{"type":"mirror","device":"drive0","len":2097152,"offset":2097152,"speed":0}}`,
127 },
128 {
129 name: `BLOCK_JOB_PENDING`,
130 input: `{"event":"BLOCK_JOB_PENDING",` +
131 `"timestamp":{"seconds":1265044230,"microseconds":450486},` +
132 `"data":{"type":"mirror","id":"backup_1"}}`,
133 },
134 {
135 name: `QUORUM_FAILURE`,
136 input: `{"event":"QUORUM_FAILURE",` +
137 `"timestamp":{"seconds":1344522075,"microseconds":745528},` +
138 `"data":{"reference":"usr1","sector-num":345435,"sectors-count":5}}`,
139 },
140 {
141 name: `QUORUM_REPORT_BAD`,
142 input: `{"event":"QUORUM_REPORT_BAD",` +
143 `"timestamp":{"seconds":1344522075,"microseconds":745528},` +
144 `"data":{"type":"read","node-name":"node0","sector-num":345435,"sectors-count":5}}`,
145 },
146 {
147 name: `QUORUM_REPORT_BAD`,
148 input: `{"event":"QUORUM_REPORT_BAD",` +
149 `"timestamp":{"seconds":1344522075,"microseconds":745528},` +
150 `"data":{"type":"flush","error":"Broken pipe","node-name":"node0","sector-num":0,"sectors-count":2097120}}`,
151 },
152 {
153 name: `VSERPORT_CHANGE`,
154 input: `{"event":"VSERPORT_CHANGE",` +
155 `"timestamp":{"seconds":1401385907,"microseconds":422329},` +
156 `"data":{"id":"channel0","open":true}}`,
157 },
158 {
159 name: `DUMP_COMPLETED`,
160 input: `{"event":"DUMP_COMPLETED",` +
161 `"timestamp":{"seconds":1265044230,"microseconds":450486},` +
162 `"data":{"result":{"status":"completed","completed":1090650112,"total":1090650112}}}`,
163 },
164 {
165 name: `NIC_RX_FILTER_CHANGED`,
166 input: `{"event":"NIC_RX_FILTER_CHANGED",` +
167 `"timestamp":{"seconds":1368697518,"microseconds":326866},` +
168 `"data":{"name":"vnet0","path":"/machine/peripheral/vnet0/virtio-backend"}}`,
169 },
170 {
171 name: `FAILOVER_NEGOTIATED`,
172 input: `{"event":"FAILOVER_NEGOTIATED",` +
173 `"timestamp":{"seconds":1368697518,"microseconds":326866},` +
174 `"data":{"device-id":"net1"}}`,
175 },
176 {
177 name: `RDMA_GID_STATUS_CHANGED`,
178 input: `{"event":"RDMA_GID_STATUS_CHANGED",` +
179 `"timestamp":{"seconds":1541579657,"microseconds":986760},` +
180 `"data":{"netdev":"bridge0","gid-status":true,` +
181 `"subnet-prefix":33022,"interface-id":15880512517475447892}}`,
182 },
183 {
184 name: `SPICE_CONNECTED`,
185 input: `{"event":"SPICE_CONNECTED",` +
186 `"timestamp":{"seconds":1290688046,"microseconds":388707},` +
187 `"data":{` +
188 `"server":{"host":"127.0.0.1","port":"5920","family":"ipv4"},` +
189 `"client":{"host":"127.0.0.1","port":"52873","family":"ipv4"}}}`,
190 },
191 {
192 name: `SPICE_INITIALIZED`,
193 input: `{"event":"SPICE_INITIALIZED",` +
194 `"timestamp":{"seconds":1290688046,"microseconds":388707},` +
195 `"data":{` +
196 `"server":{"host":"127.0.0.1","port":"5921","family":"ipv4","auth":"spice"},` +
197 `"client":{"host":"127.0.0.1","port":"49004","family":"ipv4","connection-id":1804289383,"channel-type":3,"channel-id":0,"tls":true}}}`,
198 },
199 {
200 name: `SPICE_DISCONNECTED`,
201 input: `{"event":"SPICE_DISCONNECTED",` +
202 `"timestamp":{"seconds":1290688046,"microseconds":388707},` +
203 `"data":{` +
204 `"server":{"host":"127.0.0.1","port":"5920","family":"ipv4"},` +
205 `"client":{"host":"127.0.0.1","port":"52873","family":"ipv4"}}}`,
206 },
207 {
208 name: `SPICE_MIGRATE_COMPLETED`,
209 input: `{"event":"SPICE_MIGRATE_COMPLETED",` +
210 `"timestamp":{"seconds":1290688046,"microseconds":417172}}`,
211 },
212 {
213 name: `VNC_CONNECTED`,
214 input: `{"event":"VNC_CONNECTED",` +
215 `"timestamp":{"seconds":1262976601,"microseconds":975795},` +
216 `"data":{` +
217 `"server":{"host":"0.0.0.0","service":"5901","family":"ipv4","websocket":false,"auth":"sasl"},` +
218 `"client":{"host":"127.0.0.1","service":"58425","family":"ipv4","websocket":false}}}`,
219 },
220 {
221 name: `VNC_INITIALIZED`,
222 input: `{"event":"VNC_INITIALIZED",` +
223 `"timestamp":{"seconds":1263475302,"microseconds":150772},` +
224 `"data":{` +
225 `"server":{"host":"0.0.0.0","service":"5901","family":"ipv4","websocket":false,"auth":"sasl"},` +
226 `"client":{"host":"127.0.0.1","service":"46089","family":"ipv4","websocket":false,"sasl_username":"luiz"}}}`,
227 },
228 {
229 name: `VNC_DISCONNECTED`,
230 input: `{"event":"VNC_DISCONNECTED",` +
231 `"timestamp":{"seconds":1262976601,"microseconds":975795},` +
232 `"data":{` +
233 `"server":{"host":"0.0.0.0","service":"5901","family":"ipv4","websocket":false,"auth":"sasl"},` +
234 `"client":{"host":"127.0.0.1","service":"58425","family":"ipv4","websocket":false,"sasl_username":"luiz"}}}`,
235 },
236 {
237 name: `MIGRATION`,
238 input: `{"event":"MIGRATION",` +
239 `"timestamp":{"seconds":1432121972,"microseconds":744001},` +
240 `"data":{"status":"completed"}}`,
241 },
242 {
243 name: `MIGRATION_PASS`,
244 input: `{"event":"MIGRATION_PASS",` +
245 `"timestamp":{"seconds":1432121972,"microseconds":744001},` +
246 `"data":{"pass":2}}`,
247 },
248 {
249 name: `COLO_EXIT`,
250 input: `{"event":"COLO_EXIT",` +
251 `"timestamp":{"seconds":1432121972,"microseconds":744001},` +
252 `"data":{"mode":"primary","reason":"request"}}`,
253 },
254 {
255 name: `UNPLUG_PRIMARY`,
256 input: `{"event":"UNPLUG_PRIMARY",` +
257 `"timestamp":{"seconds":1265044230,"microseconds":450486},` +
258 `"data":{"device-id":"hostdev0"}}`,
259 },
260 {
261 name: `DEVICE_DELETED`,
262 input: `{"event":"DEVICE_DELETED",` +
263 `"timestamp":{"seconds":1265044230,"microseconds":450486},` +
264 `"data":{"device":"virtio-net-pci-0","path":"/machine/peripheral/virtio-net-pci-0"}}`,
265 },
266 {
267 name: `DEVICE_UNPLUG_GUEST_ERROR`,
268 input: `{"event":"DEVICE_UNPLUG_GUEST_ERROR",` +
269 `"timestamp":{"seconds":1615570772,"microseconds":202844},` +
270 `"data":{"device":"core1","path":"/machine/peripheral/core1"}}`,
271 },
272 {
273 name: `BALLOON_CHANGE`,
274 input: `{"event":"BALLOON_CHANGE",` +
275 `"timestamp":{"seconds":1267020223,"microseconds":435656},` +
276 `"data":{"actual":944766976}}`,
277 },
278 {
279 name: `MEMORY_DEVICE_SIZE_CHANGE`,
280 input: `{"event":"MEMORY_DEVICE_SIZE_CHANGE",` +
281 `"timestamp":{"seconds":1588168529,"microseconds":201316},` +
282 `"data":{"id":"vm0","size":1073741824,"qom-path":"/machine/unattached/device[2]"}}`,
283 },
284 {
285 name: `MEM_UNPLUG_ERROR`,
286 input: `{"event":"MEM_UNPLUG_ERROR",` +
287 `"timestamp":{"seconds":1265044230,"microseconds":450486},` +
288 `"data":{"device":"dimm1","msg":"acpi: device unplug for unsupported device"}}`,
289 },
290 {
291 name: `RTC_CHANGE`,
292 input: `{"event":"RTC_CHANGE",` +
293 `"timestamp":{"seconds":1267020223,"microseconds":435656},` +
294 `"data":{"offset":78,"qom-path":"/machine/unattached/device[0]"}}`,
295 },
296 {
297 name: `ACPI_DEVICE_OST`,
298 input: `{"event":"ACPI_DEVICE_OST",` +
299 `"timestamp":{"seconds":1265044230,"microseconds":450486},` +
300 `"data":{"info":{"device":"d1","slot":"0","slot-type":"DIMM","source":1,"status":0}}}`,
301 },
302 }
303
304 for _, testCase := range tests {
305 e := Event{}
306 if err := json.Unmarshal([]byte(testCase.input), &e); err != nil {
307 t.Fatalf("(unmarshal) error on decoding %s: %s", testCase.input, err.Error())
308 } else if e.Name != testCase.name {
309 t.Fatalf("(unmarshal) event name differs:\nGot%s\nHas:%s\n", e.Name, testCase.name)
310 }
311
312 if b, err := json.Marshal(&e); err != nil {
313 t.Fatalf("(marshal) error with %s: %s\n", testCase.input, err.Error())
314 } else if strings.Compare(string(b), testCase.input) != 0 {
315 t.Fatalf("(marshal) expected output failed:\nGot:%v\nHas:%s\n", string(b), testCase.input)
316 }
317 }
318 }
319
View as plain text