// SetUp creates the database. func SetUp(seed string) { conf := newConf() // Retrieve the original DSN value originalDSN := conf.Driver.OpenStr // Remove the database name conf.Driver.OpenStr = strings.Replace(conf.Driver.OpenStr, "DBNAME", "", -1) db, err := sql.Open(conf.Driver.Name, conf.Driver.OpenStr) if err != nil { log.WithError(fail.Trace(err)).Fatal("Could not open db connection") } // Create a database for this test. dbName := "test_" + seed _, err = db.Query("CREATE DATABASE IF NOT EXISTS " + dbName) if err != nil { log.WithError(fail.Trace(err)).WithField("name", dbName).Fatal("Could not create database") } // Replace the dsn for Goose's sake with the new database name conf.Driver.OpenStr = strings.Replace(originalDSN, "DBNAME", dbName, -1) os.Setenv("DATABASE_URL", conf.Driver.OpenStr) // Get the migrations to run then run them target, err := goose.GetMostRecentDBVersion(conf.MigrationsDir) if err != nil { log.WithError(fail.Trace(err)).Fatal("Could not get most recent db version") } if err := goose.RunMigrations(conf, conf.MigrationsDir, target); err != nil { log.WithError(fail.Trace(err)).Fatal("Could not run setup migrations") } }
// TearDown destroys the database. func TearDown(seed string) { conf := newConf() // Delete the database entirely. dbName := "test_" + seed conf.Driver.OpenStr = strings.Replace(conf.Driver.OpenStr, "DBNAME", dbName, -1) db, err := sql.Open(conf.Driver.Name, conf.Driver.OpenStr) if err != nil { log.WithError(fail.Trace(err)).Fatal("Could not open db connection") } _, err = db.Query("DROP DATABASE IF EXISTS " + dbName) if err != nil { log.WithError(fail.Trace(err)).WithField("name", dbName).Fatal("Could not drop db") } }
func newConf() *goose.DBConf { file := config.String("BASE_DIR") + config.String("DBCONF_DIR", "db") conf, err := goose.NewDBConf(file, "test", "") if err != nil { log.WithError(fail.Trace(err)).WithField("filename", file).Fatal("Could not create new conf") } return conf }
// initSneakerSecrets loads any remote secrets from S3. func initSneakerSecrets() { secrets, err := RemoteSecrets() if err != nil { log.WithError(err).Fatal("Could not download secrets") } log.WithField("total", len(secrets)).Info("Found remote secrets") for name, value := range secrets { log.WithField("key", name).Info("Setting secret") os.Setenv(name, string(value)) } }
// ServeHTTP implements the http.Handler interface and will record information // about a request, and log it after the request runs. func (logger Logger) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Retrieve the last client ip from the RemoteAddr header field. clientIP := r.RemoteAddr if colon := strings.LastIndex(clientIP, ":"); colon != -1 { clientIP = clientIP[:colon] } // Create an access log record. record := &LogRecord{ ResponseWriter: w, ip: clientIP, time: time.Now(), method: r.Method, uri: r.RequestURI, protocol: r.Proto, } // Set up a function to run once the request has been served. defer func(record *LogRecord, startTime time.Time) { // Recover from a panic if possible. if recovered := recover(); recovered != nil { var err error // Ensure we have an error interface. if thisErr, ok := recovered.(error); ok { err = thisErr } else { err = fmt.Errorf("%s", recovered) } if err != nil { log.WithError(err).Error("Recovered from panic") vc.RespondWithError(w, r, err) } } // Log the response info. finishTime := time.Now() record.time = finishTime.UTC() record.duration = finishTime.Sub(startTime) log.WithFields(record.Data()).Infof("") }(record, time.Now()) // Serve the request. logger.Handler.ServeHTTP(record, r) }
// RespondWithError will return an error response with the appropriate message, // and status codes set. func RespondWithError(w http.ResponseWriter, r *http.Request, err error) { isPublicError := false errorResponse := APIError{ Error: err.Error(), } code := http.StatusInternalServerError if statusErr, ok := err.(StatusError); ok { // If we get a status code, this error can be considered a public error. isPublicError = true code = statusErr.StatusCode() } if descriptiveErr, ok := err.(DescriptiveError); ok { errorResponse.Description = descriptiveErr.ErrorDescription() } if annotatedErr, ok := err.(AnnotatedError); ok { errorResponse.Fields = annotatedErr.ErrorFields() } w.WriteHeader(code) // Now log some information about the failure. logData := map[string]interface{}{} if structuredLogErr, ok := err.(StructuredLogsError); ok { for key, value := range structuredLogErr.LogFields() { logData[key] = value } } logData["status"] = code if !isPublicError { logData["original_error"] = err.Error() err = fail.NewPrivate(err) errorResponse.Error = err.Error() } body := DefaultRenderer.RenderError(errorResponse) w.Write(body) log.WithError(err).WithFields(logrus.Fields(logData)).Error("Returning error response") }