domain_test.go 17.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*
 * This file is part of the libvirt-go project
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * Copyright (c) 2013 Alex Zorin
 * Copyright (C) 2016 Red Hat, Inc.
 *
 */

27 28 29
package libvirt

import (
30
	"strings"
31
	"testing"
32
	"time"
33 34
)

35
func buildTestDomain() (*Domain, *Connect) {
36
	conn := buildTestConnection()
37 38 39 40 41 42 43 44 45 46
	dom, err := conn.DomainDefineXML(`<domain type="test">
		<name>` + time.Now().String() + `</name>
		<memory unit="KiB">8192</memory>
		<os>
			<type>hvm</type>
		</os>
	</domain>`)
	if err != nil {
		panic(err)
	}
47
	return dom, conn
48 49
}

50
func buildSMPTestDomain() (*Domain, *Connect) {
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
	conn := buildTestConnection()
	dom, err := conn.DomainDefineXML(`<domain type="test">
		<name>` + time.Now().String() + `</name>
		<memory unit="KiB">8192</memory>
		<vcpu>8</vcpu>
  		<os>
			<type>hvm</type>
		</os>
	</domain>`)
	if err != nil {
		panic(err)
	}
	return dom, conn
}

66
func buildTransientTestDomain() (*Domain, *Connect) {
67 68
	conn := buildTestConnection()
	dom, err := conn.DomainCreateXML(`<domain type="test">
69
		<name>`+time.Now().String()+`</name>
70 71 72 73
		<memory unit="KiB">8192</memory>
		<os>
			<type>hvm</type>
		</os>
74
	</domain>`, DOMAIN_NONE)
75 76 77 78 79 80
	if err != nil {
		panic(err)
	}
	return dom, conn
}

81 82
func TestUndefineDomain(t *testing.T) {
	dom, conn := buildTestDomain()
83 84
	defer func() {
		dom.Free()
85 86
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
87
		}
88
	}()
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
	name, err := dom.GetName()
	if err != nil {
		t.Error(err)
		return
	}
	if err := dom.Undefine(); err != nil {
		t.Error(err)
		return
	}
	if _, err := conn.LookupDomainByName(name); err == nil {
		t.Fatal("Shouldn't have been able to find domain")
		return
	}
}

104
func TestGetDomainName(t *testing.T) {
105
	dom, conn := buildTestDomain()
106 107 108
	defer func() {
		dom.Undefine()
		dom.Free()
109 110
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
111
		}
112
	}()
113
	if _, err := dom.GetName(); err != nil {
114
		t.Error(err)
alexzorin's avatar
alexzorin committed
115
		return
116 117 118 119
	}
}

func TestGetDomainState(t *testing.T) {
120
	dom, conn := buildTestDomain()
121 122
	defer func() {
		dom.Free()
123 124
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
125
		}
126
	}()
127
	state, reason, err := dom.GetState()
128 129
	if err != nil {
		t.Error(err)
alexzorin's avatar
alexzorin committed
130
		return
131
	}
132 133
	if state != DOMAIN_SHUTOFF {
		t.Error("Domain state in test transport should be shutoff")
alexzorin's avatar
alexzorin committed
134
		return
135
	}
136 137
	if DomainShutoffReason(reason) != DOMAIN_SHUTOFF_UNKNOWN {
		t.Error("Domain reason in test transport should be unknown")
alexzorin's avatar
alexzorin committed
138
		return
139 140 141
	}
}

142 143 144 145
func TestGetDomainID(t *testing.T) {
	dom, conn := buildTestDomain()
	defer func() {
		dom.Free()
146 147
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
148
		}
149 150 151 152 153 154 155 156 157 158 159 160 161 162
	}()

	if err := dom.Create(); err != nil {
		t.Error("Failed to create domain")
	}

	if id, err := dom.GetID(); id == ^uint(0) || err != nil {
		dom.Destroy()
		t.Error("Couldn't get domain ID")
		return
	}
	dom.Destroy()
}

163
func TestGetDomainUUID(t *testing.T) {
164
	dom, conn := buildTestDomain()
165 166
	defer func() {
		dom.Free()
167 168
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
169
		}
170
	}()
171 172 173 174
	_, err := dom.GetUUID()
	// how to test uuid validity?
	if err != nil {
		t.Error(err)
alexzorin's avatar
alexzorin committed
175
		return
176 177 178 179
	}
}

func TestGetDomainUUIDString(t *testing.T) {
180
	dom, conn := buildTestDomain()
181 182
	defer func() {
		dom.Free()
183 184
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
185
		}
186
	}()
Alex Zorin's avatar
Alex Zorin committed
187
	_, err := dom.GetUUIDString()
188
	if err != nil {
Alex Zorin's avatar
Alex Zorin committed
189
		t.Error(err)
alexzorin's avatar
alexzorin committed
190
		return
Alex Zorin's avatar
Alex Zorin committed
191 192 193 194
	}
}

func TestGetDomainInfo(t *testing.T) {
195
	dom, conn := buildTestDomain()
196 197
	defer func() {
		dom.Free()
198 199
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
200
		}
201
	}()
Alex Zorin's avatar
Alex Zorin committed
202 203 204
	_, err := dom.GetInfo()
	if err != nil {
		t.Error(err)
alexzorin's avatar
alexzorin committed
205
		return
206 207
	}
}
Alex Zorin's avatar
Alex Zorin committed
208

Alex Zorin's avatar
Alex Zorin committed
209
func TestGetDomainXMLDesc(t *testing.T) {
210
	dom, conn := buildTestDomain()
211 212
	defer func() {
		dom.Free()
213 214
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
215
		}
216
	}()
Alex Zorin's avatar
Alex Zorin committed
217 218 219
	_, err := dom.GetXMLDesc(0)
	if err != nil {
		t.Error(err)
alexzorin's avatar
alexzorin committed
220
		return
Alex Zorin's avatar
Alex Zorin committed
221 222
	}
}
Alex Zorin's avatar
Alex Zorin committed
223 224

func TestCreateDomainSnapshotXML(t *testing.T) {
225
	dom, conn := buildTestDomain()
226 227
	defer func() {
		dom.Free()
228 229
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
230
		}
231
	}()
232
	ss, err := dom.CreateSnapshotXML(`
Alex Zorin's avatar
Alex Zorin committed
233 234 235 236
		<domainsnapshot>
			<description>Test snapshot that will fail because its unsupported</description>
		</domainsnapshot>
	`, 0)
237 238
	if err != nil {
		t.Error(err)
alexzorin's avatar
alexzorin committed
239
		return
Alex Zorin's avatar
Alex Zorin committed
240
	}
241
	defer ss.Free()
Alex Zorin's avatar
Alex Zorin committed
242
}
Alex Zorin's avatar
Alex Zorin committed
243 244

func TestSaveDomain(t *testing.T) {
245
	dom, conn := buildTestDomain()
246 247
	defer func() {
		dom.Free()
248 249
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
250
		}
251
	}()
252 253 254 255
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}
256 257
	// get the name so we can get a handle on it later
	domName, err := dom.GetName()
Alex Zorin's avatar
Alex Zorin committed
258 259
	if err != nil {
		t.Error(err)
alexzorin's avatar
alexzorin committed
260
		return
Alex Zorin's avatar
Alex Zorin committed
261
	}
262 263 264 265 266
	const tmpFile = "/tmp/libvirt-go-test.tmp"
	if err := dom.Save(tmpFile); err != nil {
		t.Error(err)
		return
	}
267
	if err := conn.DomainRestore(tmpFile); err != nil {
268 269 270
		t.Error(err)
		return
	}
271
	if dom2, err := conn.LookupDomainByName(domName); err != nil {
272 273
		t.Error(err)
		return
274 275
	} else {
		dom2.Free()
276
	}
Alex Zorin's avatar
Alex Zorin committed
277 278 279
}

func TestSaveDomainFlags(t *testing.T) {
280
	dom, conn := buildTestDomain()
281 282
	defer func() {
		dom.Free()
283 284
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
285
		}
286
	}()
287 288 289 290
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}
291 292 293
	const srcFile = "/tmp/libvirt-go-test.tmp"
	if err := dom.SaveFlags(srcFile, "", 0); err == nil {
		t.Fatal("expected xml modification unsupported")
alexzorin's avatar
alexzorin committed
294
		return
Alex Zorin's avatar
Alex Zorin committed
295 296
	}
}
297 298

func TestCreateDestroyDomain(t *testing.T) {
299
	dom, conn := buildTestDomain()
300 301
	defer func() {
		dom.Free()
302 303
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
304
		}
305
	}()
306
	if err := dom.Create(); err != nil {
307 308 309
		t.Error(err)
		return
	}
310
	state, reason, err := dom.GetState()
311 312 313 314
	if err != nil {
		t.Error(err)
		return
	}
315
	if state != DOMAIN_RUNNING {
316 317 318
		t.Fatal("Domain should be running")
		return
	}
319 320 321 322
	if DomainRunningReason(reason) != DOMAIN_RUNNING_BOOTED {
		t.Fatal("Domain reason should be booted")
		return
	}
323 324 325 326
	if err = dom.Destroy(); err != nil {
		t.Error(err)
		return
	}
327
	state, reason, err = dom.GetState()
328 329 330 331
	if err != nil {
		t.Error(err)
		return
	}
332
	if state != DOMAIN_SHUTOFF {
333 334 335
		t.Fatal("Domain should be destroyed")
		return
	}
336 337 338 339
	if DomainShutoffReason(reason) != DOMAIN_SHUTOFF_DESTROYED {
		t.Fatal("Domain reason should be destroyed")
		return
	}
340
}
alexzorin's avatar
alexzorin committed
341

342 343
func TestShutdownDomain(t *testing.T) {
	dom, conn := buildTestDomain()
344 345
	defer func() {
		dom.Free()
346 347
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
348 349
		}
	}()
350 351 352 353
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}
354 355 356 357
	if err := dom.Shutdown(); err != nil {
		t.Error(err)
		return
	}
358
	state, reason, err := dom.GetState()
359 360 361 362
	if err != nil {
		t.Error(err)
		return
	}
363 364 365 366 367 368
	if state != DOMAIN_SHUTOFF {
		t.Error("Domain state in test transport should be shutoff")
		return
	}
	if DomainShutoffReason(reason) != DOMAIN_SHUTOFF_SHUTDOWN {
		t.Error("Domain reason in test transport should be shutdown")
369 370
		return
	}
371 372 373 374
}

func TestShutdownReboot(t *testing.T) {
	dom, conn := buildTestDomain()
375 376
	defer func() {
		dom.Free()
377 378
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
379
		}
380
	}()
381 382 383 384
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}
385 386 387 388 389 390
	if err := dom.Reboot(0); err != nil {
		t.Error(err)
		return
	}
}

391
func TestDomainAutostart(t *testing.T) {
alexzorin's avatar
alexzorin committed
392
	dom, conn := buildTestDomain()
393 394
	defer func() {
		dom.Free()
395 396
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
397
		}
398
	}()
alexzorin's avatar
alexzorin committed
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421
	as, err := dom.GetAutostart()
	if err != nil {
		t.Error(err)
		return
	}
	if as {
		t.Fatal("autostart should be false")
		return
	}
	if err := dom.SetAutostart(true); err != nil {
		t.Error(err)
		return
	}
	as, err = dom.GetAutostart()
	if err != nil {
		t.Error(err)
		return
	}
	if !as {
		t.Fatal("autostart should be true")
		return
	}
}
422 423 424

func TestDomainIsActive(t *testing.T) {
	dom, conn := buildTestDomain()
425 426
	defer func() {
		dom.Free()
427 428
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
429
		}
430
	}()
431 432 433 434
	if err := dom.Create(); err != nil {
		t.Log(err)
		return
	}
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
	active, err := dom.IsActive()
	if err != nil {
		t.Error(err)
		return
	}
	if !active {
		t.Fatal("Domain should be active")
		return
	}
	if err := dom.Destroy(); err != nil {
		t.Error(err)
		return
	}
	active, err = dom.IsActive()
	if err != nil {
		t.Error(err)
		return
	}
	if active {
		t.Fatal("Domain should be inactive")
		return
	}
}
458

459 460 461 462 463 464
func TestDomainIsPersistent(t *testing.T) {
	dom, conn := buildTransientTestDomain()
	dom2, conn2 := buildTestDomain()
	defer func() {
		dom.Free()
		dom2.Free()
465 466
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
467
		}
468 469
		if res, _ := conn2.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
470
		}
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
	}()
	persistent, err := dom.IsPersistent()
	if err != nil {
		t.Error(err)
		return
	}
	if persistent {
		t.Fatal("Domain shouldn't be persistent")
		return
	}
	persistent, err = dom2.IsPersistent()
	if err != nil {
		t.Error(err)
		return
	}
	if !persistent {
		t.Fatal("Domain should be persistent")
		return
	}
}

492 493 494
func TestDomainSetMaxMemory(t *testing.T) {
	const mem = 8192 * 100
	dom, conn := buildTestDomain()
495 496
	defer func() {
		dom.Free()
497 498
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
499
		}
500
	}()
501 502 503 504 505 506 507 508
	if err := dom.SetMaxMemory(mem); err != nil {
		t.Error(err)
		return
	}
}

func TestDomainSetMemory(t *testing.T) {
	dom, conn := buildTestDomain()
509 510
	defer func() {
		dom.Free()
511 512
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
513
		}
514
	}()
515 516 517 518 519 520 521 522 523 524 525 526
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}
	if err := dom.SetMemory(1024); err != nil {
		t.Error(err)
		return
	}
}

func TestDomainSetVcpus(t *testing.T) {
	dom, conn := buildTestDomain()
527 528
	defer func() {
		dom.Free()
529 530
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
531
		}
532
	}()
533 534 535 536 537 538 539 540
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}
	if err := dom.SetVcpus(1); err != nil {
		t.Error(err)
		return
	}
541
	if err := dom.SetVcpusFlags(1, DOMAIN_VCPU_LIVE); err != nil {
542 543 544 545
		t.Error(err)
		return
	}
}
546 547 548

func TestDomainFree(t *testing.T) {
	dom, conn := buildTestDomain()
549
	defer func() {
550 551
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
552 553
		}
	}()
554 555 556 557 558
	if err := dom.Free(); err != nil {
		t.Error(err)
		return
	}
}
559 560 561 562 563

func TestDomainSuspend(t *testing.T) {
	dom, conn := buildTestDomain()
	defer func() {
		dom.Free()
564 565
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
566
		}
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
	}()
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}
	defer dom.Destroy()
	if err := dom.Suspend(); err != nil {
		t.Error(err)
		return
	}
	defer dom.Resume()
}

func TesDomainShutdownFlags(t *testing.T) {
	dom, conn := buildTestDomain()
582
	defer func() {
583 584
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
585 586
		}
	}()
587 588 589 590
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}
591
	if err := dom.ShutdownFlags(DOMAIN_SHUTDOWN_SIGNAL); err != nil {
592 593 594
		t.Error(err)
		return
	}
595
	state, reason, err := dom.GetState()
596 597 598 599
	if err != nil {
		t.Error(err)
		return
	}
600 601 602 603 604 605
	if state != DOMAIN_SHUTOFF {
		t.Error("Domain state in test transport should be shutoff")
		return
	}
	if DomainShutoffReason(reason) != DOMAIN_SHUTOFF_SHUTDOWN {
		t.Error("Domain reason in test transport should be shutdown")
606 607 608 609 610 611
		return
	}
}

func TesDomainDestoryFlags(t *testing.T) {
	dom, conn := buildTestDomain()
612
	defer func() {
613 614
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
615 616
		}
	}()
617 618 619 620
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}
621
	if err := dom.DestroyFlags(DOMAIN_DESTROY_GRACEFUL); err != nil {
622 623 624
		t.Error(err)
		return
	}
625
	state, reason, err := dom.GetState()
626 627 628 629
	if err != nil {
		t.Error(err)
		return
	}
630 631 632 633 634 635
	if state != DOMAIN_SHUTOFF {
		t.Error("Domain state in test transport should be shutoff")
		return
	}
	if DomainShutoffReason(reason) != DOMAIN_SHUTOFF_SHUTDOWN {
		t.Error("Domain reason in test transport should be shutdown")
636 637 638
		return
	}
}
Robert Xu's avatar
Robert Xu committed
639 640

func TestDomainScreenshot(t *testing.T) {
641 642 643 644
	if VERSION_NUMBER == 2005000 {
		/* 2.5.0 broke screenshot for test:///default driver */
		return
	}
Robert Xu's avatar
Robert Xu committed
645 646 647
	dom, conn := buildTestDomain()
	defer func() {
		dom.Free()
648 649
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
650
		}
Robert Xu's avatar
Robert Xu committed
651 652 653 654 655
	}()
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}
656
	stream, err := conn.NewStream(0)
Robert Xu's avatar
Robert Xu committed
657 658 659 660
	if err != nil {
		t.Fatalf("failed to create new stream: %s", err)
	}
	defer stream.Free()
661
	mime, err := dom.Screenshot(stream, 0, 0)
Robert Xu's avatar
Robert Xu committed
662 663 664
	if err != nil {
		t.Fatalf("failed to take screenshot: %s", err)
	}
665 666
	if strings.Index(mime, "image/") != 0 {
		t.Fatalf("Wanted image/*, got %s", mime)
Robert Xu's avatar
Robert Xu committed
667 668
	}
}
669 670

func TestDomainGetVcpus(t *testing.T) {
671
	dom, conn := buildSMPTestDomain()
672 673
	defer func() {
		dom.Free()
674 675
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
676
		}
677 678 679 680 681 682 683
	}()
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}
	defer dom.Destroy()

684
	stats, err := dom.GetVcpus()
685 686 687 688
	if err != nil {
		t.Fatal(err)
	}

689
	if len(stats) != 8 {
690
		t.Fatal("should have 1 cpu")
691 692 693 694 695 696 697 698 699 700 701
	}

	if stats[0].State != 1 {
		t.Fatal("state should be 1")
	}
}

func TestDomainGetVcpusFlags(t *testing.T) {
	dom, conn := buildTestDomain()
	defer func() {
		dom.Free()
702 703
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
704
		}
705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
	}()
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}
	defer dom.Destroy()

	num, err := dom.GetVcpusFlags(0)
	if err != nil {
		t.Fatal(err)
	}

	if num != 1 {
		t.Fatal("should have 1 cpu", num)
	}
}
721

722 723 724 725
func TestDomainPinVcpu(t *testing.T) {
	dom, conn := buildSMPTestDomain()
	defer func() {
		dom.Free()
726 727
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
728 729 730 731 732 733 734 735
		}
	}()
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}
	defer dom.Destroy()

736 737
	err := dom.PinVcpu(2, []bool{false, true, false, false,
		true, false, false, false})
738 739 740 741
	if err != nil {
		t.Fatal(err)
	}
}
742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818

type CPUStringData struct {
	cpustr string
	cpumap []bool
	err    bool
}

func TestParserCPUString(t *testing.T) {
	testDataList := []CPUStringData{
		CPUStringData{
			"0-1,4,7-9,^8",
			[]bool{
				true, true, false, false,
				true, false, false, true,
				false, true,
			},
			false,
		},
		CPUStringData{
			"0-0,1,^1",
			[]bool{true, false},
			false,
		},
		CPUStringData{
			"0-3,,",
			[]bool{},
			true,
		},
		CPUStringData{
			"0-3,,",
			[]bool{},
			true,
		},
		CPUStringData{
			"3-0",
			[]bool{},
			true,
		},
		CPUStringData{
			"!0-3",
			[]bool{},
			true,
		},
	}

	for _, testData := range testDataList {
		actual, err := parseCPUString(testData.cpustr)

		if testData.err {
			if err == nil {
				t.Errorf("Expected parse error from %s",
					testData.cpustr)
				return
			}
		} else {
			if err != nil {
				t.Errorf("Unexpected parse error from %s",
					testData.cpustr)
				return
			}
		}

		if len(actual) != len(testData.cpumap) {
			t.Errorf("Expected %s got %s",
				actual, testData.cpumap)
			return
		}

		for idx, val := range actual {
			if val != testData.cpumap[idx] {
				t.Errorf("Expected %s got %s",
					actual, testData.cpumap)
				return
			}
		}
	}
}
819 820 821 822 823 824 825 826 827 828 829 830 831

func TestSetMetadata(t *testing.T) {
	xmlns := "http://libvirt.org/xmlns/libvirt-go/test"
	xmlprefix := "test"
	meta := "<blob/>"

	dom, conn := buildTestDomain()
	defer func() {
		dom.Free()
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
		}
	}()
832 833 834 835 836
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}
	defer dom.Destroy()
837

838
	data, err := dom.GetMetadata(DOMAIN_METADATA_ELEMENT, xmlns, DOMAIN_AFFECT_LIVE)
839 840 841 842 843
	if err == nil {
		t.Errorf("Expected an error for missing metadata")
		return
	}

844
	err = dom.SetMetadata(DOMAIN_METADATA_ELEMENT, meta, xmlprefix, xmlns, DOMAIN_AFFECT_LIVE)
845 846 847 848 849
	if err != nil {
		t.Error(err)
		return
	}

850
	data, err = dom.GetMetadata(DOMAIN_METADATA_ELEMENT, xmlns, DOMAIN_AFFECT_LIVE)
851 852 853 854 855 856 857 858 859 860
	if err != nil {
		t.Errorf("Unexpected an error for metadata")
		return
	}

	if data != meta {
		t.Errorf("Metadata %s doesn't match %s", data, meta)
		return
	}

861
	err = dom.SetMetadata(DOMAIN_METADATA_ELEMENT, "", "", xmlns, DOMAIN_AFFECT_LIVE)
862 863 864 865 866
	if err != nil {
		t.Error(err)
		return
	}

867
	data, err = dom.GetMetadata(DOMAIN_METADATA_ELEMENT, xmlns, DOMAIN_AFFECT_LIVE)
868 869 870 871 872 873
	if err == nil {
		t.Errorf("Expected an error for deleted metadata")
		return
	}

}