Example #1
0
// createStackHandler handles the creation of a stack, given a database
// by its id and the time of creation. Returns the status of the new stack.
func (c *Conn) createStackHandler(w http.ResponseWriter, r *http.Request, databaseID string) {
	name := r.FormValue("name")
	if name == "" {
		log.Println(r.Method, r.URL, http.StatusBadRequest, "missing name")
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	db, ok := c.Pila.Database(uuid.UUID(databaseID))
	if !ok {
		c.goneHandler(w, r, fmt.Sprintf("database %s is Gone", databaseID))
		return
	}

	stack := pila.NewStack(name, c.opDate)
	err := db.AddStack(stack)
	if err != nil {
		log.Println(r.Method, r.URL, http.StatusConflict, err)
		w.WriteHeader(http.StatusConflict)
		return
	}
	stack.Update(c.opDate)

	// Do not check error as the Status of a new stack does
	// not contain types that could cause such case.
	// See http://golang.org/src/encoding/json/encode.go?s=5438:5481#L125
	res, _ := stack.Status().ToJSON()

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusCreated)
	w.Write(res)
	log.Println(r.Method, r.URL, http.StatusCreated)
}
Example #2
0
// ResourceStack will return the right Stack resource
// given a Database and a Stack ID or Name.
func ResourceStack(db *pila.Database, stackInput string) (*pila.Stack, bool) {
	stack, ok := db.Stacks[uuid.UUID(stackInput)]
	if !ok {
		// Fallback to find by stack name
		stack, ok = db.Stacks[uuid.New(db.Name+stackInput)]
	}

	return stack, ok
}
Example #3
0
// ResourceDatabase will return the right Database resource
// given a Conn and a database ID or Name.
func ResourceDatabase(conn *Conn, databaseInput string) (*pila.Database, bool) {
	db, ok := conn.Pila.Database(uuid.UUID(databaseInput))
	if !ok {
		// Fallback to find by database name
		db, ok = conn.Pila.Database(uuid.New(databaseInput))
	}

	return db, ok
}
Example #4
0
func TestDeleteStackHandler(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

	s.Push("one")

	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?full",
				vars["database_id"],
				vars["stack_id"]),
			nil)
		if err != nil {
			t.Fatal(err)
		}

		response := httptest.NewRecorder()

		conn.deleteStackHandler(response, request, db, s)

		if expectedStack := db.Stacks[uuid.UUID(vars["stack_id"])]; expectedStack != nil {
			t.Errorf("db contains %v, expected not to", vars["stack_id"])
		}

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

		// restore elements for next table test iteration
		s = pila.NewStack("stack", time.Now().UTC())
		_ = db.AddStack(s)
		s.Push("one")
	}
}
Example #5
0
func TestDatabaseHandler_Gone(t *testing.T) {
	conn := NewConn()

	request, err := http.NewRequest("GET",
		fmt.Sprintf("/databases/%s",
			"nodb"),
		nil)
	if err != nil {
		t.Fatal(err)
	}

	response := httptest.NewRecorder()

	databaseHandle := conn.databaseHandler(uuid.UUID("nodb").String())
	databaseHandle.ServeHTTP(response, request)

	if response.Code != http.StatusGone {
		t.Errorf("response code is %v, expected %v", response.Code, http.StatusGone)
	}
}
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)
		}
	}
}