From d0456116f002e3d609fc52df0df86e4f4c7bd11e Mon Sep 17 00:00:00 2001 From: nkuacac Date: Tue, 20 Oct 2015 13:55:15 +0000 Subject: [PATCH 1/2] Fix context.Clone - interface clone should not return a spcial type object Signed-off-by: Rexxar Liang --- context/context.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/context/context.go b/context/context.go index 9893029..9fe1c3c 100644 --- a/context/context.go +++ b/context/context.go @@ -16,7 +16,7 @@ type Context interface { GetBool(k string) (bool, bool) MarshalJSON() ([]byte, error) UnmarshalJSON(b []byte) error - Clone() contextMap + Clone() Context } type contextMap map[string]interface{} @@ -85,7 +85,7 @@ func (c contextMap) UnmarshalJSON(b []byte) error { return json.Unmarshal(b, &m) } -func (c contextMap) Clone() contextMap { +func (c contextMap) Clone() Context { var clone = make(contextMap) for k, v := range c { clone[k] = v From d42622106cd3cdb76c0abb9b2b198d53d37c3463 Mon Sep 17 00:00:00 2001 From: nkuacac Date: Wed, 28 Oct 2015 11:20:36 +0000 Subject: [PATCH 2/2] cf workload can support multiple user - currently there is a limitation "cf workloads assume single already-logged-in-and-targetted user" in [Known Limitations / TODOs etc.] (https://github.com/cloudfoundry-incubator/pat/blob/master/README.md#known-limitations--todos-etc) - support setting multiple user info in configuration file - round robin set user when context clone - also add the test case for the feature Signed-off-by: zyw69542 --- context/context.go | 105 ++++++++++++++++++++++++++++------------ context/context_test.go | 27 +++++++++++ 2 files changed, 101 insertions(+), 31 deletions(-) diff --git a/context/context.go b/context/context.go index 9fe1c3c..a17ff8a 100644 --- a/context/context.go +++ b/context/context.go @@ -2,6 +2,7 @@ package context import ( "encoding/json" + "io/ioutil" "strconv" ) @@ -17,78 +18,120 @@ type Context interface { MarshalJSON() ([]byte, error) UnmarshalJSON(b []byte) error Clone() Context + SetUsers(userpath string) error } -type contextMap map[string]interface{} +type user []string +type contextMap struct { + c map[string]interface{} + users []user + index int +} func New() Context { - var c contextMap = make(contextMap) + var c = contextMap{ + c: make(map[string]interface{}), + users: []user{}, + index: 0, + } return &c } -func (c contextMap) PutString(k string, v string) { - c[k] = v +func (c *contextMap) PutString(k string, v string) { + c.c[k] = v } -func (c contextMap) GetString(k string) (string, bool) { - if c[k] == nil { +func (c *contextMap) GetString(k string) (string, bool) { + if c.c[k] == nil { return "", false } else { - return c[k].(string), true + return c.c[k].(string), true } } -func (c contextMap) PutInt(k string, v int) { +func (c *contextMap) PutInt(k string, v int) { // saves as string, avoids json.Marshal turning int into json.numbers(float64) - c[k] = strconv.Itoa(v) + c.c[k] = strconv.Itoa(v) } -func (c contextMap) GetInt(k string) (int, bool) { - if c[k] == nil { +func (c *contextMap) GetInt(k string) (int, bool) { + if c.c[k] == nil { return 0, false } else { - value, _ := strconv.ParseInt(c[k].(string), 0, 0) + value, _ := strconv.ParseInt(c.c[k].(string), 0, 0) return int(value), true } } -func (c contextMap) PutFloat64(k string, v float64) { - c[k] = v +func (c *contextMap) PutFloat64(k string, v float64) { + c.c[k] = v } -func (c contextMap) GetFloat64(k string) (float64, bool) { - if c[k] == nil { +func (c *contextMap) GetFloat64(k string) (float64, bool) { + if c.c[k] == nil { return 0, false } else { - return c[k].(float64), true + return c.c[k].(float64), true } } -func (c contextMap) PutBool(k string, v bool) { - c[k] = v +func (c *contextMap) PutBool(k string, v bool) { + c.c[k] = v } -func (c contextMap) GetBool(k string) (bool, bool) { - if c[k] == nil { +func (c *contextMap) GetBool(k string) (bool, bool) { + if c.c[k] == nil { return false, false } else { - return c[k].(bool), true + return c.c[k].(bool), true } } -func (c contextMap) MarshalJSON() ([]byte, error) { - return json.Marshal(map[string]interface{}(c)) +func (c *contextMap) MarshalJSON() ([]byte, error) { + return json.Marshal(map[string]interface{}(c.c)) } -func (c contextMap) UnmarshalJSON(b []byte) error { - var m map[string]interface{} = c +func (c *contextMap) UnmarshalJSON(b []byte) error { + var m map[string]interface{} = c.c return json.Unmarshal(b, &m) } -func (c contextMap) Clone() Context { - var clone = make(contextMap) - for k, v := range c { - clone[k] = v +func (c *contextMap) Clone() Context { + var clone = contextMap{ + c: make(map[string]interface{}), } - return clone + for k, v := range c.c { + clone.c[k] = v + } + + users := c.users + userslen := len(users) + if userslen > 0 { + curindex := c.index % userslen + clone.PutString("rest:username", users[curindex][0]) + clone.PutString("rest:password", users[curindex][1]) + c.index++ + } + return &clone +} + +func ParseUser(path string) ([]user, error) { + file, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + + var users []user + err = json.Unmarshal(file, &users) + if err != nil { + return nil, err + } + + return users, nil +} + +func (c *contextMap) SetUsers(userpath string) error { + users, err := ParseUser(userpath) + c.users = users + return err } diff --git a/context/context_test.go b/context/context_test.go index 13936c6..99f99ce 100644 --- a/context/context_test.go +++ b/context/context_test.go @@ -1,6 +1,8 @@ package context_test import ( + "io/ioutil" + "github.com/cloudfoundry-incubator/pat/context" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -76,4 +78,29 @@ var _ = Describe("Context map", func() { }) }) + Context("When multiusers is set", func() { + JustBeforeEach(func() { + ioutil.WriteFile("/tmp/users.json", []byte(`[["user1", "password1"], ["user2", "password2"]]`), 0755) + err := localContext.SetUsers("/tmp/users.json") + Ω(err).ShouldNot(HaveOccurred()) + + }) + Context("Cloning map many times", func() { + It("get user sequence and loop", func() { + cloned := localContext.Clone() + result, _ := cloned.GetString("rest:username") + Ω(result).Should(Equal("user1")) + + cloned = localContext.Clone() + result, _ = cloned.GetString("rest:username") + Ω(result).Should(Equal("user2")) + + cloned = localContext.Clone() + result, _ = cloned.GetString("rest:username") + Ω(result).Should(Equal("user1")) + + }) + }) + }) + })