func TestVolumeEntryExpandMaxBrickLimit(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() // Create a large cluster err := setupSampleDbWithTopology(app, 10, // clusters 4, // nodes_per_cluster 24, // devices_per_node, 600*GB, // disksize) ) tests.Assert(t, err == nil) // Create large volume v := createSampleVolumeEntry(100) err = v.Create(app.db, app.executor, app.allocator) tests.Assert(t, err == nil) // Add a bunch of bricks until the limit fakebricks := make(sort.StringSlice, BRICK_MAX_NUM-len(v.Bricks)) v.Bricks = append(v.Bricks, fakebricks...) // Try to expand the volume, but it will return that the max number // of bricks has been reached err = v.Expand(app.db, app.executor, app.allocator, 100) tests.Assert(t, err == ErrMaxBricks, err) }
func TestNewBrickEntryNewInfoResponse(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() // Create a brick b := NewBrickEntry(10, 20, 5, "abc", "def") // Save element in database err := app.db.Update(func(tx *bolt.Tx) error { return b.Save(tx) }) tests.Assert(t, err == nil) var info *BrickInfo err = app.db.View(func(tx *bolt.Tx) error { brick, err := NewBrickEntryFromId(tx, b.Id()) if err != nil { return err } info, err = brick.NewInfoResponse(tx) return err }) tests.Assert(t, err == nil) tests.Assert(t, reflect.DeepEqual(*info, b.Info)) }
func TestGlusterFSDBFileLoad(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) db := NewGlusterFSDB(tmpfile) db.nodes["one"] = &NodeEntry{ Info: requests.NodeInfoResp{ Name: "nodetest", }, } db.volumes["a"] = &VolumeEntry{ Info: requests.VolumeInfoResp{ Name: "volumetest", }, } err := db.Commit() tests.Assert(t, err == nil) newdb := NewGlusterFSDB(tmpfile) tests.Assert(t, newdb != nil) tests.Assert(t, newdb.nodes["one"].Info.Name == db.nodes["one"].Info.Name) tests.Assert(t, newdb.volumes["a"].Info.Name == db.volumes["a"].Info.Name) }
func TestVolumeExpandIdNotFound(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() router := mux.NewRouter() app.SetRoutes(router) // Setup the server ts := httptest.NewServer(router) defer ts.Close() // JSON Request request := []byte(`{ "expand_size" : 100 }`) // Now that we have some data in the database, we can // make a request for the clutser list r, err := http.Post(ts.URL+"/volumes/12345/expand", "application/json", bytes.NewBuffer(request)) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusNotFound, r.StatusCode) body, err := ioutil.ReadAll(io.LimitReader(r.Body, r.ContentLength)) tests.Assert(t, err == nil) r.Body.Close() tests.Assert(t, strings.Contains(string(body), "Id not found")) }
func TestVolumeCreateSmallSize(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() router := mux.NewRouter() app.SetRoutes(router) // Setup the server ts := httptest.NewServer(router) defer ts.Close() // VolumeCreate JSON Request request := []byte(`{ "size" : 0 }`) // Send request r, err := http.Post(ts.URL+"/volumes", "application/json", bytes.NewBuffer(request)) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusBadRequest) body, err := ioutil.ReadAll(io.LimitReader(r.Body, r.ContentLength)) tests.Assert(t, err == nil) r.Body.Close() tests.Assert(t, strings.Contains(string(body), "Invalid volume size")) }
func TestNewBrickEntryFromId(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() // Create a brick b := NewBrickEntry(10, 20, 5, "abc", "def") // Save element in database err := app.db.Update(func(tx *bolt.Tx) error { return b.Save(tx) }) tests.Assert(t, err == nil) var brick *BrickEntry err = app.db.View(func(tx *bolt.Tx) error { var err error brick, err = NewBrickEntryFromId(tx, b.Info.Id) return err }) tests.Assert(t, err == nil) tests.Assert(t, reflect.DeepEqual(brick, b)) }
func TestVolumeEntryFromId(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() // Create a volume entry v := createSampleVolumeEntry(1024) // Save in database err := app.db.Update(func(tx *bolt.Tx) error { return v.Save(tx) }) tests.Assert(t, err == nil) // Load from database var entry *VolumeEntry err = app.db.View(func(tx *bolt.Tx) error { var err error entry, err = NewVolumeEntryFromId(tx, v.Info.Id) return err }) tests.Assert(t, err == nil) tests.Assert(t, reflect.DeepEqual(entry, v)) }
func TestVolumeListEmpty(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() router := mux.NewRouter() app.SetRoutes(router) // Setup the server ts := httptest.NewServer(router) defer ts.Close() // Get volumes, there should be none r, err := http.Get(ts.URL + "/volumes") tests.Assert(t, r.StatusCode == http.StatusOK) tests.Assert(t, err == nil) tests.Assert(t, r.Header.Get("Content-Type") == "application/json; charset=UTF-8") // Read response var msg VolumeListResponse err = utils.GetJsonFromResponse(r, &msg) tests.Assert(t, err == nil) tests.Assert(t, len(msg.Volumes) == 0) }
func TestClientCluster(t *testing.T) { db := tests.Tempfile() defer os.Remove(db) // Create the app app := glusterfs.NewTestApp(db) defer app.Close() // Setup the server ts := setupHeketiServer(app) defer ts.Close() // Create cluster with unknown user c := NewClient(ts.URL, "asdf", "") tests.Assert(t, c != nil) cluster, err := c.ClusterCreate() tests.Assert(t, err != nil) tests.Assert(t, cluster == nil) // Create cluster with bad password c = NewClient(ts.URL, "admin", "badpassword") tests.Assert(t, c != nil) cluster, err = c.ClusterCreate() tests.Assert(t, err != nil) tests.Assert(t, cluster == nil) // Create cluster correctly c = NewClient(ts.URL, "admin", TEST_ADMIN_KEY) tests.Assert(t, c != nil) cluster, err = c.ClusterCreate() tests.Assert(t, err == nil) tests.Assert(t, cluster.Id != "") tests.Assert(t, len(cluster.Nodes) == 0) tests.Assert(t, len(cluster.Volumes) == 0) // Request bad id info, err := c.ClusterInfo("bad") tests.Assert(t, err != nil) tests.Assert(t, info == nil) // Get information about the client info, err = c.ClusterInfo(cluster.Id) tests.Assert(t, err == nil) tests.Assert(t, reflect.DeepEqual(info, cluster)) // Get a list of clusters list, err := c.ClusterList() tests.Assert(t, err == nil) tests.Assert(t, len(list.Clusters) == 1) tests.Assert(t, list.Clusters[0] == info.Id) // Delete non-existent cluster err = c.ClusterDelete("badid") tests.Assert(t, err != nil) // Delete current cluster err = c.ClusterDelete(info.Id) tests.Assert(t, err == nil) }
func TestVolumeDelete(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() router := mux.NewRouter() app.SetRoutes(router) // Setup the server ts := httptest.NewServer(router) defer ts.Close() // Setup database err := setupSampleDbWithTopology(app, 1, // clusters 10, // nodes_per_cluster 10, // devices_per_node, 5*TB, // disksize) ) tests.Assert(t, err == nil) // Create a volume v := createSampleVolumeEntry(100) tests.Assert(t, v != nil) err = v.Create(app.db, app.executor, app.allocator) tests.Assert(t, err == nil) // Delete the volume req, err := http.NewRequest("DELETE", ts.URL+"/volumes/"+v.Info.Id, nil) tests.Assert(t, err == nil) r, err := http.DefaultClient.Do(req) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusAccepted) location, err := r.Location() tests.Assert(t, err == nil) // Query queue until finished for { r, err = http.Get(location.String()) tests.Assert(t, err == nil) if r.Header.Get("X-Pending") == "true" { tests.Assert(t, r.StatusCode == http.StatusOK) time.Sleep(time.Millisecond * 10) continue } else { tests.Assert(t, r.StatusCode == http.StatusNoContent) tests.Assert(t, err == nil) break } } // Check it is not there r, err = http.Get(ts.URL + "/volumes/" + v.Info.Id) tests.Assert(t, r.StatusCode == http.StatusNotFound) tests.Assert(t, err == nil) }
func TestVolumeList(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() router := mux.NewRouter() app.SetRoutes(router) // Setup the server ts := httptest.NewServer(router) defer ts.Close() // Create some volumes numvolumes := 1000 err := app.db.Update(func(tx *bolt.Tx) error { for i := 0; i < numvolumes; i++ { v := createSampleVolumeEntry(100) err := v.Save(tx) if err != nil { return err } } return nil }) tests.Assert(t, err == nil) // Get volumes, there should be none r, err := http.Get(ts.URL + "/volumes") tests.Assert(t, r.StatusCode == http.StatusOK) tests.Assert(t, err == nil) tests.Assert(t, r.Header.Get("Content-Type") == "application/json; charset=UTF-8") // Read response var msg VolumeListResponse err = utils.GetJsonFromResponse(r, &msg) tests.Assert(t, err == nil) tests.Assert(t, len(msg.Volumes) == numvolumes) // Check that all the volumes are in the database err = app.db.View(func(tx *bolt.Tx) error { for _, id := range msg.Volumes { _, err := NewVolumeEntryFromId(tx, id) if err != nil { return err } } return nil }) tests.Assert(t, err == nil) }
func TestVolumeCreateBadDispersionValues(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() router := mux.NewRouter() app.SetRoutes(router) // Setup the server ts := httptest.NewServer(router) defer ts.Close() // VolumeCreate JSON Request request := []byte(`{ "size" : 100, "durability": { "type": "disperse", "disperse": { "data" : 8, "redundancy" : 1 } } }`) // Send request r, err := http.Post(ts.URL+"/volumes", "application/json", bytes.NewBuffer(request)) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusBadRequest) body, err := ioutil.ReadAll(io.LimitReader(r.Body, r.ContentLength)) tests.Assert(t, err == nil) r.Body.Close() tests.Assert(t, strings.Contains(string(body), "Invalid dispersion combination")) // VolumeCreate JSON Request request = []byte(`{ "size" : 100, "durability": { "type": "disperse", "disperse": { "data" : 4, "redundancy" : 3 } } }`) // Send request r, err = http.Post(ts.URL+"/volumes", "application/json", bytes.NewBuffer(request)) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusBadRequest) body, err = ioutil.ReadAll(io.LimitReader(r.Body, r.ContentLength)) tests.Assert(t, err == nil) r.Body.Close() tests.Assert(t, strings.Contains(string(body), "Invalid dispersion combination")) }
func TestDeviceAddBadRequests(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Patch dbfilename so that it is restored at the end of the tests defer tests.Patch(&dbfilename, tmpfile).Restore() // Create the app app := NewApp() defer app.Close() router := mux.NewRouter() app.SetRoutes(router) // Setup the server ts := httptest.NewServer(router) defer ts.Close() // ClusterCreate JSON Request request := []byte(`{ bad json }`) // Post bad JSON r, err := http.Post(ts.URL+"/devices", "application/json", bytes.NewBuffer(request)) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == 422) // Make a request with no devices request = []byte(`{ "node" : "123", "devices" : [] }`) // Post bad JSON r, err = http.Post(ts.URL+"/devices", "application/json", bytes.NewBuffer(request)) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusBadRequest) // Make a request with unknown node request = []byte(`{ "node" : "123", "devices" : [ { "name" : "/dev/fake", "weight" : 20 } ] }`) // Post bad JSON r, err = http.Post(ts.URL+"/devices", "application/json", bytes.NewBuffer(request)) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusNotFound) }
func TestNewNodeEntryNewInfoResponse(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Patch dbfilename so that it is restored at the end of the tests defer tests.Patch(&dbfilename, tmpfile).Restore() // Create the app app := NewApp() defer app.Close() // Create a node req := &NodeAddRequest{ ClusterId: "123", Hostnames: HostAddresses{ Manage: []string{"manage"}, Storage: []string{"storage"}, }, Zone: 99, } n := NewNodeEntryFromRequest(req) // Save element in database err := app.db.Update(func(tx *bolt.Tx) error { return n.Save(tx) }) tests.Assert(t, err == nil) var info *NodeInfoResponse err = app.db.View(func(tx *bolt.Tx) error { node, err := NewNodeEntryFromId(tx, n.Info.Id) if err != nil { return err } info, err = node.NewInfoReponse(tx) if err != nil { return err } return nil }) tests.Assert(t, err == nil) tests.Assert(t, info.ClusterId == n.Info.ClusterId) tests.Assert(t, info.Id == n.Info.Id) tests.Assert(t, info.Zone == n.Info.Zone) tests.Assert(t, len(info.Hostnames.Manage) == 1) tests.Assert(t, len(info.Hostnames.Storage) == 1) tests.Assert(t, reflect.DeepEqual(info.Hostnames.Manage, n.Info.Hostnames.Manage)) tests.Assert(t, reflect.DeepEqual(info.Hostnames.Storage, n.Info.Hostnames.Storage)) }
func TestVolumeInfo(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() router := mux.NewRouter() app.SetRoutes(router) // Setup the server ts := httptest.NewServer(router) defer ts.Close() // Setup database err := setupSampleDbWithTopology(app, 1, // clusters 10, // nodes_per_cluster 10, // devices_per_node, 5*TB, // disksize) ) tests.Assert(t, err == nil) // Create a volume req := &VolumeCreateRequest{} req.Size = 100 req.Durability.Type = DURABILITY_STRING_EC v := NewVolumeEntryFromRequest(req) tests.Assert(t, v != nil) err = v.Create(app.db, app.executor, app.allocator) tests.Assert(t, err == nil) // Now that we have some data in the database, we can // make a request for the clutser list r, err := http.Get(ts.URL + "/volumes/" + v.Info.Id) tests.Assert(t, r.StatusCode == http.StatusOK) tests.Assert(t, err == nil) tests.Assert(t, r.Header.Get("Content-Type") == "application/json; charset=UTF-8") // Read response var msg VolumeInfoResponse err = utils.GetJsonFromResponse(r, &msg) tests.Assert(t, err == nil) tests.Assert(t, msg.Id == v.Info.Id) tests.Assert(t, msg.Cluster == v.Info.Cluster) tests.Assert(t, msg.Name == v.Info.Name) tests.Assert(t, msg.Size == v.Info.Size) tests.Assert(t, reflect.DeepEqual(msg.Durability, v.Info.Durability)) tests.Assert(t, reflect.DeepEqual(msg.Snapshot, v.Info.Snapshot)) for _, brick := range msg.Bricks { tests.Assert(t, utils.SortedStringHas(v.Bricks, brick.Id)) } }
func TestVolumeEntryCreateBrickCreationFailure(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() // Lots of nodes with little drives err := setupSampleDbWithTopology(app, 1, // clusters 4, // nodes_per_cluster 4, // devices_per_node, 500*GB, // disksize) ) tests.Assert(t, err == nil) // Cause a brick creation failure mockerror := errors.New("MOCK") app.xo.MockBrickCreate = func(host string, brick *executors.BrickRequest) (*executors.BrickInfo, error) { return nil, mockerror } // Create a volume with a snapshot factor of 1.5 // For a 200G vol, it would get a brick size of 100G, with a thin pool // size of 100G * 1.5 = 150GB. v := createSampleVolumeEntry(200) err = v.Create(app.db, app.executor, app.allocator) tests.Assert(t, err == mockerror) // Check database is still clean. No bricks and No volumes err = app.db.View(func(tx *bolt.Tx) error { volumes, err := VolumeList(tx) tests.Assert(t, err == nil) tests.Assert(t, len(volumes) == 0) bricks, err := BrickList(tx) tests.Assert(t, err == nil) tests.Assert(t, len(bricks) == 0) clusters, err := ClusterList(tx) tests.Assert(t, err == nil) tests.Assert(t, len(clusters) == 1) cluster, err := NewClusterEntryFromId(tx, clusters[0]) tests.Assert(t, err == nil) tests.Assert(t, len(cluster.Info.Volumes) == 0) return nil }) tests.Assert(t, err == nil) }
func TestNewDeviceEntryNewInfoResponse(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Patch dbfilename so that it is restored at the end of the tests defer tests.Patch(&dbfilename, tmpfile).Restore() // Create the app app := NewApp() defer app.Close() // Create a device req := &Device{ Name: "dev", Weight: 123, } nodeid := "abc" d := NewDeviceEntryFromRequest(req, nodeid) d.Info.Storage.Free = 10 d.Info.Storage.Total = 100 d.Info.Storage.Used = 1000 d.BrickAdd("abc") d.BrickAdd("def") // Save element in database err := app.db.Update(func(tx *bolt.Tx) error { return d.Save(tx) }) tests.Assert(t, err == nil) var info *DeviceInfoResponse err = app.db.View(func(tx *bolt.Tx) error { device, err := NewDeviceEntryFromId(tx, d.Info.Id) if err != nil { return err } info, err = device.NewInfoResponse(tx) if err != nil { return err } return nil }) tests.Assert(t, err == nil) tests.Assert(t, info.Id == d.Info.Id) tests.Assert(t, info.Name == d.Info.Name) tests.Assert(t, info.Weight == d.Info.Weight) tests.Assert(t, reflect.DeepEqual(info.Storage, d.Info.Storage)) tests.Assert(t, len(info.Bricks) == 0) }
func TestClusterCreate(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Patch dbfilename so that it is restored at the end of the tests defer tests.Patch(&dbfilename, tmpfile).Restore() // Create the app app := NewApp() defer app.Close() router := mux.NewRouter() app.SetRoutes(router) // Setup the server ts := httptest.NewServer(router) defer ts.Close() // ClusterCreate JSON Request request := []byte(`{ }`) // Post nothing r, err := http.Post(ts.URL+"/clusters", "application/json", bytes.NewBuffer(request)) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusCreated) // Read JSON var msg ClusterInfoResponse err = utils.GetJsonFromResponse(r, &msg) tests.Assert(t, err == nil) // Test JSON tests.Assert(t, len(msg.Nodes) == 0) tests.Assert(t, len(msg.Volumes) == 0) // Check that the data on the database is recorded correctly var entry ClusterEntry err = app.db.View(func(tx *bolt.Tx) error { return entry.Unmarshal( tx.Bucket([]byte(BOLTDB_BUCKET_CLUSTER)). Get([]byte(msg.Id))) }) tests.Assert(t, err == nil) // Make sure they entries are euqal tests.Assert(t, entry.Info.Id == msg.Id) tests.Assert(t, len(entry.Info.Volumes) == 0) tests.Assert(t, len(entry.Info.Nodes) == 0) }
func TestVolumeEntryCreateMaxBrickSize(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() // Create 500TB of storage err := setupSampleDbWithTopology(app, 1, // clusters 10, // nodes_per_cluster 10, // devices_per_node, 5*TB, // disksize) ) tests.Assert(t, err == nil) // Create a volume whose bricks must be at most BRICK_MAX_SIZE v := createSampleVolumeEntry(int(BRICK_MAX_SIZE / GB * 4)) err = v.Create(app.db, app.executor, app.allocator) tests.Assert(t, err == nil) // Get volume information var info *VolumeInfoResponse err = app.db.View(func(tx *bolt.Tx) error { entry, err := NewVolumeEntryFromId(tx, v.Info.Id) if err != nil { return err } info, err = entry.NewInfoResponse(tx) if err != nil { return err } return nil }) tests.Assert(t, err == nil) // Check the size of the bricks are not bigger than BRICK_MAX_SIZE tests.Assert(t, len(info.Bricks) == 8) for b := 1; b < len(info.Bricks); b++ { tests.Assert(t, info.Bricks[b].Size <= BRICK_MAX_SIZE) } tests.Assert(t, info.Cluster == v.Info.Cluster) }
func TestVolumeEntrySaveDelete(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() // Create a volume entry v := createSampleVolumeEntry(1024) // Save in database err := app.db.Update(func(tx *bolt.Tx) error { return v.Save(tx) }) tests.Assert(t, err == nil) // Delete entry which has devices var entry *VolumeEntry err = app.db.Update(func(tx *bolt.Tx) error { var err error entry, err = NewVolumeEntryFromId(tx, v.Info.Id) if err != nil { return err } err = entry.Delete(tx) if err != nil { return err } return nil }) tests.Assert(t, err == nil) // Check volume has been deleted and is not in db err = app.db.View(func(tx *bolt.Tx) error { var err error entry, err = NewVolumeEntryFromId(tx, v.Info.Id) if err != nil { return err } return nil }) tests.Assert(t, err == ErrNotFound) }
func TestDeviceInfo(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Patch dbfilename so that it is restored at the end of the tests defer tests.Patch(&dbfilename, tmpfile).Restore() // Create the app app := NewApp() defer app.Close() router := mux.NewRouter() app.SetRoutes(router) // Setup the server ts := httptest.NewServer(router) defer ts.Close() // Create a device to save in the db device := NewDeviceEntry() device.Info.Id = "abc" device.Info.Name = "/dev/fake1" device.Info.Weight = 101 device.NodeId = "def" device.StorageSet(10000) device.StorageAllocate(1000) // Save device in the db err := app.db.Update(func(tx *bolt.Tx) error { return device.Save(tx) }) tests.Assert(t, err == nil) // Get device information r, err := http.Get(ts.URL + "/devices/" + device.Info.Id) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusOK) tests.Assert(t, r.Header.Get("Content-Type") == "application/json; charset=UTF-8") var info DeviceInfoResponse err = utils.GetJsonFromResponse(r, &info) tests.Assert(t, info.Id == device.Info.Id) tests.Assert(t, info.Name == device.Info.Name) tests.Assert(t, info.Weight == device.Info.Weight) tests.Assert(t, info.Storage.Free == device.Info.Storage.Free) tests.Assert(t, info.Storage.Used == device.Info.Storage.Used) tests.Assert(t, info.Storage.Total == device.Info.Storage.Total) }
func TestDeviceDeleteErrors(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Patch dbfilename so that it is restored at the end of the tests defer tests.Patch(&dbfilename, tmpfile).Restore() // Create the app app := NewApp() defer app.Close() router := mux.NewRouter() app.SetRoutes(router) // Setup the server ts := httptest.NewServer(router) defer ts.Close() // Create a device to save in the db device := NewDeviceEntry() device.Info.Id = "abc" device.Info.Name = "/dev/fake1" device.Info.Weight = 101 device.NodeId = "def" device.StorageSet(10000) device.StorageAllocate(1000) // Save device in the db err := app.db.Update(func(tx *bolt.Tx) error { return device.Save(tx) }) tests.Assert(t, err == nil) // Delete unknown id req, err := http.NewRequest("DELETE", ts.URL+"/devices/123", nil) tests.Assert(t, err == nil) r, err := http.DefaultClient.Do(req) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusNotFound) // Delete device without a node there.. that's probably a really // bad situation req, err = http.NewRequest("DELETE", ts.URL+"/devices/"+device.Info.Id, nil) tests.Assert(t, err == nil) r, err = http.DefaultClient.Do(req) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusInternalServerError) }
func TestSimpleAllocatorInitFromDb(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Setup database app := NewTestApp(tmpfile) defer app.Close() // Create large cluster err := setupSampleDbWithTopology(app, 1, // clusters 10, // nodes_per_cluster 20, // devices_per_node, 600*GB, // disksize) ) tests.Assert(t, err == nil) // Get the cluster list var clusterId string err = app.db.View(func(tx *bolt.Tx) error { clusters, err := ClusterList(tx) if err != nil { return err } tests.Assert(t, len(clusters) == 1) clusterId = clusters[0] return nil }) tests.Assert(t, err == nil) // Create an allocator and initialize it from the DB a := NewSimpleAllocatorFromDb(app.db) tests.Assert(t, a != nil) // Get the nodes from the ring ch, _, errc := a.GetNodes(clusterId, utils.GenUUID()) var devices int for d := range ch { devices++ tests.Assert(t, d != "") } err = <-errc tests.Assert(t, devices == 10*20) tests.Assert(t, err == nil) }
func TestNewClusterEntryFromIdNotFound(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() // Test for ID not found err := app.db.View(func(tx *bolt.Tx) error { _, err := NewClusterEntryFromId(tx, "123") return err }) tests.Assert(t, err == ErrNotFound) }
func TestVolumeEntryExpandCreateBricksFailure(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() // Create large cluster err := setupSampleDbWithTopology(app, 10, // clusters 10, // nodes_per_cluster 20, // devices_per_node, 600*GB, // disksize) ) tests.Assert(t, err == nil) // Create volume v := createSampleVolumeEntry(100) err = v.Create(app.db, app.executor, app.allocator) tests.Assert(t, err == nil) // Save a copy of the volume before expansion vcopy := &VolumeEntry{} *vcopy = *v // Mock create bricks to fail ErrMock := errors.New("MOCK") app.xo.MockBrickCreate = func(host string, brick *executors.BrickRequest) (*executors.BrickInfo, error) { return nil, ErrMock } // Expand volume err = v.Expand(app.db, app.executor, app.allocator, 500) tests.Assert(t, err == ErrMock) // Check db is the same as before expansion var entry *VolumeEntry err = app.db.View(func(tx *bolt.Tx) error { var err error entry, err = NewVolumeEntryFromId(tx, v.Info.Id) return err }) tests.Assert(t, err == nil) tests.Assert(t, reflect.DeepEqual(vcopy, entry)) }
func TestNodeDeleteErrors(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Patch dbfilename so that it is restored at the end of the tests defer tests.Patch(&dbfilename, tmpfile).Restore() // Create the app app := NewApp() defer app.Close() router := mux.NewRouter() app.SetRoutes(router) // Setup the server ts := httptest.NewServer(router) defer ts.Close() // Create a node to save in the db node := NewNodeEntry() node.Info.Id = "abc" node.Info.ClusterId = "123" node.Info.Hostnames.Manage = sort.StringSlice{"manage.system"} node.Info.Hostnames.Storage = sort.StringSlice{"storage.system"} node.Info.Zone = 10 // Save node in the db err := app.db.Update(func(tx *bolt.Tx) error { return node.Save(tx) }) tests.Assert(t, err == nil) // Delete unknown id req, err := http.NewRequest("DELETE", ts.URL+"/nodes/123", nil) tests.Assert(t, err == nil) r, err := http.DefaultClient.Do(req) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusNotFound) // Delete node without a cluster there.. that's probably a really // bad situation req, err = http.NewRequest("DELETE", ts.URL+"/nodes/"+node.Info.Id, nil) tests.Assert(t, err == nil) r, err = http.DefaultClient.Do(req) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusInternalServerError) }
func TestNodeInfo(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Patch dbfilename so that it is restored at the end of the tests defer tests.Patch(&dbfilename, tmpfile).Restore() // Create the app app := NewApp() defer app.Close() router := mux.NewRouter() app.SetRoutes(router) // Setup the server ts := httptest.NewServer(router) defer ts.Close() // Create a node to save in the db node := NewNodeEntry() node.Info.Id = "abc" node.Info.ClusterId = "123" node.Info.Hostnames.Manage = sort.StringSlice{"manage.system"} node.Info.Hostnames.Storage = sort.StringSlice{"storage.system"} node.Info.Zone = 10 // Save node in the db err := app.db.Update(func(tx *bolt.Tx) error { return node.Save(tx) }) tests.Assert(t, err == nil) // Get unknown node id r, err := http.Get(ts.URL + "/nodes/" + node.Info.Id) tests.Assert(t, err == nil) tests.Assert(t, r.StatusCode == http.StatusOK) tests.Assert(t, r.Header.Get("Content-Type") == "application/json; charset=UTF-8") var info NodeInfoResponse err = utils.GetJsonFromResponse(r, &info) tests.Assert(t, info.Id == node.Info.Id) tests.Assert(t, info.Hostnames.Manage[0] == node.Info.Hostnames.Manage[0]) tests.Assert(t, len(info.Hostnames.Manage) == len(node.Info.Hostnames.Manage)) tests.Assert(t, info.Hostnames.Storage[0] == node.Info.Hostnames.Storage[0]) tests.Assert(t, len(info.Hostnames.Storage) == len(node.Info.Hostnames.Storage)) tests.Assert(t, info.Zone == node.Info.Zone) }
func TestVolumeEntryCreateRunOutOfSpaceMaxBrickLimit(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() // Lots of nodes with little drives err := setupSampleDbWithTopology(app, 1, // clusters 20, // nodes_per_cluster 40, // devices_per_node, // Must be larger than the brick min size BRICK_MIN_SIZE*2, // disksize ) tests.Assert(t, err == nil) // Create a volume who will be broken down to // Shouldn't be able to break it down enough to allocate volume v := createSampleVolumeEntry(BRICK_MAX_NUM * 2 * int(BRICK_MIN_SIZE/GB)) err = v.Create(app.db, app.executor, app.allocator) tests.Assert(t, err == ErrNoSpace) // Check database volume does not exist err = app.db.View(func(tx *bolt.Tx) error { _, err := NewVolumeEntryFromId(tx, v.Info.Id) return err }) tests.Assert(t, err == ErrNotFound) // Check no bricks or volumes exist var bricks []string var volumes []string err = app.db.View(func(tx *bolt.Tx) error { bricks = EntryKeys(tx, BOLTDB_BUCKET_BRICK) volumes = EntryKeys(tx, BOLTDB_BUCKET_VOLUME) return nil }) tests.Assert(t, len(bricks) == 0) tests.Assert(t, len(volumes) == 0) }
func TestNewDeviceEntryNewInfoResponseBadBrickIds(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Create the app app := NewTestApp(tmpfile) defer app.Close() // Create a device req := &DeviceAddRequest{} req.NodeId = "abc" req.Name = "/dev/" + utils.GenUUID() req.Weight = 123 // Add bad brick ids d := NewDeviceEntryFromRequest(req) d.Info.Storage.Free = 10 d.Info.Storage.Total = 100 d.Info.Storage.Used = 1000 d.BrickAdd("abc") d.BrickAdd("def") // Save element in database err := app.db.Update(func(tx *bolt.Tx) error { return d.Save(tx) }) tests.Assert(t, err == nil) var info *DeviceInfoResponse err = app.db.View(func(tx *bolt.Tx) error { device, err := NewDeviceEntryFromId(tx, d.Info.Id) if err != nil { return err } info, err = device.NewInfoResponse(tx) if err != nil { return err } return nil }) tests.Assert(t, err == ErrNotFound) }
func TestNewNodeEntryFromId(t *testing.T) { tmpfile := tests.Tempfile() defer os.Remove(tmpfile) // Patch dbfilename so that it is restored at the end of the tests defer tests.Patch(&dbfilename, tmpfile).Restore() // Create the app app := NewApp() defer app.Close() // Create a node req := &NodeAddRequest{ ClusterId: "123", Hostnames: HostAddresses{ Manage: []string{"manage"}, Storage: []string{"storage"}, }, Zone: 99, } n := NewNodeEntryFromRequest(req) n.DeviceAdd("abc") n.DeviceAdd("def") // Save element in database err := app.db.Update(func(tx *bolt.Tx) error { return n.Save(tx) }) tests.Assert(t, err == nil) var node *NodeEntry err = app.db.View(func(tx *bolt.Tx) error { var err error node, err = NewNodeEntryFromId(tx, n.Info.Id) if err != nil { return err } return nil }) tests.Assert(t, err == nil) tests.Assert(t, reflect.DeepEqual(node, n)) }