From 2bf1cb7397d6e9325206f6149344250e375f42ff Mon Sep 17 00:00:00 2001 From: Andrey Ivanov Date: Tue, 3 Nov 2020 19:25:35 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB=20?= =?UTF-8?q?=D0=BD=D0=B5=D0=B4=D0=BE=D1=81=D1=82=D0=B0=D1=8E=D1=89=D0=B8?= =?UTF-8?q?=D0=B5=20=D1=8E=D0=BD=D0=B8=D1=82=20=D1=82=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D1=8B.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .golangci.yml | 3 +- examples/_gopher_original_1024x504.jpg | Bin 64212 -> 0 bytes go.mod | 1 + go.sum | 31 +++++++- previewer.conf | 5 +- previewer/application/application.go | 7 +- previewer/application/handlers.go | 7 +- previewer/application/query.go | 9 ++- previewer/config/config.go | 24 +++++- previewer/converter/converter.go | 18 +++-- previewer/converter/converter_test.go | 10 +-- previewer/main.go | 3 +- previewer/main_test.go | 101 +++++++++++++++++++++++++ 13 files changed, 189 insertions(+), 30 deletions(-) delete mode 100644 examples/_gopher_original_1024x504.jpg create mode 100644 previewer/main_test.go diff --git a/.golangci.yml b/.golangci.yml index b4f133d..0e5a3b5 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -15,4 +15,5 @@ linters: - testpackage - wsl - nlreturn - - whitespace \ No newline at end of file + - whitespace + - bodyclose \ No newline at end of file diff --git a/examples/_gopher_original_1024x504.jpg b/examples/_gopher_original_1024x504.jpg deleted file mode 100644 index efc1a05ff20bbd23e25634cccfc698f83012ed45..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64212 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 diff --git a/go.mod b/go.mod index e39c786..bf37472 100644 --- a/go.mod +++ b/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 diff --git a/go.sum b/go.sum index bc0f509..5a103a4 100644 --- a/go.sum +++ b/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= diff --git a/previewer.conf b/previewer.conf index 20d8440..95b4767 100644 --- a/previewer.conf +++ b/previewer.conf @@ -3,7 +3,10 @@ Address = "localhost" Port = "80" [Cache] -Capasity = 20 +Capacity = 20 + +[Query] +Timeout = 15 [Log] File = "previewer.log" diff --git a/previewer/application/application.go b/previewer/application/application.go index 92c6461..d58ce24 100644 --- a/previewer/application/application.go +++ b/previewer/application/application.go @@ -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 diff --git a/previewer/application/handlers.go b/previewer/application/handlers.go index 007c37e..069e7bd 100644 --- a/previewer/application/handlers.go +++ b/previewer/application/handlers.go @@ -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 } diff --git a/previewer/application/query.go b/previewer/application/query.go index 4cb3c9a..d9c319f 100644 --- a/previewer/application/query.go +++ b/previewer/application/query.go @@ -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 } diff --git a/previewer/config/config.go b/previewer/config/config.go index 05d410e..773e5d4 100644 --- a/previewer/config/config.go +++ b/previewer/config/config.go @@ -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} +} diff --git a/previewer/converter/converter.go b/previewer/converter/converter.go index 9d0d184..e5730ae 100644 --- a/previewer/converter/converter.go +++ b/previewer/converter/converter.go @@ -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 } diff --git a/previewer/converter/converter_test.go b/previewer/converter/converter_test.go index f0e335c..dbb2e2a 100644 --- a/previewer/converter/converter_test.go +++ b/previewer/converter/converter_test.go @@ -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}}) diff --git a/previewer/main.go b/previewer/main.go index 4170e49..5f403e6 100644 --- a/previewer/main.go +++ b/previewer/main.go @@ -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) diff --git a/previewer/main_test.go b/previewer/main_test.go new file mode 100644 index 0000000..a42275e --- /dev/null +++ b/previewer/main_test.go @@ -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 +}