Skip to content
Snippets Groups Projects
libvirt_test.go 2.91 KiB
Newer Older
  • Learn to ignore specific revisions
  • Lars Seipel's avatar
    Lars Seipel committed
    package libvirt
    
    import (
    	"bytes"
    
    	"path/filepath"
    
    Lars Seipel's avatar
    Lars Seipel committed
    	"testing"
    	"text/template"
    
    	"slrz.net/runtopo/topology"
    
    
    	libvirtxml "libvirt.org/libvirt-go-xml"
    
    Lars Seipel's avatar
    Lars Seipel committed
    )
    
    func TestValidDomainXML(t *testing.T) {
    
    	topoFiles, err := filepath.Glob("testdata/*.dot")
    
    Lars Seipel's avatar
    Lars Seipel committed
    	if err != nil {
    		t.Fatal(err)
    	}
    
    
    	for _, file := range topoFiles {
    		topo, err := topology.ParseFile(file, topology.WithAutoMgmtNetwork)
    		if err != nil {
    			t.Fatal(err)
    		}
    
    Lars Seipel's avatar
    Lars Seipel committed
    
    
    		r := NewRunner()
    		if err := r.buildInventory(topo); err != nil {
    			t.Fatal(err)
    		}
    
    Lars Seipel's avatar
    Lars Seipel committed
    
    
    		tmpl, err := template.New("").
    			Funcs(templateFuncs).
    			Parse(domainTemplateText)
    		if err != nil {
    			t.Fatal(err)
    
    Lars Seipel's avatar
    Lars Seipel committed
    		}
    
    
    		var buf bytes.Buffer
    		for _, d := range r.devices {
    			if err := tmpl.Execute(&buf, d.templateArgs()); err != nil {
    				t.Errorf("domain %s: %v", d.name, err)
    			}
    			domXML := buf.Bytes()
    			if err := validateDomainXML(domXML); err != nil {
    				t.Errorf("domain %s: %v", d.name, err)
    			}
    			buf.Reset()
    
    Lars Seipel's avatar
    Lars Seipel committed
    		}
    	}
    }
    
    
    func TestDnsmasqHostsFile(t *testing.T) {
    	topo, err := topology.ParseFile("testdata/leafspine.dot", topology.WithAutoMgmtNetwork)
    	if err != nil {
    		t.Fatal(err)
    	}
    
    	r := NewRunner()
    	if err := r.buildInventory(topo); err != nil {
    		t.Fatal(err)
    	}
    	ctx := context.Background()
    
    	content := generateDnsmasqHostsFile(gatherHosts(ctx, r, topo))
    
    	if err != nil {
    		t.Fatal(err)
    	}
    	lines := strings.Split(string(content), "\n")
    	if lines[len(lines)-1] == "" {
    		lines = lines[:len(lines)-1]
    	}
    
    	ndevices := 0
    	for _, d := range topo.Devices() {
    		if d.Attr("no_mgmt") != "" {
    			continue
    		}
    
    		if topology.HasFunction(&d, topology.OOBServer,
    			topology.OOBSwitch, topology.Fake) {
    
    			continue
    		}
    		ndevices++
    	}
    
    	if n := len(lines); n != ndevices {
    		t.Errorf("got %d entries, want %d", n, ndevices)
    	}
    
    	for i, l := range lines {
    		xs := strings.Split(l, ",")
    		if len(xs) != 3 {
    			t.Errorf("line %d invalid: %q\n", i+1, l)
    		}
    	}
    }
    
    
    func TestDomainPXEBoot(t *testing.T) {
    	topo, err := topology.ParseFile("testdata/pxehost.dot")
    	if err != nil {
    		t.Fatal(err)
    	}
    
    	r := NewRunner()
    	if err := r.buildInventory(topo); err != nil {
    		t.Fatal(err)
    	}
    
    	tmpl, err := template.New("").
    		Funcs(templateFuncs).
    		Parse(domainTemplateText)
    	if err != nil {
    		t.Fatal(err)
    	}
    
    	var buf bytes.Buffer
    	d := r.devices["host1"]
    	if err := tmpl.Execute(&buf, d.templateArgs()); err != nil {
    		t.Errorf("domain %s: %v", d.name, err)
    	}
    	dom := new(libvirtxml.Domain)
    	if err := dom.Unmarshal(buf.String()); err != nil {
    		t.Fatalf("domain %s: %v", d.name, err)
    	}
    	disks := dom.Devices.Disks
    	if len(disks) == 0 {
    		t.Fatalf("domain %s: no disks", d.name)
    	}
    	if d0 := disks[0]; d0.Boot == nil || d0.Boot.Order != 2 {
    		t.Fatalf("domain %s: unexpected boot order: %#v", d.name, d0.Boot)
    	}
    	pxeOK := false
    	for _, intf := range dom.Devices.Interfaces {
    		if intf.Boot != nil && intf.Boot.Order == 1 {
    			pxeOK = true
    		}
    	}
    	if !pxeOK {
    		t.Fatalf("domain %s: no interface configured for booting", d.name)
    	}
    }