Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

server/api/admin: change the tso parameter of ResetTS to string #1896

Merged
merged 6 commits into from Nov 7, 2019
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 8 additions & 3 deletions server/api/admin.go
Expand Up @@ -59,13 +59,18 @@ func (h *adminHandler) ResetTS(w http.ResponseWriter, r *http.Request) {
if err := apiutil.ReadJSONRespondError(h.rd, w, r.Body, &input); err != nil {
return
}
ts, ok := input["tso"].(float64)
if !ok || ts < 0 {
tsValue, ok := input["tso"].(string)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use uint64as the type?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no such thing in js spec. 😕

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering this: https://play.golang.org/p/8-COmwYna7T

I think it is supported in go.

Copy link
Contributor

@shafreeck shafreeck Nov 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it also works by defining var input map[string]uint64.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid of it does not work in other languages, eg, rust, as it's not specified in json spec.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@overvenus The language does not matter much, maybe the encoding library does. However, there should be no precision loss when encoding a number because that JSON is based on text not binary.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you encode a large number into JSON, it is just a sequence of digitals. IMO there is no reason for an encoding library to lose precision.

if !ok || len(tsValue) == 0 {
h.rd.JSON(w, http.StatusBadRequest, "invalid tso value")
return
}
ts, err := strconv.ParseUint(tsValue, 10, 64)
if err != nil {
h.rd.JSON(w, http.StatusBadRequest, "invalid tso value")
return
}

if err := handler.ResetTS(uint64(ts)); err != nil {
if err = handler.ResetTS(ts); err != nil {
if err == server.ErrServerNotStarted {
h.rd.JSON(w, http.StatusInternalServerError, err.Error())
} else {
Expand Down
21 changes: 13 additions & 8 deletions server/api/admin_test.go
Expand Up @@ -16,7 +16,6 @@ package api
import (
"encoding/json"
"fmt"
"math"
"net/http"
"strings"
"time"
Expand Down Expand Up @@ -92,9 +91,9 @@ type testTSOSuite struct {
urlPrefix string
}

func makeTS(offset time.Duration) int64 {
func makeTS(offset time.Duration) uint64 {
physical := time.Now().Add(offset).UnixNano() / int64(time.Millisecond)
return physical << 18
return uint64(physical << 18)
}

func (s *testTSOSuite) SetUpSuite(c *C) {
Expand All @@ -115,7 +114,7 @@ func (s *testTSOSuite) TestResetTS(c *C) {
args := make(map[string]interface{})
t1 := makeTS(time.Hour)
url := s.urlPrefix
args["tso"] = t1
args["tso"] = fmt.Sprintf("%d", t1)
values, err := json.Marshal(args)
c.Assert(err, IsNil)
err = postJSON(url, values,
Expand All @@ -126,7 +125,7 @@ func (s *testTSOSuite) TestResetTS(c *C) {

c.Assert(err, IsNil)
t2 := makeTS(32 * time.Hour)
args["tso"] = t2
args["tso"] = fmt.Sprintf("%d", t2)
values, err = json.Marshal(args)
c.Assert(err, IsNil)
err = postJSON(url, values,
Expand All @@ -135,21 +134,27 @@ func (s *testTSOSuite) TestResetTS(c *C) {
c.Assert(strings.Contains(err.Error(), "too large"), IsTrue)

t3 := makeTS(-2 * time.Hour)
args["tso"] = t3
args["tso"] = fmt.Sprintf("%d", t3)
values, err = json.Marshal(args)
c.Assert(err, IsNil)
err = postJSON(url, values,
func(_ []byte, code int) { c.Assert(code, Equals, http.StatusForbidden) })
c.Assert(err, NotNil)
c.Assert(strings.Contains(err.Error(), "small"), IsTrue)

t4 := math.MinInt64
args["tso"] = t4
args["tso"] = ""
5kbpers marked this conversation as resolved.
Show resolved Hide resolved
values, err = json.Marshal(args)
c.Assert(err, IsNil)
err = postJSON(url, values,
func(_ []byte, code int) { c.Assert(code, Equals, http.StatusBadRequest) })
c.Assert(err, NotNil)
c.Assert(err.Error(), Equals, "\"invalid tso value\"\n")

args["tso"] = "test"
values, err = json.Marshal(args)
c.Assert(err, IsNil)
err = postJSON(url, values,
func(_ []byte, code int) { c.Assert(code, Equals, http.StatusBadRequest) })
c.Assert(err, NotNil)
c.Assert(err.Error(), Equals, "\"invalid tso value\"\n")
}