示例#1
0
func (s *ServerSuite) TestStartHandleStop() {
	// Start
	taskHandler := func(a *acomm.Request) (interface{}, *url.URL, error) {
		return nil, nil, nil
	}
	s.server.RegisterTask("foobar", taskHandler)

	if !s.NoError(s.server.Start(), "failed to start server") {
		return
	}
	time.Sleep(time.Second)

	// Stop
	defer s.server.Stop()

	// Handle request
	tracker := s.server.Tracker()
	handled := make(chan struct{})
	respHandler := func(req *acomm.Request, resp *acomm.Response) {
		close(handled)
	}
	req, _ := acomm.NewRequest("foobar", tracker.URL().String(), struct{}{}, respHandler, respHandler)
	providerSocket, _ := url.ParseRequestURI("unix://" + s.server.TaskSocketPath("foobar"))
	if !s.NoError(s.server.Tracker().TrackRequest(req, 5*time.Second)) {
		return
	}
	if !s.NoError(acomm.Send(providerSocket, req)) {
		return
	}
	<-handled
}
示例#2
0
func (s *RequestTestSuite) TestNewRequest() {
	task := "foobar"
	args := map[string]string{
		"foo": "bar",
	}

	sh, eh, _ := generateHandlers()

	tests := []struct {
		description  string
		task         string
		responseHook string
		args         interface{}
		sh           acomm.ResponseHandler
		eh           acomm.ResponseHandler
		expectedErr  bool
	}{
		{"missing response hook", task, "", args, sh, eh, true},
		{"invalid response hook", task, "asdf", args, sh, eh, true},
		{"missing args", task, "unix://asdf", nil, sh, eh, false},
		{"unix hook and args", task, "unix://asdf", args, sh, eh, false},
		{"http hook and args", task, "http://asdf", args, sh, eh, false},
		{"https hook and args", task, "https://asdf", args, sh, eh, false},
		{"unix hook, args, no handlers", task, "unix://asdf", args, nil, nil, false},
		{"unix hook, args, sh handler", task, "unix://asdf", args, sh, nil, false},
		{"unix hook, args, eh handler", task, "unix://asdf", args, nil, eh, false},
		{"missing task ", "", "unix://asdf", args, sh, eh, true},
	}

	for _, test := range tests {
		msg := testMsgFunc(test.description)
		req, err := acomm.NewRequest(test.task, test.responseHook, test.args, test.sh, test.eh)
		if test.expectedErr {
			s.Error(err, msg("should have failed"))
			s.Nil(req, msg("should not have returned a request"))
		} else {
			if !s.NoError(err, msg("should have succeeded")) {
				s.T().Log(msg(err.Error()))
				continue
			}
			if !s.NotNil(req, msg("should have returned a request")) {
				continue
			}

			s.NotEmpty(req.ID, msg("should have set an ID"))
			s.Equal(test.task, req.Task, msg("should have set the task"))
			s.Equal(test.responseHook, req.ResponseHook.String(), msg("should have set the response hook"))
			var args map[string]string
			s.NoError(req.UnmarshalArgs(&args))
			if test.args == nil {
				s.Nil(args, msg("should have nil arguments"))
			} else {
				s.Equal(test.args, args, msg("should have set the arguments"))
			}
			s.Equal(reflect.ValueOf(test.sh).Pointer(), reflect.ValueOf(req.SuccessHandler).Pointer(), msg("should have set success handler"))
			s.Equal(reflect.ValueOf(test.eh).Pointer(), reflect.ValueOf(req.ErrorHandler).Pointer(), msg("should have set error handler"))
		}
	}
}
示例#3
0
func (s *TrackerTestSuite) SetupTest() {
	var err error

	s.Request, err = acomm.NewRequest("foobar", s.RespServer.URL, nil, nil, nil)
	s.Require().NoError(err, "request should be valid")

	streamAddr, _ := url.ParseRequestURI(s.StreamServer.URL)
	s.Tracker, err = acomm.NewTracker("", streamAddr, 0)
	s.Require().NoError(err, "failed to create new Tracker")
	s.Require().NotNil(s.Tracker, "failed to create new Tracker")
}
示例#4
0
func (s *RequestTestSuite) TestHandleResponse() {
	sh, eh, handled := generateHandlers()
	respErr := errors.New("foobar")

	tests := []struct {
		description string
		sh          acomm.ResponseHandler
		eh          acomm.ResponseHandler
		respResult  interface{}
		respErr     error
	}{
		{"sh handler, err resp", sh, nil, nil, respErr},
		{"sh handler, success resp", sh, nil, struct{}{}, nil},
		{"eh handler, err resp", nil, eh, nil, respErr},
		{"eh handler, success resp", nil, eh, struct{}{}, nil},
		{"both handlers, err resp", sh, eh, nil, respErr},
		{"both handlers, success resp", sh, eh, struct{}{}, nil},
	}

	for _, test := range tests {
		handled["success"] = 0
		handled["error"] = 0
		msg := testMsgFunc(test.description)
		req, err := acomm.NewRequest("foobar", "unix://foo", struct{}{}, test.sh, test.eh)
		if !s.NoError(err, msg("should not fail to build req")) {
			continue
		}
		resp, err := acomm.NewResponse(req, test.respResult, nil, test.respErr)
		if !s.NoError(err, msg("should not fail to build resp")) {
			continue
		}

		req.HandleResponse(resp)
		if test.respErr != nil {
			s.Equal(0, handled["success"], msg("should not have called success handler"))
			if test.eh != nil {
				s.Equal(1, handled["error"], msg("should have called error handler"))
			} else {
				s.Equal(0, handled["error"], msg("should not have called error handler"))
			}
		} else {
			if test.sh != nil {
				s.Equal(1, handled["success"], msg("should have called success handler"))
			} else {
				s.Equal(0, handled["success"], msg("should not have called success handler"))
			}
			s.Equal(0, handled["error"], msg("should not have called error handler"))
		}
	}
}
示例#5
0
func makeRequest(coordinator, taskName, responseAddr string, taskArgs map[string]interface{}) error {
	coordinatorURL, err := url.ParseRequestURI(coordinator)
	if err != nil {
		return errors.New("invalid coordinator url")
	}

	responseHook := fmt.Sprintf("http://%s/", responseAddr)
	req, err := acomm.NewRequest(taskName, responseHook, taskArgs, nil, nil)
	if err != nil {
		return err
	}

	return acomm.Send(coordinatorURL, req)
}
示例#6
0
func (s *ResponseTestSuite) TestNewResponse() {
	result := map[string]string{
		"foo": "bar",
	}

	request, _ := acomm.NewRequest("foobar", "unix://foo", nil, nil, nil)
	respErr := errors.New("foobar")

	tests := []struct {
		description string
		request     *acomm.Request
		result      interface{}
		err         error
		expectedErr bool
	}{
		{"missing request", nil, result, nil, true},
		{"missing result and error", request, nil, nil, false},
		{"result and error", request, result, respErr, true},
		{"result only", request, result, nil, false},
		{"error only", request, nil, respErr, false},
	}

	for _, test := range tests {
		msg := testMsgFunc(test.description)
		resp, err := acomm.NewResponse(test.request, test.result, nil, test.err)
		if test.expectedErr {
			s.Error(err, msg("should have failed"))
			s.Nil(resp, msg("should not have returned a response"))
		} else {
			if !s.NoError(err, msg("should have succeeded")) {
				s.T().Log(msg(err.Error()))
				continue
			}
			if !s.NotNil(resp, msg("should have returned a response")) {
				continue
			}
			s.Equal(test.request.ID, resp.ID, msg("should have set an ID"))
			var result map[string]string
			s.NoError(resp.UnmarshalResult(&result))
			if test.result == nil {
				s.Nil(result, msg("should have nil result"))
			} else {
				s.Equal(test.result, result, msg("should have set the result"))
			}
			s.Equal(test.err, resp.Error, msg("should have set the error"))
		}
	}
}
示例#7
0
func (s *TrackerTestSuite) TestProxyUnix() {
	unixReq, err := s.Tracker.ProxyUnix(s.Request, 0)
	s.Error(err, "should fail to proxy when tracker is not listening")
	s.Nil(unixReq, "should not return a request")

	if !s.NoError(s.Tracker.Start(), "listner should start") {
		return
	}

	unixReq, err = s.Tracker.ProxyUnix(s.Request, 0)
	s.NoError(err, "should not fail proxying when tracker is listening")
	s.NotNil(unixReq, "should return a request")
	s.Equal(s.Request.ID, unixReq.ID, "new request should share ID with original")
	s.Equal("unix", unixReq.ResponseHook.Scheme, "new request should have a unix response hook")
	s.Equal(1, s.Tracker.NumRequests(), "should have tracked the new request")
	resp, err := acomm.NewResponse(unixReq, struct{}{}, nil, nil)
	if !s.NoError(err, "new response should not error") {
		return
	}
	if !s.NoError(acomm.Send(unixReq.ResponseHook, resp), "response send should not error") {
		return
	}

	lastResp := s.NextResp()
	if !s.NotNil(lastResp, "response should have been proxied to original http response hook") {
		return
	}
	s.Equal(resp.ID, lastResp.ID, "response should have been proxied to original http response hook")
	s.Equal(0, s.Tracker.NumRequests(), "should have removed the request from tracking")

	// Should not proxy a request already using unix response hook
	origUnixReq, err := acomm.NewRequest("foobar", "unix://foo", struct{}{}, nil, nil)
	if !s.NoError(err, "new request shoudl not error") {
		return
	}
	unixReq, err = s.Tracker.ProxyUnix(origUnixReq, 0)
	s.NoError(err, "should not error with unix response hook")
	s.Equal(origUnixReq, unixReq, "should not proxy unix response hook")
	s.Equal(0, s.Tracker.NumRequests(), "should not response an unproxied request")
}
示例#8
0
// SystemStatus is a task handler to retrieve info look up and return system
// information. It depends on and makes requests for several other tasks.
func (s *Simple) SystemStatus(req *acomm.Request) (interface{}, *url.URL, error) {
	var args SystemStatusArgs
	if err := req.UnmarshalArgs(&args); err != nil {
		return nil, nil, err
	}
	if args.GuestID == "" {
		return nil, nil, errors.New("missing guest_id")
	}

	// Prepare multiple requests
	multiRequest := acomm.NewMultiRequest(s.tracker, 0)

	cpuReq, err := acomm.NewRequest("CPUInfo", s.tracker.URL().String(), &CPUInfoArgs{GuestID: args.GuestID}, nil, nil)
	if err != nil {
		return nil, nil, err
	}
	diskReq, err := acomm.NewRequest("DiskInfo", s.tracker.URL().String(), &DiskInfoArgs{GuestID: args.GuestID}, nil, nil)
	if err != nil {
		return nil, nil, err
	}

	requests := map[string]*acomm.Request{
		"CPUInfo":  cpuReq,
		"DiskInfo": diskReq,
	}

	for name, req := range requests {
		if err := multiRequest.AddRequest(name, req); err != nil {
			continue
		}
		if err := acomm.Send(s.config.CoordinatorURL(), req); err != nil {
			multiRequest.RemoveRequest(req)
			continue
		}
	}

	// Wait for the results
	responses := multiRequest.Responses()
	result := &SystemStatusResult{}

	if resp, ok := responses["CPUInfo"]; ok {
		if err := resp.UnmarshalResult(&(result.CPUs)); err != nil {
			log.WithFields(log.Fields{
				"name":  "CPUInfo",
				"resp":  resp,
				"error": err,
			}).Error("failed to unarshal result")
		}
	}

	if resp, ok := responses["DiskInfo"]; ok {
		if err := resp.UnmarshalResult(&(result.Disks)); err != nil {
			log.WithFields(log.Fields{
				"name":  "DiskInfo",
				"resp":  resp,
				"error": err,
			}).Error("failed to unarshal result")
		}
	}

	return result, nil, nil
}
示例#9
0
func (s *ServerSuite) TestReqRespHandle() {
	// Start
	if !s.NoError(s.server.Start(), "failed to start server") {
		return
	}
	time.Sleep(time.Second)
	// Stop
	defer s.server.Stop()

	// Set up handlers
	result := make(chan *params, 10)

	// Task handler
	taskName := "foobar"
	taskListener := s.createTaskListener(taskName, result)
	if taskListener == nil {
		return
	}
	defer taskListener.Stop(0)

	// Response handlers
	responseServer, responseListener := s.createResponseHandlers(result)
	if responseServer != nil {
		defer responseServer.Close()
	}
	if responseListener != nil {
		defer responseListener.Stop(0)
	}
	if responseServer == nil || responseListener == nil {
		return
	}

	// Coordinator URLs
	internalURL, _ := url.ParseRequestURI("unix://" + filepath.Join(
		s.config.SocketDir(),
		"coordinator",
		s.config.ServiceName()+".sock"),
	)
	externalURL, _ := url.ParseRequestURI(fmt.Sprintf(
		"http://localhost:%v",
		s.configData.ExternalPort),
	)

	// Test cases
	tests := []struct {
		description  string
		taskName     string
		internal     bool
		params       *params
		expectFailed bool
	}{
		{"valid http", taskName, false, &params{uuid.New()}, false},
		{"valid unix", taskName, true, &params{uuid.New()}, false},
		{"bad task http", "asdf", false, &params{uuid.New()}, true},
		{"bad task unix", "asdf", true, &params{uuid.New()}, true},
	}

	for _, test := range tests {
		msg := testMsgFunc(test.description)
		hookURL := responseServer.URL
		coordinatorURL := externalURL
		if test.internal {
			hookURL = responseListener.URL().String()
			coordinatorURL = internalURL
		}

		req, _ := acomm.NewRequest(test.taskName, hookURL, test.params, nil, nil)
		if err := acomm.Send(coordinatorURL, req); err != nil {
			result <- nil
		}

		respData := <-result
		if test.expectFailed {
			s.Nil(respData, msg("should have failed"))
		} else {
			s.Equal(test.params, respData, msg("should have gotten the correct response data"))
		}

		drainChan(result)
	}
}