Skip to content

Commit

Permalink
Merge pull request cockroachdb#12 from cuongdo/fixes
Browse files Browse the repository at this point in the history
Various bug fixes
  • Loading branch information
cuongdo committed Feb 17, 2017
2 parents c736674 + 3cd3b8e commit 0748800
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 20 deletions.
2 changes: 1 addition & 1 deletion go/gorm/server.go
Expand Up @@ -45,7 +45,7 @@ func (s *Server) RegisterRouter(router *httprouter.Router) {
}

func (s *Server) ping(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
writeTextResult(w, "pong")
writeTextResult(w, "go/gorm")
}

func (s *Server) getCustomers(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
Expand Down
2 changes: 1 addition & 1 deletion java/hibernate/Makefile
Expand Up @@ -30,4 +30,4 @@ start:

.PHONY: deps
deps:
$(GRADLE) assemble
$(GRADLE) assemble --stacktrace
Expand Up @@ -10,7 +10,7 @@ public class PingService {
@GET
@Produces("text/plain")
public String ping() {
return "pong";
return "java/hibernate";
}

}
37 changes: 30 additions & 7 deletions testing/api_handler.go
Expand Up @@ -4,20 +4,23 @@ import (
"bytes"
"encoding/json"
"io/ioutil"
"net"
"net/http"
"strings"

"github.com/pkg/errors"

"github.com/cockroachdb/examples-orms/go/gorm/model"
)

const (
applicationAddr = "http://localhost:6543"
applicationAddr = "localhost:6543"
applicationURL = "http://" + applicationAddr

pingPath = applicationAddr + "/ping"
customersPath = applicationAddr + "/customer"
ordersPath = applicationAddr + "/order"
productsPath = applicationAddr + "/product"
pingPath = applicationURL + "/ping"
customersPath = applicationURL + "/customer"
ordersPath = applicationURL + "/order"
productsPath = applicationURL + "/product"

jsonContentType = "application/json"
)
Expand All @@ -27,8 +30,28 @@ const (
// across all ORMs.
type apiHandler struct{}

func (apiHandler) ping() error {
_, err := http.Get(pingPath)
func (apiHandler) canDial() bool {
conn, err := net.Dial("tcp", applicationAddr)
if err != nil {
return false
}
conn.Close()
return true
}

func (apiHandler) ping(expected string) error {
resp, err := http.Get(pingPath)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return errors.Errorf("HTTP error %s", resp.Status)
}
b, err := ioutil.ReadAll(resp.Body)
if body := strings.TrimSpace(string(b)); body != expected {
return errors.Errorf("ping response %s != expected %s", body, expected)
}
return err
}

Expand Down
38 changes: 28 additions & 10 deletions testing/main_test.go
Expand Up @@ -4,8 +4,10 @@ import (
"bytes"
"database/sql"
"fmt"
"io"
"log"
"net/url"
"os"
"os/exec"
"strings"
"syscall"
Expand All @@ -25,8 +27,12 @@ type application struct {
orm string
}

func (app application) name() string {
return fmt.Sprintf("%s/%s", app.language, app.orm)
}

func (app application) dir() string {
return fmt.Sprintf("../%s/%s", app.language, app.orm)
return fmt.Sprintf("../%s", app.name())
}

func (app application) dbName() string {
Expand Down Expand Up @@ -85,20 +91,19 @@ func initORMApp(t *testing.T, app application, dbURL *url.URL) (killFunc, restar

cmd := exec.Command(args[0], args[1:]...)

// Set up stderr so we can later verify that it's clean.
// Set up stderr to display to console and store in a buffer, so we can later
// verify that it's clean.
stderr := new(bytes.Buffer)
cmd.Stderr = stderr
cmd.Stderr = io.MultiWriter(stderr, os.Stderr)

// make will launch the application in a child process, and this is the most
// straightforward way to kill all ancestors.
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
killed := false
killCmd := func() {
if s := stderr.String(); len(s) > 0 {
log.Print("app error:", s)
}
if !killed {
syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
waitForAppExit()
}
killed = true
}
Expand All @@ -111,13 +116,12 @@ func initORMApp(t *testing.T, app application, dbURL *url.URL) (killFunc, restar
log.Printf("process %d started: %s", cmd.Process.Pid, strings.Join(args, " "))
}

if err := waitForInit(); err != nil {
if err := waitForInit(app); err != nil {
killCmd()
t.Fatalf("error waiting for http server initialization: %v stderr=%s", err, stderr.String())
}
if s := stderr.String(); len(s) > 0 {
killCmd()
t.Fatalf("stderr=%s", s)
}

restartCmd := func() (killFunc, restartFunc) {
Expand All @@ -129,15 +133,15 @@ func initORMApp(t *testing.T, app application, dbURL *url.URL) (killFunc, restar
}

// waitForInit retries until a connection is successfully established.
func waitForInit() error {
func waitForInit(app application) error {
const maxWait = 3 * time.Minute
const waitDelay = 250 * time.Millisecond
const maxWaitLoops = int(maxWait / waitDelay)

var err error
var api apiHandler
for i := 0; i < maxWaitLoops; i++ {
if err = api.ping(); err == nil {
if err = api.ping(app.name()); err == nil {
return err
}
log.Printf("waitForInit: %v", err)
Expand All @@ -146,6 +150,20 @@ func waitForInit() error {
return err
}

// waitForExit waits indefinitely for the HTTP port of the ORM to stop
// listening.
func waitForAppExit() {
const waitDelay = time.Second
var api apiHandler
for {
if !api.canDial() {
break
}
log.Print("waiting for app to exit")
time.Sleep(waitDelay)
}
}

func testORM(t *testing.T, language, orm string) {
app := application{
language: language,
Expand Down

0 comments on commit 0748800

Please sign in to comment.