From 221f3a74023e5e5bc20ec61476a7edc5eb60cd22 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Thu, 2 Jul 2026 23:05:45 +1000 Subject: [PATCH] test: add comprehensive dockerised end-to-end suite Add a black-box e2e suite (build tag dockere2e) that runs against the built container image via docker-compose, plus a static nginx mock upstream for hermetic caching tests. Coverage: - repository add/change/delete for remote, local and virtual repos - caching (miss -> hit + byte integrity) for all 10 remote package types - local uploads: generic, pypi (with generated simple index), rpm (with automatic repodata generation from a real package) - virtual merges: pypi simple index and helm index.yaml Driven by scripts/docker-e2e.sh (make docker-e2e): builds the image, brings the stack up, waits for health, runs the suite, and tears down. The artifactapi host port is parameterised (ARTIFACTAPI_PORT, default 8000; the e2e run uses 8001). Fixtures are force-tracked over the global gitignore. --- .gitignore | 4 + Makefile | 7 +- docker-compose.e2e.yml | 18 +++ docker-compose.yml | 2 +- e2e-docker/README.md | 39 +++++ e2e-docker/caching_test.go | 76 ++++++++++ .../fixtures/alpine/x86_64/testpkg-1.0-r0.apk | Bin 0 -> 3072 bytes e2e-docker/fixtures/blobs/hello.bin | 1 + e2e-docker/fixtures/charts/mychart-1.0.0.tgz | Bin 0 -> 8192 bytes .../goproxy/example.com/mod/@v/v1.0.0.zip | Bin 0 -> 4096 bytes e2e-docker/fixtures/helm-a/index.yaml | 8 ++ e2e-docker/fixtures/helm-b/index.yaml | 8 ++ e2e-docker/fixtures/mypkg/-/mypkg-1.0.0.tgz | Bin 0 -> 4096 bytes .../packages/foo-1.0-py3-none-any.whl | Bin 0 -> 2048 bytes .../puppet-releases/author-mod-1.0.0.tar.gz | Bin 0 -> 5120 bytes .../Packages/e2e-testpkg-1.0-1.noarch.rpm | Bin 0 -> 6838 bytes .../providers/hashicorp/aws/download/pkg.zip | Bin 0 -> 6144 bytes .../v2/library/testimg/blobs/blobdata | Bin 0 -> 7168 bytes e2e-docker/helpers_test.go | 108 ++++++++++++++ e2e-docker/local_test.go | 93 ++++++++++++ e2e-docker/repos_test.go | 134 ++++++++++++++++++ e2e-docker/virtual_test.go | 54 +++++++ scripts/docker-e2e.sh | 40 ++++++ 23 files changed, 590 insertions(+), 2 deletions(-) create mode 100644 docker-compose.e2e.yml create mode 100644 e2e-docker/README.md create mode 100644 e2e-docker/caching_test.go create mode 100644 e2e-docker/fixtures/alpine/x86_64/testpkg-1.0-r0.apk create mode 100644 e2e-docker/fixtures/blobs/hello.bin create mode 100644 e2e-docker/fixtures/charts/mychart-1.0.0.tgz create mode 100644 e2e-docker/fixtures/goproxy/example.com/mod/@v/v1.0.0.zip create mode 100644 e2e-docker/fixtures/helm-a/index.yaml create mode 100644 e2e-docker/fixtures/helm-b/index.yaml create mode 100644 e2e-docker/fixtures/mypkg/-/mypkg-1.0.0.tgz create mode 100644 e2e-docker/fixtures/packages/foo-1.0-py3-none-any.whl create mode 100644 e2e-docker/fixtures/puppet-releases/author-mod-1.0.0.tar.gz create mode 100644 e2e-docker/fixtures/rpmrepo/Packages/e2e-testpkg-1.0-1.noarch.rpm create mode 100644 e2e-docker/fixtures/v1/providers/hashicorp/aws/download/pkg.zip create mode 100644 e2e-docker/fixtures/v2/library/testimg/blobs/blobdata create mode 100644 e2e-docker/helpers_test.go create mode 100644 e2e-docker/local_test.go create mode 100644 e2e-docker/repos_test.go create mode 100644 e2e-docker/virtual_test.go create mode 100755 scripts/docker-e2e.sh diff --git a/.gitignore b/.gitignore index 897030b..472957c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ bin/ terraform/ + +# e2e-docker fixtures are real package files (.rpm, .tgz, .whl, .zip, ...) that +# are intentionally tracked, overriding any global ignore of those extensions. +!e2e-docker/fixtures/** diff --git a/Makefile b/Makefile index e2d1889..62b99aa 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: build test lint fmt e2e docker docker-ui compose clean tidy check-go +.PHONY: build test lint fmt e2e docker-e2e docker docker-ui compose clean tidy check-go BINARY := bin/artifactapi MODULE := git.unkin.net/unkin/artifactapi @@ -28,6 +28,11 @@ fmt: check-go e2e: check-go TESTCONTAINERS_RYUK_DISABLED=true go test -tags=e2e -race -count=1 -timeout=5m ./e2e/... +# Build the container, bring up the full docker-compose stack + a mock upstream, +# and run the black-box suite against the running product. +docker-e2e: check-go + ./scripts/docker-e2e.sh + docker: docker build -t artifactapi:$(VERSION) . diff --git a/docker-compose.e2e.yml b/docker-compose.e2e.yml new file mode 100644 index 0000000..8bfa2d6 --- /dev/null +++ b/docker-compose.e2e.yml @@ -0,0 +1,18 @@ +# Overlay for the dockerised end-to-end suite (scripts/docker-e2e.sh). +# Adds a static mock upstream that the artifactapi container proxies, so the +# caching tests are hermetic and need no internet access. +services: + mockupstream: + image: nginx:alpine + volumes: + - ./e2e-docker/fixtures:/usr/share/nginx/html:ro,z + # No host port needed: only the artifactapi container talks to it, and the + # tests compare served bytes against the on-disk fixtures. + + artifactapi: + # The host port is set via ARTIFACTAPI_PORT (see scripts/docker-e2e.sh), + # defaulting to 8000; the e2e run uses 8001 to avoid colliding with a + # locally-running instance. + depends_on: + mockupstream: + condition: service_started diff --git a/docker-compose.yml b/docker-compose.yml index 7687e20..0ee2dba 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ services: artifactapi: build: . ports: - - "8000:8000" + - "${ARTIFACTAPI_PORT:-8000}:8000" environment: LISTEN_ADDR: ":8000" DBHOST: postgres diff --git a/e2e-docker/README.md b/e2e-docker/README.md new file mode 100644 index 0000000..3a7773a --- /dev/null +++ b/e2e-docker/README.md @@ -0,0 +1,39 @@ +# Dockerised end-to-end suite + +Black-box tests that run against a fully **containerised** artifactapi stack +(built image + Postgres + Redis + MinIO) plus a static mock upstream. Unlike the +in-process `e2e/` suite (testcontainers, server run in-process), these only speak +HTTP to the running product, so they exercise the shipped container image. + +## Run + +```bash +make docker-e2e # build image, compose up, run suite, compose down +``` + +`scripts/docker-e2e.sh` builds and starts `docker-compose.yml` + +`docker-compose.e2e.yml`, waits for `/health`, then runs +`go test -tags=dockere2e ./e2e-docker/...` and tears everything down. + +The stack publishes artifactapi on host port **8001** (to avoid colliding with a +local instance on 8000). Override with `ARTIFACTAPI_URL` to point the tests at an +already-running stack. + +## Coverage + +- **Repository lifecycle** — add / change / delete for remote, local and virtual repos. +- **Caching** — one immutable artifact per remote package type (generic, docker, + helm, pypi, npm, rpm, alpine, puppet, terraform, goproxy) proxied through the + mock upstream: first fetch `X-Artifact-Source: remote`, second `cache`, bytes + verified against the origin fixture. +- **Local uploads** — generic (upload/download), pypi (wheel + generated `simple/` + index), rpm (real package + **automatic repodata** generation). +- **Virtual repositories** — pypi simple-index merge and helm `index.yaml` merge + across two members. + +## Fixtures + +`fixtures/` is served by the mock upstream at its web root. Paths mirror each +provider's upstream URL layout (e.g. `v2/...` for docker, `v1/providers/...` for +terraform). The RPM under `fixtures/rpmrepo/Packages/` is a real package so the +rpm provider can parse its metadata for repodata generation. diff --git a/e2e-docker/caching_test.go b/e2e-docker/caching_test.go new file mode 100644 index 0000000..8f60307 --- /dev/null +++ b/e2e-docker/caching_test.go @@ -0,0 +1,76 @@ +//go:build dockere2e + +package e2edocker + +import ( + "bytes" + "fmt" + "net/http" + "testing" +) + +// TestCachingPerProvider proxies one immutable artifact for every remote +// package type through the mock upstream and asserts: first fetch is served +// from the remote, the second from cache, and the bytes match the origin. +func TestCachingPerProvider(t *testing.T) { + cases := []struct { + pkgType string + // path is the request path under /api/v1/remote//. The provider + // derives the upstream URL from it (docker prepends /v2/, terraform + // prepends /v1/providers/), and the fixture lives at that resolved path. + path string + fixture string + }{ + {"generic", "blobs/hello.bin", "blobs/hello.bin"}, + {"npm", "mypkg/-/mypkg-1.0.0.tgz", "mypkg/-/mypkg-1.0.0.tgz"}, + {"helm", "charts/mychart-1.0.0.tgz", "charts/mychart-1.0.0.tgz"}, + {"pypi", "packages/foo-1.0-py3-none-any.whl", "packages/foo-1.0-py3-none-any.whl"}, + {"rpm", "rpmrepo/Packages/e2e-testpkg-1.0-1.noarch.rpm", "rpmrepo/Packages/e2e-testpkg-1.0-1.noarch.rpm"}, + {"alpine", "alpine/x86_64/testpkg-1.0-r0.apk", "alpine/x86_64/testpkg-1.0-r0.apk"}, + {"puppet", "puppet-releases/author-mod-1.0.0.tar.gz", "puppet-releases/author-mod-1.0.0.tar.gz"}, + {"goproxy", "goproxy/example.com/mod/@v/v1.0.0.zip", "goproxy/example.com/mod/@v/v1.0.0.zip"}, + {"terraform", "hashicorp/aws/download/pkg.zip", "v1/providers/hashicorp/aws/download/pkg.zip"}, + {"docker", "library/testimg/blobs/blobdata", "v2/library/testimg/blobs/blobdata"}, + } + + for _, tc := range cases { + t.Run(tc.pkgType, func(t *testing.T) { + name := "cache-" + tc.pkgType + createRepo(t, fmt.Sprintf(`{ + "name": %q, + "package_type": %q, + "repo_type": "remote", + "base_url": %q, + "stale_on_error": true + }`, name, tc.pkgType, mockUpstream())) + defer deleteRepo(t, name) + + want := fixtureBytes(t, tc.fixture) + url := api("/api/v1/remote/" + name + "/" + tc.path) + + // First fetch: from remote. + resp, body := doRequest(t, http.MethodGet, url, nil, "") + if resp.StatusCode != http.StatusOK { + t.Fatalf("first fetch: status %d: %s", resp.StatusCode, body) + } + if src := resp.Header.Get("X-Artifact-Source"); src != "remote" { + t.Fatalf("first fetch source = %q, want remote", src) + } + if !bytes.Equal(body, want) { + t.Fatalf("first fetch body mismatch: got %d bytes, want %d", len(body), len(want)) + } + + // Second fetch: from cache, identical bytes. + resp, body = doRequest(t, http.MethodGet, url, nil, "") + if resp.StatusCode != http.StatusOK { + t.Fatalf("second fetch: status %d: %s", resp.StatusCode, body) + } + if src := resp.Header.Get("X-Artifact-Source"); src != "cache" { + t.Fatalf("second fetch source = %q, want cache", src) + } + if !bytes.Equal(body, want) { + t.Fatalf("cached body mismatch: got %d bytes, want %d", len(body), len(want)) + } + }) + } +} diff --git a/e2e-docker/fixtures/alpine/x86_64/testpkg-1.0-r0.apk b/e2e-docker/fixtures/alpine/x86_64/testpkg-1.0-r0.apk new file mode 100644 index 0000000000000000000000000000000000000000..9b901a67a3fefa91b09f3b54f5527f724236cdd8 GIT binary patch literal 3072 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 literal 0 HcmV?d00001 diff --git a/e2e-docker/fixtures/helm-a/index.yaml b/e2e-docker/fixtures/helm-a/index.yaml new file mode 100644 index 0000000..79c1f28 --- /dev/null +++ b/e2e-docker/fixtures/helm-a/index.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +entries: + alpha: + - name: alpha + version: 1.0.0 + urls: + - charts/alpha-1.0.0.tgz +generated: "2026-01-01T00:00:00Z" diff --git a/e2e-docker/fixtures/helm-b/index.yaml b/e2e-docker/fixtures/helm-b/index.yaml new file mode 100644 index 0000000..7d0c06b --- /dev/null +++ b/e2e-docker/fixtures/helm-b/index.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +entries: + beta: + - name: beta + version: 2.0.0 + urls: + - charts/beta-2.0.0.tgz +generated: "2026-01-01T00:00:00Z" diff --git a/e2e-docker/fixtures/mypkg/-/mypkg-1.0.0.tgz b/e2e-docker/fixtures/mypkg/-/mypkg-1.0.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..be1df0161c669a41460215598e089a13a6b93df1 GIT binary patch literal 4096 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 literal 0 HcmV?d00001 diff --git a/e2e-docker/fixtures/puppet-releases/author-mod-1.0.0.tar.gz b/e2e-docker/fixtures/puppet-releases/author-mod-1.0.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..46abd920d147c015a6792dce38ecf25197902db6 GIT binary patch literal 5120 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 SW8{-ZWYbB~@K?={ACD6f_Xhs} literal 0 HcmV?d00001 diff --git a/e2e-docker/fixtures/v2/library/testimg/blobs/blobdata b/e2e-docker/fixtures/v2/library/testimg/blobs/blobdata new file mode 100644 index 0000000000000000000000000000000000000000..ed84624e30c344a6d62dd655c8c6ca81ae65377f GIT binary patch literal 7168 zcmV+b9RK5TdSUDPL_@9c(9{-#qYn-KmGQ|q90`9=YK>jVUzPR_4DYx+fM8o6x2J1t z*_bY!%M8>0PNaf~>`$K668jwY3QX&w_g5>7n1UkbsKpv`!)Qnyx9bVM_%R0#rz(WU zCI0aZj(lG)J~pfdJu5@2uP)Fvy@s1g6W!7&tHbkWi)-hm>Oc|S*S#7isi3)+HbYsH zaJJLJ#ji+ROw5d8$er9ZiP3JElW{FD4S&agJoXkkV4^C8P=ONuTU^)Ist%_S%4aqH z5Sv&%=$)X~$Me~MBFg63lX%|y*%q~Rlp8;a%4{*?VA3=nZ19t6g_045 z$jOm}wJeQh5r3DA6Luv!DEZdnn{zN$5<@~mm>`+E5FQ|b-9^j#Q?#xR8Hq5i#X3RV zOE(5vJkhqtIx%5j?inC<0ll<4CU-ii@SQu54a_d}aHgXkx^qU#eUKIDmf&=G2VWy! z`P3I;>EB2k;HIPIPyJUe*}Wh8V$Bz4i2x*yjhPfT^t_2@vtUX*#4^zto(ucAgzWRa zQuVTOaV-+p)=(Xom>%^Fe_nmTVYJFG>fPe=knW{#=MHY|fX;T23=n7x$ssD`r zU0rqUQ_7`7;y|;noe6bg(1w9b0C(Vao-v0I{FrlMJ5+MI(9~6ncSovMex=>Lz-U+b z*qF0Cm^R_djyjhvBMWLM-ob%CZgZcwZD*PK#J_!3SOOny`smZbpQ zM=I`7xk^Dysx~pCWk>9A-_RX|#WNLv0OZyiw=RSs#xCP0BNYwL%YV_(2w@SmtSN#a zcW238vD;R{6!f%nViRoa9KCYoGjZIDoxJ+bt|w`O7?KF2r)6O(Z5Oj`G7x0r=b;;; zsO70;D2D_QkGjcwJHc#xBG23!5d;we(<>#b?W8}tcT*A>WV2|MvCU)NLc_&>L}E@& z_u^(m0bp8Qy1KOmHjT__A8>yDv$0`VugBmw_8ofE3Wh7W)bTnNP-g*_kZ9iyJY;NV zE=%ffDmcYDEcGwS5}{_P&YuQ6i{KHPq=bDsjO%v`gnB!9uO6bbW)Xc%HrRuo-snF& zY_0r?PGDSjVUVv$-c90@!-O(4B`b~;A^o$@({g?FKKEmH&1U;lKW)8UJ?}+7an^*N z{w?7KG=dJt8E{7M;u1k~n4>(JdKs@I!`5dLsL?R4Nzmu-FSAnia=+}<*>y|6?(Y+c zfC(N2R}y#c<$B0x5GfjNQv$$>Wpn)qvIUT8>Mm=mc>(3!jq1J{7k1{DY(qtg`m)MNIO6=URb|7k8G zvrKy4%Yi8<`;mZGaK1@85Csjbx-rPf%_$Ei-b`T>^^XYha$w5C63C~J0#LADOnp20 zfD`jN*f%fu!_>LSkWFVhi>VJ1 z56myK_cPXcZ1vD+6FycvXS><|ZDYu$wjxJiHT6F3YGoI!PSO`~)!Web{v|o}Td+kH zJY=s>%<)56_eZ^>iekF2R80DKnhC0Eym8(Ni;^bF1I`LX?I)}Nhnd7e2>-zvV zd&akCMjMX!m@#y1Meh2zr9b99MbAF%u&vIM^yLERxT0moz+e+ZaJ^>w z*?ISU?g$ZvPYU!41v%X^!qq5dyp(bOE&&hre9hf>@_qwEQADUc@9Uvt0lXkmhW|Vf zWD$}p!WX{{7XV&g+YXdy4MyRhADQ=fBK0}oefQ2EEz=J*LmO74lz6#}iH1SofHGfY zCW);xAn^hNUe&0AzhFVwI>g+xsbe>CDC1jD=kXgf8H-$JbA7z9C|q-lymZ;BwwsWIxzrB<-_W>^0Q> z=#BU4+7Nw_tTP7Ty+GbN4+K?tfP;Lid5`wx*c9?S`l1IhXrW7FZ$5?TapxSv~ZUT z{9yCXgfrx>!a7_CMgMe6dArtW7X*_nbi?T~eH|K!w7ukk?DKF|+rx?P9aWGuXGAi>baPhX%?ADGYrZnoVBrcQ54FtzjJoNjY7B)D#Pvx{&4|&qFS9QEF(Qfe zv>9gCS~@)B_^#Br*o^m+Ye99i%#1vpi1HHe zhIZg&cjEwaPNEb(!SN4|R5Yn0pP5jK#p3ePGi@3d zH+|Mmhi>Uoz5NfaJgWrVUy%!5&7L(4u80K1@MG%{;Pr8RRezjinNKzKuQ2_7+;||~ z5FAG=KHKZvG1!(aGjWRS6ss&6K~q4c&}g7rPH?-vfNV!iX}TVfn>O{4r+j96`V8 zviI1&mWvdAxb%S|RO-oM=5~pcU38eB=ve0t5`GTW?_xHEhkvYJh{|-n2dLICFat##9TB^no{KxN{f&Fg=+ z3on&E)(?$G;bV~(^a^cZm0(Z`Pp5yJS3K54g+C8;fs(g!q{$k?Zms9w?&ZJ_lLwOP z836mYrEEYROwerbn76GTAdAK|XhDC2SEa1*v3xEN+r^OwAV)WUVsyG6{joF3J0+uV znPfNi2(xNS6DRkYy1wlDsXCQ_oD6kknUX|)u~bQ;m~-@r6;!_aQ42=exE`Q5TSgnv zjy~0?(Zi{GbrM|4A@6RCYN&p1X>EcunsS z3BJ9A9?A@09|Y7!>uFSEt-pe5Y9VrnKddH!<+7(cJN{J4r6`L0hHdtRlI+@NDWUyL zs||I%gI*T-yXi-W8nS)?%fq~;8ElkrKdm>;kF^-)0u!A#TH4D8p5W9KQ37{xUj8aS zZ=tXD){}mVvwBAVe%*ArvT=1*|JOPyxUR3j_*&2C@1+Q&Ul=U_uBG2`i=bD(djQ4o zJ_3W-n_i%8Lyp_X{hi9SLS#0GQ=j1G{vl)Z#LFh2O`ohXMs{qHZ6L;y3LD#m6z?>Viu5g&=-EP%oi|= zPONJ*;KaMC43Z@0MDU-*0k5OIR-vNgdY77D7U`-mv}Iye!np6!jZP6+r$32IkP$YXD~ zYdukfvAleNU1fA_dE`nT&8INHWi{o0+~z|dC}aRh>)LZPqfc>w$0w5%wD(TRc(M^CV9n}z3nCQS3-*2FJqpT zx!T-vj`SC$q0%J5bEiUnx>CaV*gEAt46Lsd1h<9@m9Db8fj=F;&B7T=dr2>q!SrPh zuHPrXjk|l*8JwcBV_Qd$3*k2?cLD*zReg&lm*+o6m?h{5tm}t7bE+0_TOKs2~=ShXmx@PzWbx~$Mo7q@8X>j z_#y2(;F2Qe0xJ15t=T0nrnsf?(aM|kLqxt03&!<7dE+MA33mFT{Q*`KWiuN(FD-dq5ZGHz=FvS>{hvT-l`g{u=XHuq>vzvzIaHwA zKWr@-SsONeMltw<23^HzDu97Noyl;(TyK!)3r^(c;)l@l0wM8C;N+kWcd89MaJg&F6T|FQT%}z3tjUk; zDzS+{dX$#KNm=Gcm0NRPC`CQ6iCZb~qylRbB zg>(GF$uucq`or$-N_Fm3)3vhqu0DM1pDCp@ny)!11K>FlU=2uE5r)XBF4Lr)^FA{B z^rE*YRC!^teWQN2*6;CtRNtQ2WOt}J*S}-(ui--2V&!c}x+MGvZJ}-!XYO<<0u1cc z;V*jtJzfW^JWmA3Qk=@>DK>_P(npt9+PNKk)zpo1gy}I3cB2bOy|ew&mk`B+%>e^+ z(W+~sG#nX5EJmzusn}{a`RUHqj(|e~7v-wdXP%ng1qqf4dQ`qj!c=Cu?;ilkcn#Gd z(i_EUTtr$b)-^VY%U3_huJOli0Z8b`=u%s}%n+)r#OT0$(wcW_pH`sRD@i zq>&h*Webj^$pr)V8OQTeu7@8_LP7)b>QmTZ@dw6~&O@R6I*t&n{U6t)eQ=SVPVMr? zAxnIDNUA{a(!H&8jA5hx<{Ux3kp2ZWHx_ANy21>lDZvHkqE;a{RSv^2DYwNmzCNyQ zSVqDw@=Ihuzwf!hfeoLOpMc;MNKKL!Ju@*}?XW!8nR`+rWQ+*;qs>I>PObboL4FlF zM(K?_n{741AHI&7cKQG_CD@RbqB&8e;gm2_sjMrhZLgAJ%Z3%bcZVd&6$EX#Z~{8G ze)}SlKBPJoprJb=JY8}r&NoZ~k%&ovcF#A)e|_%Rm4_Wv1C23cWSe&0Q*fisrt#aaCa=EZt&mpsb~^zuUcD{Moo9A3B?!Jw1TIXYOic&}(B;ZCW?Y5w z2~_btnu)iE{(PfeSHCs(za`gtu~-&od7HW$6wFX66>T#66E03r&sMg5vDi^#;OO>E^0`Y`xRG<6&PI*1eW#jR&BZq z*jaIM-Z9jAO2EcKn9k3W>&=U@HW^-OEuzmD*{jVy+jyc&D@y&JJugniOuP;S7IsZ9 zF~HBj#+MZa?tOjji^H9fCuoY{E=2tJB$@ah4RH=yfzYaJYx1`1^11+%*I;8{@`Tij znsg%ZdQPtq&vXG)$LI`KIYu}_7W7d+tV1{l7qHSfRL&!D-p!ywaA*h-%=W3l;$R80 z``8y0YPS)3NxZ8MnOjjnSwg?ZgmH(&rX~OkvnGo|XFLDrkl-f+GtfNAtheHS&*ZzR zK-+}s=%sfwhsO?;iO;LA02yG`4Uds`QI7B@IV1>1@?96I+rL5>!wscc&O)j}_IYlU zY6Wb(7=cbPH5);%Lpzo7NjHJ4hPw$TfwI^*a-5mzR59IC;xPIsJ-{`Q9~TMn+kpZN zTqB1&f-`s(yczNKws@kxf~%d=zJdN~knNg#KNz-p)i4=oeBL7?!V_5r9=8gk`Bwwz z%F`X=b_JAuv)}}DP0;4w;*lmhj^1JVB^XIQ#$M5O`at04G_aFX%g;Uo2~=2t0>Tqy z0=5RkheZ9r>z1`E$u;jT*hK60k6Ff8NUbWGCNJWth69oy$}AxR5>q@5Hwa-y^lRiM8-eV!G1`~q8%=Q$1DoNgliT6e+8r-nXm!NoM}=aWQx?#vZ#93)X^BV z%8d*XDbdg9Us_`MV|Ghk`z!s}`oMeb-}r}c?|E-Yk_gNdF)hsG_|X5k*v40%8~VIK z?g%nRq9#C=roppmD-gq){0fjcW#rDP|rjfCdQnEhe&h&HT) zH>s9PvDw1rwXPfzI6j~A&=B%zb5>%^=9x!zNq|ZlhyU(pb7Z4;l2*oj1@#E*Qc0C@ z)9h?K*8i4Cgjhc@y$A0IP+D{*n*?ZSiDQePOp3~f0-!c6NyI8)u>ZdLDy6XkWOZl} zEfg6qouIMo43-9a-#Lw9&d~{<-D1roG- tearing down stack" + "${COMPOSE[@]}" down -v --remove-orphans >/dev/null 2>&1 || true +} +trap cleanup EXIT + +echo "==> building and starting stack (postgres, redis, minio, mockupstream, artifactapi)" +"${COMPOSE[@]}" up -d --build postgres redis minio mockupstream artifactapi + +echo "==> waiting for artifactapi health at ${API_URL}" +for i in $(seq 1 60); do + if curl -fsS "${API_URL}/health" >/dev/null 2>&1; then + echo " healthy after ${i}s" + break + fi + if [ "$i" -eq 60 ]; then + echo "!!! artifactapi did not become healthy in time; recent logs:" + "${COMPOSE[@]}" logs --tail=50 artifactapi + exit 1 + fi + sleep 1 +done + +echo "==> running dockerised e2e suite" +ARTIFACTAPI_URL="${API_URL}" \ +MOCK_UPSTREAM_INTERNAL="${MOCK_UPSTREAM_INTERNAL:-http://mockupstream}" \ + go test -tags=dockere2e -count=1 -timeout=10m -v ./e2e-docker/...