integration_test.go 36.7 KB
Newer Older
alexzorin's avatar
alexzorin committed
1
// +build integration
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 27
/*
 * 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.
 *
 */
alexzorin's avatar
alexzorin committed
28 29 30 31

package libvirt

import (
32 33
	"bytes"
	"fmt"
dorzheh's avatar
dorzheh committed
34 35
	"io/ioutil"
	"os"
36
	"strings"
alexzorin's avatar
alexzorin committed
37 38 39 40
	"testing"
	"time"
)

41 42
func buildTestQEMUConnection() *Connect {
	conn, err := NewConnect("qemu:///system")
43 44 45 46 47 48
	if err != nil {
		panic(err)
	}
	return conn
}

49
func buildTestQEMUDomain(transient bool, name string) (*Domain, *Connect) {
50
	conn := buildTestQEMUConnection()
51 52 53 54 55 56 57 58 59
	fullname := fmt.Sprintf("libvirt-go-test-%s", name)

	dom, err := conn.LookupDomainByName(fullname)
	if err == nil {
		dom.Destroy()
		dom.Undefine()
		dom.Free()
	}

60 61
	xml := fmt.Sprintf(`<domain type="qemu">
		<name>libvirt-go-test-%s</name>
62
		<memory unit="KiB">128</memory>
63 64 65 66
                <features>
                  <acpi/>
                  <apic/>
                </features>
67 68 69
		<os>
			<type>hvm</type>
		</os>
70
	</domain>`, name)
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
	if transient {
		if dom, err = conn.DomainCreateXML(xml, 0); err != nil {
			panic(err)
		}
	} else {
		if dom, err = conn.DomainDefineXML(xml); err != nil {
			panic(err)
		}
	}
	return dom, conn
}

func getDefaultStoragePool(conn *Connect) *StoragePool {
	pool, err := conn.LookupStoragePoolByName("default")
	if err == nil {
		return pool
	}

	pool, err = conn.StoragePoolDefineXML(`<pool type='dir'>
                                                 <name>default</name>
                                                 <target>
                                                   <path>/var/lib/libvirt/images</path>
                                                 </target>
                                               </pool>`, 0)
	if err := pool.Create(0); err != nil {
		pool.Undefine()
		panic(err)
	}

	return pool
}

func getOrCreateStorageVol(pool *StoragePool, name string, size int64) *StorageVol {
	vol, err := pool.LookupStorageVolByName(name)
	if err == nil {
		return vol
	}

	vol, err = pool.StorageVolCreateXML(fmt.Sprintf(
		`<volume type="file">
                   <name>%s</name>
                   <allocation unit="b">%d</allocation>
                   <capacity unit="b">%d</capacity>
                   </volume>`, name, size, size), 0)
115 116 117
	if err != nil {
		panic(err)
	}
118 119

	return vol
120 121 122 123 124 125 126 127
}

func TestMultipleCloseCallback(t *testing.T) {
	nbCall1 := 0
	nbCall2 := 0
	nbCall3 := 0
	conn := buildTestQEMUConnection()
	defer func() {
128
		res, _ := conn.Close()
129 130 131 132
		// Blacklist versions of libvirt which had a ref counting
		// bug wrt close callbacks
		if VERSION_NUMBER <= 1002019 || VERSION_NUMBER >= 1003003 {
			if res != 0 {
133
				t.Errorf("Close() == %d, expected 0", res)
134
			}
135 136 137 138 139 140 141 142
		}
		if nbCall1 != 0 || nbCall2 != 0 || nbCall3 != 1 {
			t.Errorf("Wrong number of calls to callback, got %v, expected %v",
				[]int{nbCall1, nbCall2, nbCall3},
				[]int{0, 0, 1})
		}
	}()

143
	callback := func(conn *Connect, reason ConnectCloseReason) {
144
		if reason != CONNECT_CLOSE_REASON_KEEPALIVE {
145
			t.Errorf("Expected close reason to be %d, got %d",
146
				CONNECT_CLOSE_REASON_KEEPALIVE, reason)
147 148
		}
	}
149
	err := conn.RegisterCloseCallback(func(conn *Connect, reason ConnectCloseReason) {
150
		callback(conn, reason)
151 152 153 154 155
		nbCall1++
	})
	if err != nil {
		t.Fatalf("Unable to register close callback: %+v", err)
	}
156
	err = conn.RegisterCloseCallback(func(conn *Connect, reason ConnectCloseReason) {
157
		callback(conn, reason)
158 159 160 161 162
		nbCall2++
	})
	if err != nil {
		t.Fatalf("Unable to register close callback: %+v", err)
	}
163
	err = conn.RegisterCloseCallback(func(conn *Connect, reason ConnectCloseReason) {
164
		callback(conn, reason)
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
		nbCall3++
	})
	if err != nil {
		t.Fatalf("Unable to register close callback: %+v", err)
	}

	// To trigger a disconnect, we use a keepalive
	if err := conn.SetKeepAlive(1, 1); err != nil {
		t.Fatalf("Unable to enable keeplive: %+v", err)
	}
	EventRunDefaultImpl()
	time.Sleep(2 * time.Second)
	EventRunDefaultImpl()
}

func TestUnregisterCloseCallback(t *testing.T) {
	nbCall := 0
	conn := buildTestQEMUConnection()
	defer func() {
184 185
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
186 187 188 189 190 191
		}
		if nbCall != 0 {
			t.Errorf("Expected no call to close callback, got %d", nbCall)
		}
	}()

192
	callback := func(conn *Connect, reason ConnectCloseReason) {
193 194
		nbCall++
	}
195
	err := conn.RegisterCloseCallback(callback)
196 197 198 199 200 201 202 203 204 205 206 207
	if err != nil {
		t.Fatalf("Unable to register close callback: %+v", err)
	}
	err = conn.UnregisterCloseCallback()
	if err != nil {
		t.Fatalf("Unable to unregister close callback: %+v", err)
	}
}

func TestSetKeepalive(t *testing.T) {
	conn := buildTestQEMUConnection() // The test driver doesn't support keepalives
	defer func() {
208 209
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
		}
	}()
	if err := conn.SetKeepAlive(1, 1); err != nil {
		t.Error(err)
		return
	}

	// It should block until we have a keepalive message
	done := make(chan struct{})
	timeout := time.After(5 * time.Second)
	go func() {
		EventRunDefaultImpl()
		close(done)
	}()
	select {
	case <-done: // OK!
	case <-timeout:
		t.Fatalf("timeout reached while waiting for keepalive")
	}
}

func TestConnectionWithAuth(t *testing.T) {
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
	callback := func(creds []*ConnectCredential) {
		for _, cred := range creds {
			if cred.Type == CRED_AUTHNAME {
				cred.Result = "user"
				cred.ResultLen = len(cred.Result)
			} else if cred.Type == CRED_PASSPHRASE {
				cred.Result = "pass"
				cred.ResultLen = len(cred.Result)
			}
		}
	}
	auth := &ConnectAuth{
		CredType: []ConnectCredentialType{
			CRED_AUTHNAME, CRED_PASSPHRASE,
		},
		Callback: callback,
	}
	conn, err := NewConnectWithAuth("test+tcp://127.0.0.1/default", auth, 0)
250 251 252 253
	if err != nil {
		t.Error(err)
		return
	}
254
	res, err := conn.Close()
255 256 257 258 259
	if err != nil {
		t.Error(err)
		return
	}
	if res != 0 {
260
		t.Errorf("Close() == %d, expected 0", res)
261 262 263 264
	}
}

func TestConnectionWithWrongCredentials(t *testing.T) {
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
	callback := func(creds []*ConnectCredential) {
		for _, cred := range creds {
			if cred.Type == CRED_AUTHNAME {
				cred.Result = "user"
				cred.ResultLen = len(cred.Result)
			} else if cred.Type == CRED_PASSPHRASE {
				cred.Result = "wrongpass"
				cred.ResultLen = len(cred.Result)
			}
		}
	}
	auth := &ConnectAuth{
		CredType: []ConnectCredentialType{
			CRED_AUTHNAME, CRED_PASSPHRASE,
		},
		Callback: callback,
	}
	conn, err := NewConnectWithAuth("test+tcp://127.0.0.1/default", auth, 0)
283
	if err == nil {
284
		conn.Close()
285 286 287 288 289 290
		t.Error(err)
		return
	}
}

func TestQemuMonitorCommand(t *testing.T) {
291
	dom, conn := buildTestQEMUDomain(false, "monitor")
292 293 294 295
	defer func() {
		dom.Destroy()
		dom.Undefine()
		dom.Free()
296 297
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
298 299 300 301 302 303 304 305
		}
	}()

	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}

306
	if _, err := dom.QemuMonitorCommand("{\"execute\" : \"query-cpus\"}", DOMAIN_QEMU_MONITOR_COMMAND_DEFAULT); err != nil {
307 308 309 310
		t.Error(err)
		return
	}

311
	if _, err := dom.QemuMonitorCommand("info cpus", DOMAIN_QEMU_MONITOR_COMMAND_HMP); err != nil {
312 313 314 315 316 317
		t.Error(err)
		return
	}
}

func TestDomainCreateWithFlags(t *testing.T) {
318
	dom, conn := buildTestQEMUDomain(false, "create")
319 320 321 322
	defer func() {
		dom.Destroy()
		dom.Undefine()
		dom.Free()
323 324
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
325 326 327
		}
	}()

328
	if err := dom.CreateWithFlags(DOMAIN_START_PAUSED); err != nil {
329
		state, reason, err := dom.GetState()
330 331 332 333 334
		if err != nil {
			t.Error(err)
			return
		}

335
		if state != DOMAIN_PAUSED {
336
			t.Fatalf("Domain should be paused")
337 338 339 340 341
			return
		}
		if DomainPausedReason(reason) != DOMAIN_PAUSED_STARTING_UP {
			t.Fatal("Domain reason should be starting up")
			return
342 343 344 345
		}
	}
}

346 347 348 349 350 351 352
func defineTestLxcDomain(conn *Connect, name string) (*Domain, error) {
	fullname := "libvirt-go-test-" + name
	dom, err := conn.LookupDomainByName(fullname)
	if err == nil {
		dom.Destroy()
		dom.Undefine()
		dom.Free()
alexzorin's avatar
alexzorin committed
353
	}
354

alexzorin's avatar
alexzorin committed
355
	xml := `<domain type='lxc'>
356 357
	  <name>` + fullname + `</name>
	  <title>` + name + `</title>
alexzorin's avatar
alexzorin committed
358 359 360 361 362 363 364 365 366
	  <memory>102400</memory>
	  <os>
	    <type>exe</type>
	    <init>/bin/sh</init>
	  </os>
	  <devices>
	    <console type='pty'/>
	  </devices>
	</domain>`
367
	dom, err = conn.DomainDefineXML(xml)
368 369 370 371 372 373 374 375 376 377
	return dom, err
}

// Integration tests are run against LXC using Libvirt 1.2.x
// on Debian Wheezy (libvirt from wheezy-backports)
//
// To run,
// 		go test -tags integration

func TestIntegrationGetMetadata(t *testing.T) {
378
	conn, err := NewConnect("lxc:///")
379 380 381 382
	if err != nil {
		t.Error(err)
		return
	}
383
	defer func() {
384 385
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
386 387
		}
	}()
388
	dom, err := defineTestLxcDomain(conn, "meta")
alexzorin's avatar
alexzorin committed
389 390 391 392
	if err != nil {
		t.Error(err)
		return
	}
393 394 395 396 397
	defer func() {
		dom.Undefine()
		dom.Destroy()
		dom.Free()
	}()
alexzorin's avatar
alexzorin committed
398 399 400 401
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}
402
	v, err := dom.GetMetadata(DOMAIN_METADATA_TITLE, "", 0)
alexzorin's avatar
alexzorin committed
403 404 405 406
	if err != nil {
		t.Error(err)
		return
	}
407 408
	if v != "meta" {
		t.Fatalf("title didnt match: expected meta, got %s", v)
409 410
		return
	}
alexzorin's avatar
alexzorin committed
411
}
412 413

func TestIntegrationSetMetadata(t *testing.T) {
414
	conn, err := NewConnect("lxc:///")
415 416 417 418
	if err != nil {
		t.Error(err)
		return
	}
419
	defer func() {
420 421
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
422 423
		}
	}()
424
	dom, err := defineTestLxcDomain(conn, "meta")
425 426 427 428
	if err != nil {
		t.Error(err)
		return
	}
429 430 431 432
	defer func() {
		dom.Undefine()
		dom.Free()
	}()
433
	const domTitle = "newtitle"
434
	if err := dom.SetMetadata(DOMAIN_METADATA_TITLE, domTitle, "", "", 0); err != nil {
435 436 437
		t.Error(err)
		return
	}
438
	v, err := dom.GetMetadata(DOMAIN_METADATA_TITLE, "", 0)
439 440 441 442 443
	if err != nil {
		t.Error(err)
		return
	}
	if v != domTitle {
444
		t.Fatalf("DOMAIN_METADATA_TITLE should have been %s, not %s", domTitle, v)
445 446 447
		return
	}
}
448 449

func TestIntegrationGetSysinfo(t *testing.T) {
450
	conn, err := NewConnect("lxc:///")
451 452 453 454
	if err != nil {
		t.Error(err)
		return
	}
455
	defer func() {
456 457
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
458 459
		}
	}()
460 461 462 463 464 465 466 467 468 469
	info, err := conn.GetSysinfo(0)
	if err != nil {
		t.Error(err)
		return
	}
	if strings.Index(info, "<sysinfo") != 0 {
		t.Fatalf("Sysinfo not valid: %s", info)
		return
	}
}
470 471 472 473 474 475 476 477 478 479 480 481 482 483

func testNWFilterXML(name, chain string) string {
	defName := name
	if defName == "" {
		defName = time.Now().String()
	}
	return `<filter name='` + defName + `' chain='` + chain + `'>
            <rule action='drop' direction='out' priority='500'>
            <ip match='no' srcipaddr='$IP'/>
            </rule>
			</filter>`
}

func TestIntergrationDefineUndefineNWFilterXML(t *testing.T) {
484
	conn, err := NewConnect("lxc:///")
485 486 487 488
	if err != nil {
		t.Error(err)
		return
	}
489
	defer func() {
490 491
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
492 493
		}
	}()
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
	filter, err := conn.NWFilterDefineXML(testNWFilterXML("", "ipv4"))
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		if err := filter.Undefine(); err != nil {
			t.Fatal(err)
		}
		filter.Free()
	}()
	_, err = conn.NWFilterDefineXML(testNWFilterXML("", "bad"))
	if err == nil {
		t.Fatal("Should have had an error")
	}
}

func TestIntegrationNWFilterGetName(t *testing.T) {
511
	conn, err := NewConnect("lxc:///")
512 513 514 515
	if err != nil {
		t.Error(err)
		return
	}
516
	defer func() {
517 518
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
519 520
		}
	}()
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535
	filter, err := conn.NWFilterDefineXML(testNWFilterXML("", "ipv4"))
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
		filter.Undefine()
		filter.Free()
	}()
	if _, err := filter.GetName(); err != nil {
		t.Error(err)
	}
}

func TestIntegrationNWFilterGetUUID(t *testing.T) {
536
	conn, err := NewConnect("lxc:///")
537 538 539 540
	if err != nil {
		t.Error(err)
		return
	}
541
	defer func() {
542 543
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
544 545
		}
	}()
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560
	filter, err := conn.NWFilterDefineXML(testNWFilterXML("", "ipv4"))
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
		filter.Undefine()
		filter.Free()
	}()
	if _, err := filter.GetUUID(); err != nil {
		t.Error(err)
	}
}

func TestIntegrationNWFilterGetUUIDString(t *testing.T) {
561
	conn, err := NewConnect("lxc:///")
562 563 564 565
	if err != nil {
		t.Error(err)
		return
	}
566
	defer func() {
567 568
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
569 570
		}
	}()
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
	filter, err := conn.NWFilterDefineXML(testNWFilterXML("", "ipv4"))
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
		filter.Undefine()
		filter.Free()
	}()
	if _, err := filter.GetUUIDString(); err != nil {
		t.Error(err)
	}
}

func TestIntegrationNWFilterGetXMLDesc(t *testing.T) {
586
	conn, err := NewConnect("lxc:///")
587 588 589 590
	if err != nil {
		t.Error(err)
		return
	}
591
	defer func() {
592 593
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
594 595
		}
	}()
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610
	filter, err := conn.NWFilterDefineXML(testNWFilterXML("", "ipv4"))
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
		filter.Undefine()
		filter.Free()
	}()
	if _, err := filter.GetXMLDesc(0); err != nil {
		t.Error(err)
	}
}

func TestIntegrationLookupNWFilterByName(t *testing.T) {
611
	conn, err := NewConnect("lxc:///")
612 613 614 615
	if err != nil {
		t.Error(err)
		return
	}
616
	defer func() {
617 618
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
619 620
		}
	}()
621 622 623 624 625 626 627 628 629 630
	origName := time.Now().String()
	filter, err := conn.NWFilterDefineXML(testNWFilterXML(origName, "ipv4"))
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
		filter.Undefine()
		filter.Free()
	}()
631
	filter2, err := conn.LookupNWFilterByName(origName)
632 633 634 635
	if err != nil {
		t.Error(err)
		return
	}
636
	defer filter2.Free()
637
	var newName string
638
	newName, err = filter2.GetName()
639 640 641 642 643 644 645 646 647 648
	if err != nil {
		t.Error(err)
		return
	}
	if newName != origName {
		t.Fatalf("expected filter name: %s ,got: %s", origName, newName)
	}
}

func TestIntegrationLookupNWFilterByUUIDString(t *testing.T) {
649
	conn, err := NewConnect("lxc:///")
650 651 652 653
	if err != nil {
		t.Error(err)
		return
	}
654
	defer func() {
655 656
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
657 658
		}
	}()
659 660 661 662 663 664 665 666 667 668
	origName := time.Now().String()
	filter, err := conn.NWFilterDefineXML(testNWFilterXML(origName, "ipv4"))
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
		filter.Undefine()
		filter.Free()
	}()
669
	filter2, err := conn.LookupNWFilterByName(origName)
670 671 672 673
	if err != nil {
		t.Error(err)
		return
	}
674
	defer filter2.Free()
675
	var filterUUID string
676
	filterUUID, err = filter2.GetUUIDString()
677 678 679 680
	if err != nil {
		t.Error(err)
		return
	}
681 682
	filter3, err := conn.LookupNWFilterByUUIDString(filterUUID)
	defer filter3.Free()
683 684 685 686
	if err != nil {
		t.Error(err)
		return
	}
687
	name, err := filter3.GetName()
688 689 690 691 692 693 694 695
	if err != nil {
		t.Error(err)
		return
	}
	if name != origName {
		t.Fatalf("fetching by UUID: expected filter name: %s ,got: %s", name, origName)
	}
}
696 697

func TestIntegrationDomainAttachDetachDevice(t *testing.T) {
698
	conn, err := NewConnect("lxc:///")
699 700 701 702
	if err != nil {
		t.Error(err)
		return
	}
703
	defer func() {
704 705
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
706 707
		}
	}()
708

709
	dom, err := defineTestLxcDomain(conn, "attach")
710 711 712 713 714 715 716 717 718 719 720 721 722
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
		dom.Undefine()
		dom.Free()
	}()
	const nwXml = `<interface type='network'>
		<mac address='52:54:00:37:aa:c7'/>
		<source network='default'/>
		<model type='virtio'/>
		</interface>`
723
	if err := dom.AttachDeviceFlags(nwXml, DOMAIN_DEVICE_MODIFY_CONFIG); err != nil {
724 725 726
		t.Error(err)
		return
	}
727
	if err := dom.DetachDeviceFlags(nwXml, DOMAIN_DEVICE_MODIFY_CONFIG); err != nil {
728 729 730 731
		t.Error(err)
		return
	}
}
dorzheh's avatar
dorzheh committed
732 733

func TestStorageVolResize(t *testing.T) {
734
	conn, err := NewConnect("lxc:///")
dorzheh's avatar
dorzheh committed
735 736 737 738
	if err != nil {
		t.Error(err)
		return
	}
739
	defer func() {
740 741
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
742 743
		}
	}()
dorzheh's avatar
dorzheh committed
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

	poolPath, err := ioutil.TempDir("", "default-pool-test-1")
	if err != nil {
		t.Error(err)
		return
	}
	defer os.RemoveAll(poolPath)
	pool, err := conn.StoragePoolDefineXML(`<pool type='dir'>
                                          <name>default-pool-test-1</name>
                                          <target>
                                          <path>`+poolPath+`</path>
                                          </target>
                                          </pool>`, 0)
	defer func() {
		pool.Undefine()
		pool.Free()
	}()
	if err := pool.Create(0); err != nil {
		t.Error(err)
		return
	}
	defer pool.Destroy()
	vol, err := pool.StorageVolCreateXML(testStorageVolXML("", poolPath), 0)
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
772
		vol.Delete(STORAGE_VOL_DELETE_NORMAL)
dorzheh's avatar
dorzheh committed
773 774 775
		vol.Free()
	}()
	const newCapacityInBytes = 12582912
776
	if err := vol.Resize(newCapacityInBytes, STORAGE_VOL_RESIZE_ALLOCATE); err != nil {
dorzheh's avatar
dorzheh committed
777 778 779 780 781
		t.Fatal(err)
	}
}

func TestStorageVolWipe(t *testing.T) {
782
	conn, err := NewConnect("lxc:///")
dorzheh's avatar
dorzheh committed
783 784 785 786
	if err != nil {
		t.Error(err)
		return
	}
787
	defer func() {
788 789
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
790 791
		}
	}()
dorzheh's avatar
dorzheh committed
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 819

	poolPath, err := ioutil.TempDir("", "default-pool-test-1")
	if err != nil {
		t.Error(err)
		return
	}
	defer os.RemoveAll(poolPath)
	pool, err := conn.StoragePoolDefineXML(`<pool type='dir'>
                                          <name>default-pool-test-1</name>
                                          <target>
                                          <path>`+poolPath+`</path>
                                          </target>
                                          </pool>`, 0)
	defer func() {
		pool.Undefine()
		pool.Free()
	}()
	if err := pool.Create(0); err != nil {
		t.Error(err)
		return
	}
	defer pool.Destroy()
	vol, err := pool.StorageVolCreateXML(testStorageVolXML("", poolPath), 0)
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
820
		vol.Delete(STORAGE_VOL_DELETE_NORMAL)
dorzheh's avatar
dorzheh committed
821 822 823 824 825 826 827 828
		vol.Free()
	}()
	if err := vol.Wipe(0); err != nil {
		t.Fatal(err)
	}
}

func TestStorageVolWipePattern(t *testing.T) {
829
	conn, err := NewConnect("lxc:///")
dorzheh's avatar
dorzheh committed
830 831 832 833
	if err != nil {
		t.Error(err)
		return
	}
834
	defer func() {
835 836
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
837 838
		}
	}()
dorzheh's avatar
dorzheh committed
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866

	poolPath, err := ioutil.TempDir("", "default-pool-test-1")
	if err != nil {
		t.Error(err)
		return
	}
	defer os.RemoveAll(poolPath)
	pool, err := conn.StoragePoolDefineXML(`<pool type='dir'>
                                          <name>default-pool-test-1</name>
                                          <target>
                                          <path>`+poolPath+`</path>
                                          </target>
                                          </pool>`, 0)
	defer func() {
		pool.Undefine()
		pool.Free()
	}()
	if err := pool.Create(0); err != nil {
		t.Error(err)
		return
	}
	defer pool.Destroy()
	vol, err := pool.StorageVolCreateXML(testStorageVolXML("", poolPath), 0)
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
867
		vol.Delete(STORAGE_VOL_DELETE_NORMAL)
dorzheh's avatar
dorzheh committed
868 869
		vol.Free()
	}()
870
	if err := vol.WipePattern(STORAGE_VOL_WIPE_ALG_ZERO, 0); err != nil {
dorzheh's avatar
dorzheh committed
871 872 873
		t.Fatal(err)
	}
}
874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889

func testSecretTypeCephFromXML(name string) string {
	var setName string
	if name == "" {
		setName = time.Now().String()
	} else {
		setName = name
	}
	return `<secret ephemeral='no' private='no'>
            <usage type='ceph'>
            <name>` + setName + `</name>
            </usage>
            </secret>`
}

func TestIntegrationSecretDefineUndefine(t *testing.T) {
890
	conn, err := NewConnect("lxc:///")
891 892 893 894
	if err != nil {
		t.Error(err)
		return
	}
895
	defer func() {
896 897
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
898 899
		}
	}()
900 901 902 903 904 905 906 907 908 909 910 911
	sec, err := conn.SecretDefineXML(testSecretTypeCephFromXML(""), 0)
	if err != nil {
		t.Fatal(err)
	}
	defer sec.Free()

	if err := sec.Undefine(); err != nil {
		t.Fatal(err)
	}
}

func TestIntegrationSecretGetUUID(t *testing.T) {
912
	conn, err := NewConnect("lxc:///")
913 914 915 916
	if err != nil {
		t.Error(err)
		return
	}
917
	defer func() {
918 919
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
920 921
		}
	}()
922 923 924 925 926 927 928 929 930 931 932 933 934 935 936
	sec, err := conn.SecretDefineXML(testSecretTypeCephFromXML(""), 0)
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
		sec.Undefine()
		sec.Free()
	}()
	if _, err := sec.GetUUID(); err != nil {
		t.Error(err)
	}
}

func TestIntegrationSecretGetUUIDString(t *testing.T) {
937
	conn, err := NewConnect("lxc:///")
938 939 940 941
	if err != nil {
		t.Error(err)
		return
	}
942
	defer func() {
943 944
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
945 946
		}
	}()
947 948 949 950 951 952 953 954 955 956 957 958 959 960 961
	sec, err := conn.SecretDefineXML(testSecretTypeCephFromXML(""), 0)
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
		sec.Undefine()
		sec.Free()
	}()
	if _, err := sec.GetUUIDString(); err != nil {
		t.Error(err)
	}
}

func TestIntegrationSecretGetXMLDesc(t *testing.T) {
962
	conn, err := NewConnect("lxc:///")
963 964 965 966
	if err != nil {
		t.Error(err)
		return
	}
967
	defer func() {
968 969
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
970 971
		}
	}()
972 973 974 975 976 977 978 979 980 981 982 983 984 985 986
	sec, err := conn.SecretDefineXML(testSecretTypeCephFromXML(""), 0)
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
		sec.Undefine()
		sec.Free()
	}()
	if _, err := sec.GetXMLDesc(0); err != nil {
		t.Error(err)
	}
}

func TestIntegrationSecretGetUsageType(t *testing.T) {
987
	conn, err := NewConnect("lxc:///")
988 989 990 991
	if err != nil {
		t.Error(err)
		return
	}
992
	defer func() {
993 994
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
995 996
		}
	}()
997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
	sec, err := conn.SecretDefineXML(testSecretTypeCephFromXML(""), 0)
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
		sec.Undefine()
		sec.Free()
	}()
	uType, err := sec.GetUsageType()
	if err != nil {
		t.Error(err)
		return
	}
1011
	if uType != SECRET_USAGE_TYPE_CEPH {
1012 1013 1014 1015 1016
		t.Fatal("unexpected usage type.Expected usage type is Ceph")
	}
}

func TestIntegrationSecretGetUsageID(t *testing.T) {
1017
	conn, err := NewConnect("lxc:///")
1018 1019 1020 1021
	if err != nil {
		t.Error(err)
		return
	}
1022
	defer func() {
1023 1024
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
1025 1026
		}
	}()
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
	setUsageID := time.Now().String()
	sec, err := conn.SecretDefineXML(testSecretTypeCephFromXML(setUsageID), 0)
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
		sec.Undefine()
		sec.Free()
	}()
	recUsageID, err := sec.GetUsageID()
	if err != nil {
		t.Error(err)
		return
	}
	if recUsageID != setUsageID {
		t.Fatalf("exepected usage ID: %s, got: %s", setUsageID, recUsageID)
	}
}

func TestIntegrationLookupSecretByUsage(t *testing.T) {
1048
	conn, err := NewConnect("lxc:///")
1049 1050 1051 1052
	if err != nil {
		t.Error(err)
		return
	}
1053
	defer func() {
1054 1055
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
1056 1057
		}
	}()
1058 1059 1060 1061 1062 1063 1064 1065 1066 1067
	usageID := time.Now().String()
	sec, err := conn.SecretDefineXML(testSecretTypeCephFromXML(usageID), 0)
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
		sec.Undefine()
		sec.Free()
	}()
1068
	sec2, err := conn.LookupSecretByUsage(SECRET_USAGE_TYPE_CEPH, usageID)
1069 1070 1071
	if err != nil {
		t.Fatal(err)
	}
1072
	sec2.Free()
1073 1074
}

1075
func TestIntegrationGetDomainCPUStats(t *testing.T) {
1076
	conn, err := NewConnect("lxc:///")
1077 1078 1079
	if err != nil {
		t.Fatal(err)
	}
1080
	defer func() {
1081 1082
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
1083 1084
		}
	}()
1085
	dom, err := defineTestLxcDomain(conn, "cpustats")
1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		dom.Undefine()
		dom.Free()
	}()

	if err := dom.Create(); err != nil {
		t.Fatal(err)
	}
	defer dom.Destroy()

1099
	stats, err := dom.GetCPUStats(0, 0, 0)
1100
	if err != nil {
1101 1102 1103 1104
		lverr, ok := err.(Error)
		if ok && lverr.Code == ERR_NO_SUPPORT {
			return
		}
1105 1106 1107
		t.Fatal(err)
	}

1108 1109
	if len(stats) < 1 {
		t.Errorf("Expected stats for at least one CPU")
1110 1111
	}

1112 1113
	if !stats[0].CpuTimeSet {
		t.Errorf("Expected CpuTime to be set")
1114 1115 1116 1117 1118 1119 1120 1121 1122
	}
}

// Not supported on libvirt driver, so no integration test
// func TestGetInterfaceParameters(t *testing.T) {
// 	dom, conn := buildTestDomain()
// 	defer func() {
// 		dom.Undefine()
// 		dom.Free()
1123 1124
// 		if res, _ := conn.Close(); res != 0 {
// 			t.Errorf("Close() == %d, expected 0", res)
1125
// 		}
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139
// 	}()
// 	iface := "either mac or path to interface"
// 	nparams := int(0)
// 	if _, err := dom.GetInterfaceParameters(iface, nil, &nparams, 0); err != nil {
// 		t.Error(err)
// 		return
// 	}

// 	var params VirTypedParameters
// 	if _, err := dom.GetInterfaceParameters(iface, &params, &nparams, 0); err != nil {
// 		t.Error(err)
// 		return
// 	}
// }
1140

1141
func TestIntegrationListAllInterfaces(t *testing.T) {
1142
	conn, err := NewConnect("lxc:///")
1143 1144 1145 1146
	if err != nil {
		t.Error(err)
		return
	}
1147
	defer func() {
1148 1149
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
1150 1151
		}
	}()
1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165
	ifaces, err := conn.ListAllInterfaces(0)
	if err != nil {
		t.Fatal(err)
	}
	lookingFor := "lo"
	found := false
	for _, iface := range ifaces {
		name, err := iface.GetName()
		if err != nil {
			t.Fatal(err)
		}
		if name == lookingFor {
			found = true
		}
1166
		iface.Free()
1167 1168 1169 1170 1171
	}
	if found == false {
		t.Fatalf("interface %s not found", lookingFor)
	}
}
1172 1173

func TestIntergrationListAllNWFilters(t *testing.T) {
1174
	conn, err := NewConnect("lxc:///")
1175 1176 1177 1178
	if err != nil {
		t.Error(err)
		return
	}
1179
	defer func() {
1180 1181
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
1182 1183
		}
	}()
1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197

	testNWFilterName := time.Now().String()
	filter, err := conn.NWFilterDefineXML(testNWFilterXML(testNWFilterName, "ipv4"))
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
		filter.Undefine()
		filter.Free()
	}()

	filters, err := conn.ListAllNWFilters(0)
	if len(filters) == 0 {
1198
		t.Fatal("length of []NWFilter shouldn't be 0")
1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212
	}

	found := false
	for _, f := range filters {
		name, _ := f.GetName()
		if name == testNWFilterName {
			found = true
		}
		f.Free()
	}
	if found == false {
		t.Fatalf("NWFilter %s not found", testNWFilterName)
	}
}
1213

1214
func TestIntegrationDomainInterfaceStats(t *testing.T) {
1215
	conn, err := NewConnect("lxc:///")
1216 1217 1218
	if err != nil {
		t.Fatal(err)
	}
1219
	defer func() {
1220 1221
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
1222 1223
		}
	}()
1224

1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240
	net, err := conn.LookupNetworkByName("default")
	if err != nil {
		return
	}

	defer net.Free()

	active, err := net.IsActive()
	if err != nil {
		t.Fatal(err)
	}

	if !active {
		return
	}

1241
	dom, err := defineTestLxcDomain(conn, "ifacestats")
1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		dom.Undefine()
		dom.Free()
	}()
	const nwXml = `<interface type='network'>
		<mac address='52:54:00:37:aa:c7'/>
		<source network='default'/>
		<model type='virtio'/>
1253
                <target dev="lvgotest0"/>
1254
		</interface>`
1255
	if err := dom.AttachDeviceFlags(nwXml, DOMAIN_DEVICE_MODIFY_CONFIG); err != nil {
1256 1257 1258 1259 1260 1261 1262
		t.Fatal(err)
	}

	if err := dom.Create(); err != nil {
		t.Fatal(err)
	}

1263
	if _, err := dom.InterfaceStats("lvgotest0"); err != nil {
1264 1265 1266 1267 1268 1269 1270
		t.Error(err)
	}

	if err := dom.Destroy(); err != nil {
		t.Fatal(err)
	}

1271
	if err := dom.DetachDeviceFlags(nwXml, DOMAIN_DEVICE_MODIFY_CONFIG); err != nil {
1272 1273 1274
		t.Fatal(err)
	}
}
1275 1276

func TestStorageVolUploadDownload(t *testing.T) {
1277
	conn, err := NewConnect("lxc:///")
1278 1279 1280 1281
	if err != nil {
		t.Error(err)
		return
	}
1282
	defer func() {
1283 1284
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
1285 1286
		}
	}()
1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314

	poolPath, err := ioutil.TempDir("", "default-pool-test-1")
	if err != nil {
		t.Error(err)
		return
	}
	defer os.RemoveAll(poolPath)
	pool, err := conn.StoragePoolDefineXML(`<pool type='dir'>
                                          <name>default-pool-test-1</name>
                                          <target>
                                          <path>`+poolPath+`</path>
                                          </target>
                                          </pool>`, 0)
	defer func() {
		pool.Undefine()
		pool.Free()
	}()
	if err := pool.Create(0); err != nil {
		t.Error(err)
		return
	}
	defer pool.Destroy()
	vol, err := pool.StorageVolCreateXML(testStorageVolXML("", poolPath), 0)
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
1315
		vol.Delete(STORAGE_VOL_DELETE_NORMAL)
1316 1317 1318 1319 1320 1321 1322
		vol.Free()
	}()

	data := []byte{1, 2, 3, 4, 5, 6}

	// write above data to the vol
	// 1. create a stream
1323
	stream, err := conn.NewStream(0)
1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		stream.Free()
	}()

	// 2. set it up to upload from stream
	if err := vol.Upload(stream, 0, uint64(len(data)), 0); err != nil {
		stream.Abort()
		t.Fatal(err)
	}

	// 3. do the actual writing
1338
	if n, err := stream.Send(data); err != nil || n != len(data) {
1339 1340 1341 1342
		t.Fatal(err, n)
	}

	// 4. finish!
1343
	if err := stream.Finish(); err != nil {
1344 1345 1346 1347 1348
		t.Fatal(err)
	}

	// read back the data
	// 1. create a stream
1349
	downStream, err := conn.NewStream(0)
1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		downStream.Free()
	}()

	// 2. set it up to download from stream
	if err := vol.Download(downStream, 0, uint64(len(data)), 0); err != nil {
		downStream.Abort()
		t.Fatal(err)
	}

	// 3. do the actual reading
	buf := make([]byte, 1024)
1365
	if n, err := downStream.Recv(buf); err != nil || n != len(data) {
1366 1367 1368 1369 1370 1371
		t.Fatal(err, n)
	}

	t.Logf("read back: %#v", buf[:len(data)])

	// 4. finish!
1372
	if err := downStream.Finish(); err != nil {
1373 1374 1375
		t.Fatal(err)
	}
}
1376

1377 1378 1379 1380 1381 1382 1383
func TestStorageVolUploadDownloadCallbacks(t *testing.T) {
	conn, err := NewConnect("lxc:///")
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
1384 1385
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462
		}
	}()

	poolPath, err := ioutil.TempDir("", "default-pool-test-1")
	if err != nil {
		t.Error(err)
		return
	}
	defer os.RemoveAll(poolPath)
	pool, err := conn.StoragePoolDefineXML(`<pool type='dir'>
                                          <name>default-pool-test-1</name>
                                          <target>
                                          <path>`+poolPath+`</path>
                                          </target>
                                          </pool>`, 0)
	defer func() {
		pool.Undefine()
		pool.Free()
	}()
	if err := pool.Create(0); err != nil {
		t.Error(err)
		return
	}
	defer pool.Destroy()
	vol, err := pool.StorageVolCreateXML(testStorageVolXML("", poolPath), 0)
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
		vol.Delete(STORAGE_VOL_DELETE_NORMAL)
		vol.Free()
	}()

	input := make([]byte, 1024*1024)
	for i := 0; i < len(input); i++ {
		input[i] = (byte)(((i % 256) ^ (i / 256)) % 256)
	}

	// write above data to the vol
	// 1. create a stream
	stream, err := conn.NewStream(0)
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		stream.Free()
	}()

	// 2. set it up to upload from stream
	if err := vol.Upload(stream, 0, uint64(len(input)), 0); err != nil {
		stream.Abort()
		t.Fatal(err)
	}

	sent := 0
	source := func(stream *Stream, nbytes int) ([]byte, error) {
		tosend := nbytes
		if tosend > (len(input) - sent) {
			tosend = len(input) - sent
		}

		if tosend == 0 {
			return []byte{}, nil
		}

		data := input[sent : sent+tosend]
		sent += tosend
		return data, nil
	}

	// 3. do the actual writing
	if err := stream.SendAll(source); err != nil {
		t.Fatal(err)
	}

	if sent != len(input) {
1463
		t.Fatalf("Wanted %d but only sent %d bytes",
1464
			len(input), sent)
1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526
	}

	// 4. finish!
	if err := stream.Finish(); err != nil {
		t.Fatal(err)
	}

	// read back the data
	// 1. create a stream
	downStream, err := conn.NewStream(0)
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		downStream.Free()
	}()

	// 2. set it up to download from stream
	if err := vol.Download(downStream, 0, uint64(len(input)), 0); err != nil {
		downStream.Abort()
		t.Fatal(err)
	}

	// 3. do the actual reading
	output := make([]byte, len(input))

	got := 0
	sink := func(st *Stream, data []byte) (int, error) {
		toget := len(data)
		if (got + toget) > len(output) {
			toget = len(output) - got
		}
		if toget == 0 {
			return 0, fmt.Errorf("Output buffer is full")
		}

		target := output[got : got+toget]
		copied := copy(target, data)
		got += copied

		return copied, nil
	}

	if err := downStream.RecvAll(sink); err != nil {
		t.Fatal(err)
	}

	if got != len(input) {
		t.Fatalf("Wanted %d but only received %d bytes",
			len(input), got)
	}

	// 4. finish!
	if err := downStream.Finish(); err != nil {
		t.Fatal(err)
	}

	if !bytes.Equal(input, output) {
		t.Fatal("Input and output arrays are different")
	}
}

1527
/*func TestDomainMemoryStats(t *testing.T) {
1528
	conn, err := NewConnect("lxc:///")
1529 1530 1531 1532
	if err != nil {
		t.Error(err)
		return
	}
1533
	defer func() {
1534 1535
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
1536 1537
		}
	}()
1538

1539
	dom, err := defineTestLxcDomain(conn, "memstats")
1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560
	if err != nil {
		t.Error(err)
		return
	}
	defer func() {
		dom.Undefine()
		dom.Free()
	}()
	if err := dom.Create(); err != nil {
		t.Fatal(err)
	}
	defer dom.Destroy()

	ms, err := dom.MemoryStats(1, 0)
	if err != nil {
		t.Fatal(err)
	}
	if len(ms) != 1 {
		t.Fatal("Should have got one result, got", len(ms))
	}
}*/
1561 1562

func TestDomainListAllInterfaceAddresses(t *testing.T) {
1563
	dom, conn := buildTestQEMUDomain(false, "ifaces")
1564
	defer func() {
1565 1566
		dom.Destroy()
		dom.Undefine()
1567
		dom.Free()
1568 1569
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
1570 1571 1572 1573 1574 1575
		}
	}()
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}
1576

1577 1578
	ifaces, err := dom.ListAllInterfaceAddresses(0)
	if err != nil {
1579 1580 1581 1582
		lverr, ok := err.(Error)
		if ok && lverr.Code == ERR_NO_SUPPORT {
			return
		}
1583 1584 1585 1586 1587 1588 1589
		t.Fatal(err)
	}

	if len(ifaces) != 0 {
		t.Fatal("should have 0 interfaces", len(ifaces))
	}
}
1590 1591

func TestDomainGetAllStats(t *testing.T) {
1592
	dom, conn := buildTestQEMUDomain(false, "stats")
1593
	defer func() {
1594 1595
		dom.Destroy()
		dom.Undefine()
1596
		dom.Free()
1597 1598
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
1599 1600 1601 1602 1603 1604 1605
		}
	}()
	if err := dom.Create(); err != nil {
		t.Error(err)
		return
	}

1606
	stats, err := conn.GetAllDomainStats([]*Domain{}, DOMAIN_STATS_STATE|DOMAIN_STATS_CPU_TOTAL|DOMAIN_STATS_INTERFACE|DOMAIN_STATS_BALLOON|DOMAIN_STATS_BLOCK|DOMAIN_STATS_PERF|DOMAIN_STATS_VCPU, 0)
1607 1608

	if err != nil {
1609 1610 1611 1612
		lverr, ok := err.(Error)
		if ok && lverr.Code == ERR_NO_SUPPORT {
			return
		}
1613 1614 1615
		t.Error(err)
		return
	}
1616 1617 1618 1619

	for _, stat := range stats {
		stat.Domain.Free()
	}
1620
}
1621 1622

func TestDomainBlockCopy(t *testing.T) {
1623 1624 1625
	if VERSION_NUMBER < 1002008 {
		return
	}
1626
	dom, conn := buildTestQEMUDomain(true, "blockcopy")
1627
	defer func() {
1628
		dom.Destroy()
1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690
		dom.Free()
		if res, _ := conn.Close(); res != 0 {
			t.Errorf("Close() == %d, expected 0", res)
		}
	}()

	pool := getDefaultStoragePool(conn)
	defer pool.Free()

	srcVol := getOrCreateStorageVol(pool, "libvirt-go-test-block-copy-src.img", 1024*1024*10)
	defer func() {
		srcVol.Delete(0)
		srcVol.Free()
	}()

	dstVol := getOrCreateStorageVol(pool, "libvirt-go-test-block-copy-dst.img", 1024*1024*10)
	defer func() {
		dstVol.Delete(0)
		dstVol.Free()
	}()

	srcPath, err := srcVol.GetPath()
	if err != nil {
		t.Error(err)
		return
	}
	dstPath, err := dstVol.GetPath()
	if err != nil {
		t.Error(err)
		return
	}

	params := DomainBlockCopyParameters{
		BandwidthSet:   true,
		Bandwidth:      2147483648,
		GranularitySet: true,
		Granularity:    512,
	}

	srcXML := fmt.Sprintf(`<disk type="file">
                                 <driver type="raw"/>
                                 <source file="%s"/>
                                 <target dev="vda"/>
                               </disk>`, srcPath)

	err = dom.AttachDeviceFlags(srcXML, DOMAIN_DEVICE_MODIFY_LIVE)
	if err != nil {
		t.Error(err)
		return
	}

	dstXML := fmt.Sprintf(`<disk type='file'>
                                  <driver type='raw'/>
                                  <source file='%s'/>
                               </disk>`, dstPath)

	err = dom.BlockCopy(srcPath, dstXML, &params, DOMAIN_BLOCK_COPY_REUSE_EXT)
	if err != nil {
		t.Error(err)
		return
	}
}
1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710

func TestNodeGetMemoryStats(t *testing.T) {

	c := buildTestQEMUConnection()
	defer c.Close()

	stats, err := c.GetMemoryStats(0, 0)

	if err != nil {
		t.Error(err)
		return
	}

	if stats.TotalSet && stats.Total == 0 {
		t.Error("Expected non-zero total memory")
	}
	if stats.FreeSet && stats.Free == 0 {
		t.Error("Expected non-zero free memory")
	}
}
1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730

func TestNodeGetCPUStats(t *testing.T) {

	c := buildTestQEMUConnection()
	defer c.Close()

	stats, err := c.GetCPUStats(0, 0)

	if err != nil {
		t.Error(err)
		return
	}

	if stats.KernelSet && stats.Kernel == 0 {
		t.Error("Expected non-zero kernel time")
	}
	if stats.UserSet && stats.User