예제 #1
0
파일: cluster.go 프로젝트: jbeda/kubernetes
func (c *Client) ClusterList() (*api.ClusterListResponse, error) {

	// Create request
	req, err := http.NewRequest("GET", c.host+"/clusters", nil)
	if err != nil {
		return nil, err
	}

	// Set token
	err = c.setToken(req)
	if err != nil {
		return nil, err
	}

	// Get info
	r, err := c.do(req)
	if err != nil {
		return nil, err
	}
	if r.StatusCode != http.StatusOK {
		return nil, utils.GetErrorFromResponse(r)
	}

	// Read JSON response
	var clusters api.ClusterListResponse
	err = utils.GetJsonFromResponse(r, &clusters)
	if err != nil {
		return nil, err
	}

	return &clusters, nil
}
예제 #2
0
파일: cluster.go 프로젝트: jbeda/kubernetes
func (c *Client) ClusterCreate() (*api.ClusterInfoResponse, error) {

	// Create a request
	req, err := http.NewRequest("POST", c.host+"/clusters", bytes.NewBuffer([]byte(`{}`)))
	if err != nil {
		return nil, err
	}
	req.Header.Set("Content-Type", "application/json")

	// Set token
	err = c.setToken(req)
	if err != nil {
		return nil, err
	}

	// Send request
	r, err := c.do(req)
	if err != nil {
		return nil, err
	}
	if r.StatusCode != http.StatusCreated {
		return nil, utils.GetErrorFromResponse(r)
	}

	// Read JSON response
	var cluster api.ClusterInfoResponse
	err = utils.GetJsonFromResponse(r, &cluster)
	r.Body.Close()
	if err != nil {
		return nil, err
	}

	return &cluster, nil
}
예제 #3
0
func (c *Client) VolumeInfo(id string) (*api.VolumeInfoResponse, error) {

	// Create request
	req, err := http.NewRequest("GET", c.host+"/volumes/"+id, nil)
	if err != nil {
		return nil, err
	}

	// Set token
	err = c.setToken(req)
	if err != nil {
		return nil, err
	}

	// Get info
	r, err := c.do(req)
	if err != nil {
		return nil, err
	}
	if r.StatusCode != http.StatusOK {
		return nil, utils.GetErrorFromResponse(r)
	}

	// Read JSON response
	var volume api.VolumeInfoResponse
	err = utils.GetJsonFromResponse(r, &volume)
	r.Body.Close()
	if err != nil {
		return nil, err
	}

	return &volume, nil
}
예제 #4
0
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 api.VolumeListResponse
	err = utils.GetJsonFromResponse(r, &msg)
	tests.Assert(t, err == nil)
	tests.Assert(t, len(msg.Volumes) == 0)
}
예제 #5
0
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 api.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)

}
예제 #6
0
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 := &api.VolumeCreateRequest{}
	req.Size = 100
	req.Durability.Type = api.DurabilityEC
	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 api.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))
	}
}
예제 #7
0
func (c *Client) VolumeExpand(id string, request *api.VolumeExpandRequest) (
	*api.VolumeInfoResponse, error) {

	// Marshal request to JSON
	buffer, err := json.Marshal(request)
	if err != nil {
		return nil, err
	}

	// Create a request
	req, err := http.NewRequest("POST",
		c.host+"/volumes/"+id+"/expand",
		bytes.NewBuffer(buffer))
	if err != nil {
		return nil, err
	}
	req.Header.Set("Content-Type", "application/json")

	// Set token
	err = c.setToken(req)
	if err != nil {
		return nil, err
	}

	// Send request
	r, err := c.do(req)
	if err != nil {
		return nil, err
	}
	if r.StatusCode != http.StatusAccepted {
		return nil, utils.GetErrorFromResponse(r)
	}

	// Wait for response
	r, err = c.waitForResponseWithTimer(r, time.Second)
	if err != nil {
		return nil, err
	}
	if r.StatusCode != http.StatusOK {
		return nil, utils.GetErrorFromResponse(r)
	}

	// Read JSON response
	var volume api.VolumeInfoResponse
	err = utils.GetJsonFromResponse(r, &volume)
	r.Body.Close()
	if err != nil {
		return nil, err
	}

	return &volume, nil

}
예제 #8
0
파일: node.go 프로젝트: jbeda/kubernetes
func (c *Client) NodeAdd(request *api.NodeAddRequest) (*api.NodeInfoResponse, error) {

	// Marshal request to JSON
	buffer, err := json.Marshal(request)
	if err != nil {
		return nil, err
	}

	// Create a request
	req, err := http.NewRequest("POST", c.host+"/nodes", bytes.NewBuffer(buffer))
	if err != nil {
		return nil, err
	}
	req.Header.Set("Content-Type", "application/json")

	// Set token
	err = c.setToken(req)
	if err != nil {
		return nil, err
	}

	// Send request
	r, err := c.do(req)
	if err != nil {
		return nil, err
	}
	if r.StatusCode != http.StatusAccepted {
		return nil, utils.GetErrorFromResponse(r)
	}

	// Wait for response
	r, err = c.waitForResponseWithTimer(r, time.Millisecond*250)
	if err != nil {
		return nil, err
	}
	if r.StatusCode != http.StatusOK {
		return nil, utils.GetErrorFromResponse(r)
	}

	// Read JSON response
	var node api.NodeInfoResponse
	err = utils.GetJsonFromResponse(r, &node)
	r.Body.Close()
	if err != nil {
		return nil, err
	}

	return &node, nil
}
예제 #9
0
func TestClusterCreate(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()

	// 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 api.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)
}
예제 #10
0
func TestDeviceInfo(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 a device to save in the db
	device := NewDeviceEntry()
	device.Info.Id = "abc"
	device.Info.Name = "/dev/fake1"
	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 api.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.State == "online")
	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)

}
예제 #11
0
func TestNodeInfo(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 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 api.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)

}
예제 #12
0
func TestVolumeCreate(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)

	// VolumeCreate using default durability
	request := []byte(`{
        "size" : 100
    }`)

	// 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.StatusAccepted)
	location, err := r.Location()
	tests.Assert(t, err == nil)

	// Query queue until finished
	var info api.VolumeInfoResponse
	for {
		r, err = http.Get(location.String())
		tests.Assert(t, err == nil)
		tests.Assert(t, r.StatusCode == http.StatusOK)
		if r.ContentLength <= 0 {
			time.Sleep(time.Millisecond * 10)
			continue
		} else {
			// Should have node information here
			tests.Assert(t, r.Header.Get("Content-Type") == "application/json; charset=UTF-8")
			err = utils.GetJsonFromResponse(r, &info)
			tests.Assert(t, err == nil)
			break
		}
	}
	tests.Assert(t, info.Id != "")
	tests.Assert(t, info.Cluster != "")
	tests.Assert(t, len(info.Bricks) == 2) // Only two 50GB bricks needed
	tests.Assert(t, info.Bricks[0].Size == 50*GB)
	tests.Assert(t, info.Bricks[1].Size == 50*GB)
	tests.Assert(t, info.Name == "vol_"+info.Id)
	tests.Assert(t, info.Snapshot.Enable == false)
	tests.Assert(t, info.Snapshot.Factor == 1)
	tests.Assert(t, info.Durability.Type == api.DurabilityDistributeOnly)
}
예제 #13
0
func TestVolumeExpand(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 a cluster
	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)

	// Keep a copy
	vc := &VolumeEntry{}
	*vc = *v

	// JSON Request
	request := []byte(`{
        "expand_size" : 1000
    }`)

	// Send request
	r, err := http.Post(ts.URL+"/volumes/"+v.Info.Id+"/expand",
		"application/json",
		bytes.NewBuffer(request))
	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
	var info api.VolumeInfoResponse
	for {
		r, err := http.Get(location.String())
		tests.Assert(t, err == nil)
		tests.Assert(t, r.StatusCode == http.StatusOK)
		if r.Header.Get("X-Pending") == "true" {
			time.Sleep(time.Millisecond * 10)
			continue
		} else {
			err = utils.GetJsonFromResponse(r, &info)
			tests.Assert(t, err == nil)
			break
		}
	}

	tests.Assert(t, info.Size == 100+1000)
	tests.Assert(t, len(vc.Bricks) < len(info.Bricks))
}
예제 #14
0
func TestDeviceState(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 mock allocator
	mockAllocator := NewMockAllocator(app.db)
	app.allocator = mockAllocator

	// Create a client
	c := client.NewClientNoAuth(ts.URL)
	tests.Assert(t, c != nil)

	// Create Cluster
	cluster, err := c.ClusterCreate()
	tests.Assert(t, err == nil)

	// Create Node
	nodeReq := &api.NodeAddRequest{
		Zone:      1,
		ClusterId: cluster.Id,
	}
	nodeReq.Hostnames.Manage = sort.StringSlice{"manage.host"}
	nodeReq.Hostnames.Storage = sort.StringSlice{"storage.host"}
	node, err := c.NodeAdd(nodeReq)
	tests.Assert(t, err == nil)

	// Add device
	deviceReq := &api.DeviceAddRequest{}
	deviceReq.Name = "/dev/fake1"
	deviceReq.NodeId = node.Id

	err = c.DeviceAdd(deviceReq)
	tests.Assert(t, err == nil)

	// Get node information again
	node, err = c.NodeInfo(node.Id)
	tests.Assert(t, err == nil)

	// Get device information
	deviceId := node.DevicesInfo[0].Id
	device, err := c.DeviceInfo(deviceId)
	tests.Assert(t, err == nil)

	// Get info
	deviceInfo, err := c.DeviceInfo(device.Id)
	tests.Assert(t, err == nil)
	tests.Assert(t, deviceInfo.State == "online")

	// Check that the device is in the ring
	tests.Assert(t, len(mockAllocator.clustermap[cluster.Id]) == 1)
	tests.Assert(t, mockAllocator.clustermap[cluster.Id][0] == device.Id)

	// Set offline
	request := []byte(`{
				"state" : "offline"
				}`)
	r, err := http.Post(ts.URL+"/devices/"+device.Id+"/state",
		"application/json", bytes.NewBuffer(request))
	tests.Assert(t, err == nil)
	tests.Assert(t, r.StatusCode == http.StatusOK)

	// Check it was removed from the ring
	tests.Assert(t, len(mockAllocator.clustermap[cluster.Id]) == 0)

	// Get Device Info
	r, err = http.Get(ts.URL + "/devices/" + device.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 api.DeviceInfoResponse
	err = utils.GetJsonFromResponse(r, &info)
	tests.Assert(t, info.Id == device.Id)
	tests.Assert(t, info.Name == device.Name)
	tests.Assert(t, info.State == "offline")
	tests.Assert(t, info.Storage.Free == device.Storage.Free)
	tests.Assert(t, info.Storage.Used == device.Storage.Used)
	tests.Assert(t, info.Storage.Total == device.Storage.Total)

	// Set online again
	request = []byte(`{
				"state" : "online"
				}`)
	r, err = http.Post(ts.URL+"/devices/"+device.Id+"/state",
		"application/json", bytes.NewBuffer(request))
	tests.Assert(t, err == nil)
	tests.Assert(t, r.StatusCode == http.StatusOK)

	// Check that the device is in the ring
	tests.Assert(t, len(mockAllocator.clustermap[cluster.Id]) == 1)
	tests.Assert(t, mockAllocator.clustermap[cluster.Id][0] == device.Id)

	// Get Device Info
	r, err = http.Get(ts.URL + "/devices/" + device.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")

	err = utils.GetJsonFromResponse(r, &info)
	tests.Assert(t, info.Id == device.Id)
	tests.Assert(t, info.Name == device.Name)
	tests.Assert(t, info.State == "online")
	tests.Assert(t, info.Storage.Free == device.Storage.Free)
	tests.Assert(t, info.Storage.Used == device.Storage.Used)
	tests.Assert(t, info.Storage.Total == device.Storage.Total)

	// Set to unknown state
	request = []byte(`{
				"state" : "blah"
				}`)
	r, err = http.Post(ts.URL+"/devices/"+device.Id+"/state",
		"application/json", bytes.NewBuffer(request))
	tests.Assert(t, err == nil)
	tests.Assert(t, r.StatusCode == http.StatusBadRequest)

	// Check that the device is still in the ring
	tests.Assert(t, len(mockAllocator.clustermap[cluster.Id]) == 1)
	tests.Assert(t, mockAllocator.clustermap[cluster.Id][0] == device.Id)

	// Make sure the state did not change
	r, err = http.Get(ts.URL + "/devices/" + device.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")

	err = utils.GetJsonFromResponse(r, &info)
	tests.Assert(t, info.Id == device.Id)
	tests.Assert(t, info.Name == device.Name)
	tests.Assert(t, info.State == "online")
	tests.Assert(t, info.Storage.Free == device.Storage.Free)
	tests.Assert(t, info.Storage.Used == device.Storage.Used)
	tests.Assert(t, info.Storage.Total == device.Storage.Total)
}
예제 #15
0
func TestPeerProbe(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()

	// 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)
	tests.Assert(t, r.Header.Get("Content-Type") == "application/json; charset=UTF-8")

	// Read cluster information
	var clusterinfo api.ClusterInfoResponse
	err = utils.GetJsonFromResponse(r, &clusterinfo)
	tests.Assert(t, err == nil)

	// Override mock to check if the peer function was called
	probe_called := false
	app.xo.MockPeerProbe = func(exec_host, newnode string) error {
		probe_called = true
		return nil
	}

	// Create node on this cluster
	request = []byte(`{
		"cluster" : "` + clusterinfo.Id + `",
		"hostnames" : {
			"storage" : [ "storage0.hostname.com" ],
			"manage" : [ "manage0.hostname.com"  ]
		},
		"zone" : 1
    }`)

	// Create node
	r, err = http.Post(ts.URL+"/nodes", "application/json", bytes.NewBuffer(request))
	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)
		tests.Assert(t, r.StatusCode == http.StatusOK)
		if r.ContentLength <= 0 {
			time.Sleep(time.Millisecond * 10)
			continue
		} else {
			// Should have node information here
			tests.Assert(t, r.Header.Get("Content-Type") == "application/json; charset=UTF-8")
			tests.Assert(t, err == nil)
			break
		}
	}
	tests.Assert(t, probe_called == false)

	// Now add another and check that probe was called
	request = []byte(`{
		"cluster" : "` + clusterinfo.Id + `",
		"hostnames" : {
			"storage" : [ "storage1.hostname.com" ],
			"manage" : [ "manage1.hostname.com"  ]
		},
		"zone" : 1
    }`)

	// Create node
	r, err = http.Post(ts.URL+"/nodes", "application/json", bytes.NewBuffer(request))
	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)
		tests.Assert(t, r.StatusCode == http.StatusOK)
		if r.ContentLength <= 0 {
			time.Sleep(time.Millisecond * 10)
			continue
		} else {
			// Should have node information here
			tests.Assert(t, r.Header.Get("Content-Type") == "application/json; charset=UTF-8")
			tests.Assert(t, err == nil)
			break
		}
	}
	tests.Assert(t, probe_called == true)
}
예제 #16
0
func TestNodeAddDelete(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()

	// 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)
	tests.Assert(t, r.Header.Get("Content-Type") == "application/json; charset=UTF-8")

	// Read cluster information
	var clusterinfo api.ClusterInfoResponse
	err = utils.GetJsonFromResponse(r, &clusterinfo)
	tests.Assert(t, err == nil)

	// Create node on this cluster
	request = []byte(`{
		"cluster" : "` + clusterinfo.Id + `",
		"hostnames" : {
			"storage" : [ "storage.hostname.com" ],
			"manage" : [ "manage.hostname.com"  ]
		},
		"zone" : 1
    }`)

	// Create node
	r, err = http.Post(ts.URL+"/nodes", "application/json", bytes.NewBuffer(request))
	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
	var node api.NodeInfoResponse
	for {
		r, err = http.Get(location.String())
		tests.Assert(t, err == nil)
		tests.Assert(t, r.StatusCode == http.StatusOK)
		if r.ContentLength <= 0 {
			time.Sleep(time.Millisecond * 10)
			continue
		} else {
			// Should have node information here
			tests.Assert(t, r.Header.Get("Content-Type") == "application/json; charset=UTF-8")
			err = utils.GetJsonFromResponse(r, &node)
			tests.Assert(t, err == nil)
			break
		}
	}
	tests.Assert(t, len(node.Id) > 0)
	tests.Assert(t, len(node.Hostnames.Manage) == 1)
	tests.Assert(t, len(node.Hostnames.Storage) == 1)
	tests.Assert(t, node.Hostnames.Manage[0] == "manage.hostname.com")
	tests.Assert(t, node.Hostnames.Storage[0] == "storage.hostname.com")
	tests.Assert(t, node.Zone == 1)
	tests.Assert(t, node.ClusterId == clusterinfo.Id)
	tests.Assert(t, len(node.DevicesInfo) == 0)

	// Check that the node has registered
	err = app.db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(BOLTDB_BUCKET_NODE))
		tests.Assert(t, b != nil)

		val := b.Get([]byte("STORAGE" + node.Hostnames.Storage[0]))
		tests.Assert(t, string(val) == node.Id)

		val = b.Get([]byte("MANAGE" + node.Hostnames.Manage[0]))
		tests.Assert(t, string(val) == node.Id)

		return nil
	})
	tests.Assert(t, err == nil)

	//---- OK, now it should have been registered
	// now let's add it again
	// It should return a conflict
	r, err = http.Post(ts.URL+"/nodes", "application/json", bytes.NewBuffer(request))
	tests.Assert(t, err == nil)
	tests.Assert(t, r.StatusCode == http.StatusConflict)
	tests.Assert(t, err == nil)

	// Check Cluster has node
	r, err = http.Get(ts.URL + "/clusters/" + clusterinfo.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")

	err = utils.GetJsonFromResponse(r, &clusterinfo)
	tests.Assert(t, len(clusterinfo.Nodes) == 1)
	tests.Assert(t, clusterinfo.Nodes[0] == node.Id)

	// Check the data is in the database correctly
	var entry *NodeEntry
	err = app.db.View(func(tx *bolt.Tx) error {
		entry, err = NewNodeEntryFromId(tx, node.Id)
		return err
	})
	tests.Assert(t, err == nil)
	tests.Assert(t, entry != nil)
	tests.Assert(t, entry.Info.Id == node.Id)
	tests.Assert(t, len(entry.Info.Hostnames.Manage) == 1)
	tests.Assert(t, len(entry.Info.Hostnames.Storage) == 1)
	tests.Assert(t, entry.Info.Hostnames.Manage[0] == node.Hostnames.Manage[0])
	tests.Assert(t, entry.Info.Hostnames.Storage[0] == node.Hostnames.Storage[0])
	tests.Assert(t, len(entry.Devices) == 0)

	// Add some devices to check if delete conflict works
	err = app.db.Update(func(tx *bolt.Tx) error {
		entry, err = NewNodeEntryFromId(tx, node.Id)
		if err != nil {
			return err
		}

		entry.DeviceAdd("123")
		entry.DeviceAdd("456")
		return entry.Save(tx)
	})
	tests.Assert(t, err == nil)

	// Now delete node and check for conflict
	req, err := http.NewRequest("DELETE", ts.URL+"/nodes/"+node.Id, nil)
	tests.Assert(t, err == nil)
	r, err = http.DefaultClient.Do(req)
	tests.Assert(t, err == nil)
	tests.Assert(t, r.StatusCode == http.StatusConflict)

	// Check that nothing has changed in the db
	var cluster *ClusterEntry
	err = app.db.View(func(tx *bolt.Tx) error {
		entry, err = NewNodeEntryFromId(tx, node.Id)
		if err != nil {
			return err
		}

		cluster, err = NewClusterEntryFromId(tx, entry.Info.ClusterId)
		if err != nil {
			return err
		}

		return nil
	})
	tests.Assert(t, err == nil)
	tests.Assert(t, utils.SortedStringHas(cluster.Info.Nodes, node.Id))

	// Node delete the drives
	err = app.db.Update(func(tx *bolt.Tx) error {
		entry, err = NewNodeEntryFromId(tx, node.Id)
		if err != nil {
			return err
		}

		entry.DeviceDelete("123")
		entry.DeviceDelete("456")
		return entry.Save(tx)
	})
	tests.Assert(t, err == nil)

	// Now delete node
	req, err = http.NewRequest("DELETE", ts.URL+"/nodes/"+node.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)

	// Wait for deletion
	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)
			break
		}
	}

	// Check db to make sure key is removed
	err = app.db.View(func(tx *bolt.Tx) error {
		_, err = NewNodeEntryFromId(tx, node.Id)
		return err
	})
	tests.Assert(t, err == ErrNotFound)

	// Check the cluster does not have this node id
	r, err = http.Get(ts.URL + "/clusters/" + clusterinfo.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")

	err = utils.GetJsonFromResponse(r, &clusterinfo)
	tests.Assert(t, len(clusterinfo.Nodes) == 0)

	// It should have deregistered the node
	// We should be able to add it again
	r, err = http.Post(ts.URL+"/nodes", "application/json", bytes.NewBuffer(request))
	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)
		tests.Assert(t, r.StatusCode == http.StatusOK)
		if r.ContentLength <= 0 {
			time.Sleep(time.Millisecond * 10)
			continue
		} else {
			// Should have node information here
			tests.Assert(t, r.Header.Get("Content-Type") == "application/json; charset=UTF-8")
			err = utils.GetJsonFromResponse(r, &node)
			tests.Assert(t, err == nil)
			break
		}
	}
}
예제 #17
0
func TestClusterList(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()

	// Save some objects in the database
	numclusters := 5
	err := app.db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(BOLTDB_BUCKET_CLUSTER))
		if b == nil {
			return errors.New("Unable to open bucket")
		}

		for i := 0; i < numclusters; i++ {
			var entry ClusterEntry

			entry.Info.Id = fmt.Sprintf("%v", 5000+i)
			buffer, err := entry.Marshal()
			if err != nil {
				return err
			}

			err = b.Put([]byte(entry.Info.Id), buffer)
			if err != nil {
				return err
			}
		}

		return nil

	})
	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 + "/clusters")
	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 api.ClusterListResponse
	err = utils.GetJsonFromResponse(r, &msg)
	tests.Assert(t, err == nil)

	// Thanks to BoltDB they come back in order
	mockid := 5000 // This is the mock id value we set above
	for _, id := range msg.Clusters {
		tests.Assert(t, id == fmt.Sprintf("%v", mockid))
		mockid++
	}
}
예제 #18
0
func TestClusterInfo(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 a new ClusterInfo
	entry := NewClusterEntry()
	entry.Info.Id = "123"
	for _, node := range []string{"a1", "a2", "a3"} {
		entry.NodeAdd(node)
	}
	for _, vol := range []string{"b1", "b2", "b3"} {
		entry.VolumeAdd(vol)
	}

	// Save the info in the database
	err := app.db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(BOLTDB_BUCKET_CLUSTER))
		if b == nil {
			return errors.New("Unable to open bucket")
		}

		buffer, err := entry.Marshal()
		if err != nil {
			return err
		}

		err = b.Put([]byte(entry.Info.Id), buffer)
		if err != nil {
			return err
		}

		return nil

	})
	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 + "/clusters/" + "123")
	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 api.ClusterInfoResponse
	err = utils.GetJsonFromResponse(r, &msg)
	tests.Assert(t, err == nil)

	// Check values are equal
	tests.Assert(t, entry.Info.Id == msg.Id)
	tests.Assert(t, entry.Info.Volumes[0] == msg.Volumes[0])
	tests.Assert(t, entry.Info.Volumes[1] == msg.Volumes[1])
	tests.Assert(t, entry.Info.Volumes[2] == msg.Volumes[2])
	tests.Assert(t, entry.Info.Nodes[0] == msg.Nodes[0])
	tests.Assert(t, entry.Info.Nodes[1] == msg.Nodes[1])
	tests.Assert(t, entry.Info.Nodes[2] == msg.Nodes[2])
}