Example #1
0
// pushStackHandler adds an element into a Stack and returns 200 and the element.
func (c *Conn) pushStackHandler(w http.ResponseWriter, r *http.Request, stack *pila.Stack) {
	if r.Body == nil {
		log.Println(r.Method, r.URL, http.StatusBadRequest,
			"no element provided")
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	var element pila.Element
	err := element.Decode(r.Body)
	if err != nil {
		log.Println(r.Method, r.URL, http.StatusBadRequest,
			"error on decoding element:", err)
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	stack.Push(element.Value)
	stack.Update(c.opDate)

	log.Println(r.Method, r.URL, http.StatusOK, element.Value)
	w.Header().Set("Content-Type", "application/json")

	// Do not check error as we consider our element
	// suitable for a JSON encoding.
	b, _ := element.ToJSON()
	w.Write(b)
}
Example #2
0
func TestPeekStackHandler(t *testing.T) {
	s := pila.NewStack("stack", time.Now().UTC())

	db := pila.NewDatabase("db")
	_ = db.AddStack(s)

	p := pila.NewPila()
	_ = p.AddDatabase(db)

	conn := NewConn()
	conn.Pila = p

	element := pila.Element{Value: "test-element"}
	expectedElementJSON, _ := element.ToJSON()

	s.Push(element.Value)

	request, err := http.NewRequest("GET",
		fmt.Sprintf("/databases/%s/stacks/%s?peek",
			db.ID.String(),
			s.ID.String()),
		nil)
	if err != nil {
		t.Fatal(err)
	}
	request.Header.Set("Content-Type", "application/json")

	response := httptest.NewRecorder()

	conn.peekStackHandler(response, request, s)

	if peekElement := db.Stacks[s.ID].Peek(); peekElement != element.Value {
		t.Errorf("peek element is %v, expected %v", peekElement, element.Value)
	}

	if contentType := response.Header().Get("Content-Type"); contentType != "application/json" {
		t.Errorf("Content-Type is %v, expected %v", contentType, "application/json")
	}

	if response.Code != http.StatusOK {
		t.Errorf("response code is %v, expected %v", response.Code, http.StatusOK)
	}

	elementJSON, err := ioutil.ReadAll(response.Body)
	if err != nil {
		t.Fatal(err)
	}

	if string(elementJSON) != string(expectedElementJSON) {
		t.Errorf("peek element is %v, expected %v", string(elementJSON), string(expectedElementJSON))
	}
}
Example #3
0
// peekStackHandler returns the peek of the Stack without modifying it.
func (c *Conn) peekStackHandler(w http.ResponseWriter, r *http.Request, stack *pila.Stack) {
	var element pila.Element
	element.Value = stack.Peek()
	stack.Read(c.opDate)

	log.Println(r.Method, r.URL, http.StatusOK, element.Value)
	w.Header().Set("Content-Type", "application/json")

	// Do not check error as we consider our element
	// suitable for a JSON encoding.
	b, _ := element.ToJSON()
	w.Write(b)
}
Example #4
0
// popStackHandler extracts the peek element of a Stack, returns 200 and returns it.
func (c *Conn) popStackHandler(w http.ResponseWriter, r *http.Request, stack *pila.Stack) {
	value, ok := stack.Pop()
	if !ok {
		log.Println(r.Method, r.URL, http.StatusNoContent)
		w.WriteHeader(http.StatusNoContent)
		return
	}
	stack.Update(c.opDate)

	element := pila.Element{Value: value}

	log.Println(r.Method, r.URL, http.StatusOK, element.Value)
	w.Header().Set("Content-Type", "application/json")

	// Do not check error as we consider our element
	// suitable for a JSON encoding.
	b, _ := element.ToJSON()
	w.Write(b)
}
Example #5
0
// configKeyHandler handles a config value.
func (c *Conn) configKeyHandler(configKey string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		vars := mux.Vars(r)

		// we override the mux vars to be able to test
		// an arbitrary configKey
		if configKey != "" {
			vars = map[string]string{
				"key": configKey,
			}
		}
		value := c.Config.Get(vars["key"])
		if value == nil {
			c.goneHandler(w, r, fmt.Sprintf("%s is not set", vars["key"]))
			return
		}

		var element pila.Element
		if r.Method == "GET" {
			value := c.Config.Get(vars["key"])
			element.Value = value
		}
		if r.Method == "POST" {
			if r.Body == nil {
				log.Println(r.Method, r.URL, http.StatusBadRequest,
					"no element provided")
				w.WriteHeader(http.StatusBadRequest)
				return
			}
			err := element.Decode(r.Body)
			if err != nil {
				log.Println(r.Method, r.URL, http.StatusBadRequest,
					"error on decoding element:", err)
				w.WriteHeader(http.StatusBadRequest)
				return
			}

			c.Config.Set(vars["key"], element.Value)
		}

		log.Println(r.Method, r.URL, http.StatusOK, element.Value)
		w.Header().Set("Content-Type", "application/json")

		b, err := element.ToJSON()
		if err != nil {
			log.Println(r.Method, r.URL, http.StatusBadRequest,
				"error on decoding element:", err)
			w.WriteHeader(http.StatusBadRequest)
			return
		}
		w.Write(b)
	})
}
Example #6
0
func TestStackHandler_DELETE(t *testing.T) {
	element := pila.Element{Value: "test-element"}
	expectedElementJSON, _ := element.ToJSON()

	s := pila.NewStack("stack", time.Now().UTC())

	db := pila.NewDatabase("db")
	_ = db.AddStack(s)

	p := pila.NewPila()
	_ = p.AddDatabase(db)

	conn := NewConn()
	conn.Pila = p

	s.Push(element.Value)

	inputOutput := []struct {
		input struct {
			database, stack, op string
		}
		output struct {
			response []byte
			code     int
		}
	}{
		{struct {
			database, stack, op string
		}{db.ID.String(), s.ID.String(), ""},
			struct {
				response []byte
				code     int
			}{expectedElementJSON, http.StatusOK},
		},
		{struct {
			database, stack, op string
		}{db.Name, s.Name, ""},
			struct {
				response []byte
				code     int
			}{expectedElementJSON, http.StatusOK},
		},
		{struct {
			database, stack, op string
		}{db.Name, s.Name, "flush"},
			struct {
				response []byte
				code     int
			}{nil, http.StatusOK},
		},
		{struct {
			database, stack, op string
		}{db.Name, s.Name, "full"},
			struct {
				response []byte
				code     int
			}{nil, http.StatusNoContent},
		},
	}

	for _, io := range inputOutput {
		request, err := http.NewRequest("DELETE",
			fmt.Sprintf("/databases/%s/stacks/%s?%s",
				io.input.database,
				io.input.stack,
				io.input.op),
			nil)
		if err != nil {
			t.Fatal(err)
		}

		response := httptest.NewRecorder()

		params := map[string]string{
			"database_id": io.input.database,
			"stack_id":    io.input.stack,
		}

		stackHandle := conn.stackHandler(&params)
		stackHandle.ServeHTTP(response, request)

		if response.Code != io.output.code {
			t.Errorf("on op %s response code is %v, expected %v", io.input.op, response.Code, io.output.code)
		}

		responseJSON, err := ioutil.ReadAll(response.Body)
		if err != nil {
			t.Fatal(err)
		}

		if io.input.op == "flush" {
			s.Update(conn.opDate)
			stackStatus := s.Status()

			expectedStackStatusJSON, err := stackStatus.ToJSON()
			if err != nil {
				t.Fatal(err)
			}
			if string(responseJSON) != string(expectedStackStatusJSON) {
				t.Errorf("on op %s response is %s, expected %s", io.input.op, string(responseJSON), string(expectedStackStatusJSON))
			}
		} else if string(responseJSON) != string(io.output.response) {
			t.Errorf("on op %s response is %s, expected %s", io.input.op, string(responseJSON), string(io.output.response))
		}

		if io.input.op == "full" {
			if s := db.Stacks[uuid.UUID(io.input.stack)]; s != nil {
				t.Errorf("db contains %v, expected not to", io.input.stack)
			}
		} else {
			if peek, ok := db.Stacks[s.ID].Pop(); ok {
				t.Errorf("stack contains %v, expected to be empty", peek)
			}

			if contentType := response.Header().Get("Content-Type"); contentType != "application/json" {
				t.Errorf("Content-Type is %v, expected %v", contentType, "application/json")
			}

			// restore element for next table test iteration
			s.Push(element.Value)
		}
	}
}
Example #7
0
func TestStackHandler_POST(t *testing.T) {
	s := pila.NewStack("stack", time.Now().UTC())

	db := pila.NewDatabase("db")
	_ = db.AddStack(s)

	p := pila.NewPila()
	_ = p.AddDatabase(db)

	conn := NewConn()
	conn.Pila = p
	conn.opDate = time.Now().UTC()

	element := pila.Element{Value: "test-element"}
	expectedElementJSON, _ := element.ToJSON()

	paramss := []map[string]string{
		{
			"database_id": db.ID.String(),
			"stack_id":    s.ID.String(),
		},
		{
			"database_id": db.Name,
			"stack_id":    s.Name,
		},
	}

	for _, params := range paramss {
		request, err := http.NewRequest("POST",
			fmt.Sprintf("/databases/%s/stacks/%s",
				params["database_id"],
				params["stack_id"]),
			bytes.NewBuffer(expectedElementJSON))
		if err != nil {
			t.Fatal(err)
		}
		request.Header.Set("Content-Type", "application/json")

		response := httptest.NewRecorder()

		stackHandle := conn.stackHandler(&params)
		stackHandle.ServeHTTP(response, request)

		if contentType := response.Header().Get("Content-Type"); contentType != "application/json" {
			t.Errorf("Content-Type is %v, expected %v", contentType, "application/json")
		}

		if response.Code != http.StatusOK {
			t.Errorf("response code is %v, expected %v", response.Code, http.StatusOK)
		}

		elementJSON, err := ioutil.ReadAll(response.Body)
		if err != nil {
			t.Fatal(err)
		}

		if string(elementJSON) != string(expectedElementJSON) {
			t.Errorf("pushed element is %v, expected %v", string(elementJSON), string(expectedElementJSON))
		}
	}
}
Example #8
0
func TestStackHandler_GET(t *testing.T) {
	element := pila.Element{Value: "test-element"}
	expectedElementJSON, _ := element.ToJSON()

	createDate := time.Now().UTC()
	s := pila.NewStack("stack", createDate)
	s.Update(createDate)

	db := pila.NewDatabase("db")
	_ = db.AddStack(s)

	p := pila.NewPila()
	_ = p.AddDatabase(db)

	conn := NewConn()
	conn.Pila = p
	conn.opDate = time.Now().UTC()

	s.Push(element.Value)

	expectedStackStatusJSON, err := s.Status().ToJSON()
	if err != nil {
		t.Fatal(err)
	}

	expectedSizeJSON := s.SizeToJSON()

	inputOutput := []struct {
		input struct {
			database, stack, op string
		}
		output struct {
			response []byte
			code     int
		}
	}{
		{struct {
			database, stack, op string
		}{db.ID.String(), s.ID.String(), ""},
			struct {
				response []byte
				code     int
			}{expectedStackStatusJSON, http.StatusOK},
		},
		{struct {
			database, stack, op string
		}{db.ID.String(), s.ID.String(), "peek"},
			struct {
				response []byte
				code     int
			}{expectedElementJSON, http.StatusOK},
		},
		{struct {
			database, stack, op string
		}{db.ID.String(), s.ID.String(), "size"},
			struct {
				response []byte
				code     int
			}{expectedSizeJSON, http.StatusOK},
		},
	}

	for _, io := range inputOutput {
		request, err := http.NewRequest("GET",
			fmt.Sprintf("/databases/%s/stacks/%s?%s",
				io.input.database,
				io.input.stack,
				io.input.op),
			nil)
		if err != nil {
			t.Fatal(err)
		}

		response := httptest.NewRecorder()

		params := map[string]string{
			"database_id": io.input.database,
			"stack_id":    io.input.stack,
		}

		stackHandle := conn.stackHandler(&params)
		stackHandle.ServeHTTP(response, request)

		if peek := db.Stacks[s.ID].Peek(); peek != element.Value {
			t.Errorf("peek is %v, expected %v", peek, element.Value)
		}

		if contentType := response.Header().Get("Content-Type"); contentType != "application/json" {
			t.Errorf("Content-Type is %v, expected %v", contentType, "application/json")
		}

		if response.Code != io.output.code {
			t.Errorf("on %s response code is %v, expected %v", io.input.op, response.Code, io.output.code)
		}

		responseJSON, err := ioutil.ReadAll(response.Body)
		if err != nil {
			t.Fatal(err)
		}

		if io.input.op == "" {
			expectedStackStatusJSON, err := s.Status().ToJSON()
			if err != nil {
				t.Fatal(err)
			} else if string(responseJSON) != string(expectedStackStatusJSON) {
				t.Errorf("on %s response is %s, expected %s", io.input.op, string(responseJSON), string(expectedStackStatusJSON))
			}

		} else if string(responseJSON) != string(io.output.response) {
			t.Errorf("on %s response is %s, expected %s", io.input.op, string(responseJSON), string(io.output.response))
		}
	}
}
Example #9
0
func TestPopStackHandler(t *testing.T) {
	element := pila.Element{Value: "test-element"}
	expectedElementJSON, _ := element.ToJSON()

	s := pila.NewStack("stack", time.Now().UTC())
	s.Push(element.Value)

	db := pila.NewDatabase("db")
	_ = db.AddStack(s)

	p := pila.NewPila()
	_ = p.AddDatabase(db)

	conn := NewConn()
	conn.Pila = p

	varss := []map[string]string{
		{
			"database_id": db.ID.String(),
			"stack_id":    s.ID.String(),
		},
		{
			"database_id": db.Name,
			"stack_id":    s.Name,
		},
	}

	for _, vars := range varss {
		request, err := http.NewRequest("DELETE",
			fmt.Sprintf("/databases/%s/stacks/%s",
				vars["database_id"],
				vars["stack_id"]),
			nil)
		if err != nil {
			t.Fatal(err)
		}

		response := httptest.NewRecorder()

		conn.popStackHandler(response, request, s)

		if peek, ok := db.Stacks[s.ID].Pop(); ok {
			t.Errorf("stack contains %v, expected to be empty", peek)
		}

		if contentType := response.Header().Get("Content-Type"); contentType != "application/json" {
			t.Errorf("Content-Type is %v, expected %v", contentType, "application/json")
		}

		if response.Code != http.StatusOK {
			t.Errorf("response code is %v, expected %v", response.Code, http.StatusOK)
		}

		elementJSON, err := ioutil.ReadAll(response.Body)
		if err != nil {
			t.Fatal(err)
		}

		if string(elementJSON) != string(expectedElementJSON) {
			t.Errorf("popped element is %s, expected %s", string(elementJSON), string(expectedElementJSON))
		}

		// restore element for next table test iteration
		s.Push(element.Value)
	}
}
Example #10
0
func TestConfigKeyHandler(t *testing.T) {
	conn := NewConn()
	conn.Config = config.NewConfig()
	conn.Config.Set(vars.MaxStackSize, 2)

	element := pila.Element{Value: 2}
	expectedElementJSON, _ := element.ToJSON()

	newElement := pila.Element{Value: 10}
	expectedNewElementJSON, _ := newElement.ToJSON()

	inputOutput := []struct {
		input struct {
			method, key string
			payload     io.Reader
		}
		output struct {
			value    interface{}
			response []byte
		}
	}{
		{struct {
			method, key string
			payload     io.Reader
		}{"GET", vars.MaxStackSize, nil},
			struct {
				value    interface{}
				response []byte
			}{2, expectedElementJSON},
		},
		{struct {
			method, key string
			payload     io.Reader
		}{"POST", vars.MaxStackSize, bytes.NewBuffer(expectedNewElementJSON)},
			struct {
				value    interface{}
				response []byte
			}{10, expectedNewElementJSON},
		},
	}

	for _, io := range inputOutput {
		request, err := http.NewRequest(io.input.method,
			fmt.Sprintf("/_config/%s", io.input.key),
			io.input.payload)
		if err != nil {
			t.Fatal(err)
		}

		response := httptest.NewRecorder()

		configKeyHandle := conn.configKeyHandler(io.input.key)
		configKeyHandle.ServeHTTP(response, request)

		if value := conn.Config.MaxStackSize(); value != io.output.value {
			t.Errorf("value is %d, expected %d", value, io.output.value)
		}

		if contentType := response.Header().Get("Content-Type"); contentType != "application/json" {
			t.Errorf("Content-Type is %v, expected %v", contentType, "application/json")
		}

		if response.Code != http.StatusOK {
			t.Errorf("response code is %v, expected %v", response.Code, http.StatusOK)
		}

		responseJSON, err := ioutil.ReadAll(response.Body)
		if err != nil {
			t.Fatal(err)
		}

		if string(responseJSON) != string(io.output.response) {
			t.Errorf("response is %s, expected %s", string(responseJSON), string(io.output.response))
		}
	}
}