- Improved existing tests.
Test implementation is separated per datasets and pools to avoid one big complex file. Tests are dependent so order of execution is forced by adding a_test.go running test with sub tests in required order.
This commit is contained in:
		
							parent
							
								
									65eb260be4
								
							
						
					
					
						commit
						c0b415fe50
					
				| 
						 | 
				
			
			@ -0,0 +1,23 @@
 | 
			
		|||
package zfs_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------- */
 | 
			
		||||
// TESTS ARE DEPENDED AND MUST RUN IN DEPENDENT ORDER
 | 
			
		||||
 | 
			
		||||
func Test(t *testing.T) {
 | 
			
		||||
	zpoolTestPoolCreate(t)
 | 
			
		||||
	zpoolTestPoolOpenAll(t)
 | 
			
		||||
	zpoolTestFailPoolOpen(t)
 | 
			
		||||
 | 
			
		||||
	zfsTestDatasetCreate(t)
 | 
			
		||||
	zfsTestDatasetOpen(t)
 | 
			
		||||
	zfsTestDatasetSnapshot(t)
 | 
			
		||||
	zfsTestDatasetOpenAll(t)
 | 
			
		||||
 | 
			
		||||
	zfsTestDatasetDestroy(t)
 | 
			
		||||
 | 
			
		||||
	zpoolTestPoolDestroy(t)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,171 @@
 | 
			
		|||
package zfs_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/bicomsystems/go-libzfs"
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------- */
 | 
			
		||||
// HELPERS:
 | 
			
		||||
var TST_DATASET_PATH = TST_POOL_NAME + "/DATASET"
 | 
			
		||||
var TST_VOLUME_PATH = TST_DATASET_PATH + "/VOLUME"
 | 
			
		||||
var TST_DATASET_PATH_SNAP = TST_DATASET_PATH + "@test"
 | 
			
		||||
 | 
			
		||||
func printDatasets(ds []zfs.Dataset) error {
 | 
			
		||||
	for _, d := range ds {
 | 
			
		||||
 | 
			
		||||
		path, err := d.Path()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		p, err := d.GetProperty(zfs.ZFSPropType)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Printf(" %30s | %10s\n", path,
 | 
			
		||||
			p.Value)
 | 
			
		||||
		if len(d.Children) > 0 {
 | 
			
		||||
			printDatasets(d.Children)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------- */
 | 
			
		||||
// TESTS:
 | 
			
		||||
 | 
			
		||||
func zfsTestDatasetCreate(t *testing.T) {
 | 
			
		||||
	// reinit names used in case TESTPOOL was in conflict
 | 
			
		||||
	TST_DATASET_PATH = TST_POOL_NAME + "/DATASET"
 | 
			
		||||
	TST_VOLUME_PATH = TST_DATASET_PATH + "/VOLUME"
 | 
			
		||||
	TST_DATASET_PATH_SNAP = TST_DATASET_PATH + "@test"
 | 
			
		||||
 | 
			
		||||
	println("TEST DatasetCreate(", TST_DATASET_PATH, ") (filesystem) ... ")
 | 
			
		||||
	props := make(map[zfs.ZFSProp]zfs.Property)
 | 
			
		||||
	d, err := zfs.DatasetCreate(TST_DATASET_PATH, zfs.DatasetTypeFilesystem, props)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	d.Close()
 | 
			
		||||
	println("PASS\n")
 | 
			
		||||
 | 
			
		||||
	strSize := "536870912" // 512M
 | 
			
		||||
 | 
			
		||||
	println("TEST DatasetCreate(", TST_VOLUME_PATH, ") (volume) ... ")
 | 
			
		||||
	props[zfs.ZFSPropVolsize] = zfs.Property{Value: strSize}
 | 
			
		||||
	// In addition I explicitly choose some more properties to be set.
 | 
			
		||||
	props[zfs.ZFSPropVolblocksize] = zfs.Property{Value: "4096"}
 | 
			
		||||
	props[zfs.ZFSPropReservation] = zfs.Property{Value: strSize}
 | 
			
		||||
	d, err = zfs.DatasetCreate(TST_VOLUME_PATH, zfs.DatasetTypeVolume, props)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	d.Close()
 | 
			
		||||
	println("PASS\n")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func zfsTestDatasetOpen(t *testing.T) {
 | 
			
		||||
	println("TEST DatasetOpen(", TST_DATASET_PATH, ") ... ")
 | 
			
		||||
	d, err := zfs.DatasetOpen(TST_DATASET_PATH)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	d.Close()
 | 
			
		||||
	println("PASS\n")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func zfsTestDatasetOpenAll(t *testing.T) {
 | 
			
		||||
	println("TEST DatasetOpenAll()/DatasetCloseAll() ... ")
 | 
			
		||||
	ds, err := zfs.DatasetOpenAll()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if err = printDatasets(ds); err != nil {
 | 
			
		||||
		zfs.DatasetCloseAll(ds)
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	zfs.DatasetCloseAll(ds)
 | 
			
		||||
	println("PASS\n")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func zfsTestDatasetSnapshot(t *testing.T) {
 | 
			
		||||
	println("TEST DatasetSnapshot(", TST_DATASET_PATH, ", true, ...) ... ")
 | 
			
		||||
	props := make(map[zfs.ZFSProp]zfs.Property)
 | 
			
		||||
	d, err := zfs.DatasetSnapshot(TST_DATASET_PATH_SNAP, true, props)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	defer d.Close()
 | 
			
		||||
	println("PASS\n")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func zfsTestDatasetDestroy(t *testing.T) {
 | 
			
		||||
	println("TEST DATASET Destroy( ", TST_DATASET_PATH, " ) ... ")
 | 
			
		||||
	d, err := zfs.DatasetOpen(TST_DATASET_PATH)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	defer d.Close()
 | 
			
		||||
	if err = d.DestroyRecursive(); err != nil {
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	println("PASS\n")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------- */
 | 
			
		||||
// EXAMPLES:
 | 
			
		||||
 | 
			
		||||
// Example of creating ZFS volume
 | 
			
		||||
func ExampleDatasetCreate() {
 | 
			
		||||
	// Create map to represent ZFS dataset properties. This is equivalent to
 | 
			
		||||
	// list of properties you can get from ZFS CLI tool, and some more
 | 
			
		||||
	// internally used by libzfs.
 | 
			
		||||
	props := make(map[zfs.ZFSProp]zfs.Property)
 | 
			
		||||
 | 
			
		||||
	// I choose to create (block) volume 1GiB in size. Size is just ZFS dataset
 | 
			
		||||
	// property and this is done as map of strings. So, You have to either
 | 
			
		||||
	// specify size as base 10 number in string, or use strconv package or
 | 
			
		||||
	// similar to convert in to string (base 10) from numeric type.
 | 
			
		||||
	strSize := "1073741824"
 | 
			
		||||
 | 
			
		||||
	props[zfs.ZFSPropVolsize] = zfs.Property{Value: strSize}
 | 
			
		||||
	// In addition I explicitly choose some more properties to be set.
 | 
			
		||||
	props[zfs.ZFSPropVolblocksize] = zfs.Property{Value: "4096"}
 | 
			
		||||
	props[zfs.ZFSPropReservation] = zfs.Property{Value: strSize}
 | 
			
		||||
 | 
			
		||||
	// Lets create desired volume
 | 
			
		||||
	d, err := zfs.DatasetCreate("TESTPOOL/VOLUME1", zfs.DatasetTypeVolume, props)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		println(err.Error())
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	// Dataset have to be closed for memory cleanup
 | 
			
		||||
	defer d.Close()
 | 
			
		||||
 | 
			
		||||
	println("Created zfs volume TESTPOOL/VOLUME1")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ExampleDatasetOpen() {
 | 
			
		||||
	// Open dataset and read its available space
 | 
			
		||||
	d, err := zfs.DatasetOpen("TESTPOOL/DATASET1")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err.Error())
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	defer d.Close()
 | 
			
		||||
	var p zfs.Property
 | 
			
		||||
	if p, err = d.GetProperty(zfs.ZFSPropAvailable); err != nil {
 | 
			
		||||
		panic(err.Error())
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	println(d.PropertyToName(zfs.ZFSPropAvailable), " = ", p.Value)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										261
									
								
								zpool_test.go
								
								
								
								
							
							
						
						
									
										261
									
								
								zpool_test.go
								
								
								
								
							| 
						 | 
				
			
			@ -1,17 +1,17 @@
 | 
			
		|||
package zfs
 | 
			
		||||
package zfs_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/bicomsystems/go-libzfs"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	TST_POOL_NAME    = "TESTPOOL"
 | 
			
		||||
	TST_DATASET_PATH = "TESTPOOL/DATASET"
 | 
			
		||||
)
 | 
			
		||||
/* ------------------------------------------------------------------------- */
 | 
			
		||||
// HELPERS:
 | 
			
		||||
 | 
			
		||||
var TST_POOL_NAME = "TESTPOOL"
 | 
			
		||||
 | 
			
		||||
func CreateTmpSparse(prefix string, size int64) (path string, err error) {
 | 
			
		||||
	sf, err := ioutil.TempFile("/tmp", prefix)
 | 
			
		||||
| 
						 | 
				
			
			@ -26,9 +26,24 @@ func CreateTmpSparse(prefix string, size int64) (path string, err error) {
 | 
			
		|||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create 3 sparse file 5G in /tmp directory each 5G size, and use them to create mirror TESTPOOL with one spare "disk"
 | 
			
		||||
func TestPoolCreate(t *testing.T) {
 | 
			
		||||
	print("TEST PoolCreate ... ")
 | 
			
		||||
/* ------------------------------------------------------------------------- */
 | 
			
		||||
// TESTS:
 | 
			
		||||
 | 
			
		||||
// Create 3 sparse file in /tmp directory each 5G size, and use them to create
 | 
			
		||||
// mirror TESTPOOL with one spare "disk"
 | 
			
		||||
func zpoolTestPoolCreate(t *testing.T) {
 | 
			
		||||
	println("TEST PoolCreate ... ")
 | 
			
		||||
	// first check if pool with same name already exist
 | 
			
		||||
	// we don't want conflict
 | 
			
		||||
	for {
 | 
			
		||||
		p, err := zfs.PoolOpen(TST_POOL_NAME)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		p.Close()
 | 
			
		||||
		TST_POOL_NAME += "0"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var s1path, s2path, s3path string
 | 
			
		||||
	var err error
 | 
			
		||||
	if s1path, err = CreateTmpSparse("zfs_test_", 0x140000000); err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -50,27 +65,27 @@ func TestPoolCreate(t *testing.T) {
 | 
			
		|||
	}
 | 
			
		||||
	disks := [2]string{s1path, s2path}
 | 
			
		||||
 | 
			
		||||
	var vdevs, mdevs, sdevs []VDevSpec
 | 
			
		||||
	var vdevs, mdevs, sdevs []zfs.VDevSpec
 | 
			
		||||
	for _, d := range disks {
 | 
			
		||||
		mdevs = append(mdevs,
 | 
			
		||||
			VDevSpec{Type: VDevTypeFile, Path: d})
 | 
			
		||||
			zfs.VDevSpec{Type: zfs.VDevTypeFile, Path: d})
 | 
			
		||||
	}
 | 
			
		||||
	sdevs = []VDevSpec{
 | 
			
		||||
		{Type: VDevTypeFile, Path: s3path}}
 | 
			
		||||
	vdevs = []VDevSpec{
 | 
			
		||||
		VDevSpec{Type: VDevTypeMirror, Devices: mdevs},
 | 
			
		||||
		VDevSpec{Type: VDevTypeSpare, Devices: sdevs},
 | 
			
		||||
	sdevs = []zfs.VDevSpec{
 | 
			
		||||
		{Type: zfs.VDevTypeFile, Path: s3path}}
 | 
			
		||||
	vdevs = []zfs.VDevSpec{
 | 
			
		||||
		zfs.VDevSpec{Type: zfs.VDevTypeMirror, Devices: mdevs},
 | 
			
		||||
		zfs.VDevSpec{Type: zfs.VDevTypeSpare, Devices: sdevs},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	props := make(map[PoolProp]string)
 | 
			
		||||
	fsprops := make(map[ZFSProp]string)
 | 
			
		||||
	props := make(map[zfs.PoolProp]string)
 | 
			
		||||
	fsprops := make(map[zfs.ZFSProp]string)
 | 
			
		||||
	features := make(map[string]string)
 | 
			
		||||
	fsprops[ZFSPropMountpoint] = "none"
 | 
			
		||||
	fsprops[zfs.ZFSPropMountpoint] = "none"
 | 
			
		||||
	features["async_destroy"] = "enabled"
 | 
			
		||||
	features["empty_bpobj"] = "enabled"
 | 
			
		||||
	features["lz4_compress"] = "enabled"
 | 
			
		||||
 | 
			
		||||
	pool, err := PoolCreate(TST_POOL_NAME, vdevs, features, props, fsprops)
 | 
			
		||||
	pool, err := zfs.PoolCreate(TST_POOL_NAME, vdevs, features, props, fsprops)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		// try cleanup
 | 
			
		||||
| 
						 | 
				
			
			@ -84,15 +99,15 @@ func TestPoolCreate(t *testing.T) {
 | 
			
		|||
	os.Remove(s1path)
 | 
			
		||||
	os.Remove(s2path)
 | 
			
		||||
	os.Remove(s3path)
 | 
			
		||||
	println("PASS")
 | 
			
		||||
	println("PASS\n")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Open and list all pools and them state on the system
 | 
			
		||||
// Then list properties of last pool in the list
 | 
			
		||||
func TestPoolOpenAll(t *testing.T) {
 | 
			
		||||
func zpoolTestPoolOpenAll(t *testing.T) {
 | 
			
		||||
	println("TEST PoolOpenAll() ... ")
 | 
			
		||||
	var pname string
 | 
			
		||||
	pools, err := PoolOpenAll()
 | 
			
		||||
	pools, err := zfs.PoolOpenAll()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			@ -114,123 +129,12 @@ func TestPoolOpenAll(t *testing.T) {
 | 
			
		|||
		println("\tPool: ", pname, " state: ", pstate)
 | 
			
		||||
		p.Close()
 | 
			
		||||
	}
 | 
			
		||||
	if len(pname) > 0 {
 | 
			
		||||
		// test open on last pool
 | 
			
		||||
		println("\tTry to open pool ", pname)
 | 
			
		||||
		p, err := PoolOpen(pname)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			t.Error(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		println("\tOpen pool: ", pname, " success")
 | 
			
		||||
		println("\t", pname, " PROPERTIES:")
 | 
			
		||||
 | 
			
		||||
		pc, _ := strconv.Atoi(p.Properties[PoolNumProps].Value)
 | 
			
		||||
		if len(p.Properties) != (pc + 1) {
 | 
			
		||||
			p.Close()
 | 
			
		||||
			t.Error(fmt.Sprint("Number of zpool properties does not match ",
 | 
			
		||||
				len(p.Properties), " != ", pc+1))
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		for key, value := range p.Properties {
 | 
			
		||||
			pkey := PoolProp(key)
 | 
			
		||||
			println("\t\t", p.PropertyToName(pkey), " = ", value.Value, " <- ", value.Source)
 | 
			
		||||
		}
 | 
			
		||||
		for key, value := range p.Features {
 | 
			
		||||
			fmt.Printf("\t feature@%s = %s <- local\n", key, value)
 | 
			
		||||
		}
 | 
			
		||||
		if p.Properties[PoolPropListsnaps].Value == "off" {
 | 
			
		||||
			println("\tlistsnapshots to on")
 | 
			
		||||
			if err = p.SetProperty(PoolPropListsnaps, "on"); err != nil {
 | 
			
		||||
				t.Error(err)
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			println("\tlistsnapshots to off")
 | 
			
		||||
			if err = p.SetProperty(PoolPropListsnaps, "off"); err != nil {
 | 
			
		||||
				t.Error(err)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			println("\tlistsnapshots", "is changed to ",
 | 
			
		||||
				p.Properties[PoolPropListsnaps].Value, " <- ",
 | 
			
		||||
				p.Properties[PoolPropListsnaps].Source)
 | 
			
		||||
		}
 | 
			
		||||
		p.Close()
 | 
			
		||||
	}
 | 
			
		||||
	println("PASS")
 | 
			
		||||
	println("PASS\n")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestDatasetCreate(t *testing.T) {
 | 
			
		||||
	print("TEST DatasetCreate(", TST_DATASET_PATH, ") ... ")
 | 
			
		||||
	props := make(map[ZFSProp]Property)
 | 
			
		||||
	d, err := DatasetCreate(TST_DATASET_PATH, DatasetTypeFilesystem, props)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	d.Close()
 | 
			
		||||
	println("PASS")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestDatasetOpen(t *testing.T) {
 | 
			
		||||
	print("TEST DatasetOpen(", TST_DATASET_PATH, ") ... ")
 | 
			
		||||
	d, err := DatasetOpen(TST_DATASET_PATH)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	d.Close()
 | 
			
		||||
	println("PASS")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func printDatasets(ds []Dataset) error {
 | 
			
		||||
	for _, d := range ds {
 | 
			
		||||
		path, err := d.Path()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		println("\t", path)
 | 
			
		||||
		if len(d.Children) > 0 {
 | 
			
		||||
			printDatasets(d.Children)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestDatasetOpenAll(t *testing.T) {
 | 
			
		||||
	println("TEST DatasetOpenAll()/DatasetCloseAll() ... ")
 | 
			
		||||
	ds, err := DatasetOpenAll()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if err = printDatasets(ds); err != nil {
 | 
			
		||||
		DatasetCloseAll(ds)
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	DatasetCloseAll(ds)
 | 
			
		||||
	println("PASS")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestDatasetDestroy(t *testing.T) {
 | 
			
		||||
	print("TEST DATASET Destroy()", TST_DATASET_PATH, " ... ")
 | 
			
		||||
	d, err := DatasetOpen(TST_DATASET_PATH)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	defer d.Close()
 | 
			
		||||
	if err = d.Destroy(false); err != nil {
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	println("PASS")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestPoolDestroy(t *testing.T) {
 | 
			
		||||
	print("TEST POOL Destroy()", TST_POOL_NAME, " ... ")
 | 
			
		||||
	p, err := PoolOpen(TST_POOL_NAME)
 | 
			
		||||
func zpoolTestPoolDestroy(t *testing.T) {
 | 
			
		||||
	println("TEST POOL Destroy( ", TST_POOL_NAME, " ) ... ")
 | 
			
		||||
	p, err := zfs.PoolOpen(TST_POOL_NAME)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error(err)
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			@ -240,15 +144,15 @@ func TestPoolDestroy(t *testing.T) {
 | 
			
		|||
		t.Error(err.Error())
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	println("PASS")
 | 
			
		||||
	println("PASS\n")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestFailPoolOpen(t *testing.T) {
 | 
			
		||||
	print("TEST failing to open pool ... ")
 | 
			
		||||
func zpoolTestFailPoolOpen(t *testing.T) {
 | 
			
		||||
	println("TEST open of non existing pool ... ")
 | 
			
		||||
	pname := "fail to open this pool"
 | 
			
		||||
	p, err := PoolOpen(pname)
 | 
			
		||||
	p, err := zfs.PoolOpen(pname)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		println("PASS")
 | 
			
		||||
		println("PASS\n")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	t.Error("PoolOpen pass when it should fail")
 | 
			
		||||
| 
						 | 
				
			
			@ -256,19 +160,22 @@ func TestFailPoolOpen(t *testing.T) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func ExamplePoolProp() {
 | 
			
		||||
	if pool, err := PoolOpen("SSD"); err == nil {
 | 
			
		||||
		print("Pool size is: ", pool.Properties[PoolPropSize].Value)
 | 
			
		||||
	if pool, err := zfs.PoolOpen("SSD"); err == nil {
 | 
			
		||||
		print("Pool size is: ", pool.Properties[zfs.PoolPropSize].Value)
 | 
			
		||||
		// Turn on snapshot listing for pool
 | 
			
		||||
		pool.SetProperty(PoolPropListsnaps, "on")
 | 
			
		||||
		pool.SetProperty(zfs.PoolPropListsnaps, "on")
 | 
			
		||||
	} else {
 | 
			
		||||
		print("Error: ", err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------- */
 | 
			
		||||
// EXAMPLES:
 | 
			
		||||
 | 
			
		||||
// Open and list all pools on system with them properties
 | 
			
		||||
func ExamplePoolOpenAll() {
 | 
			
		||||
	// Lets open handles to all active pools on system
 | 
			
		||||
	pools, err := PoolOpenAll()
 | 
			
		||||
	pools, err := zfs.PoolOpenAll()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		println(err)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -277,15 +184,15 @@ func ExamplePoolOpenAll() {
 | 
			
		|||
	for _, p := range pools {
 | 
			
		||||
		// Print fancy header
 | 
			
		||||
		fmt.Printf("\n -----------------------------------------------------------\n")
 | 
			
		||||
		fmt.Printf("   POOL: %49s   \n", p.Properties[PoolPropName].Value)
 | 
			
		||||
		fmt.Printf("   POOL: %49s   \n", p.Properties[zfs.PoolPropName].Value)
 | 
			
		||||
		fmt.Printf("|-----------------------------------------------------------|\n")
 | 
			
		||||
		fmt.Printf("|  PROPERTY      |  VALUE                |  SOURCE          |\n")
 | 
			
		||||
		fmt.Printf("|-----------------------------------------------------------|\n")
 | 
			
		||||
 | 
			
		||||
		// Iterate pool properties and print name, value and source
 | 
			
		||||
		for key, prop := range p.Properties {
 | 
			
		||||
			pkey := PoolProp(key)
 | 
			
		||||
			if pkey == PoolPropName {
 | 
			
		||||
			pkey := zfs.PoolProp(key)
 | 
			
		||||
			if pkey == zfs.PoolPropName {
 | 
			
		||||
				continue // Skip name its already printed above
 | 
			
		||||
			}
 | 
			
		||||
			fmt.Printf("|%14s  | %20s  | %15s  |\n", p.PropertyToName(pkey),
 | 
			
		||||
| 
						 | 
				
			
			@ -302,33 +209,33 @@ func ExamplePoolOpenAll() {
 | 
			
		|||
func ExamplePoolCreate() {
 | 
			
		||||
	disks := [2]string{"/dev/disk/by-id/ATA-123", "/dev/disk/by-id/ATA-456"}
 | 
			
		||||
 | 
			
		||||
	var vdevs, mdevs, sdevs []VDevSpec
 | 
			
		||||
	var vdevs, mdevs, sdevs []zfs.VDevSpec
 | 
			
		||||
 | 
			
		||||
	// build mirror devices specs
 | 
			
		||||
	for _, d := range disks {
 | 
			
		||||
		mdevs = append(mdevs,
 | 
			
		||||
			VDevSpec{Type: VDevTypeDisk, Path: d})
 | 
			
		||||
			zfs.VDevSpec{Type: zfs.VDevTypeDisk, Path: d})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// spare device specs
 | 
			
		||||
	sdevs = []VDevSpec{
 | 
			
		||||
		{Type: VDevTypeDisk, Path: "/dev/disk/by-id/ATA-789"}}
 | 
			
		||||
	sdevs = []zfs.VDevSpec{
 | 
			
		||||
		{Type: zfs.VDevTypeDisk, Path: "/dev/disk/by-id/ATA-789"}}
 | 
			
		||||
 | 
			
		||||
	// pool specs
 | 
			
		||||
	vdevs = []VDevSpec{
 | 
			
		||||
		VDevSpec{Type: VDevTypeMirror, Devices: mdevs},
 | 
			
		||||
		VDevSpec{Type: VDevTypeSpare, Devices: sdevs},
 | 
			
		||||
	vdevs = []zfs.VDevSpec{
 | 
			
		||||
		zfs.VDevSpec{Type: zfs.VDevTypeMirror, Devices: mdevs},
 | 
			
		||||
		zfs.VDevSpec{Type: zfs.VDevTypeSpare, Devices: sdevs},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// pool properties
 | 
			
		||||
	props := make(map[PoolProp]string)
 | 
			
		||||
	props := make(map[zfs.PoolProp]string)
 | 
			
		||||
	// root dataset filesystem properties
 | 
			
		||||
	fsprops := make(map[ZFSProp]string)
 | 
			
		||||
	fsprops := make(map[zfs.ZFSProp]string)
 | 
			
		||||
	// pool features
 | 
			
		||||
	features := make(map[string]string)
 | 
			
		||||
 | 
			
		||||
	// Turn off auto mounting by ZFS
 | 
			
		||||
	fsprops[ZFSPropMountpoint] = "none"
 | 
			
		||||
	fsprops[zfs.ZFSPropMountpoint] = "none"
 | 
			
		||||
 | 
			
		||||
	// Enable some features
 | 
			
		||||
	features["async_destroy"] = "enabled"
 | 
			
		||||
| 
						 | 
				
			
			@ -337,7 +244,7 @@ func ExamplePoolCreate() {
 | 
			
		|||
 | 
			
		||||
	// Based on specs formed above create test pool as 2 disk mirror and
 | 
			
		||||
	// one spare disk
 | 
			
		||||
	pool, err := PoolCreate("TESTPOOL", vdevs, features, props, fsprops)
 | 
			
		||||
	pool, err := zfs.PoolCreate("TESTPOOL", vdevs, features, props, fsprops)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		println("Error: ", err.Error())
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			@ -349,7 +256,7 @@ func ExamplePool_Destroy() {
 | 
			
		|||
	pname := "TESTPOOL"
 | 
			
		||||
 | 
			
		||||
	// Need handle to pool at first place
 | 
			
		||||
	p, err := PoolOpen(pname)
 | 
			
		||||
	p, err := zfs.PoolOpen(pname)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		println("Error: ", err.Error())
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			@ -363,33 +270,3 @@ func ExamplePool_Destroy() {
 | 
			
		|||
		return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Example of creating ZFS volume
 | 
			
		||||
func ExampleDatasetCreate() {
 | 
			
		||||
	// Create map to represent ZFS dataset properties. This is equivalent to
 | 
			
		||||
	// list of properties you can get from ZFS CLI tool, and some more
 | 
			
		||||
	// internally used by libzfs.
 | 
			
		||||
	props := make(map[ZFSProp]Property)
 | 
			
		||||
 | 
			
		||||
	// I choose to create (block) volume 1GiB in size. Size is just ZFS dataset
 | 
			
		||||
	// property and this is done as map of strings. So, You have to either
 | 
			
		||||
	// specify size as base 10 number in string, or use strconv package or
 | 
			
		||||
	// similar to convert in to string (base 10) from numeric type.
 | 
			
		||||
	strSize := "1073741824"
 | 
			
		||||
 | 
			
		||||
	props[ZFSPropVolsize] = Property{Value: strSize}
 | 
			
		||||
	// In addition I explicitly choose some more properties to be set.
 | 
			
		||||
	props[ZFSPropVolblocksize] = Property{Value: "4096"}
 | 
			
		||||
	props[ZFSPropReservation] = Property{Value: strSize}
 | 
			
		||||
 | 
			
		||||
	// Lets create desired volume
 | 
			
		||||
	d, err := DatasetCreate("TESTPOOL/VOLUME1", DatasetTypeVolume, props)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		println(err.Error())
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	// Dataset have to be closed for memory cleanup
 | 
			
		||||
	defer d.Close()
 | 
			
		||||
 | 
			
		||||
	println("Created zfs volume TESTPOOL/VOLUME1")
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue