Bläddra i källkod

session test case update

master
Patrick Peng Sun 8 år sedan
förälder
incheckning
5e2326c94d
2 ändrade filer med 48 tillägg och 58 borttagningar
  1. +39
    -55
      chatSession.go
  2. +9
    -3
      chatSession_test.go

+ 39
- 55
chatSession.go Visa fil

"time" "time"
) )


//a Procedure is a alphanumerical string lessthan 128 bytes.

//when messages comes in we need to differentiate what Procedure is this in.
//default Procedure is where command can happen

//where the Procedure is stored,
// in sessions/openID.json

//if there is no such file, we are in default Procedure.

//First Procedure is to record user's name, email, and phone number.
// for individual Procedure
// Procedure/Procedurename/openID.json

//openSession is the biggest description for a user's openID
// | it contains a name called procedure, whose data is stored elsewhere
// |
// +-- a Procedure name is a alphanumerical string lessthan 128 bytes.
// |
// +--- state is part of procedure, a procedure consists of sequence of states

//where to find session data
var sessionDir = "sessions" var sessionDir = "sessions"


//where to find the procedure state information //where to find the procedure state information
var ProcedureDir = "procedure"
var procedureDir = "procedure"


//openIDSessionData openID user's session //openIDSessionData openID user's session
type openIDSessionData struct { type openIDSessionData struct {
OpenID string `json:"OpenID"` //who's session this is belongs to
Procedure string `json:"Procedure"` //name of the current current process, alphanumerical
CreateAt int32 `json:"CreateAt"` //when is this session created
UpdateAt int32 `json:"UpdateAt"` //when is this session updated
Expire int32 `json:"Expire"` //unix timestamp of when this Procedure expires
States map[string]chatState `json:"States"` //each procedure will have a state
OpenID string `json:"OpenID"` //who's session this is belongs to
Procedure string `json:"Procedure"` //name of the current current process, alphanumerical
CreateAt int32 `json:"CreateAt"` //when is this session created
UpdateAt int32 `json:"UpdateAt"` //when is this session updated
Expire int32 `json:"Expire"` //unix timestamp of when this Procedure expires
KvPair map[string]string `json:"KvPair"` //key value pair persistant for this session
} }


func writeSession(openid string, ss openIDSessionData) (err error) {
path := getSessionPath(openid)
func writeSession(ss openIDSessionData) (err error) {
openID := ss.OpenID
path := getSessionPath(openID)
r, err := json.Marshal(ss) r, err := json.Marshal(ss)
if err == nil { if err == nil {
err = ioutil.WriteFile(path, r, 0600) err = ioutil.WriteFile(path, r, 0600)
if err != nil { if err != nil {
log.Printf("Error writing session %s: \r\n %s \r\n", openid, r)
log.Printf("Error writing session %s: \r\n %s \r\n", openID, r)
log.Println(err) log.Println(err)
} else { } else {
log.Println("write session to " + path) log.Println("write session to " + path)
} }
} else { } else {
log.Printf("Error encoding session %s ", openid)
log.Printf("Error encoding session %s ", openID)
log.Println(err) log.Println(err)
} }
return return
} }


//create if not available
func setSessionProcedure(openID, procedure string, expireAfter int32) (updatedSession openIDSessionData, err error) {
s, err := getCurrentSesssion(openID)
now := int32(time.Now().Unix())
if s.CreateAt == 0 {
s.CreateAt = now
}
s.UpdateAt = now
s.Procedure = procedure
s.Expire = now + expireAfter
err = writeSession(openID, s)
return s, err
}

func isExpired(timestamp int32) bool { func isExpired(timestamp int32) bool {
now := int32(time.Now().Unix()) now := int32(time.Now().Unix())
return now > timestamp return now > timestamp
} }


func getProcedurePath(openID, ProcedureName string) (path string) { func getProcedurePath(openID, ProcedureName string) (path string) {
path = ProcedureDir + string(os.PathSeparator) + ProcedureName + string(os.PathSeparator) + openID + ".json"
path = procedureDir + string(os.PathSeparator) + ProcedureName + string(os.PathSeparator) + openID + ".json"
ensurePathExist(path) ensurePathExist(path)
return return
} }
err := os.Remove(path) err := os.Remove(path)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
} else {
log.Println("delete session :" + path)
} }
} }
} }


//OneMessage a description of what to send /receive
type OneMessage struct {
Type string `json:"Type"` //MessageType
Text string `json:"Text"` //for text messages
Pic MediaID `json:"Pic"`
Voice MediaID `json:"Voice"`
ShortVideo MediaID `json:"ShortVideo"`
Video MediaID `json:"Video"`
}

type initProcFunc func(openid string) (newstate chatState) type initProcFunc func(openid string) (newstate chatState)
type sendProcMsgFunc func(openid string) (newstate chatState) type sendProcMsgFunc func(openid string) (newstate chatState)
type recvProcMsgFunc func(openid string, msg OneMessage) (newstate chatState)
type recvProcMsgFunc func(openid string) (newstate chatState)
type cleanProcFunc func(openid string) (newstate chatState) type cleanProcFunc func(openid string) (newstate chatState)


//Procedure a description about all procedure //Procedure a description about all procedure
} }


func (c *openIDSessionData) Save() { func (c *openIDSessionData) Save() {
//TODO: save real session date to disk
//invalid procedure
if isExpired(c.Expire) || c.Procedure == "" {
deleteSession(c.OpenID)
} else {
writeSession(*c)
}
} }


//read sessions/openID.json to check whether its a Procedure for ongoing dialog //read sessions/openID.json to check whether its a Procedure for ongoing dialog
result.CreateAt = now result.CreateAt = now
result.UpdateAt = now result.UpdateAt = now
result.Expire = now + expire result.Expire = now + expire
result.States = map[string]chatState{}
result.KvPair = map[string]string{}
return return
} }

func (c *openIDSessionData) setProcedure(procedure string) {
c.Procedure = procedure
c.UpdateAt = int32(time.Now().Unix())
}

func (c *openIDSessionData) setKvPair(key, val string) {
c.KvPair[key] = val
c.UpdateAt = int32(time.Now().Unix())
}

+ 9
- 3
chatSession_test.go Visa fil

AssertEqual(t, isFileExist(path), false, "Session file should not exist") AssertEqual(t, isFileExist(path), false, "Session file should not exist")


//create new //create new
setSessionProcedure(id, procedure, 100)
original := createEmptySession(id, 100)
original.Procedure = procedure
original.Save()


//wait 1 sec //wait 1 sec
log.Print("wait for 1 sec for testing timestamp ......") log.Print("wait for 1 sec for testing timestamp ......")
AssertEqual(t, isExpired(now), false, "current time should not be expired") AssertEqual(t, isExpired(now), false, "current time should not be expired")


//update existing session //update existing session
s, _ = setSessionProcedure(id, procedure, 100)
s.setKvPair("key", "value")
s.setKvPair("key1", "value1")
//timeing should be exactly 1s diff //timeing should be exactly 1s diff
AssertEqual(t, s.CreateAt+1 == s.UpdateAt, true, "second Update should be bigger create") AssertEqual(t, s.CreateAt+1 == s.UpdateAt, true, "second Update should be bigger create")

s.Save()
n, _ := getCurrentSesssion(id) n, _ := getCurrentSesssion(id)
AssertEqual(t, s, n, "session should be equal")
AssertEqual(t, n.KvPair["key"], "value", "key = value ")
AssertEqual(t, n.KvPair["key1"], "value1", "key1 = value1")


//delete session, for clean up //delete session, for clean up
deleteSession(id) deleteSession(id)

Laddar…
Avbryt
Spara