Example #1
0
func register(t *testing.T, port uint16) []string {
	ids := make([]string, len(instances))

	url := fmt.Sprintf("http://localhost:%d%s", port, amalgam8.InstanceCreateURL())
	for index, inst := range instances {
		b, err := json.Marshal(inst)
		assert.NoError(t, err)

		req, err1 := http.NewRequest("POST", url, bytes.NewReader(b))
		assert.NoError(t, err1)
		assert.NotNil(t, req)

		req.Header.Set("Content-Type", "application/json")
		req.Header.Set("X-Forwarded-Proto", "https")

		res, err2 := http.DefaultClient.Do(req)
		assert.NoError(t, err2)
		assert.NotNil(t, res)
		assert.EqualValues(t, 201, res.StatusCode)

		data, err3 := ioutil.ReadAll(res.Body)
		assert.NoError(t, err3)
		res.Body.Close()

		var si amalgam8.ServiceInstance
		err = json.Unmarshal(data, &si)
		assert.NoError(t, err)
		ids[index] = si.ID
	}

	return ids
}
Example #2
0
// instances:methods
func TestInstancesMethodInvalid(t *testing.T) {
	const fake = "fakeid"
	var methods = []string{"CONNECT", "DELETE", "HEAD", "OPTIONS", "PATCH", "PUT", "TRACE"}
	var urls = []string{
		serverURL + amalgam8.InstanceCreateURL(),
		serverURL + amalgam8.InstanceURL(fake),
	}

	c := defaultServerConfig()
	handler, err := setupServer(c)
	assert.Nil(t, err)

	assert.Nil(t, err)
	for _, url := range urls {
		for _, method := range methods {
			if method == "DELETE" && url == serverURL+amalgam8.InstanceURL(fake) {
				continue // this is a valid combination
			}
			recorder := httptest.NewRecorder()
			req, err := http.NewRequest(method, url, nil)
			assert.Nil(t, err)
			handler.ServeHTTP(recorder, req)
			assert.Equal(t, http.StatusMethodNotAllowed, recorder.Code, method+":"+url)
		}
	}
}
Example #3
0
// instances:create
func TestInstancesCreate(t *testing.T) {
	invalidMetadata := json.RawMessage("{\"INVALID\":\"INVALID\"}")

	cases := []createTestCase{
		newCreateTestCase("", "192.168.1.1:8081", "tcp", "UP", 0, metadata, http.StatusBadRequest),                               // empty service name
		newCreateTestCase("http", "", "tcp", "UP", 0, metadata, http.StatusBadRequest),                                           // empty endpoint value
		newCreateTestCase("http", "192.168.1.1:8081", "", "UP", 0, metadata, http.StatusBadRequest),                              // empty endpoint type
		newCreateTestCase("http", "192.168.1.1:8082", "icmp", "UP", 30, metadata, http.StatusBadRequest),                         // invalid endpoint type
		newCreateTestCase("http", "192.168.1.1:8083", "tcp", "UP", 0, invalidMetadata, http.StatusBadRequest),                    // invalid metadata
		newCreateTestCase("http", "192.168.1.1:8084", "tcp", "UP", 0, []byte("1"), http.StatusCreated),                           // valid metadata - int
		newCreateTestCase("http", "192.168.1.1:8085", "tcp", "UP", 0, []byte("true"), http.StatusCreated),                        // valid metadata - bool
		newCreateTestCase("http", "192.168.1.1:8086", "tcp", "UP", 0, []byte("\"string\""), http.StatusCreated),                  // valid metadata - string
		newCreateTestCase("http", "192.168.1.1:8087", "tcp", "UP", 0, metadata, http.StatusCreated),                              // valid metadata - object
		newCreateTestCase("http", "192.168.1.1:8088", "tcp", "UP", 30, metadata, http.StatusCreated),                             // valid, duplicate
		newCreateTestCase("http", "192.168.1.1:8089", "tcp", "STARTING", 30, metadata, http.StatusCreated),                       // valid, STARTING status
		newCreateTestCase("http", "192.168.1.1:8090", "tcp", "OUT_OF_SERVICE", 30, metadata, http.StatusCreated),                 // valid, OUT_OF_SERVICE status
		newCreateTestCase("http", "192.168.1.1:8091", "tcp", "blah", 30, metadata, http.StatusBadRequest),                        // invalid status
		newCreateTestCaseWithTags("http", "192.168.1.1:8088", "tcp", "UP", 30, metadata, http.StatusCreated, []string{"a", "b"}), // valid, with tags
		newCreateTestCaseWithTags("http", "192.168.1.1:8088", "tcp", "UP", 30, metadata, http.StatusCreated, []string{}),         // valid, with empty tags
	}

	url := serverURL + amalgam8.InstanceCreateURL()
	c := defaultServerConfig()
	handler, err := setupServer(c)
	assert.Nil(t, err)

	for _, tc := range cases {
		recorder := httptest.NewRecorder()
		b, err := json.Marshal(&tc.instance)

		assert.NoError(t, err)

		if reflect.DeepEqual(tc.instance.Metadata, invalidMetadata) {
			b = tc.toByteswithFaultyMetadata()
		}

		req, err := http.NewRequest("POST", url, bytes.NewReader(b))

		assert.Nil(t, err)
		req.Header.Set("Content-Type", "application/json")
		handler.ServeHTTP(recorder, req)
		assert.Equal(t, tc.expected, recorder.Code, string(b), "\nResponse:", string(recorder.Body.Bytes()))
		if recorder.Code == http.StatusCreated { // verify links
			reply := &amalgam8.ServiceInstance{}

			err = json.Unmarshal(recorder.Body.Bytes(), &reply)
			assert.NoError(t, err)
			assert.Nil(t, reply.Endpoint)
			assert.NotNil(t, reply.Links)
			assert.NotEmpty(t, reply.TTL)
		}
	}
}
Example #4
0
func TestInstanceCreateMissingEndpoint(t *testing.T) {
	url := serverURL + amalgam8.InstanceCreateURL()
	c := defaultServerConfig()
	handler, err := setupServer(c)
	assert.Nil(t, err)

	var buggyReq = []byte(`{ "service_name": "service", "host": "whatnot.example.org", "port": 80, "ttl" : 25}`)
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(buggyReq))
	assert.Nil(t, err)

	recorder := httptest.NewRecorder()
	req.Header.Set("Content-Type", "application/json")
	handler.ServeHTTP(recorder, req)
	assert.Equal(t, http.StatusBadRequest, recorder.Code, string(buggyReq))
}
Example #5
0
func (client *client) Register(instance *ServiceInstance) (*ServiceInstance, error) {
	// Record a pessimistic last heartbeat time - Better safe than sorry!
	lastHeartbeat := time.Now()

	body, err := client.doRequest("POST", amalgam8.InstanceCreateURL(), instance, http.StatusCreated)
	if err != nil {
		return nil, err
	}

	m := make(map[string]interface{})
	err = json.Unmarshal(body, &m)
	if err != nil {
		return nil, newError(ErrorCodeInternalClientError, "error unmarshaling HTTP response body", err, "")
	}

	// TODO: recover type conversion panic
	registeredInstance := &*instance
	registeredInstance.ID = m["id"].(string)
	registeredInstance.TTL = int(m["ttl"].(float64))
	registeredInstance.LastHeartbeat = lastHeartbeat
	return registeredInstance, nil
}