func TestFileWriteBadPath(t *testing.T) { eng := engine.New() err := eng.Execute(`$file.write('/blah/test.txt', 'test');`) if err == nil { t.Fail() } }
func TestFileCopyBadPath(t *testing.T) { eng := engine.New() err := eng.Execute(`$file.copy('test', '/blah/test1');`) if err == nil { t.Fail() } }
//DELETE func TestFileDelete(t *testing.T) { createTestFile() eng := engine.New() err := eng.Execute(`$file.delete('test')`) if err != nil { t.Error(err) } }
func TestFileInfo(t *testing.T) { createTestFile() defer os.Remove("test") script := `if ($file.info("test").size != 4) {throw new Error();}` eng := engine.New() err := eng.Execute(script) if err != nil { t.Fatal(err) } }
//READSTRING func TestFileReadString(t *testing.T) { createTestFile() eng := engine.New() err := eng.Execute(`if ($file.readString('test') != 'test') { throw new Error(); }`) if err != nil { t.Error(err) } defer os.Remove("test") }
func TestFileMoveBadPath(t *testing.T) { createTestFile() eng := engine.New() err := eng.Execute(`$file.move('test', '/blah/test');`) if err == nil { t.Fail() } defer os.Remove("test") }
func TestValidate(t *testing.T) { var script = ` var test = ` eng := engine.New() err := eng.Validate(script) if err == nil { t.Fatal("No error reported for bad syntax") } }
func TestGetNumberVar(t *testing.T) { script := ` var test = 1` eng := engine.New() v, err := eng.GetVar("test", script) if err != nil { t.Fatal(err) } if v.(int64) != 1 { t.Fatal("Return value not valid") } }
func TestGetStringVar(t *testing.T) { script := ` var test = "test123"; ` eng := engine.New() v, err := eng.GetVar("test", script) if err != nil { t.Fatal(err) } if v.(string) != "test123" { t.Fatal("Return value not valid") } }
//COPY func TestFileCopy(t *testing.T) { createTestFile() eng := engine.New() err := eng.Execute(`$file.copy('test', 'test1');`) if err != nil { t.Error(err) } if !fileExists("test1") { t.Error("destination file does not exist") } defer os.Remove("test") defer os.Remove("test1") }
//MKDIR func TestFileMkdir(t *testing.T) { dir, _ := filepath.Abs(filepath.Dir(os.Args[0])) eng := engine.New() err := eng.Execute(`$file.mkdir('` + dir + `/test/test1');`) if err != nil { t.Error(err) } if !fileExists(dir + "/test/test1") { t.Error("Directory does not exist: ", dir) } defer os.RemoveAll(dir + "/test/test1") }
func TestAgentCommand(t *testing.T) { mailbox.OpenMemDB() key := mailbox.AccessKey{FullAccess: true} key.Create() agent.Address = ":6112" agent.AccessKey = key.Secret go agent.Start() engine.Agents["test"] = ":6112" engine.AgentAccessKey = key.Secret eng := engine.New() err := eng.Execute(`$agent("test", function() { console.log("test"); });`) if err != nil { t.Fatal(err) } }
//EXISTS func TestFileExists(t *testing.T) { createTestFile() eng := engine.New() err := eng.Execute(`if (!$file.exists('test')) { throw new Error(); }`) if err != nil { t.Error(err) } err = eng.Execute(`if ($file.exists('test2')) { throw new Error(); }`) if err != nil { t.Error(err) } defer os.Remove("test") }
//WRITE func TestFileWrite(t *testing.T) { eng := engine.New() err := eng.Execute(`$file.write('write_test.txt', 'test');`) if err != nil { t.Error(err) } data, err := ioutil.ReadFile("write_test.txt") if err != nil { t.Error(err) } if string(data) != "test" { t.Error("expecting contents to be 'test' but got", string(data)) } defer os.Remove("write_test.txt") }
func TestExecuteFunction(t *testing.T) { var script = ` var test = "test"; test2 = "test"; $local = function() { return true; }; ` eng := engine.New() res, err := eng.ExecuteFunction("$local", script) if err != nil { t.Fatal(err) } if res != "true" { t.Fatal("No Return value") } }
// command will process any request to the server. It will validate the request // and then process any script given. func command(w http.ResponseWriter, r *http.Request) { request, err := getRequest(r) response := &api.AgentResponse{} if !request.Validate(AccessKey) { response.Success = false response.Error = "Could not validate signature" response.Sign("", AccessKey) writeResponse(w, response) return } if err != nil { response.Success = false response.Error = err.Error() response.Sign("", AccessKey) writeResponse(w, response) return } if !request.Validate(AccessKey) { response.Success = false response.Error = "Invalid signature" response.Sign("", AccessKey) writeResponse(w, response) return } eng := engine.New() err = eng.Execute(request.Function) if err != nil { response.Success = false response.Error = err.Error() response.Sign("", AccessKey) writeResponse(w, response) return } response.Success = true response.Sign("", AccessKey) writeResponse(w, response) }
func runClient(noLoop bool) { viper.SetDefault("script_timeout", 300) log.LogFile = true if viper.GetBool("master.enabled") { log.Info("Launching master server") go runProxy() } log.Info("Waiting for messages...") client, _ := ClientFromConfig() if viper.IsSet("master.host") { client.UseProxy = true client.ProxyAddress = "http://" + viper.GetString("master.host") } var persistantScripts = []*engine.ScriptEngine{} if viper.IsSet("agents") { engine.Agents = viper.GetStringMapString("agents") engine.AgentAccessKey = viper.GetString("access_key") } // Begin polling cycle for { time.Sleep(time.Duration(rand.Intn(1000)+2000) * time.Millisecond) resp, err := client.Get() // If an error is returned by the client we will begin an exponential back // off in retrying. The backoff caps out at 15 retries. if err != nil { log.Error("Error getting messages: " + err.Error()) if errorCount < 15 { errorCount++ } expBackoff := int(math.Pow(float64(errorCount), 2)) displacement := rand.Intn(errorCount + 1) sleepTime := expBackoff + displacement time.Sleep(time.Duration(sleepTime) * time.Second) continue } // A response was received but it might be an empty response from the // server timing out the long poll. errorCount = 0 if resp.Body != "" { log.Infof("Script receieved (%s)", resp.Message) eng := engine.New() eng.Constant("DEPLOYMENT_ID", resp.Deployment) eng.Constant("SCRIPT_ID", resp.Message) persistant, _ := eng.GetVar("$persistant", resp.Body) if p, ok := persistant.(bool); ok { if p { persistantScripts = append(persistantScripts, eng) } } if resp.Asset != "" { assetPath, err := client.DownloadAsset(resp.Asset) if err != nil { client.Respond(resp.Message, "Could not download asset", true) log.Error("Could not download asset") _, err = client.Delete(resp.Message) continue } else { log.Infof("Downloaded asset to %s", assetPath) } eng.SetAsset(assetPath) } executionStartTime := time.Now() errChan := make(chan string, 1) timeoutSeconds := viper.GetInt("script_timeout") go func() { err = eng.Execute(resp.Body) if err != nil { errChan <- err.Error() } else { errChan <- "" } }() select { case e := <-errChan: if e != "" { err = errors.New(e) } case <-time.After(time.Second * time.Duration(timeoutSeconds)): log.Warn("Timing out script") err = errors.New("Scirpt timeed out") } executionTime := time.Since(executionStartTime) log.Infof("Script executed in %s", executionTime) if err != nil { log.Error("Error executing script " + resp.Message) log.Debug(err.Error()) client.Respond(resp.Message, err.Error(), true) } _, err = client.Delete(resp.Message) if err != nil { log.Debug(err.Error()) log.Error("Could not confirm script.") } else { log.Debug("Script confirmed: " + resp.Message) } } if noLoop == true { break } } }
ShowRequests: viper.GetBool("show_requests"), } if len(args) == 0 { log.Fatal("No script specified.") } filename := args[0] mailboxes := args[1:] pattern := cmd.Flag("pattern").Value.String() if pattern == "" && len(mailboxes) == 0 { log.Fatal("Must provide either a list of mailboxes, a pattern, or both.") } data, err := ioutil.ReadFile(filename) if err != nil { log.Fatal(err.Error()) } eng := engine.New() err = eng.Validate(string(data)) if err != nil { log.Error(err.Error()) log.Fatal("Bad script syntax") } res, err := eng.ExecuteFunction("$local", string(data)) if err != nil { log.Debug(err.Error()) log.Fatal("Local execution error") } if res != "" && res != "undefined" { log.Info("Local: " + res) } resp, err := client.Put(mailboxes, pattern, string(data), cmd.Flag("name").Value.String(), cmd.Flag("attach").Value.String())