func TestMultiToolStatus(t *testing.T) { // Build the Queue with the SimpleTool timer q := Queue{authToken: "ResourceTest"} // Add the tool st := new(SimpleTimerTooler) st.SetUUID(uuid.New()) q.tools = append(q.tools, st) // Create the RPC server and bind the Queue listen := startRPCOnce("tcp", addr, &q) defer listen.Close() // Connect to the RPC server client, err := rpc.Dial("tcp", addr) if err != nil { t.Fatal("Error dailing RPC server.", err) } defer client.Close() // Setup the Job information to start the service params := map[string]string{"timer": "20"} j := common.NewJob(st.UUID(), "Testing Job", "GoTestSuite", params) // Create RPC call for starting a job startJob := common.RPCCall{Auth: "ResourceTest", Job: j} // Add our first job err = client.Call("Queue.AddTask", startJob, &j) if err != nil { t.Fatal("Error starting SimpleTimer task.", err) } // Add our second job j = common.NewJob(st.UUID(), "Testing Job", "GoTestSuite", params) err = client.Call("Queue.AddTask", startJob, &j) if err != nil { t.Fatal("Error starting SimpleTimer task.", err) } // Get the status of both and check that the Job UUIDs aren't the same getStatus := common.RPCCall{Auth: "ResourceTest"} jobs := []common.Job{} err = client.Call("Queue.AllTaskStatus", getStatus, &jobs) if err != nil { t.Fatal("Failure getting multiple jobs status.", err) } var firstUUID string for i, v := range jobs { if i == 0 { firstUUID = v.UUID } else if firstUUID == v.UUID { t.Fatal("Both jobs have the same UUID.") } } }
func TestRunFailure(t *testing.T) { // Create a queue & start the resource q := Queue{authToken: "FailureTest"} l := startRPCOnce("tcp", addr, &q) defer l.Close() // Add the failure tool tool := new(simpleFailerTooler) tool.SetUUID(uuid.New()) q.tools = append(q.tools, tool) // Build the RPC client client, err := rpc.Dial("tcp", addr) if err != nil { t.Fatal("Error dailing RPC servers.", err) } // Build the job to send to the simpleFailureTask params := map[string]string{"failFunc": "Run"} job := common.NewJob(tool.UUID(), "Failure Test", "GoTestSuite", params) // Try and create the job... we should get a failure call := common.RPCCall{Auth: "FailureTest", Job: job} err = client.Call("Queue.AddTask", call, nil) if err == nil { t.Fatal("Failure task's error was not returned.") } }
func TestToolDoesNotExist(t *testing.T) { // Build the Queue with the SimpleTool timer q := Queue{authToken: "ResourceTest"} // Add the tool st := new(SimpleTimerTooler) st.SetUUID(uuid.New()) q.tools = append(q.tools, st) // Create the RPC server and bind the Queue listen := startRPCOnce("tcp", addr, &q) defer listen.Close() // Connect to the RPC server client, err := rpc.Dial("tcp", addr) if err != nil { t.Fatal("Error dailing RPC server.", err) } defer client.Close() // Setup the Job information to start the service params := map[string]string{"timer": "1"} j := common.NewJob(uuid.New(), "Testing Job", "GoTestSuite", params) // Create RPC call for starting a job startJob := common.RPCCall{Auth: "ResourceTest", Job: j} // Make call and expect an error of bad job err = client.Call("Queue.AddTask", startJob, &j) if err == nil || err.Error() != ERROR_NO_TOOL { t.Fatal("No tool error was not returned.", err) } }
func TestSimplePauseTask(t *testing.T) { // Build the Queue with the simpleTool timer q := Queue{authToken: "ResourceTest"} // Add the tool st := new(SimpleTimerTooler) st.SetUUID(uuid.New()) q.tools = append(q.tools, st) // Create the RPC server and bind the queue listen := startRPCOnce("tcp", addr, &q) defer listen.Close() // Connect client to RPC server client, err := rpc.Dial("tcp", addr) if err != nil { t.Fatal("Error dailing RPC server.", err) } defer client.Close() // Setup the Job information to start the service params := map[string]string{"timer": "5"} j := common.NewJob(st.UUID(), "Testing Job", "GoTestSuite", params) // Create the RPC call for starting a job startJob := common.RPCCall{Auth: "ResourceTest", Job: j} // Make the call to create the task err = client.Call("Queue.AddTask", startJob, &j) if err != nil { t.Fatal("Error starting simpleTimer task.", err) } // Wait 2 seconds before pausing <-time.After(2 * time.Second) // Pause the job pauseJob := common.RPCCall{Auth: "ResourceTest", Job: j} err = client.Call("Queue.TaskPause", pauseJob, &j) if err != nil { t.Fatal("Error pausing simpleTimer status.", err) } // Get the status of the job statusJob := common.RPCCall{Auth: "ResourceTest", Job: j} err = client.Call("Queue.TaskStatus", statusJob, &j) if err != nil { t.Fatal("Error getting simpleTimer status.", err) } if j.Status != common.STATUS_PAUSED { t.Errorf("Status was not paused, which was expected. Status:%s", j.Status) } }
func TestQueueAddJob(t *testing.T) { // Build the main queue queue := NewQueue() // Build the resource res := resource.NewResourceQueue("QueueTest") tool := new(resource.SimpleTimerTooler) res.AddTool(tool) closed := resource.StartResource("localhost:4444", &res) err := queue.AddResource("localhost:4444", "test", "QueueTest") if err != nil { t.Fatal("TestQueueAddJob:" + err.Error()) } // Get the Queue Tools so we can get the UUID var juuid string for _, v := range queue.Tools() { if v.Name == "Simple Timer Tool" { juuid = v.UUID } } // Build a simple jobs to run and add it to the queue params := map[string]string{"timer": "1"} j := common.NewJob(juuid, "Simple Timer Queue Test", "GoTestSuite", params) err = queue.AddJob(j) if err != nil { t.Fatal("Error adding Job: " + err.Error()) } // Wait for the job to finish <-time.After(2 * time.Second) println("MADE IT") jobs := queue.Quit() println("MADE IT 2") // Check for done status for _, v := range jobs { if v.Status != common.STATUS_DONE { t.Fatal("Job was not finished and should have been.") } } <-closed }
func TestSimpleQuitTask(t *testing.T) { // Build the Queue with the SimpleTool timer q := Queue{authToken: "ResourceTest"} // Add the tool st := new(SimpleTimerTooler) q.tools = append(q.tools, st) // Create the RPC server and bind the Queue listen := startRPCOnce("tcp", addr, &q) defer listen.Close() // Connect to the RPC server client, err := rpc.Dial("tcp", addr) if err != nil { t.Fatal("Error dailing RPC server.", err) } defer client.Close() // Setup the Job information to start the service params := map[string]string{"timer": "10"} j := common.NewJob(st.UUID(), "Testing Job", "GoTestSuite", params) // Create RPC call for starting a job startJob := common.RPCCall{Auth: "ResourceTest", Job: j} // Make call err = client.Call("Queue.AddTask", startJob, &j) if err != nil { t.Fatal("Error starting SimpleTimer task.", err) } // Wait 2 seconds so the timer finishes <-time.After(2 * time.Second) // Get the job status and check for finished status err = client.Call("Queue.TaskQuit", startJob, &j) if err != nil { t.Fatal("Error getting simpleTimer status.", err) } if j.Status != common.STATUS_QUIT { t.Errorf("Status was not quit, which was expected. Status:%s", j.Status) } }
func TestRunAfterPauseFailure(t *testing.T) { // Create a queue & start the resource q := Queue{authToken: "FailureTest"} l := startRPCOnce("tcp", addr, &q) defer l.Close() // Add the failure tool tool := new(simpleFailerTooler) tool.SetUUID(uuid.New()) q.tools = append(q.tools, tool) // Build the RPC client client, err := rpc.Dial("tcp", addr) if err != nil { t.Fatal("Error dailing RPC servers.", err) } // Build the job to send to the simpleFailureTask params := map[string]string{"failFunc": "RunAfterPause"} job := common.NewJob(tool.UUID(), "Failure Test", "GoTestSuite", params) // Create the failure job call := common.RPCCall{Auth: "FailureTest", Job: job} err = client.Call("Queue.AddTask", call, nil) if err != nil { t.Fatal("Failure task failed on the wrong call.") } // Try to pause the job... we should get an error call = common.RPCCall{Auth: "FailureTest", Job: job} err = client.Call("Queue.TaskPause", call, nil) if err != nil { println("TEST::" + err.Error()) t.Fatal("Failure task failed on the wrong call.") } call = common.RPCCall{Auth: "FailureTest", Job: job} err = client.Call("Queue.TaskRun", call, nil) if err == nil { t.Fatal("Failure task did not fail on Resume.") } }
// Create a new job (POST - /api/job) func (a *AppController) CreateJob(rw http.ResponseWriter, r *http.Request) { // Response and Request structures var req JobCreateReq var resp JobCreateResp // JSON Encoder and Decoder reqJSON := json.NewDecoder(r.Body) respJSON := json.NewEncoder(rw) // Get the authorization header token := r.Header.Get("AuthorizationToken") if !a.T.CheckToken(token) { resp.Status = RESP_CODE_UNAUTHORIZED resp.Message = RESP_CODE_UNAUTHORIZED_T rw.WriteHeader(RESP_CODE_UNAUTHORIZED) respJSON.Encode(resp) log.Warn("An unknown token attempted to create a job.") return } // Check for standard user level at least user, _ := a.T.GetUser(token) if !user.Allowed(StandardUser) { resp.Status = RESP_CODE_UNAUTHORIZED resp.Message = RESP_CODE_UNAUTHORIZED_T rw.WriteHeader(RESP_CODE_UNAUTHORIZED) respJSON.Encode(resp) log.WithField("user", user.Username).Warn("An unauthorized user attempted to create a job.") return } // Decode the request err := reqJSON.Decode(&req) if err != nil { log.WithField("err", err).Error("Error parsing the request.") resp.Status = RESP_CODE_BADREQ resp.Message = RESP_CODE_BADREQ_T rw.WriteHeader(RESP_CODE_BADREQ) respJSON.Encode(resp) return } // Some types might not be strings so let's build a map for the params input params := map[string]string{} for key, value := range req.Params { switch v := value.(type) { case string: params[key] = v case bool: params[key] = strconv.FormatBool(v) case int: params[key] = strconv.Itoa(v) case float64: params[key] = strconv.FormatFloat(v, 'g', -1, 64) case float32: params[key] = strconv.FormatFloat(float64(v), 'g', -1, 32) } } // Build a job structure job := common.NewJob(req.ToolID, req.Name, user.Username, params) err = a.Q.AddJob(job) if err != nil { log.Println(err.Error()) resp.Status = RESP_CODE_BADREQ resp.Message = "An error occured when trying to create the job: " + err.Error() rw.WriteHeader(RESP_CODE_BADREQ) respJSON.Encode(resp) return } // Job was created so populate the response structure and return resp.Status = RESP_CODE_OK resp.Message = RESP_CODE_OK_T resp.JobID = job.UUID rw.WriteHeader(RESP_CODE_OK) respJSON.Encode(resp) log.WithFields(log.Fields{ "uuid": job.UUID, "name": job.Name, }).Info("New job created.") }
// Create a new job (POST - /api/job) func (a *AppController) CreateJob(rw http.ResponseWriter, r *http.Request) { // Response and Request structures var req JobCreateReq var resp JobCreateResp // JSON Encoder and Decoder reqJSON := json.NewDecoder(r.Body) respJSON := json.NewEncoder(rw) // Get the authorization header token := r.Header.Get("AuthorizationToken") if !a.T.CheckToken(token) { resp.Status = RESP_CODE_UNAUTHORIZED resp.Message = RESP_CODE_UNAUTHORIZED_T rw.WriteHeader(RESP_CODE_UNAUTHORIZED) respJSON.Encode(resp) log.Warn("An unknown token attempted to create a job.") return } // Check for standard user level at least user, _ := a.T.GetUser(token) if !user.Allowed(StandardUser) { resp.Status = RESP_CODE_UNAUTHORIZED resp.Message = RESP_CODE_UNAUTHORIZED_T rw.WriteHeader(RESP_CODE_UNAUTHORIZED) respJSON.Encode(resp) log.WithField("user", user.Username).Warn("An unauthorized user attempted to create a job.") return } // Decode the request err := reqJSON.Decode(&req) if err != nil { resp.Status = RESP_CODE_BADREQ resp.Message = RESP_CODE_BADREQ_T rw.WriteHeader(RESP_CODE_BADREQ) respJSON.Encode(resp) return } // Build a job structure job := common.NewJob(req.ToolID, req.Name, user.Username, req.Params) err = a.Q.AddJob(job) if err != nil { log.Println(err.Error()) resp.Status = RESP_CODE_BADREQ resp.Message = "An error occured when trying to create the job: " + err.Error() rw.WriteHeader(RESP_CODE_BADREQ) respJSON.Encode(resp) return } // Job was created so populate the response structure and return resp.Status = RESP_CODE_OK resp.Message = RESP_CODE_OK_T resp.JobID = job.UUID rw.WriteHeader(RESP_CODE_OK) respJSON.Encode(resp) log.WithFields(log.Fields{ "uuid": job.UUID, "name": job.Name, }).Info("New job created.") }
func TestMultiResourceMultiJobs2(t *testing.T) { // Build the main queue queue := NewQueue() KeeperDuration = 100 * time.Millisecond // Build the first resource res1 := resource.NewResourceQueue("Resource 1") tool := new(resource.SimpleTimerTooler) res1.AddTool(tool) // Start the first resource close1 := resource.StartResource("localhost:4441", &res1) // Add the first resource err := queue.AddResource("localhost:4441", "name", "Resource 1") if err != nil { t.Fatal("Error adding resource: " + err.Error()) } // Build the second resource res2 := resource.NewResourceQueue("Resource 2") tool = new(resource.SimpleTimerTooler) res2.AddTool(tool) // Start the second resource close2 := resource.StartResource("localhost:4442", &res2) // Add the second resource err = queue.AddResource("localhost:4442", "name", "Resource 2") if err != nil { t.Fatal("Error adding resource: " + err.Error()) } // Build the second resource res3 := resource.NewResourceQueue("Resource 3") tool3 := new(resource.SimpleTimerTooler) res3.AddTool(tool3) // Start the second resource close3 := resource.StartResource("localhost:4443", &res3) // Add the second resource err = queue.AddResource("localhost:4443", "name", "Resource 3") if err != nil { t.Fatal("Error adding resource: " + err.Error()) } // Build several jobs to add param := map[string]string{"timer": "3"} var tu1 string for _, v := range queue.Tools() { tu1 = v.UUID } j1 := common.NewJob(tu1, "Simple Timer Queue Test 1", "GoTestSuite", param) j2 := common.NewJob(tu1, "Simple Timer Queue Test 2", "GoTestSuite", param) j3 := common.NewJob(tu1, "Simple Timer Queue Test 3", "GoTestSuite", param) j4 := common.NewJob(tu1, "Simple Timer Queue Test 4", "GoTestSuite", param) j5 := common.NewJob(tu1, "Simple Timer Queue Test 5", "GoTestSuite", param) j6 := common.NewJob(tu1, "Simple Timer Queue Test 6", "GoTestSuite", param) err = queue.AddJob(j1) if err != nil { t.Fatal("Job was not added successfully: " + err.Error()) } err = queue.AddJob(j2) if err != nil { t.Fatal("Job was not added successfully: " + err.Error()) } err = queue.AddJob(j3) if err != nil { t.Fatal("Job was not added successfully: " + err.Error()) } err = queue.AddJob(j4) if err != nil { t.Fatal("Job was not added successfully: " + err.Error()) } err = queue.AddJob(j5) if err != nil { t.Fatal("Job was not added successfully: " + err.Error()) } err = queue.AddJob(j6) if err != nil { t.Fatal("Job was not added successfully: " + err.Error()) } for { running := false select { case <-time.After(1 * time.Second): // Check if all jobs are done for _, v := range queue.AllJobs() { if v.Status != common.STATUS_DONE { running = true } } } if !running { break } } queue.Quit() <-close1 <-close2 <-close3 }
func TestJobQuit(t *testing.T) { // Build the main queue queue := NewQueue() KeeperDuration = 1 * time.Second // Build the resource res := resource.NewResourceQueue("QueueTest") tool := new(resource.SimpleTimerTooler) res.AddTool(tool) closed := resource.StartResource("localhost:4444", &res) err := queue.AddResource("localhost:4444", "test", "QueueTest") if err != nil { t.Fatal("TestQueueAddJob:" + err.Error()) } // Get the Queue Tools so we can get the UUID var juuid string for _, v := range queue.Tools() { if v.Name == "Simple Timer Tool" { juuid = v.UUID } } // Add two jobs with 2 second timers params := map[string]string{"timer": "4"} j1 := common.NewJob(juuid, "Simple Timer Queue Test 1", "GoTestSuite", params) err = queue.AddJob(j1) if err != nil { t.Fatal("Error adding Job: " + err.Error()) } params = map[string]string{"timer": "2"} j2 := common.NewJob(juuid, "Simple Timer Queue Test 2", "GoTestSuite", params) err = queue.AddJob(j2) if err != nil { t.Fatal("Error adding Job: " + err.Error()) } // Now pause the first job we added so the second finished first err = queue.QuitJob(j1.UUID) if err != nil { t.Fatal("Quiting job failed: " + err.Error()) } // The first jobs should now be paused so lets pull all statuses and check jobs := queue.AllJobs() for _, v := range jobs { if v.UUID == j1.UUID { if v.Status != common.STATUS_QUIT { t.Fatal("Job was not quit and should have been.") } } } // Wait the total runtime to make sure everything eventually finished <-time.After(4 * time.Second) jobs = queue.Quit() for _, v := range jobs { if v.Status != common.STATUS_DONE && v.Status != common.STATUS_QUIT { t.Fatal("Not all jobs were finished. Status:" + v.Status) } } <-closed }
func TestQueuePause(t *testing.T) { // Build the main queue queue := NewQueue() KeeperDuration = 1 * time.Second // Build the resource res := resource.NewResourceQueue("QueueTest") tool := new(resource.SimpleTimerTooler) res.AddTool(tool) closed := resource.StartResource("localhost:4444", &res) err := queue.AddResource("localhost:4444", "test", "QueueTest") if err != nil { t.Fatal("TestQueueAddJob:" + err.Error()) } // Get the Queue Tools so we can get the UUID var juuid string for _, v := range queue.Tools() { if v.Name == "Simple Timer Tool" { juuid = v.UUID } } // Add two jobs with 2 second timers params := map[string]string{"timer": "2"} j := common.NewJob(juuid, "Simple Timer Queue Test 1", "GoTestSuite", params) err = queue.AddJob(j) if err != nil { t.Fatal("Error adding Job: " + err.Error()) } params = map[string]string{"timer": "2"} j = common.NewJob(juuid, "Simple Timer Queue Test 2", "GoTestSuite", params) err = queue.AddJob(j) if err != nil { t.Fatal("Error adding Job: " + err.Error()) } // Wait 1 second then pause <-time.After(1 * time.Second) // Pause the queue errs := queue.PauseQueue() if len(errs) != 0 { t.Fatal(errs) } if queue.status != STATUS_PAUSED { t.Fatal("Queue was not paused.") } // Add two more jobs params = map[string]string{"timer": "2"} j = common.NewJob(juuid, "Simple Timer Queue Test 3", "GoTestSuite", params) err = queue.AddJob(j) if err != nil { t.Fatal("Error adding Job: " + err.Error()) } params = map[string]string{"timer": "2"} j = common.NewJob(juuid, "Simple Timer Queue Test 4", "GoTestSuite", params) err = queue.AddJob(j) if err != nil { t.Fatal("Error adding Job: " + err.Error()) } // Restart the Queue queue.ResumeQueue() // Wait enough time for jobs to finish <-time.After(10 * time.Second) jobs := queue.Quit() // Check for done status for _, v := range jobs { if v.Status != common.STATUS_DONE { t.Fatal("Job was not finished and should have been.") } } <-closed }
func TestQueueDelayAddMultipleJob(t *testing.T) { // Build the main queue queue := NewQueue() KeeperDuration = 1 * time.Second // Build the resource res := resource.NewResourceQueue("QueueTest") tool := new(resource.SimpleTimerTooler) res.AddTool(tool) closed := resource.StartResource("localhost:4444", &res) err := queue.AddResource("localhost:4444", "test", "QueueTest") if err != nil { t.Fatal("TestQueueAddJob:" + err.Error()) } // Get the Queue Tools so we can get the UUID var juuid string for _, v := range queue.Tools() { if v.Name == "Simple Timer Tool" { juuid = v.UUID } } // Build a simple jobs to run and add it to the queue params := map[string]string{"timer": "1"} j := common.NewJob(juuid, "Simple Timer Queue Test 1", "GoTestSuite", params) err = queue.AddJob(j) if err != nil { t.Fatal("Error adding Job: " + err.Error()) } // Build another job that runs longer params = map[string]string{"timer": "2"} j = common.NewJob(juuid, "Simple Timer Queue Test 2", "GoTestSuite", params) err = queue.AddJob(j) if err != nil { t.Fatal("Error adding Job: " + err.Error()) } // Build a third that runs longer params = map[string]string{"timer": "3"} j = common.NewJob(juuid, "Simple Timer Queue Test 3", "GoTestSuite", params) err = queue.AddJob(j) if err != nil { t.Fatal("Error adding Job: " + err.Error()) } // Wait for the job to finish <-time.After(8 * time.Second) // Build a four and final job much delayed params = map[string]string{"timer": "2"} j = common.NewJob(juuid, "Simple Timer Queue Test 3", "GoTestSuite", params) err = queue.AddJob(j) if err != nil { t.Fatal("Error adding Job: " + err.Error()) } <-time.After(3 * time.Second) jobs := queue.Quit() // Check for done status for _, v := range jobs { if v.Status != common.STATUS_DONE { t.Fatal("Job was not finished and should have been.") } } <-closed }