func TestHandler_SequentialAddRemove(t *testing.T) { w := httptest.NewRecorder() h := cart.NewHandler() var slice []tuple for i := 0; i <= NumberOfIterations; i++ { var item uint32 = uint32(rand.Intn(2048)) var customer uint32 = uint32(rand.Intn(2048)) i := tuple{customer, item} slice = append(slice, i) } for _, pair := range slice { r := modRequest(t, "add", pair.customer, pair.item) h.Mod(cart.AddToSet)(w, r) if !strings.HasPrefix(w.Body.String(), "OK") { t.Fatalf("expected `OK`, got `%s`", w.Body.String()) } } for _, pair := range slice { r := modRequest(t, "remove", pair.customer, pair.item) h.Mod(cart.RemoveFromSet)(w, r) if !strings.HasPrefix(w.Body.String(), "OK") { t.Fatalf("expected `OK`, got `%s`", w.Body.String()) } } h.Close() cart.RemoveContents("shards/") }
func main() { var flush = flag.Bool("flush", false, "Flush the persistent storage.") flag.Parse() if *flush { cart.RemoveContents("shards/") } // Parse configuration. c, err := ParseConfigFile("cmd/cartd/cart.sample.toml") if err != nil { fmt.Println("Failed to load configuration:", err.Error()) os.Exit(1) } // Create handler. h := cart.NewHandler() // Start HTTP server. fmt.Println("Starting cart server on", c.Address()) // Associate a function with each query type. http.HandleFunc("/add", h.Mod(cart.AddToSet)) http.HandleFunc("/remove", h.Mod(cart.RemoveFromSet)) http.HandleFunc("/list", h.List) http.HandleFunc("/ping", h.Ping) // Creates a new service goroutine for each requst. log.Fatal(http.ListenAndServe(c.Address(), nil)) }
// Ensure the Handler returns a 404 Not Found for an unknown path. func TestHandler_NotFound(t *testing.T) { r, err := http.NewRequest("GET", "http://localhost/foo", nil) if err != nil { t.Fatalf("unexpected error: %s", err) } w := httptest.NewRecorder() cart.NewHandler().ServeHTTP(w, r) if w.Code != 404 { t.Fatalf("expected status code 404, got %d", w.Code) } }
// Ensure the Handler can respond to a ping request. func TestHandler_Ping(t *testing.T) { r, err := http.NewRequest("GET", "http://localhost/ping", nil) if err != nil { t.Fatalf("unexpected error: %s", err) } w := httptest.NewRecorder() cart.NewHandler().Ping(w, r) if w.Body.String() != "ping\n" { t.Fatalf("expected `ping`, got `%s`", w.Body.String()) } else if w.Code != 200 { t.Fatalf("expected status code 200, got %d", w.Code) } }
func TestHandler_Remove(t *testing.T) { var item uint32 = 1234 var customer uint32 = 4321 r := modRequest(t, "remove", customer, item) w := httptest.NewRecorder() h := cart.NewHandler() h.Mod(cart.RemoveFromSet)(w, r) h.Close() cart.RemoveContents("shards/") if !strings.HasPrefix(w.Body.String(), "error:") { t.Fatalf("expected `error:`, got `%s`", w.Body.String()) } }
func TestHandler_Add(t *testing.T) { var item uint32 = 1234 var customer uint32 = 4321 r := modRequest(t, "add", customer, item) w := httptest.NewRecorder() h := cart.NewHandler() h.Mod(cart.AddToSet)(w, r) h.Close() cart.RemoveContents("shards/") if w.Body.String() != "OK\n" { t.Fatalf("expected `OK`, got `%s`", w.Body.String()) } else if w.Code != 200 { t.Fatalf("expected status code 200, got %d", w.Code) } }
func TestHandler_ParallelAdd(t *testing.T) { h := cart.NewHandler() var wg sync.WaitGroup data := make(chan map[uint32]map[uint32]uint32) done := make(chan map[uint32]map[uint32]uint32) go aggregator(data, done) for i := 0; i < NumberOfThreads; i++ { wg.Add(1) go parallelAdd(t, h, &wg, data) } total := <-done h.Close() checkCorrectness(t, total, h) h.Close() cart.RemoveContents("shards/") }