func main() { const ( URLRecord = "/a8/record" URLVerify = "/a8/verify" ) myAddrStr := flag.String("myaddr", "localhost:9002", "Address to listen on") a8AddrStr := flag.String("a8addr", "localhost:9003", "Address of A8 scheduler") flag.Parse() versionStr := "Mock A8 Scheduler Test" serverSetup := httpctxserver.HTTPServerSetup{AddrStr: *myAddrStr, VersionStr: versionStr} //Subscribe to Mock A8 scheduler var subscribeReq = comdef.SubscribeReq{ RequestID: "c4646160-6448-11df-9c5e-0050569339e3", RecordingLocality: "mile-high", MaxEntries: 10, RecordURL: "http://" + *myAddrStr + URLRecord, VerifyURL: "http://" + *myAddrStr + URLVerify, } var subscribeResp comdef.SubscribeResp httpStatus, err := httputilfuncs.PostHTTPJSONString("http://"+*a8AddrStr+comdef.URLSubscribe, subscribeReq, &subscribeResp, timeOut) if err != nil { log.Printf("Failed on Subscribe request! err:%v\n", err) return } log.Printf("HttpStatus: %d, resp: %v", httpStatus, subscribeResp) if httpStatus != http.StatusOK { log.Printf("HttpStatus is not ok, exit") return } if subscribeResp.RequestID != subscribeReq.RequestID { log.Printf("Resp.RequstID: %s is not same as Req.RequestID: %s", subscribeResp.RequestID, subscribeReq.RequestID) } a8VerifyURL = subscribeResp.VerifyURL mockScheduler := httpctxserver.NewHTTPServer(serverSetup) //Add handler mockScheduler.AddHandler(URLRecord, handleRecord) mockScheduler.AddHandler(URLVerify, handleVerify) //Start go routine to send update and verify request go sendUpdateAndVerify(dataChan, doneChan) //Start Server mockScheduler.Start() }
func recordReq() { req := getrecPayload() resp := comdef.RecordResp{} httpStatus, err := httputilfuncs.PostHTTPJSONString(recordURL, req, &resp, 10*time.Second) if err != nil { log.Printf("Failed on send Record request! err:%v\n", err) return } log.Printf("Http Status: %d, resp: %v", httpStatus, resp) }
// Test - A good Set Recording Message func testSetRecordingsHappyPath() error { var statusCode int // Make sure A8 test server is ready and there is no error a8Status, err := checkA8TestServerStatus() if err != nil { return err } // ------ TEST HAPPY PATH ------ // Now we really set everything to DB, this should be successful! testRecs := createTestRecEntries(a8Status.MaxEntriesToRM) statusCode, _, err = setRecordings(a8Status.RecordURL, testRecs) if err != nil { return fmt.Errorf("SetRecording, failed, err:%v", err) } if statusCode != http.StatusNoContent { return fmt.Errorf("SetRecording, expect http status code: %d, got: %d", http.StatusNoContent, statusCode) } // Read Back from Mock Metadata Service var resp recordingtbl.RespRecRead for _, rec := range testRecs { req := recordingtbl.ReqRecRead{ ReadType: recordingtbl.ReadRecByXRID, XRID: rec.RecordingID, } statusCode, err = httputilfuncs.PostHTTPJSONString(dbServerURL+recordingtbl.URLRecRead, &req, &resp, 2*time.Second) if err != nil { return fmt.Errorf("SetRecording, failed to read Recording from Mock MetaData, err:%v", err) } if statusCode != http.StatusOK { return fmt.Errorf("SetRecording, failed to read Recording from Mock MetaData, got http status code: %d", statusCode) } if len(resp.Recordings) != 1 { return fmt.Errorf("SetRecording, recording with XRID:%s is not found in Mock MetaData", rec.RecordingID) } } // for return nil }
func setRecording(recordURL string, req comdef.RecordReq) (int, comdef.RecordResp, error) { resp := comdef.RecordResp{} statusCode, err := httputilfuncs.PostHTTPJSONString(recordURL, req, &resp, 10*time.Second) if err != nil { return statusCode, resp, err } if statusCode == http.StatusOK { if resp.RequestID != req.RequestID { return statusCode, resp, fmt.Errorf("Mismatch Request ID, received:%s, should be: %s", resp.RequestID, req.RequestID) } return statusCode, resp, nil } return statusCode, resp, nil }
func upsertRecToDB(recUpdate recordingtbl.RecUpdate) (uint64, error) { var ( req recordingtbl.ReqUpdateRec resp recordingtbl.RespUpdateRec statusCode int err error ) req.Entries = append(req.Entries, recUpdate) statusCode, err = httputilfuncs.PostHTTPJSONString(dbServerURL+recordingtbl.URLUpsert, &req, &resp, 2*time.Second) if err != nil { return 0, fmt.Errorf("Failed on upsert recording to Mock MetaData, err:%v", err) } if statusCode != http.StatusOK { return 0, fmt.Errorf("Failed on upsert recording to Mock MetaData, got http status code: %d", statusCode) } if len(resp.Entries) != len(req.Entries) { return 0, fmt.Errorf("Failed on upsert recording to Mock MetaData, expect %d entries return, got %d", len(req.Entries), len(resp.Entries)) } return resp.Entries[0].IRID, nil }
func setRecordings(recordURL string, recEntries []*record.RecEntry) (int, []*a8common.RespObject, error) { var resp record.Response req := record.Request{ RequestID: fmt.Sprintf("Req-%d", time.Now().UnixNano()), Entries: recEntries, } statusCode, err := httputilfuncs.PostHTTPJSONString(recordURL, &req, &resp, 2*time.Second) if err != nil { return statusCode, nil, err } if statusCode == http.StatusOK { if resp.RequestID != req.RequestID { return statusCode, nil, fmt.Errorf("Mismatch Request ID, received:%s, should be: %s", resp.RequestID, req.RequestID) } return statusCode, resp.Entries, nil } return statusCode, nil, nil }
func testUpdateMessage() error { restartA8Server() a8Status := getA8ServerStatus() if a8Status == nil { return fmt.Errorf("A8 Server is not ready") } if a8Status.Err != nil { return fmt.Errorf("A8 Server is in Error State: %v", a8Status.Err) } // We will create some recordings first req := getrecPayload(1, a8Status.MaxEntriesFromRM) //1*30 second recordings recDataGlb = req.Entries statusCode, _, err := setRecording(a8Status.RecordURL, req) if err != nil { return fmt.Errorf("SetRecording, failed, err:%v", err) } if statusCode != http.StatusNoContent { return fmt.Errorf("SetRecording, expect http status code: %d, got: %d", http.StatusNoContent, statusCode) } fmt.Println("---Waiting for recording to be Started---") time.Sleep(20 * time.Second) a8Status = getA8ServerStatus() if a8Status == nil { return fmt.Errorf("A8 Server is not ready") } if a8Status.Err != nil { return fmt.Errorf("A8 Server is in Error State: %v", a8Status.Err) } if len(a8Status.UpdateEntries) != len(req.Entries) { fmt.Println("Failing here") return fmt.Errorf("Expect %d status obj in update message test, got %d", len(req.Entries), len(a8Status.UpdateEntries)) } for _, ent := range a8Status.UpdateEntries { if ent.Status != "STARTED" { return fmt.Errorf("For recording with XRID:%s, status is %s, should be STARTED", ent.RecordingID, ent.Status) } } // Read it back from Mock Data to make sure RMNotified is set to true var mdRespStart recordingtbl.RespRecRead for _, rec := range recDataGlb { mdReq := recordingtbl.ReqRecRead{ ReadType: recordingtbl.ReadRecByXRID, XRID: rec.RecordingID, } statusCode, err = httputilfuncs.PostHTTPJSONString(dbServerURL+recordingtbl.URLRecRead, &mdReq, &mdRespStart, 2*time.Second) if err != nil { return fmt.Errorf("UpdateMessage, failed to read Recording from Mock MetaData, err:%v", err) } if statusCode != http.StatusOK { return fmt.Errorf("UpdateMessage, failed to read Recording from Mock MetaData, got http status code: %d", statusCode) } if len(mdRespStart.Recordings) != 1 { return fmt.Errorf("UpdateMessage, recording with XRID:%s is not found in Mock MetaData", mdReq.XRID) } if mdRespStart.Recordings[0].XRID != mdReq.XRID { return fmt.Errorf("UpdateMessage, got resp for XRID:%s, not %s", mdRespStart.Recordings[0].XRID, mdReq.XRID) } if mdRespStart.Recordings[0].RMNotified != true { return fmt.Errorf("UpdateMessage, got resp for XRID:%s, RMNotified is not set to true", mdReq.XRID) } } //Wait for the recording to be completed fmt.Println("---Waiting for recording to be completed---") time.Sleep(30 * time.Second) a8Status = getA8ServerStatus() if a8Status == nil { return fmt.Errorf("A8 Server is not ready") } if a8Status.Err != nil { return fmt.Errorf("A8 Server is in Error State: %v", a8Status.Err) } exp_updt_entries := len(req.Entries) * 2 //Expecting update entries for START AND COMPLETE if len(a8Status.UpdateEntries) != exp_updt_entries { return fmt.Errorf("Expect %d status obj in update message, got %d", exp_updt_entries, len(a8Status.UpdateEntries)) } a8_exp_status := []string{"STARTED", "COMPLETE"} //Setting the expected A8 status to be STARTED and COMPLETE i := 0 for _, ent := range a8Status.UpdateEntries { if ent.Status != a8_exp_status[i] { return fmt.Errorf("For recording with XRID:%s, status is %s, should be %s", ent.RecordingID, ent.Status, a8_exp_status[i]) } i = i + 1 } // Read it back from Mock Data to make sure RMNotified is set to true var mdRespComp recordingtbl.RespRecRead for _, rec := range recDataGlb { mdReq := recordingtbl.ReqRecRead{ ReadType: recordingtbl.ReadRecByXRID, XRID: rec.RecordingID, } statusCode, err = httputilfuncs.PostHTTPJSONString(dbServerURL+recordingtbl.URLRecRead, &mdReq, &mdRespComp, 2*time.Second) if err != nil { return fmt.Errorf("UpdateMessage, failed to read Recording from Mock MetaData, err:%v", err) } if statusCode != http.StatusOK { return fmt.Errorf("UpdateMessage, failed to read Recording from Mock MetaData, got http status code: %d", statusCode) } if len(mdRespComp.Recordings) != 1 { return fmt.Errorf("UpdateMessage, recording with XRID:%s is not found in Mock MetaData", mdReq.XRID) } if mdRespComp.Recordings[0].XRID != mdReq.XRID { return fmt.Errorf("UpdateMessage, got resp for XRID:%s, not %s", mdRespComp.Recordings[0].XRID, mdReq.XRID) } if mdRespComp.Recordings[0].RMNotified != true { return fmt.Errorf("UpdateMessage, got resp for XRID:%s, RMNotified is not set to true", mdReq.XRID) } } return nil }
func sendUpdateAndVerify(dataChan <-chan comdef.RecordData, doneChan chan<- byte) { quit := false pendingUpdateList := []updateData{} pendingVerifyList := []updateData{} for !quit { select { case data := <-dataChan: statusObject := comdef.StatusObject{Status: "UNKNOWN", RecordingID: data.RecordingID, ScheduledTime: data.ScheduledTime, SegmentCount: 0, } updataData := updateData{StatusObj: statusObject, RecordObj: data} pendingUpdateList = append(pendingUpdateList, updataData) break case <-time.After(time.Second * 1): if len(pendingVerifyList) > 0 { verifyReq := comdef.VerifyReq{RequestID: fmt.Sprintf("r12345678-1234-aaaa-bbbb-%d", time.Now().Unix()), Entries: []comdef.VerifyReqData{}} for _, obj := range pendingVerifyList { verifyData := comdef.VerifyReqData{RecordingID: obj.RecordObj.RecordingID} verifyReq.Entries = append(verifyReq.Entries, verifyData) } //send verify req, we assume all status Obj has the same update URL for now log.Printf("Sending Verify Request: req:%v", verifyReq) verifyResp := comdef.VerifyResp{} httpStatus, err := httputilfuncs.PostHTTPJSONString(a8VerifyURL, verifyReq, &verifyResp, timeOut) if err != nil { log.Printf("Error when sending Update Request, err: %v", err) } else { log.Printf("HttpStatus: %d, Resp: %v", httpStatus, verifyResp) } //clear list for gc pendingVerifyList = []updateData{} } if len(pendingUpdateList) > 0 { updateReq := comdef.UpdateReq{RequestID: fmt.Sprintf("r12345678-1234-cccc-dddd-%d", time.Now().Unix()), Entries: []comdef.StatusObject{}} for _, obj := range pendingUpdateList { updateReq.Entries = append(updateReq.Entries, obj.StatusObj) } //send update req, we assume all status Obj has the same update URL for now log.Printf("1 -- Sending Update Request: req:%v", updateReq) updateResp := comdef.UpdateResp{} fmt.Println(pendingUpdateList[0].RecordObj.UpdateURL) httpStatus, err := httputilfuncs.PostHTTPJSONString(pendingUpdateList[0].RecordObj.UpdateURL, updateReq, &updateResp, timeOut) if err != nil { log.Printf("Error when sending Update Request, err: %v", err) } else { log.Printf("HttpStatus: %d, Resp: %v", httpStatus, updateResp) } //clear list for gc pendingVerifyList = pendingUpdateList pendingUpdateList = []updateData{} } break } //end switch } //end for doneChan <- 1 }
func teststopRecordings() error { restartA8Server() a8Status, err := checkA8TestServerStatus1() if err != nil { return err } //Sending request to start a recording and validate the STARTED update message from RM req := getrecPayload(5, 1) //5*30 second 1 recording will be created recDataGlb = req.Entries statusCode, _, err := setRecording(a8Status.RecordURL, req) if err != nil { return fmt.Errorf("SetRecording, failed, err:%v", err) } if statusCode != http.StatusNoContent { return fmt.Errorf("SetRecording, expect http status code: %d, got: %d", http.StatusNoContent, statusCode) } fmt.Println("---Waiting for recording to be Started---") time.Sleep(25 * time.Second) a8Status = getA8ServerStatus() resp, err := http.Get("http://localhost:9003/updateClient") if err != nil { // handle error } defer resp.Body.Close() fmt.Println(resp) body, err := ioutil.ReadAll(resp.Body) var data A8ServerStatus fmt.Println(body) err1 := json.Unmarshal(body, &data) fmt.Println(data) if err1 != nil { fmt.Println(err1) } if a8Status == nil { return fmt.Errorf("A8 Server is not ready") } if a8Status.Err != nil { return fmt.Errorf("A8 Server is in Error State: %v", a8Status.Err) } if len(a8Status.UpdateEntries) != len(req.Entries) { return fmt.Errorf("Expect %d status obj in update message, got %d", len(req.Entries), len(a8Status.UpdateEntries)) } for _, ent := range a8Status.UpdateEntries { if ent.Status != "STARTED" { return fmt.Errorf("For recording with XRID:%s, status is %s, should be STARTED", ent.RecordingID, ent.Status) } } //Sending request to stop recording and validatin the COMPLETE update message from RM nowTime := time.Now() req.Entries[0].EndTime = nowTime.Format(comdef.TimeFrmtStr) statusCode1, _, err1 := setRecording(a8Status.RecordURL, req) if err1 != nil { return fmt.Errorf("SetRecording, failed, err:%v", err) } if statusCode1 != http.StatusNoContent { return fmt.Errorf("SetRecording, expect http status code: %d, got: %d", http.StatusNoContent, statusCode1) } fmt.Println("---Waiting for recording to be Stopped---") time.Sleep(15 * time.Second) a8Status = getA8ServerStatus() if a8Status == nil { return fmt.Errorf("A8 Server is not ready") } if a8Status.Err != nil { return fmt.Errorf("A8 Server is in Error State: %v", a8Status.Err) } exp_updt_entries := len(req.Entries) * 2 //Expecting update entries for START AND COMPLETE if len(a8Status.UpdateEntries) != exp_updt_entries { return fmt.Errorf("Expect %d status obj in update message, got %d", exp_updt_entries, len(a8Status.UpdateEntries)) } a8_exp_status := []string{"STARTED", "COMPLETE"} i := 0 for _, ent := range a8Status.UpdateEntries { if ent.Status != a8_exp_status[i] { return fmt.Errorf("For recording with XRID:%s, status is %s, should be %s", ent.RecordingID, ent.Status, a8_exp_status[i]) } i = i + 1 } // Read it back from Mock Data to make sure EndTime matches the one we send in stop request var mdResp recordingtbl.RespRecRead for _, rec := range recDataGlb { mdReq := recordingtbl.ReqRecRead{ ReadType: recordingtbl.ReadRecByXRID, XRID: rec.RecordingID, } statusCode, err = httputilfuncs.PostHTTPJSONString(dbServerURL+recordingtbl.URLRecRead, &mdReq, &mdResp, 2*time.Second) if err != nil { return fmt.Errorf("UpdateMessage, failed to read Recording from Mock MetaData, err:%v", err) } if statusCode != http.StatusOK { return fmt.Errorf("UpdateMessage, failed to read Recording from Mock MetaData, got http status code: %d", statusCode) } if len(mdResp.Recordings) != 1 { return fmt.Errorf("UpdateMessage, recording with XRID:%s is not found in Mock MetaData", mdReq.XRID) } if mdResp.Recordings[0].XRID != mdReq.XRID { return fmt.Errorf("UpdateMessage, got resp for XRID:%s, not %s", mdResp.Recordings[0].XRID, mdReq.XRID) } t := mdResp.Recordings[0].EndTime.Format(a8common.ISO8601FmtStr) if t != req.Entries[0].EndTime { return fmt.Errorf("UpdateMEssage, got resp for XRID:%s, EndTime is not matching", mdReq.XRID) } } return nil }
func testdelRecordings() error { restartA8Server() a8Status, err := checkA8TestServerStatus1() if err != nil { return err } //Sending request to start a recording and validate the STARTED update message from RM req := getrecPayload(5, 1) //5*30 second 1 recording will be created delDataGlb = req.Entries statusCode, _, err := setRecording(a8Status.RecordURL, req) if err != nil { return fmt.Errorf("SetRecording, failed, err:%v", err) } if statusCode != http.StatusNoContent { return fmt.Errorf("SetRecording, expect http status code: %d, got: %d", http.StatusNoContent, statusCode) } fmt.Println("---Waiting for recording to be Started---") time.Sleep(20 * time.Second) a8Status = getA8ServerStatus() if a8Status == nil { return fmt.Errorf("A8 Server is not ready") } if a8Status.Err != nil { return fmt.Errorf("A8 Server is in Error State: %v", a8Status.Err) } if len(a8Status.UpdateEntries) != len(req.Entries) { return fmt.Errorf("Expect %d status obj in update message, got %d", len(req.Entries), len(a8Status.UpdateEntries)) } for _, ent := range a8Status.UpdateEntries { if ent.Status != "STARTED" { return fmt.Errorf("For recording with XRID:%s, status is %s, should be STARTED", ent.RecordingID, ent.Status) } } //Sending request to Delete recording delReq := getdelPayload() statusCode1, _, err1 := setRecording(a8Status.RecordURL, delReq) if err1 != nil { return fmt.Errorf("SetRecording, failed, err:%v", err) } if statusCode1 != http.StatusNoContent { return fmt.Errorf("SetRecording, expect http status code: %d, got: %d", http.StatusNoContent, statusCode1) } fmt.Println("---Waiting for recording to be Deleted---") time.Sleep(5 * time.Second) a8Status = getA8ServerStatus() if a8Status == nil { return fmt.Errorf("A8 Server is not ready") } if a8Status.Err != nil { return fmt.Errorf("A8 Server is in Error State: %v", a8Status.Err) } exp_updt_entries := len(req.Entries) * 2 //Expecting update entries for START AND COMPLETE if len(a8Status.UpdateEntries) != exp_updt_entries { return fmt.Errorf("Expect %d status obj in update message, got %d", exp_updt_entries, len(a8Status.UpdateEntries)) } a8_exp_status := []string{"STARTED", "COMPLETE"} i := 0 for _, ent := range a8Status.UpdateEntries { if ent.Status != a8_exp_status[i] { return fmt.Errorf("For recording with XRID:%s, status is %s, should be %s", ent.RecordingID, ent.Status, a8_exp_status[i]) } i = i + 1 } // Read it back from Mock Data to make sure Erased time is updated in the table var mdResp recordingtbl.RespRecRead for _, rec := range delDataGlb { mdReq := recordingtbl.ReqRecRead{ ReadType: recordingtbl.ReadRecByXRID, XRID: rec.RecordingID, } statusCode, err = httputilfuncs.PostHTTPJSONString(dbServerURL+recordingtbl.URLRecRead, &mdReq, &mdResp, 2*time.Second) if err != nil { return fmt.Errorf("UpdateMessage, failed to read Recording from Mock MetaData, err:%v", err) } if statusCode != http.StatusOK { return fmt.Errorf("UpdateMessage, failed to read Recording from Mock MetaData, got http status code: %d", statusCode) } if len(mdResp.Recordings) != 1 { return fmt.Errorf("UpdateMessage, recording with XRID:%s is not found in Mock MetaData", mdReq.XRID) } if mdResp.Recordings[0].XRID != mdReq.XRID { return fmt.Errorf("UpdateMessage, got resp for XRID:%s, not %s", mdResp.Recordings[0].XRID, mdReq.XRID) } erased_time := mdResp.Recordings[0].ErasedTime.Format(a8common.ISO8601FmtStr) if erased_time == "" { return fmt.Errorf("UpdateMEssage, got resp for XRID:%s, ErasedTime is not updated", mdReq.XRID) } actual_end_time := mdResp.Recordings[0].ActualEndTime.Format(a8common.ISO8601FmtStr) if actual_end_time == "" { return fmt.Errorf("UpdateMEssage, got resp for XRID:%s, Actual EndTime is not updated", mdReq.XRID) } } return nil }