func main() { auction := tyche.NewAuction() master := tyche.NewMaster(auction) events := make(tyche.Producer) master.AddProducer(events) sa := tyche.NewSleepAgent(100, master.Auction) master.AddConsumer(sa.Consumer()) go master.StartAgent(sa) ra := tyche.NewReadingAgent(70, master.Auction) master.AddConsumer(ra.Consumer()) go master.StartAgent(ra) go func() { for { select { case b := <-auction.Leaders: log.Print("NEW TOP BID: %+v", b) } } }() for i := 0; i < 200; i++ { time.Sleep(1 * time.Second) e := models.NewEvent() e.Name = "test " events <- e } }
// TestStream test the `stream" command func TestStream(t *testing.T) { ui, db, user, c := newMockStreamCommand(t) // in another go routine start streaming go c.Run([]string{}) // now give it an event changes := db.Changes() e := models.NewEvent() e.SetID(db.NewID()) e.SetOwner(user) eventName := "event name" e.Name = eventName if err := db.Save(e); err != nil { t.Fatal(err) } time.Sleep(10 * time.Millisecond) // give the go routine running command time to read from channel // wait for that change to go through the pipeline select { case change := <-*changes: t.Logf("Change received:\n%+v", change) t.Logf("Record received:\n%+v", change.Record) case <-time.After(100 * time.Millisecond): t.Fatal("timeout waiting for change") } // now check outputs errput := ui.ErrorWriter.String() if ui.ErrorWriter == nil { errput = "" } output := ui.OutputWriter.String() if ui.OutputWriter == nil { output = "" } t.Logf("Error output:\n %s", errput) t.Logf("Output:\n %s", output) // verify there were no errors if errput != "" { t.Fatalf("Expected no error output, got: %s", errput) } // verify some of the output if !strings.Contains(output, eventName) { t.Fatalf("Output should have the event's name: '%s'", eventName) } }
func TestMobileLocationPOST(t *testing.T) { db, _, s := testInstance(t, context.Background()) defer s.Close() _, cred := testUser(t, db) altitude, latitude, longitude := 50.0, 60.0, 70.0 params := url.Values{} params.Set("altitude", strconv.FormatFloat(altitude, 'E', -1, 64)) params.Set("latitude", strconv.FormatFloat(latitude, 'E', -1, 64)) params.Set("longitude", strconv.FormatFloat(longitude, 'E', -1, 64)) url := s.URL + routes.MobileLocation + "?" + params.Encode() t.Logf("Constructed URL: %s", url) req, err := http.NewRequest("POST", url, nil) if err != nil { t.Fatal(err) } req.SetBasicAuth(cred.Public, cred.Private) resp, err := http.DefaultClient.Do(req) if err != nil { t.Fatal(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatal(err) } t.Logf("Code: %d", resp.StatusCode) t.Logf("Body:\n%s", body) if resp.StatusCode != http.StatusCreated { t.Fatalf("Expected status code of %d", http.StatusCreated) } var respData map[string]interface{} if err := json.Unmarshal(body, &respData); err != nil { t.Fatal(err) } t.Logf("Response data:\n%+v", respData) iter, err := db.Query(models.EventKind).Select(data.AttrMap{ "id": respData["id"].(string), }).Execute() if err != nil { t.Fatal(err) } e := models.NewEvent() if !iter.Next(e) { t.Fatal("There should be at least one event") } l, err := e.Location(db) if err != nil { t.Fatal(err) } if l.Altitude != altitude { t.Fatal("Altitudes don't match") } }
func TestDB(t *testing.T) { db, _, s := testInstance(t, context.Background()) defer s.Close() user, cred := testUser(t, db) gdb := &gaia.DB{ URL: s.URL, Username: cred.Public, Password: cred.Private, Client: http.DefaultClient, } t.Log("Creating a test task") taskName := "task name" task := models.NewTask() task.SetID(db.NewID()) task.CreatedAt = time.Now() task.OwnerId = user.Id task.Name = taskName task.UpdatedAt = time.Now() if err := db.Save(task); err != nil { t.Fatal(err) } t.Log("Test task created") t.Log("Creating a task to retrieve using the gaia db") getTask := models.NewTask() getTask.SetID(task.ID()) // use task's id t.Logf("Retrieving task using ID: %s and the gaia db", task.ID().String()) if err := gdb.PopulateByID(getTask); err != nil { t.Fatal(err) } t.Logf("Task retrieved: %+v", getTask) if getTask.Name != taskName { t.Fatal("Task names should match") } t.Log("Deleting task using the gaia db") if err := gdb.Delete(getTask); err != nil { t.Fatal(err) } t.Log("Task deleted") t.Log("Checking that task is no longer in real database") if err := db.PopulateByID(task); err != data.ErrNotFound { t.Fatal("Task should be gone") } t.Log("Checked") t.Log("Using gaia db to recreate that task") if err := gdb.Save(task); err != nil { t.Fatal(err) } t.Log("Recreated") t.Log("Checking that task back in real database") if err := db.PopulateByID(task); err != nil { t.Fatal("Task should be back") } if task.Name != taskName { t.Fatalf("Task name should be %s", taskName) } t.Log("Checked") t.Log("Changing task name") newName := "new name" getTask.Name = newName t.Log("Changed") t.Log("Using gaia db to update the task") if err := gdb.Save(getTask); err != nil { t.Fatal(err) } t.Log("Updated") t.Log("Re-retrieving that task from the real db") if err := db.PopulateByID(task); err != nil { t.Fatal(err) } t.Log("Retrieved") t.Log("Checking that the task was updated") if task.Name != newName { t.Fatalf("Save should have updated the task") } t.Log("Checked") t.Log("Querying for the task using gaia db") q := gdb.Query(models.TaskKind) q.Select(data.AttrMap{ "name": newName, }) iter, err := q.Execute() if err != nil { t.Fatal(err) } t.Log("Query executed") t.Log("Examining query results") result := models.NewTask() iter.Next(result) if iter.Next(result) != false { t.Fatal("Should only be one result") } if err := iter.Close(); err != nil { t.Fatal(err) } if result.ID().String() != task.ID().String() { t.Fatal("Ids should match") } if result.Name != newName { t.Fatal("should ahve retrievied the task with the new name") } t.Log("Examined") changes := db.Changes() eventName := "hello" e := models.NewEvent() e.SetID(db.NewID()) e.SetOwner(user) e.Name = eventName if err := db.Save(e); err != nil { t.Fatal(err) } select { case c := <-*changes: t.Logf("Change received:\n%++v", c) if c.Record.(*models.Event).Name != eventName { t.Fatalf("Change should have been recieved with event record and name '%s'", eventName) } case <-time.After(50 * time.Millisecond): t.Fatalf("Timed out waiting for change") } }
func MobileLocationPOST(ctx context.Context, w http.ResponseWriter, r *http.Request, l services.Logger, db data.DB) { // Parse the form value if err := r.ParseForm(); err != nil { l.Printf("MobileLocationPOST Error: %s", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } // Altitude alt := r.FormValue(altitudeParam) if alt == "" { http.Error(w, "You must specify an altitude", http.StatusBadRequest) return } altitude, err := strconv.ParseFloat(alt, 64) if err != nil { http.Error(w, "Parsing altitude", http.StatusBadRequest) return } // Latitude lat := r.FormValue(latitudeParam) if lat == "" { http.Error(w, "You must specify a latitude", http.StatusBadRequest) return } latitude, err := strconv.ParseFloat(lat, 64) if err != nil { http.Error(w, "Parsing latitude", http.StatusBadRequest) return } // Longitude lon := r.FormValue(longitudeParam) if lon == "" { http.Error(w, "You must specify an longitude", http.StatusBadRequest) return } longitude, err := strconv.ParseFloat(lon, 64) if err != nil { http.Error(w, "Parsing longitude", http.StatusBadRequest) return } // Retrieve the user this request was authenticated as u, ok := user.FromContext(ctx) if !ok { // This is certainly an issue, and should _never_ happen l.Print("MobileLocationPOST Error: failed to retrieve user from context") http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } // Create location loc := location.NewCoords(altitude, latitude, longitude) loc.SetID(db.NewID()) loc.SetOwner(u) now := loc.CreatedAt e := models.NewEvent() e.CreatedAt = now e.SetID(db.NewID()) e.SetOwner(u) e.Name = "Location Update" e.SetLocation(loc) e.Time = now e.UpdatedAt = now locationTag, err1 := tag.ForName(db, u, tag.Location) updateTag, err2 := tag.ForName(db, u, tag.Update) mobileTag, err3 := tag.ForName(db, u, tag.Mobile) if err1 != nil || err2 != nil || err3 != nil { l.Printf("MobileLocationPOST Error: %s", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } e.IncludeTag(locationTag) e.IncludeTag(updateTag) e.IncludeTag(mobileTag) if err = db.Save(loc); err != nil { l.Printf("MobileLocationPOST Error: %s", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if err = db.Save(e); err != nil { l.Printf("MobileLocationPOST Error: %s", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } bytes, err := json.MarshalIndent(e, "", " ") if err != nil { l.Printf("MobileLocationPOST Error: while marshalling json %s", err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } w.WriteHeader(http.StatusCreated) w.Header().Set("Content-Type", "application/json") w.Write(bytes) }