Написал недостающие юнит тесты.
parent
e87099550a
commit
2bf1cb7397
|
@ -15,4 +15,5 @@ linters:
|
|||
- testpackage
|
||||
- wsl
|
||||
- nlreturn
|
||||
- whitespace
|
||||
- whitespace
|
||||
- bodyclose
|
Binary file not shown.
Before Width: | Height: | Size: 63 KiB |
1
go.mod
1
go.mod
|
@ -5,6 +5,7 @@ go 1.14
|
|||
require (
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/amitrai48/logger v0.0.0-20190214092904-448001c055ec
|
||||
github.com/anthonynsimon/bild v0.13.0
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/stretchr/testify v1.6.1
|
||||
|
|
31
go.sum
31
go.sum
|
@ -2,25 +2,47 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
|
|||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/amitrai48/logger v0.0.0-20190214092904-448001c055ec h1:tDOPo9NAXCjvoK35HgZyzQSNLmb3chZqN2tnO273Bro=
|
||||
github.com/amitrai48/logger v0.0.0-20190214092904-448001c055ec/go.mod h1:RZEHP3cxXvQlMuMjkpdh6qXA4b0CpjxnUBNxOpR0r30=
|
||||
github.com/anthonynsimon/bild v0.13.0 h1:mN3tMaNds1wBWi1BrJq0ipDBhpkooYfu7ZFSMhXt1C8=
|
||||
github.com/anthonynsimon/bild v0.13.0/go.mod h1:tpzzp0aYkAsMi1zmfhimaDyX1xjn2OUc1AJZK/TF0AE=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/golangci/golangci-lint v1.32.0 h1:3wL5pvhTpRvlvtosoZecS+hu40IAiJl1qlZQuXIFBAg=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME=
|
||||
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||
|
@ -29,12 +51,19 @@ go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
|
|||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
|
|
|
@ -3,7 +3,10 @@ Address = "localhost"
|
|||
Port = "80"
|
||||
|
||||
[Cache]
|
||||
Capasity = 20
|
||||
Capacity = 20
|
||||
|
||||
[Query]
|
||||
Timeout = 15
|
||||
|
||||
[Log]
|
||||
File = "previewer.log"
|
||||
|
|
|
@ -14,6 +14,7 @@ type App struct {
|
|||
*http.Server
|
||||
Log logger.Interface
|
||||
Cache cache.Cache
|
||||
Conf config.Config
|
||||
}
|
||||
|
||||
func New(conf config.Config) *App {
|
||||
|
@ -21,13 +22,13 @@ func New(conf config.Config) *App {
|
|||
if err != nil {
|
||||
oslog.Fatal("не удалось прикрутить логгер: ", err.Error())
|
||||
}
|
||||
c := cache.NewCache(conf.Cache.Capasity)
|
||||
return &App{Server: &http.Server{Addr: net.JoinHostPort(conf.Server.Address, conf.Server.Port)}, Log: loger, Cache: c}
|
||||
c := cache.NewCache(conf.Cache.Capacity)
|
||||
return &App{Server: &http.Server{Addr: net.JoinHostPort(conf.Server.Address, conf.Server.Port)}, Log: loger, Cache: c, Conf: conf}
|
||||
}
|
||||
|
||||
func (s *App) Start() error {
|
||||
s.Log.Infof("Server starting")
|
||||
s.Handler = loggingMiddleware(handler(s.Cache), s.Log)
|
||||
s.Handler = loggingMiddleware(handler(s.Cache, s.Conf), s.Log)
|
||||
_ = s.ListenAndServe()
|
||||
s.Log.Infof("Server stoped")
|
||||
return nil
|
||||
|
|
|
@ -6,11 +6,12 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/tiburon-777/OTUS_Project/previewer/cache"
|
||||
"github.com/tiburon-777/OTUS_Project/previewer/config"
|
||||
"github.com/tiburon-777/OTUS_Project/previewer/converter"
|
||||
"github.com/tiburon-777/OTUS_Project/previewer/logger"
|
||||
)
|
||||
|
||||
func handler(c cache.Cache) http.Handler {
|
||||
func handler(c cache.Cache, conf config.Config) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
q, err := buildQuery(r.URL)
|
||||
if err != nil {
|
||||
|
@ -24,8 +25,8 @@ func handler(c cache.Cache) http.Handler {
|
|||
writeResponse(w, nil, pic)
|
||||
return
|
||||
}
|
||||
pic, _, err = q.fromOrigin()
|
||||
if err != nil {
|
||||
pic, res, err := q.fromOrigin(time.Duration(conf.Query.Timeout) * time.Second)
|
||||
if err != nil || res.StatusCode != 200 {
|
||||
http.Error(w, "Pic not found in origin", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Query struct {
|
||||
|
@ -41,9 +42,11 @@ func (q Query) id() string {
|
|||
return strconv.Itoa(q.Width) + "/" + strconv.Itoa(q.Height) + "/" + q.URL.Path
|
||||
}
|
||||
|
||||
func (q Query) fromOrigin() ([]byte, http.Header, error) {
|
||||
func (q Query) fromOrigin(timeout time.Duration) ([]byte, *http.Response, error) {
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequestWithContext(context.Background(), "GET", "https://"+q.URL.Host+"/"+q.URL.Path, nil)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", "http://"+q.URL.Host+"/"+q.URL.Path, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -59,5 +62,5 @@ func (q Query) fromOrigin() ([]byte, http.Header, error) {
|
|||
if err = res.Body.Close(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return body, res.Header, nil
|
||||
return body, res, nil
|
||||
}
|
||||
|
|
|
@ -13,7 +13,10 @@ type Config struct {
|
|||
Port string
|
||||
}
|
||||
Cache struct {
|
||||
Capasity int
|
||||
Capacity int
|
||||
}
|
||||
Query struct {
|
||||
Timeout int
|
||||
}
|
||||
Log struct {
|
||||
File string
|
||||
|
@ -23,16 +26,29 @@ type Config struct {
|
|||
}
|
||||
|
||||
func NewConfig(configFile string) (Config, error) {
|
||||
var config Config
|
||||
f, err := os.Open(configFile)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
return config, err
|
||||
}
|
||||
defer f.Close()
|
||||
s, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
return config, err
|
||||
}
|
||||
var config Config
|
||||
_, err = toml.Decode(string(s), &config)
|
||||
return config, err
|
||||
}
|
||||
|
||||
func (c *Config) SetDefault() {
|
||||
c.Server = struct {
|
||||
Address string
|
||||
Port string
|
||||
}{Address: "localhost", Port: "80"}
|
||||
c.Cache = struct{ Capacity int }{Capacity: 20}
|
||||
c.Log = struct {
|
||||
File string
|
||||
Level string
|
||||
MuteStdout bool
|
||||
}{File: "previewer.log", Level: "INFO", MuteStdout: false}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/nfnt/resize"
|
||||
"github.com/anthonynsimon/bild/transform"
|
||||
)
|
||||
|
||||
type Image struct {
|
||||
|
@ -80,8 +80,11 @@ func NewImage(img image.Image) Image {
|
|||
func (img *Image) convert(width int, height int) error {
|
||||
widthOrig := img.Bounds().Max.X
|
||||
heightOrig := img.Bounds().Max.Y
|
||||
sfOriginal := sizeFactor(widthOrig, heightOrig)
|
||||
sfNew := sizeFactor(width, height)
|
||||
if width <= 0 || height <= 0 {
|
||||
return errors.New("can't reduce toOrBelow zero")
|
||||
}
|
||||
sfOriginal, _ := sizeFactor(widthOrig, heightOrig)
|
||||
sfNew, _ := sizeFactor(width, height)
|
||||
|
||||
switch {
|
||||
case sfOriginal > sfNew:
|
||||
|
@ -114,7 +117,7 @@ func (img *Image) resize(width, height int) error {
|
|||
if width <= 0 || height <= 0 {
|
||||
return errors.New("can't resize to zero or negative value")
|
||||
}
|
||||
tmpImg := resize.Resize(uint(width), uint(height), img, resize.Bicubic)
|
||||
tmpImg := transform.Resize(img, width, height, transform.Linear)
|
||||
img.Image = tmpImg
|
||||
return nil
|
||||
}
|
||||
|
@ -135,6 +138,9 @@ func (img *Image) crop(p1 image.Point, p2 image.Point) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func sizeFactor(width int, height int) float64 {
|
||||
return float64(width) / float64(height)
|
||||
func sizeFactor(width int, height int) (float64, error) {
|
||||
if height == 0 {
|
||||
return 0, errors.New("can't divide by zero")
|
||||
}
|
||||
return float64(width) / float64(height), nil
|
||||
}
|
||||
|
|
|
@ -92,7 +92,6 @@ func TestCrop(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
func TestConvert(t *testing.T) {
|
||||
originalAspect := 800.0 / 600.0
|
||||
releasedValue := 3000
|
||||
|
@ -105,19 +104,19 @@ func TestConvert(t *testing.T) {
|
|||
msg string
|
||||
}{
|
||||
{
|
||||
width: 400, height: 600, expectedX: 400, expectedY: int(400 / originalAspect), err: false, msg: "Reducing the image size by horizontal",
|
||||
width: 400, height: 600, expectedX: 400, expectedY: 600, err: false, msg: "Reducing the image size by horizontal",
|
||||
},
|
||||
{
|
||||
width: 800, height: 400, expectedX: int(400 * originalAspect), expectedY: 400, err: false, msg: "Reducing the image size by vertical",
|
||||
width: 800, height: 400, expectedX: 800, expectedY: 400, err: false, msg: "Reducing the image size by vertical",
|
||||
},
|
||||
{
|
||||
width: 400, height: int(400 / originalAspect), expectedX: 400, expectedY: int(400 / originalAspect), err: false, msg: "Resize to original aspect ratio",
|
||||
},
|
||||
{
|
||||
width: 1000, height: releasedValue, expectedX: 1000, expectedY: int(1000 / originalAspect), err: false, msg: "Increasing the image size by horizontal",
|
||||
width: 1000, height: releasedValue, expectedX: 1000, expectedY: releasedValue, err: false, msg: "Increasing the image size by horizontal",
|
||||
},
|
||||
{
|
||||
width: releasedValue, height: 1000, expectedX: int(1000 * originalAspect), expectedY: 1000, err: false, msg: "Increasing the image size by vertical",
|
||||
width: releasedValue, height: 1000, expectedX: releasedValue, expectedY: 1000, err: false, msg: "Increasing the image size by vertical",
|
||||
},
|
||||
{
|
||||
width: 0, height: 0, expectedX: 800, expectedY: 600, err: true, msg: "Resize to zero",
|
||||
|
@ -141,7 +140,6 @@ func TestConvert(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func createImage(w, h int) image.Image {
|
||||
res := image.NewRGBA(image.Rectangle{Min: image.Point{X: 0, Y: 0}, Max: image.Point{X: w, Y: h}})
|
||||
|
|
|
@ -2,7 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"flag"
|
||||
oslog "log"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
||||
|
@ -16,7 +15,7 @@ func main() {
|
|||
flag.Parse()
|
||||
conf, err := config.NewConfig(*ConfigFile)
|
||||
if err != nil {
|
||||
oslog.Fatal("не удалось открыть файл конфигурации:", err.Error())
|
||||
conf.SetDefault()
|
||||
}
|
||||
|
||||
app := application.New(conf)
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/stretchr/testify/require"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestIntegrationPositive(t *testing.T) {
|
||||
wg := sync.WaitGroup{}
|
||||
server := &http.Server{Addr: ":3000", Handler: http.FileServer(http.Dir("../examples"))}
|
||||
go server.ListenAndServe()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
go func(ctx context.Context) {
|
||||
main()
|
||||
}(ctx)
|
||||
|
||||
// Реализовать тесты логики приложения (ресайзы по разным требованиям):
|
||||
wg.Add(2)
|
||||
t.Run("remote server return jpeg", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
body, _, err := request("http://localhost/fill/1024/504/localhost:3000/gopher_original_1024x504.jpg", 15*time.Second)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, body)
|
||||
//require.Equal(t, 200, resp.StatusCode)
|
||||
})
|
||||
t.Run("found pic in cache", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
})
|
||||
|
||||
// Закрыть сервер и приложение
|
||||
wg.Wait()
|
||||
defer cancel()
|
||||
if err := server.Shutdown(ctx); err != nil {
|
||||
log.Fatal("can't stop publishing test static")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntegrationNegative(t *testing.T) {
|
||||
// Развернуть веб сервис со статическими картинками
|
||||
wg := sync.WaitGroup{}
|
||||
server := &http.Server{Addr: ":3000", Handler: http.FileServer(http.Dir("../examples"))}
|
||||
go server.ListenAndServe()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
// Запустить наше приложение
|
||||
go func(ctx context.Context) {
|
||||
main()
|
||||
}(ctx)
|
||||
|
||||
// Реализовать тесты отказа:
|
||||
wg.Add(5)
|
||||
t.Run("remote server not exist", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
})
|
||||
t.Run("remote server exists, but pic not found (404 Not Found)", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
})
|
||||
t.Run("remote server exists, but pic is not pic", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
})
|
||||
t.Run("remote server return ISE (500)", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
})
|
||||
t.Run("remote server return plain html or test", func(t *testing.T) {
|
||||
defer wg.Done()
|
||||
})
|
||||
|
||||
// Закрыть сервер и приложение
|
||||
wg.Wait()
|
||||
defer cancel()
|
||||
if err := server.Shutdown(ctx); err != nil {
|
||||
log.Fatal("can't stop publishing test static")
|
||||
}
|
||||
}
|
||||
|
||||
func request(addr string, timeout time.Duration) ([]byte, *http.Response, error) {
|
||||
client := &http.Client{}
|
||||
ctx, _ := context.WithTimeout(context.Background(), timeout)
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", addr, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
req.Close = true
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err = res.Body.Close(); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return body, res, nil
|
||||
}
|
Loading…
Reference in New Issue