Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package fortio for openSUSE:Factory checked 
in at 2022-05-14 22:57:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/fortio (Old)
 and      /work/SRC/openSUSE:Factory/.fortio.new.1538 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "fortio"

Sat May 14 22:57:04 2022 rev:10 rq:977240 version:1.30.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/fortio/fortio.changes    2022-04-26 
20:17:52.564768491 +0200
+++ /work/SRC/openSUSE:Factory/.fortio.new.1538/fortio.changes  2022-05-14 
22:58:49.771490894 +0200
@@ -1,0 +2,20 @@
+Sat May 14 11:44:13 UTC 2022 - ka...@b1-systems.de
+
+- Update to version 1.30.0:
+  Same release as 1.29.0 to avoid a change in binary URLs (there was an extra 
v in 1.29.0 release)
+
+-------------------------------------------------------------------
+Sat May 14 11:40:59 UTC 2022 - ka...@b1-systems.de
+
+- Update to version 1.29.0:
+  * 1.29 and go 1.18 base + #566 (round robin dns) + #564 (revamp of build 
through go install module buildinfo) (#560)
+  * fix spurious dns change message when dns isn't changing (#565)
+  * no need to put :8079 for default grpc port without TLS
+  * also allow main echo/http port to be disabled; so a server can be sta??? 
(#559)
+  * Switch to demo.fortio.org for live demo, use new logo for browse/report 
mode
+  * Add more visibility to IP address resolution when using DNS and stdclient 
socket count (#556)
+  * fix up the tag name used
+  * fixing manual build try #2
+  * adding manual build for next time ci fails in the middle mysteriously 
(#555)
+
+-------------------------------------------------------------------

Old:
----
  fortio-1.28.0.tar.gz

New:
----
  fortio-1.30.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ fortio.spec ++++++
--- /var/tmp/diff_new_pack.oF2w2f/_old  2022-05-14 22:58:50.239491479 +0200
+++ /var/tmp/diff_new_pack.oF2w2f/_new  2022-05-14 22:58:50.247491489 +0200
@@ -19,7 +19,7 @@
 %define __arch_install_post export NO_BRP_STRIP_DEBUG=true
 
 Name:           fortio
-Version:        1.28.0
+Version:        1.30.0
 Release:        0
 Summary:        Load testing library, command line tool, advanced echo server 
and web UI
 License:        Apache-2.0

++++++ _service ++++++
--- /var/tmp/diff_new_pack.oF2w2f/_old  2022-05-14 22:58:50.275491524 +0200
+++ /var/tmp/diff_new_pack.oF2w2f/_new  2022-05-14 22:58:50.279491529 +0200
@@ -3,10 +3,11 @@
     <param name="url">https://github.com/fortio/fortio</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">v1.28.0</param>
+    <param name="revision">v1.30.0</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="changesgenerate">enable</param>
     <param name="versionrewrite-pattern">v(.*)</param>
+    <param name="match-tag">v*</param>
   </service>
   <service name="set_version" mode="disabled">
     <param name="basename">fortio</param>
@@ -16,7 +17,7 @@
     <param name="compression">gz</param>
   </service>
   <service name="go_modules" mode="disabled">
-    <param name="archive">fortio-1.28.0.tar.gz</param>
+    <param name="archive">fortio-1.30.0.tar.gz</param>
   </service>
 </services>
 

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.oF2w2f/_old  2022-05-14 22:58:50.299491554 +0200
+++ /var/tmp/diff_new_pack.oF2w2f/_new  2022-05-14 22:58:50.303491559 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/fortio/fortio</param>
-              <param 
name="changesrevision">57e9d8f01c342a4c1b5d96f883f81128b04d991a</param></service></servicedata>
+              <param 
name="changesrevision">15150b657787587ddfe972935a0633da2251ae5a</param></service></servicedata>
 (No newline at EOF)
 

++++++ fortio-1.28.0.tar.gz -> fortio-1.30.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/.circleci/config.yml 
new/fortio-1.30.0/.circleci/config.yml
--- old/fortio-1.28.0/.circleci/config.yml      2022-04-26 02:16:27.000000000 
+0200
+++ new/fortio-1.30.0/.circleci/config.yml      2022-05-14 01:39:50.000000000 
+0200
@@ -7,7 +7,7 @@
 defaultEnv: &defaultEnv
     docker:
       # specify the version
-      - image: docker.io/fortio/fortio.build:v39
+      - image: docker.io/fortio/fortio.build:v40
     working_directory: /go/src/fortio.org/fortio
 
 jobs:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/.github/workflows/main.yml 
new/fortio-1.30.0/.github/workflows/main.yml
--- old/fortio-1.28.0/.github/workflows/main.yml        2022-04-26 
02:16:27.000000000 +0200
+++ new/fortio-1.30.0/.github/workflows/main.yml        2022-05-14 
01:39:50.000000000 +0200
@@ -68,4 +68,5 @@
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
         run: |
           tag_name="${GITHUB_REF##*/}"
+          echo "tag_name=$tag_name"
           gh release upload "${tag_name}" release/*.{tgz,zip,rpm,deb,gz}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/.github/workflows/manual-build.yml 
new/fortio-1.30.0/.github/workflows/manual-build.yml
--- old/fortio-1.28.0/.github/workflows/manual-build.yml        1970-01-01 
01:00:00.000000000 +0100
+++ new/fortio-1.30.0/.github/workflows/manual-build.yml        2022-05-14 
01:39:50.000000000 +0200
@@ -0,0 +1,48 @@
+
+name: Manual Release Update/Rebuild
+
+on:
+  workflow_dispatch:
+    inputs:
+      tag:
+        description: 'Tag to rebuild'
+        required: true
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: test
+        run: |
+          echo "tag is ${{ github.event.inputs.tag }}"
+
+      - uses: actions/checkout@v2
+        with:
+          ref: ${{ github.event.inputs.tag }}
+
+      - name: Set up QEMU
+        uses: docker/setup-qemu-action@v1
+
+      - name: Set up Docker Buildx
+        id: buildx
+        uses: docker/setup-buildx-action@v1
+
+      - name: Build
+        id: build
+        run: |
+          make info
+          make release
+          VERSION=$(make echo-version)
+          echo ::set-output name=VERSION::${VERSION}
+          PACKAGE_VERSION=$(make echo-package-version)
+          echo ::set-output name=PACKAGE_VERSION::${PACKAGE_VERSION}
+          echo "Version $VERSION, Package version $PACKAGE_VERSION"
+
+      - name: Upload release artifacts
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        run: |
+          tag_name="${{ github.event.inputs.tag }}"
+          echo "tag_name=$tag_name"
+          gh release upload "${tag_name}" release/*.{tgz,zip,rpm,deb,gz}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/.golangci.yml 
new/fortio-1.30.0/.golangci.yml
--- old/fortio-1.28.0/.golangci.yml     2022-04-26 02:16:27.000000000 +0200
+++ new/fortio-1.30.0/.golangci.yml     2022-05-14 01:39:50.000000000 +0200
@@ -355,6 +355,7 @@
     - wrapcheck
     - exhaustivestruct
     - tagliatelle
+    - nonamedreturns
 # TODO consider putting these back, when they stop being bugged (ifshort, 
wastedassign,...)
     - paralleltest
     - thelper
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/Dockerfile new/fortio-1.30.0/Dockerfile
--- old/fortio-1.28.0/Dockerfile        2022-04-26 02:16:27.000000000 +0200
+++ new/fortio-1.30.0/Dockerfile        2022-05-14 01:39:50.000000000 +0200
@@ -1,10 +1,11 @@
 # Build the binaries in larger image
-FROM docker.io/fortio/fortio.build:v39 as build
+FROM docker.io/fortio/fortio.build:v40 as build
 WORKDIR /go/src/fortio.org
 COPY . fortio
+ARG MODE=install
 # We moved a lot of the logic into the Makefile so it can be reused in brew
 # but that also couples the 2, this expects to find binaries in the right 
place etc
-RUN make -C fortio official-build-version BUILD_DIR=/build 
OFFICIAL_BIN=../fortio_go_latest.bin
+RUN make -C fortio official-build-version BUILD_DIR=/build MODE=${MODE}
 
 # Minimal image with just the binary and certs
 FROM scratch as release
@@ -13,7 +14,7 @@
 # TODO: get rid of *.bak, *~ and other spurious non source files
 #COPY --from=build /go/src/fortio.org/fortio/ui/static /usr/share/fortio/static
 #COPY --from=build /go/src/fortio.org/fortio/ui/templates 
/usr/share/fortio/templates
-COPY --from=build /go/src/fortio.org/fortio_go_latest.bin /usr/bin/fortio
+COPY --from=build /build/result/fortio /usr/bin/fortio
 EXPOSE 8078
 EXPOSE 8079
 EXPOSE 8080
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/Dockerfile.build 
new/fortio-1.30.0/Dockerfile.build
--- old/fortio-1.28.0/Dockerfile.build  2022-04-26 02:16:27.000000000 +0200
+++ new/fortio-1.30.0/Dockerfile.build  2022-05-14 01:39:50.000000000 +0200
@@ -1,5 +1,5 @@
 # Dependencies and linters for build:
-FROM golang:1.17.9
+FROM golang:1.18.2
 # Need gcc for -race test (and some linters though those work with 
CGO_ENABLED=0)
 RUN apt-get -y update && \
   apt-get --no-install-recommends -y upgrade && \
@@ -11,9 +11,7 @@
 RUN go version # check it's indeed the version we expect
 
 # golangci-lint
-# See https://github.com/golangci/golangci-lint/issues/2673 (and 2374)
-# Use 1.44.2 which works on arm while 1.45.2 doesn't... somehow
-RUN curl -sSfL 
https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh 
-s -- -b $(go env GOPATH)/bin v1.44.2
+RUN curl -sSfL 
https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh 
-s -- -b $(go env GOPATH)/bin
 RUN golangci-lint version
 
 # Docker:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/Dockerfile.echosrv 
new/fortio-1.30.0/Dockerfile.echosrv
--- old/fortio-1.28.0/Dockerfile.echosrv        2022-04-26 02:16:27.000000000 
+0200
+++ new/fortio-1.30.0/Dockerfile.echosrv        2022-05-14 01:39:50.000000000 
+0200
@@ -1,5 +1,5 @@
 # Build the binaries in larger image
-FROM docker.io/fortio/fortio.build:v39 as build
+FROM docker.io/fortio/fortio.build:v40 as build
 WORKDIR /go/src/fortio.org
 COPY . fortio
 RUN make -C fortio official-build-version BUILD_DIR=/build 
OFFICIAL_TARGET=fortio.org/fortio/echosrv OFFICIAL_BIN=../echosrv.bin
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/Dockerfile.fcurl 
new/fortio-1.30.0/Dockerfile.fcurl
--- old/fortio-1.28.0/Dockerfile.fcurl  2022-04-26 02:16:27.000000000 +0200
+++ new/fortio-1.30.0/Dockerfile.fcurl  2022-05-14 01:39:50.000000000 +0200
@@ -1,5 +1,5 @@
 # Build the binaries in larger image
-FROM docker.io/fortio/fortio.build:v39 as build
+FROM docker.io/fortio/fortio.build:v40 as build
 WORKDIR /go/src/fortio.org
 COPY . fortio
 # fcurl should not need vendor/no dependencies
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/Dockerfile.test 
new/fortio-1.30.0/Dockerfile.test
--- old/fortio-1.28.0/Dockerfile.test   2022-04-26 02:16:27.000000000 +0200
+++ new/fortio-1.30.0/Dockerfile.test   1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +0,0 @@
-# Getting the source tree ready for running tests (sut)
-FROM docker.io/fortio/fortio.build:v39
-WORKDIR /go/src/fortio.org
-COPY . fortio
-RUN make -C fortio dependencies
-RUN go dep vendor
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/Makefile new/fortio-1.30.0/Makefile
--- old/fortio-1.28.0/Makefile  2022-04-26 02:16:27.000000000 +0200
+++ new/fortio-1.30.0/Makefile  2022-05-14 01:39:50.000000000 +0200
@@ -7,7 +7,7 @@
 IMAGES=echosrv fcurl # plus the combo image / Dockerfile without ext.
 
 DOCKER_PREFIX := docker.io/fortio/fortio
-BUILD_IMAGE_TAG := v39
+BUILD_IMAGE_TAG := v40
 BUILDX_PLATFORMS := linux/amd64,linux/arm64,linux/ppc64le,linux/s390x
 BUILDX_POSTFIX :=
 ifeq '$(shell echo $(BUILDX_PLATFORMS) | awk -F "," "{print NF-1}")' '0'
@@ -98,7 +98,7 @@
 # (bump BUILD_IMAGE_TAG), also change this list if the image is used in
 # more places.
 FILES_WITH_IMAGE:= .circleci/config.yml Dockerfile Dockerfile.echosrv \
-       Dockerfile.test Dockerfile.fcurl release/Dockerfile.in Webtest.sh
+       Dockerfile.fcurl release/Dockerfile.in Webtest.sh
 # then run make update-build-image and check the diff, etc... see 
release/README.md
 update-build-image:
        docker buildx create --use
@@ -118,7 +118,7 @@
 
 docker-internal: dependencies
        @echo "### Now building $(DOCKER_TAG)"
-       docker buildx build --platform $(BUILDX_PLATFORMS) -f 
Dockerfile$(IMAGE) -t $(DOCKER_TAG) $(BUILDX_POSTFIX) .
+       docker buildx build --platform $(BUILDX_PLATFORMS) --build-arg 
MODE=$(MODE) -f Dockerfile$(IMAGE) -t $(DOCKER_TAG) $(BUILDX_POSTFIX) .
 
 docker-push-internal: docker-internal docker-buildx-push
 
@@ -137,9 +137,11 @@
 
 # Targets used for official builds (initially from Dockerfile)
 BUILD_DIR := /tmp/fortio_build
-LIB_DIR := /usr/share/fortio
-DATA_DIR := .
-OFFICIAL_BIN := ../fortio.bin
+BUILD_DIR_ABS := $(abspath $(BUILD_DIR))
+BUILD_DIR_BIN := $(BUILD_DIR_ABS)/bin
+OFFICIAL_BIN ?= $(BUILD_DIR)/result/fortio
+OFFICIAL_DIR ?= $(dir $(OFFICIAL_BIN))
+
 GOOS :=
 GO_BIN := go
 GIT_TAG ?= $(shell git describe --tags --match 'v*' --dirty)
@@ -147,6 +149,7 @@
 GIT_SHA ?= $(shell git rev-parse HEAD)
 # Main/default binary to build: (can be changed to build fcurl or echosrv 
instead)
 OFFICIAL_TARGET := fortio.org/fortio
+MODE ?= install
 
 debug-tags:
        @echo "GIT_TAG=$(GIT_TAG)"
@@ -159,38 +162,34 @@
 echo-package-version:
        @echo "$(DIST_VERSION)" | sed -e "s/-/_/g"
 
-# Putting spaces in linker replaced variables is hard but does work.
-# This sets up the static directory outside of the go source tree and
-# the default data directory to a /var/lib/... volume
-# + rest of build time/git/version magic.
-
-$(BUILD_DIR)/build-info.txt:
-       -mkdir -p $(BUILD_DIR)
-       echo "$(shell date +'%Y-%m-%d %H:%M') $(GIT_SHA)" > $@
-
-# This needs to be redone between build targets (so the windows build for 
instance gets the right LIB_DIR)
-$(BUILD_DIR)/link-flags.txt: $(BUILD_DIR)/build-info.txt
-       echo "-s -X main.defaultDataDir=$(DATA_DIR) \
-  -X \"fortio.org/fortio/version.buildInfo=$(shell cat $<)\" \
-  -X fortio.org/fortio/version.version=$(DIST_VERSION)" | tee $@
-
-.PHONY: official-build official-build-internal official-build-version 
official-build-clean clean-link-flags
-
-official-build: clean-link-flags official-build-internal
-
-# Fix 474
-clean-link-flags:
-       -$(RM) $(BUILD_DIR)/link-flags.txt
+$(BUILD_DIR):
+       mkdir -p $(BUILD_DIR)
+
+$(OFFICIAL_DIR):
+       mkdir -p $(OFFICIAL_DIR)
+
+.PHONY: official-build official-build-internal official-build-version 
official-build-clean
 
-official-build-internal: $(BUILD_DIR)/link-flags.txt
+official-build: official-build-internal
+
+official-build-internal: $(BUILD_DIR) $(OFFICIAL_DIR)
        $(GO_BIN) version
-       CGO_ENABLED=0 GOOS=$(GOOS) $(GO_BIN) build -a -ldflags '$(shell cat 
$(BUILD_DIR)/link-flags.txt)' -o $(OFFICIAL_BIN) $(OFFICIAL_TARGET)
+ifeq ($(MODE),install)
+       GOPATH=$(BUILD_DIR_ABS) CGO_ENABLED=0 GOOS=$(GOOS) $(GO_BIN) install -a 
-ldflags -s $(OFFICIAL_TARGET)@v$(DIST_VERSION)
+       # rename when building cross architecture (on windows it has .exe 
suffix thus the *)
+       ls -lR $(BUILD_DIR_BIN)
+       -mv -f $(BUILD_DIR_BIN)/*_*/fortio* $(BUILD_DIR_BIN)
+       -rmdir $(BUILD_DIR_BIN)/*_*
+       mv -f $(BUILD_DIR_BIN)/fortio* $(OFFICIAL_DIR)
+else
+       CGO_ENABLED=0 GOOS=$(GOOS) $(GO_BIN) build -a -ldflags -s -o 
$(OFFICIAL_BIN) $(OFFICIAL_TARGET)
+endif
 
 official-build-version: official-build
        $(OFFICIAL_BIN) version
 
 official-build-clean:
-       -$(RM) $(BUILD_DIR)/build-info.txt $(BUILD_DIR)/link-flags.txt 
$(OFFICIAL_BIN) release/Makefile
+       -$(RM) $(OFFICIAL_BIN) release/Makefile
 
 # Create a complete source tree with naming matching debian package conventions
 TAR ?= tar # on macos need gtar to get --owner
@@ -231,16 +230,12 @@
 .PHONY: install official-install
 
 BIN_INSTALL_DIR = $(DESTDIR)/usr/bin
-LIB_INSTALL_DIR = $(DESTDIR)$(LIB_DIR)
 MAN_INSTALL_DIR = $(DESTDIR)/usr/share/man/man1
-#DATA_INSTALL_DIR = $(DESTDIR)$(DATA_DIR)
 BIN_INSTALL_EXEC = fortio
 
 official-install: official-build-clean official-build-version
-       -mkdir -p $(BIN_INSTALL_DIR) $(MAN_INSTALL_DIR) # $(LIB_INSTALL_DIR) 
$(DATA_INSTALL_DIR)
-       # -chmod 1777 $(DATA_INSTALL_DIR)
+       -mkdir -p $(BIN_INSTALL_DIR) $(MAN_INSTALL_DIR)
        cp $(OFFICIAL_BIN) $(BIN_INSTALL_DIR)/$(BIN_INSTALL_EXEC)
-       #cp -r ui/templates ui/static $(LIB_INSTALL_DIR)
        cp docs/fortio.1 $(MAN_INSTALL_DIR)
 
 # Test distribution (only used by maintainer)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/README.md new/fortio-1.30.0/README.md
--- old/fortio-1.28.0/README.md 2022-04-26 02:16:27.000000000 +0200
+++ new/fortio-1.30.0/README.md 2022-05-14 01:39:50.000000000 +0200
@@ -44,19 +44,19 @@
 
 You can install from source:
 
-1. [Install go](https://golang.org/doc/install) (golang 1.16 or later)
-2. `go get fortio.org/fortio`
+1. [Install go](https://golang.org/doc/install) (golang 1.18 or later)
+2. `go install fortio.org/fortio@latest`
 3. you can now run `fortio` (from your gopath bin/ directory)
 
 
 ```shell
-curl -L 
https://github.com/fortio/fortio/releases/download/v1.28.0/fortio-linux_amd64-1.28.0.tgz
 \
+curl -L 
https://github.com/fortio/fortio/releases/download/v1.30.0/fortio-linux_amd64-1.30.0.tgz
 \
  | sudo tar -C / -xvzpf -
 # or the debian package
-wget 
https://github.com/fortio/fortio/releases/download/v1.28.0/fortio_1.28.0_amd64.deb
-dpkg -i fortio_1.28.0_amd64.deb
+wget 
https://github.com/fortio/fortio/releases/download/v1.30.0/fortio_1.30.0_amd64.deb
+dpkg -i fortio_1.30.0_amd64.deb
 # or the rpm
-rpm -i 
https://github.com/fortio/fortio/releases/download/v1.28.0/fortio-1.28.0-1.x86_64.rpm
+rpm -i 
https://github.com/fortio/fortio/releases/download/v1.30.0/fortio-1.30.0-1.x86_64.rpm
 # and more, see assets in release page
 ```
 
@@ -66,7 +66,7 @@
 brew install fortio
 ```
 
-On Windows, download 
https://github.com/fortio/fortio/releases/download/v1.28.0/fortio_win_1.28.0.zip
 and extract `fortio.exe` to any location, then using the Windows Command 
Prompt:
+On Windows, download 
https://github.com/fortio/fortio/releases/download/v1.30.0/fortio_win_1.30.0.zip
 and extract `fortio.exe` to any location, then using the Windows Command 
Prompt:
 ```
 fortio.exe server
 ```
@@ -74,8 +74,10 @@
 
 Once `fortio server` is running, you can visit its web UI at 
[http://localhost:8080/fortio/](http://localhost:8080/fortio/)
 
-You can get a preview of the reporting/graphing UI at 
[https://fortio.istio.io/](https://fortio.istio.io/)
+You can get a preview of the reporting/graphing UI at 
[https://demo.fortio.org/](https://demo.fortio.org/).
+<!--
 and on 
[istio.io/docs/performance-and-scalability/synthetic-benchmarks/](https://istio.io/docs/performance-and-scalability/synthetic-benchmarks/)
+-->
 
 ## Command line arguments
 
@@ -112,7 +114,7 @@
 <details>
 <!-- use release/updateFlags.sh to update this section -->
 <pre>
-???????????? 1.28.0 usage:
+???????????? 1.30.0 usage:
 where command is one of: load (load testing), server (starts ui, http-echo,
  redirect, proxies, tcp-echo and grpc ping servers), tcp-echo (only the 
tcp-echo
  server), report (report only UI server), redirect (only the redirect server),
@@ -195,7 +197,7 @@
         which service string to pass to health check
   -http-port port
         http echo server port. Can be in the form of host:port, ip:port, port
-or /unix/domain/path. (default "8080")
+or /unix/domain/path or "disabled". (default "8080")
   -http1.0
         Use http1.0 (instead of http 1.1)
   -httpbufferkb kbytes
@@ -277,6 +279,9 @@
 disable the feature. (default "8081")
   -resolve IP
         Resolve host name to this IP
+  -resolve-ip-type type
+        Resolve type: ip4 for ipv4, ip6 for ipv6 only, use ip for both (default
+ip4)
   -runid int
         Optional RunID to add to json result and auto save filename, to match
 server mode
@@ -1111,7 +1116,7 @@
 Code 503 : 15 (0.5 %)
 ```
 
-There are newer/live examples on 
[istio.io/docs/concepts/performance-and-scalability/#synthetic-end-to-end-benchmarks](https://archive.istio.io/v1.0/docs/concepts/performance-and-scalability/#synthetic-end-to-end-benchmarks)
+There are live examples on [demo.fortio.org](https://demo.fortio.org/)
 
 ## Contributing
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/Webtest.sh new/fortio-1.30.0/Webtest.sh
--- old/fortio-1.28.0/Webtest.sh        2022-04-26 02:16:27.000000000 +0200
+++ new/fortio-1.30.0/Webtest.sh        2022-05-14 01:39:50.000000000 +0200
@@ -16,7 +16,7 @@
 # Check we can build the image
 NATIVE_PLATFORM=$(docker buildx --builder default inspect | tail -1 | sed -e 
"s/Platforms: //" -e "s/,//g" | awk '{print $1}')
 echo "Building for $NATIVE_PLATFORM"
-make docker-internal TAG=webtest BUILDX_PLATFORMS="$NATIVE_PLATFORM" || exit 1
+make docker-internal TAG=webtest BUILDX_PLATFORMS="$NATIVE_PLATFORM" MODE=dev 
|| exit 1
 FORTIO_UI_PREFIX=/newprefix/ # test the non default prefix (not /fortio/)
 FILE_LIMIT=25 # must be low to detect leaks, go 1.14 seems to need more than 
go1.8 (!)
 LOGLEVEL=info # change to debug to debug
@@ -105,19 +105,19 @@
 # Do a grpcping
 docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping localhost
 # Do a grpcping to a scheme-prefixed destination. Fortio should append port 
number
-# re-enable once we get https://demo.fortio.org/
-# docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping https://fortio.istio.io
-# docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping http://fortio.istio.io
+# re-enable once we get https://grpc.fortio.org:/ fully working with https too
+# docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping https://grpc.fortio.org
+docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping grpc.fortio.org # uses 
default non tls 8079
 # Do a grpcping with -cert flag. Fortio should use valid cert.
-# docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping -cacert $CERT 
fortio.istio.io:443
-# docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping -cacert $CERT 
https://fortio.istio.io
+# docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping -cacert $CERT 
grpc.fortio.org:443
+# docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping -cacert $CERT 
https://grpc.fortio.org
 # Do a local grpcping. Fortio should append default grpc port number to 
destination
 docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping localhost
 # pprof should be there, no 404/error
 PPROF_URL="$BASE_URL/debug/pprof/heap?debug=1"
 $CURL "$PPROF_URL" | grep -i TotalAlloc # should find this in memory profile
 # creating dummy container to hold a volume for test certs due to remote 
docker bind mount limitation.
-docker create -v $TEST_CERT_VOL --name $DOCKERSECVOLNAME 
docker.io/fortio/fortio.build:v39 /bin/true # cleaned up by name
+docker create -v $TEST_CERT_VOL --name $DOCKERSECVOLNAME 
docker.io/fortio/fortio.build:v40 /bin/true # cleaned up by name
 # copying cert files into the certs volume of the dummy container
 for f in ca.crt server.crt server.key; do docker cp "$PWD/cert-tmp/$f" 
"$DOCKERSECVOLNAME:$TEST_CERT_VOL/$f"; done
 # start server in secure grpc mode. uses non-default ports to avoid conflicts 
with fortio_server container.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/bincommon/commonflags.go 
new/fortio-1.30.0/bincommon/commonflags.go
--- old/fortio-1.28.0/bincommon/commonflags.go  2022-04-26 02:16:27.000000000 
+0200
+++ new/fortio-1.30.0/bincommon/commonflags.go  2022-05-14 01:39:50.000000000 
+0200
@@ -125,7 +125,7 @@
                        // so `fortio version -s` is the short version; 
everything else is long/full
                        fmt.Println(version.Short())
                } else {
-                       fmt.Println(version.Long())
+                       fmt.Println(version.Full())
                }
                os.Exit(0)
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/dflag/configmap/updater_test.go 
new/fortio-1.30.0/dflag/configmap/updater_test.go
--- old/fortio-1.28.0/dflag/configmap/updater_test.go   2022-04-26 
02:16:27.000000000 +0200
+++ new/fortio-1.30.0/dflag/configmap/updater_test.go   2022-05-14 
01:39:50.000000000 +0200
@@ -124,7 +124,8 @@
 
 // eventually tries a given Assert function 5 times over the period of time.
 func eventually(t *testing.T, duration time.Duration,
-       af assertFunc, expected interface{}, actual getter, msgFmt string, 
msgArgs ...interface{}) {
+       af assertFunc, expected interface{}, actual getter, msgFmt string, 
msgArgs ...interface{},
+) {
        increment := duration / 5
        for i := 0; i < 5; i++ {
                time.Sleep(increment)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/dflag/dynstringset.go 
new/fortio-1.30.0/dflag/dynstringset.go
--- old/fortio-1.28.0/dflag/dynstringset.go     2022-04-26 02:16:27.000000000 
+0200
+++ new/fortio-1.30.0/dflag/dynstringset.go     2022-05-14 01:39:50.000000000 
+0200
@@ -78,7 +78,8 @@
 // WithNotifier adds a function that is called every time a new value is 
successfully set.
 // Each notifier is executed asynchronously in a new go-routine.
 func (d *DynStringSetValue) WithNotifier(notifier func(oldValue 
map[string]struct{},
-       newValue map[string]struct{})) *DynStringSetValue {
+       newValue map[string]struct{}),
+) *DynStringSetValue {
        d.notifier = notifier
        return d
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/fhttp/http_client.go 
new/fortio-1.30.0/fhttp/http_client.go
--- old/fortio-1.28.0/fhttp/http_client.go      2022-04-26 02:16:27.000000000 
+0200
+++ new/fortio-1.30.0/fhttp/http_client.go      2022-05-14 01:39:50.000000000 
+0200
@@ -46,6 +46,8 @@
        // Close() cleans up connections and state - must be paired with 
NewClient calls.
        // returns how many sockets have been used (Fastclient only)
        Close() int
+       // GetIPAddress() get the ip address that DNS resolves to
+       GetIPAddress() string
 }
 
 const (
@@ -308,6 +310,7 @@
        bodyContainsUUID     bool // if body contains the "{uuid}" pattern 
(lowercase)
        logErrors            bool
        id                   int
+       socketCount          int
 }
 
 // Close cleans up any resources used by NewStdClient.
@@ -324,7 +327,7 @@
        if c.transport != nil {
                c.transport.CloseIdleConnections()
        }
-       return 0 // TODO: find a way to track std client socket usage.
+       return c.socketCount
 }
 
 // ChangeURL only for standard client, allows fetching a different URL.
@@ -396,6 +399,11 @@
        return code, data, 0
 }
 
+// GetIPAddress get the ip address that DNS resolves to when using stdClient.
+func (c *Client) GetIPAddress() string {
+       return c.req.RemoteAddr
+}
+
 // NewClient creates either a standard or fast client (depending on
 // the DisableFastClient flag).
 func NewClient(o *HTTPOptions) (Fetcher, error) {
@@ -415,6 +423,23 @@
        if req == nil {
                return nil, err
        }
+
+       client := Client{
+               url:                  o.URL,
+               path:                 req.URL.Path,
+               pathContainsUUID:     strings.Contains(req.URL.Path, uuidToken),
+               rawQuery:             req.URL.RawQuery,
+               rawQueryContainsUUID: strings.Contains(req.URL.RawQuery, 
uuidToken),
+               body:                 o.PayloadString(),
+               bodyContainsUUID:     strings.Contains(o.PayloadString(), 
uuidToken),
+               req:                  req,
+               client: &http.Client{
+                       Timeout: o.HTTPReqTimeOut,
+               },
+               id:        o.ID,
+               logErrors: o.LogErrors,
+       }
+
        tr := http.Transport{
                MaxIdleConns:        o.NumConnections,
                MaxIdleConnsPerHost: o.NumConnections,
@@ -426,35 +451,34 @@
                        if o.Resolve != "" {
                                addr = o.Resolve + addr[strings.LastIndex(addr, 
":"):]
                        }
-                       return (&net.Dialer{
+                       conn, err := (&net.Dialer{
                                Timeout: o.HTTPReqTimeOut,
                        }).DialContext(ctx, network, addr)
+
+                       if conn != nil {
+                               newRemoteAddress := conn.RemoteAddr().String()
+                               // No change when it wasn't set before (first 
time) and when the value isn't actually changing either.
+                               if req.RemoteAddr != "" && newRemoteAddress != 
req.RemoteAddr {
+                                       log.Infof("[%d] Standard client IP 
address changed from %s to %s", client.id, req.RemoteAddr, newRemoteAddress)
+                               }
+                               req.RemoteAddr = newRemoteAddress
+                               client.socketCount++
+                       }
+
+                       return conn, err
                },
                TLSHandshakeTimeout: o.HTTPReqTimeOut,
        }
+
+       client.client.Transport = &tr
+       client.transport = &tr
+
        if o.https {
                tr.TLSClientConfig, err = o.TLSOptions.TLSClientConfig()
                if err != nil {
                        return nil, err
                }
        }
-       client := Client{
-               url:                  o.URL,
-               path:                 req.URL.Path,
-               pathContainsUUID:     strings.Contains(req.URL.Path, uuidToken),
-               rawQuery:             req.URL.RawQuery,
-               rawQueryContainsUUID: strings.Contains(req.URL.RawQuery, 
uuidToken),
-               body:                 o.PayloadString(),
-               bodyContainsUUID:     strings.Contains(o.PayloadString(), 
uuidToken),
-               req:                  req,
-               client: &http.Client{
-                       Timeout:   o.HTTPReqTimeOut,
-                       Transport: &tr,
-               },
-               transport: &tr,
-               id:        o.ID,
-               logErrors: o.LogErrors,
-       }
        if !o.FollowRedirects {
                // Lets us see the raw response instead of auto following 
redirects.
                client.client.CheckRedirect = func(req *http.Request, via 
[]*http.Request) error {
@@ -511,6 +535,11 @@
        tlsConfig    *tls.Config
 }
 
+// GetIPAddress get the ip address that DNS resolves to when using fast client.
+func (c *FastClient) GetIPAddress() string {
+       return c.dest.String()
+}
+
 // Close cleans up any resources used by FastClient.
 func (c *FastClient) Close() int {
        log.Debugf("Closing %p %s socket count %d", c, c.url, c.socketCount)
@@ -647,14 +676,15 @@
        c.socketCount++
        var socket net.Conn
        var err error
+       d := &net.Dialer{Timeout: c.reqTimeout}
        if c.https {
-               socket, err = tls.Dial(c.dest.Network(), c.dest.String(), 
c.tlsConfig)
+               socket, err = tls.DialWithDialer(d, c.dest.Network(), 
c.dest.String(), c.tlsConfig)
                if err != nil {
                        log.Errf("[%d] Unable to TLS connect to %v : %v", c.id, 
c.dest, err)
                        return nil
                }
        } else {
-               socket, err = net.Dial(c.dest.Network(), c.dest.String())
+               socket, err = d.Dial(c.dest.Network(), c.dest.String())
                if err != nil {
                        log.Errf("[%d] Unable to connect to %v : %v", c.id, 
c.dest, err)
                        return nil
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/fhttp/http_server.go 
new/fortio-1.30.0/fhttp/http_server.go
--- old/fortio-1.28.0/fhttp/http_server.go      2022-04-26 02:16:27.000000000 
+0200
+++ new/fortio-1.30.0/fhttp/http_server.go      2022-05-14 01:39:50.000000000 
+0200
@@ -172,14 +172,21 @@
 // Port can include binding address and/or be port 0.
 func HTTPServer(name string, port string) (*http.ServeMux, net.Addr) {
        m := http.NewServeMux()
+       return m, HTTPServerWithHandler(name, port, m)
+}
+
+// HTTPServerWithHandler creates and h2c compatible server named name on 
address/port port.
+// Port can include binding address and/or be port 0.
+// Takes in a handler.
+func HTTPServerWithHandler(name string, port string, hdlr http.Handler) 
net.Addr {
        h2s := &http2.Server{}
        s := &http.Server{
                IdleTimeout: serverIdleTimeout.Get(),
-               Handler:     h2c.NewHandler(m, h2s),
+               Handler:     h2c.NewHandler(hdlr, h2s),
        }
        listener, addr := fnet.Listen(name, port)
        if listener == nil {
-               return nil, nil // error already logged
+               return nil // error already logged
        }
        go func() {
                err := s.Serve(listener)
@@ -187,7 +194,7 @@
                        log.Fatalf("Unable to serve %s on %s: %v", name, 
addr.String(), err)
                }
        }()
-       return m, addr
+       return addr
 }
 
 // DynamicHTTPServer listens on an available port, sets up an http or a closing
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/fhttp/http_test.go 
new/fortio-1.30.0/fhttp/http_test.go
--- old/fortio-1.28.0/fhttp/http_test.go        2022-04-26 02:16:27.000000000 
+0200
+++ new/fortio-1.30.0/fhttp/http_test.go        2022-05-14 01:39:50.000000000 
+0200
@@ -676,7 +676,7 @@
        cli.Close()
 }
 
-func TestBadUrl(t *testing.T) {
+func TestBadUrlFastClient(t *testing.T) {
        opts := NewHTTPOptions("not a valid url")
        cli, err := NewFastClient(opts)
        if cli != nil || err == nil {
@@ -691,6 +691,22 @@
        }
 }
 
+func TestBadURLStdClient(t *testing.T) {
+       opts := NewHTTPOptions("not a valid url")
+       cli, err := NewStdClient(opts)
+       if cli != nil || err == nil {
+               t.Errorf("config1: got a client %v despite bogus url %s", cli, 
opts.URL)
+               cli.Close()
+       }
+
+       opts.URL = "http://doesnotexist.fortio.org";
+       cli, _ = NewStdClient(opts)
+       code, _, _ := cli.Fetch()
+       if code != -1 {
+               t.Errorf("config2: client can send request despite bogus url 
%s", opts.URL)
+       }
+}
+
 func TestDefaultPort(t *testing.T) {
        // TODO: change back to fortio demo server once setup
        url := "http://istio.io/"; // shall imply port 80
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/fhttp/httprunner.go 
new/fortio-1.30.0/fhttp/httprunner.go
--- old/fortio-1.28.0/fhttp/httprunner.go       2022-04-26 02:16:27.000000000 
+0200
+++ new/fortio-1.30.0/fhttp/httprunner.go       2022-05-14 01:39:50.000000000 
+0200
@@ -35,8 +35,9 @@
 // Also is the internal type used per thread/goroutine.
 type HTTPRunnerResults struct {
        periodic.RunnerResults
-       client   Fetcher
-       RetCodes map[int]int64
+       client     Fetcher
+       RetCodes   map[int]int64
+       IPCountMap map[string]int // TODO: Move it to a shared results struct 
where all runner should have this field
        // internal type/data
        sizes       *stats.Histogram
        headerSizes *stats.Histogram
@@ -92,12 +93,13 @@
        log.Infof("Starting http test for %s with %d threads at %.1f qps and %s 
warmup", o.URL, o.NumThreads, o.QPS, warmupMode)
        r := periodic.NewPeriodicRunner(&o.RunnerOptions)
        defer r.Options().Abort()
-       numThreads := r.Options().NumThreads
+       numThreads := r.Options().NumThreads // can change during run for c > 2 
n
        o.HTTPOptions.Init(o.URL)
        out := r.Options().Out // Important as the default value is set from 
nil to stdout inside NewPeriodicRunner
        total := HTTPRunnerResults{
                HTTPOptions: o.HTTPOptions,
                RetCodes:    make(map[int]int64),
+               IPCountMap:  make(map[string]int),
                sizes:       stats.NewHistogram(0, 100),
                headerSizes: stats.NewHistogram(0, 5),
                AbortOn:     o.AbortOn,
@@ -178,10 +180,16 @@
                fm.Close()
                _, _ = fmt.Fprintf(out, "Wrote profile data to %s.{cpu|mem}\n", 
o.Profiler)
        }
-       // Numthreads may have reduced but it should be ok to accumulate 0s from
-       // unused ones. We also must cleanup all the created clients.
+       // Numthreads may have reduced:
+       numThreads = total.RunnerResults.NumThreads
+       // But we also must cleanup all the created clients.
        keys := []int{}
        for i := 0; i < numThreads; i++ {
+               // Get the report on the IP address each thread use to send 
traffic
+               ip := httpstate[i].client.GetIPAddress()
+               log.Infof("[%d] %s resolve to IP address: %s\n", i, o.URL, ip)
+               total.IPCountMap[ip]++
+
                total.SocketCount += httpstate[i].client.Close()
                // Q: is there some copying each time stats[i] is used?
                for k := range httpstate[i].RetCodes {
@@ -193,14 +201,27 @@
                total.sizes.Transfer(httpstate[i].sizes)
                total.headerSizes.Transfer(httpstate[i].headerSizes)
        }
-       // Cleanup state:
+
+       // Sort the ip address form largest to smallest based on its usage count
+       ipList := make([]string, 0, len(total.IPCountMap))
+       for k := range total.IPCountMap {
+               ipList = append(ipList, k)
+       }
+
+       sort.Slice(ipList, func(i, j int) bool {
+               return total.IPCountMap[ipList[i]] > total.IPCountMap[ipList[j]]
+       })
+
+       // Cleanup state: (original num thread)
        r.Options().ReleaseRunners()
        sort.Ints(keys)
        totalCount := float64(total.DurationHistogram.Count)
-       if !o.DisableFastClient {
-               _, _ = fmt.Fprintf(out, "Sockets used: %d (for perfect 
keepalive, would be %d)\n", total.SocketCount, r.Options().NumThreads)
-       }
+       _, _ = fmt.Fprintf(out, "Sockets used: %d (for perfect keepalive, would 
be %d)\n", total.SocketCount, r.Options().NumThreads)
        _, _ = fmt.Fprintf(out, "Uniform: %t, Jitter: %t\n", total.Uniform, 
total.Jitter)
+       _, _ = fmt.Fprintf(out, "IP addresses distribution:\n")
+       for _, v := range ipList {
+               _, _ = fmt.Fprintf(out, "%s: %d\n", v, total.IPCountMap[v])
+       }
        for _, k := range keys {
                _, _ = fmt.Fprintf(out, "Code %3d : %d (%.1f %%)\n", k, 
total.RetCodes[k], 100.*float64(total.RetCodes[k])/totalCount)
        }
@@ -216,7 +237,7 @@
        return &total, nil
 }
 
-// A errgroup is a collection of goroutines working on subtasks that are part 
of
+// An errgroup is a collection of goroutines working on subtasks that are part 
of
 // the same overall task.
 type errgroup struct {
        wg sync.WaitGroup
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/fhttp/httprunner_test.go 
new/fortio-1.30.0/fhttp/httprunner_test.go
--- old/fortio-1.28.0/fhttp/httprunner_test.go  2022-04-26 02:16:27.000000000 
+0200
+++ new/fortio-1.30.0/fhttp/httprunner_test.go  2022-05-14 01:39:50.000000000 
+0200
@@ -60,6 +60,10 @@
        if res.SocketCount != res.RunnerResults.NumThreads {
                t.Errorf("%d socket used, expected same as thread# %d", 
res.SocketCount, res.RunnerResults.NumThreads)
        }
+       count := getIPUsageCount(res.IPCountMap)
+       if count != res.RunnerResults.NumThreads {
+               t.Errorf("Total IP usage count %d, expected same as thread %d", 
count, res.RunnerResults.NumThreads)
+       }
        // Test raw client, should get warning about non init timeout:
        rawOpts := HTTPOptions{
                URL: opts.URL,
@@ -121,11 +125,8 @@
        if ngAfter > ngBefore2+8 {
                t.Errorf("Goroutines after test %d, expected it to stay near 
%d", ngAfter, ngBefore2)
        }
-       if !opts.DisableFastClient {
-               // only fast client so far has a socket count
-               if res.SocketCount != res.RunnerResults.NumThreads {
-                       t.Errorf("%d socket used, expected same as thread# %d", 
res.SocketCount, res.RunnerResults.NumThreads)
-               }
+       if res.SocketCount != res.RunnerResults.NumThreads {
+               t.Errorf("%d socket used, expected same as thread# %d", 
res.SocketCount, res.RunnerResults.NumThreads)
        }
 }
 
@@ -190,17 +191,16 @@
        }
 }
 
-func TestClosingAndSocketCount(t *testing.T) {
+func testClosingAndSocketCount(t *testing.T, o *HTTPRunnerOptions) {
        mux, addr := DynamicHTTPServer(false)
        mux.HandleFunc("/echo42/", EchoHandler)
        URL := fmt.Sprintf("http://localhost:%d/echo42/?close=true";, addr.Port)
-       opts := HTTPRunnerOptions{}
-       opts.Init(URL)
-       opts.QPS = 10
+       o.Init(URL)
+       o.QPS = 10
        numReq := int64(50) // can't do too many without running out of fds on 
mac
-       opts.Exactly = numReq
-       opts.NumThreads = 5
-       res, err := RunHTTPTest(&opts)
+       o.Exactly = numReq
+       o.NumThreads = 5
+       res, err := RunHTTPTest(o)
        if err != nil {
                t.Fatal(err)
        }
@@ -217,6 +217,14 @@
        }
 }
 
+func TestClosingAndSocketCountFastClient(t *testing.T) {
+       testClosingAndSocketCount(t, &HTTPRunnerOptions{})
+}
+
+func TestClosingAndSocketCountStdClient(t *testing.T) {
+       testClosingAndSocketCount(t, &HTTPRunnerOptions{HTTPOptions: 
HTTPOptions{DisableFastClient: true}})
+}
+
 func TestHTTPRunnerBadServer(t *testing.T) {
        // Using http to an https server (or the current 'close all' dummy 
https server)
        // should fail:
@@ -462,3 +470,11 @@
                t.Errorf("Abort2 not working, did %d requests expecting ideally 
1 and <= %d", count, o.NumThreads)
        }
 }
+
+func getIPUsageCount(ipCountMap map[string]int) (count int) {
+       for _, v := range ipCountMap {
+               count += v
+       }
+
+       return count
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/fnet/network.go 
new/fortio-1.30.0/fnet/network.go
--- old/fortio-1.28.0/fnet/network.go   2022-04-26 02:16:27.000000000 +0200
+++ new/fortio-1.30.0/fnet/network.go   2022-05-14 01:39:50.000000000 +0200
@@ -15,7 +15,9 @@
 package fnet // import "fortio.org/fortio/fnet"
 
 import (
+       "context"
        "errors"
+       "flag"
        "fmt"
        "io"
        "io/ioutil"
@@ -25,8 +27,10 @@
        "strconv"
        "strings"
        "sync"
+       "sync/atomic"
        "time"
 
+       "fortio.org/fortio/dflag"
        "fortio.org/fortio/log"
        "fortio.org/fortio/version"
 )
@@ -59,6 +63,14 @@
        MaxPayloadSize = 256 * KILOBYTE
        // Payload that is returned during echo call.
        Payload []byte
+       // Atomically incremented counter for dns resolution.
+       dnsRoundRobin uint32 = 0xffffffff // we want the first one, after 
increment to be 0
+       // FlagResolveIPType indicates which IP types to resolve.
+       // With round robin resolution now the default, you are likely to get 
ipv6 which may not work if
+       // use both type (`ip`). In particular some test environments like the 
CI do have ipv6
+       // for localhost but fail to connect. So we made the default ip4 only.
+       FlagResolveIPType = dflag.DynString(flag.CommandLine, 
"resolve-ip-type", "ip4",
+               "Resolve `type`: ip4 for ipv4, ip6 for ipv6 only, use ip for 
both")
 )
 
 // nolint: gochecknoinits // needed here (unit change)
@@ -286,6 +298,9 @@
 
 // ResolveByProto returns the address of the host,port suitable for net.Dial.
 // nil in case of errors. works for both "tcp" and "udp" proto.
+// Limit which address type is returned using `resolve-ip` ip4/ip6/ip (for 
both, default).
+// If the same host is requested, and it has more than 1 IP, returned value 
will roundrobin
+// over the ips.
 func ResolveByProto(host string, port string, proto string) (*HostPortAddr, 
error) {
        log.Debugf("Resolve() called with host=%s port=%s proto=%s", host, 
port, proto)
        dest := &HostPortAddr{}
@@ -294,29 +309,33 @@
                host = host[1 : len(host)-1]
        }
        isAddr := net.ParseIP(host)
+       filter := FlagResolveIPType.Get()
        var err error
        if isAddr != nil {
                log.Debugf("Host already an IP, will go to %s", isAddr)
                dest.IP = isAddr
        } else {
                var addrs []net.IP
-               addrs, err = net.LookupIP(host)
+               addrs, err = net.DefaultResolver.LookupIP(context.Background(), 
filter, host)
                if err != nil {
                        log.Errf("Unable to lookup '%s' : %v", host, err)
                        return nil, err
                }
-               if len(addrs) > 1 && log.LogDebug() {
-                       log.Debugf("Using only the first of the addresses for 
%s : %v", host, addrs)
+               idx := uint32(0)
+               l := uint32(len(addrs))
+               if l > 1 {
+                       idx = (atomic.AddUint32(&dnsRoundRobin, 1) % l)
+                       log.Debugf("Using address #%d for %s : %v", idx, host, 
addrs)
                }
-               log.Debugf("%s will go to %s", proto, addrs[0])
-               dest.IP = addrs[0]
+               log.Debugf("%s will go to %s", proto, addrs[idx])
+               dest.IP = addrs[idx]
        }
        dest.Port, err = net.LookupPort(proto, port)
        if err != nil {
                log.Errf("Unable to resolve port '%s' : %v", port, err)
                return nil, err
        }
-       log.LogVf("Resolved %s:%s to %s addr %+v", host, port, proto, dest)
+       log.LogVf("Resolved %s:%s to %s %s addr %+v", host, port, proto, 
filter, dest)
        return dest, nil
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/fortio_main.go 
new/fortio-1.30.0/fortio_main.go
--- old/fortio-1.28.0/fortio_main.go    2022-04-26 02:16:27.000000000 +0200
+++ new/fortio-1.30.0/fortio_main.go    2022-05-14 01:39:50.000000000 +0200
@@ -110,7 +110,7 @@
        profileFlag     = flag.String("profile", "", "write .cpu and .mem 
profiles to `file`")
        grpcFlag        = flag.Bool("grpc", false, "Use GRPC (health check by 
default, add -ping for ping) for load testing")
        echoPortFlag    = flag.String("http-port", "8080",
-               "http echo server port. Can be in the form of host:port, 
ip:port, `port` or /unix/domain/path.")
+               "http echo server port. Can be in the form of host:port, 
ip:port, `port` or /unix/domain/path or \""+disabled+"\".")
        tcpPortFlag = flag.String("tcp-port", "8078",
                "tcp echo server port. Can be in the form of host:port, 
ip:port, `port` or /unix/domain/path or \""+disabled+"\".")
        udpPortFlag = flag.String("udp-port", "8078",
@@ -130,15 +130,13 @@
        // do not remove the flag for backward compatibility.  Was absolute 
`path` to the dir containing the static files dir
        // which is now embedded in the binary thanks to that support in golang 
1.16.
        _            = flag.String("static-dir", "", "Deprecated/unused 
`path`.")
-       dataDirFlag  = flag.String("data-dir", defaultDataDir, "`Directory` 
where JSON results are stored/read")
+       dataDirFlag  = flag.String("data-dir", ".", "`Directory` where JSON 
results are stored/read")
        proxiesFlags proxiesFlagList
        proxies      = make([]string, 0)
        // -M flag.
        httpMultiFlags httpMultiFlagList
        httpMulties    = make([]string, 0)
 
-       defaultDataDir = "."
-
        allowInitialErrorsFlag = flag.Bool("allow-initial-errors", false, 
"Allow and don't abort on initial warmup errors")
        abortOnFlag            = flag.Int("abort-on", 0,
                "Http `code` that if encountered aborts the run. e.g. 503 or -1 
for socket errors.")
@@ -185,7 +183,7 @@
        calcQPS = flag.Bool("calc-qps", false, "Calculate the qps based on 
number of requests (-n) and duration (-t)")
 )
 
-// nolint: funlen // well yes it's fairly big and lotsa ifs.
+// nolint: funlen,gocyclo // well yes it's fairly big and lotsa ifs.
 func main() {
        flag.Var(&proxiesFlags, "P",
                "Tcp proxies to run, e.g -P \"localport1 
dest_host1:dest_port1\" -P \"[::1]:0 www.google.com:443\" ...")
@@ -271,8 +269,10 @@
                if *redirectFlag != disabled {
                        fhttp.RedirectToHTTPS(*redirectFlag)
                }
-               if !ui.Serve(baseURL, *echoPortFlag, *echoDbgPathFlag, 
*uiPathFlag, *dataDirFlag, percList) {
-                       os.Exit(1) // error already logged
+               if *echoPortFlag != disabled {
+                       if !ui.Serve(baseURL, *echoPortFlag, *echoDbgPathFlag, 
*uiPathFlag, *dataDirFlag, percList) {
+                               os.Exit(1) // error already logged
+                       }
                }
                startProxies()
        case "grpcping":
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/go.mod new/fortio-1.30.0/go.mod
--- old/fortio-1.28.0/go.mod    2022-04-26 02:16:27.000000000 +0200
+++ new/fortio-1.30.0/go.mod    2022-05-14 01:39:50.000000000 +0200
@@ -1,12 +1,22 @@
 module fortio.org/fortio
 
-go 1.16
+go 1.18
 
 require (
-       github.com/fsnotify/fsnotify v1.5.1
+       github.com/fsnotify/fsnotify v1.5.4
        github.com/golang/protobuf v1.5.2
        github.com/google/uuid v1.3.0
-       github.com/stretchr/testify v1.7.0
-       golang.org/x/net v0.0.0-20220225172249-27dd8689420f
-       google.golang.org/grpc v1.44.0
+       github.com/stretchr/testify v1.7.1
+       golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4
+       google.golang.org/grpc v1.46.0
+)
+
+require (
+       github.com/davecgh/go-spew v1.1.0 // indirect
+       github.com/pmezard/go-difflib v1.0.0 // indirect
+       golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
+       golang.org/x/text v0.3.7 // indirect
+       google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // 
indirect
+       google.golang.org/protobuf v1.27.1 // indirect
+       gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/go.sum new/fortio-1.30.0/go.sum
--- old/fortio-1.28.0/go.sum    2022-04-26 02:16:27.000000000 +0200
+++ new/fortio-1.30.0/go.sum    2022-05-14 01:39:50.000000000 +0200
@@ -8,8 +8,8 @@
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod 
h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod 
h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod 
h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
-github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod 
h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod 
h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod 
h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod 
h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/davecgh/go-spew v1.1.0 
h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
 github.com/davecgh/go-spew v1.1.0/go.mod 
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -17,10 +17,10 @@
 github.com/envoyproxy/go-control-plane 
v0.9.1-0.20191026205805-5f8ba28d4473/go.mod 
h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod 
h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
 github.com/envoyproxy/go-control-plane 
v0.9.9-0.20201210154907-fd9021fe5dad/go.mod 
h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/go-control-plane 
v0.9.10-0.20210907150352-cf90f659a021/go.mod 
h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
+github.com/envoyproxy/go-control-plane 
v0.10.2-0.20220325020618-49ff273808a1/go.mod 
h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod 
h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/fsnotify/fsnotify v1.5.1 
h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
-github.com/fsnotify/fsnotify v1.5.1/go.mod 
h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
+github.com/fsnotify/fsnotify v1.5.4 
h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
+github.com/fsnotify/fsnotify v1.5.4/go.mod 
h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
 github.com/ghodss/yaml v1.0.0/go.mod 
h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod 
h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/mock v1.1.1/go.mod 
h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@@ -43,8 +43,9 @@
 github.com/google/go-cmp v0.3.1/go.mod 
h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.4.0/go.mod 
h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.0/go.mod 
h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
 github.com/google/go-cmp v0.5.5/go.mod 
h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
+github.com/google/go-cmp v0.5.6/go.mod 
h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/uuid v1.1.2/go.mod 
h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
 github.com/google/uuid v1.3.0/go.mod 
h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -55,8 +56,9 @@
 github.com/rogpeppe/fastuuid v1.2.0/go.mod 
h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
 github.com/stretchr/objx v0.1.0/go.mod 
h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.5.1/go.mod 
h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/stretchr/testify v1.7.0 
h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 github.com/stretchr/testify v1.7.0/go.mod 
h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1 
h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
+github.com/stretchr/testify v1.7.1/go.mod 
h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 go.opentelemetry.io/proto/otlp v0.7.0/go.mod 
h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod 
h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod 
h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -71,8 +73,9 @@
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod 
h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod 
h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod 
h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f 
h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod 
h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod 
h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 
h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=
+golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod 
h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod 
h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod 
h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -83,12 +86,12 @@
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod 
h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e 
h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
-golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod 
h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20220412211240-33da011f77ad 
h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
+golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod 
h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -112,8 +115,8 @@
 google.golang.org/grpc v1.27.0/go.mod 
h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/grpc v1.33.1/go.mod 
h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
 google.golang.org/grpc v1.36.0/go.mod 
h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg=
-google.golang.org/grpc v1.44.0/go.mod 
h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
+google.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8=
+google.golang.org/grpc v1.46.0/go.mod 
h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod 
h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod 
h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod 
h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -124,8 +127,9 @@
 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod 
h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 google.golang.org/protobuf v1.25.0/go.mod 
h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod 
h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0 
h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
 google.golang.org/protobuf v1.26.0/go.mod 
h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.27.1 
h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
+google.golang.org/protobuf v1.27.1/go.mod 
h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 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/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/release/Dockerfile.in 
new/fortio-1.30.0/release/Dockerfile.in
--- old/fortio-1.28.0/release/Dockerfile.in     2022-04-26 02:16:27.000000000 
+0200
+++ new/fortio-1.30.0/release/Dockerfile.in     2022-05-14 01:39:50.000000000 
+0200
@@ -1,5 +1,5 @@
 # Concatenated after ../Dockerfile to create the tgz
-FROM docker.io/fortio/fortio.build:v39 as stage
+FROM docker.io/fortio/fortio.build:v40 as stage
 ARG archs="amd64 arm64 ppc64le s390x"
 ENV archs=${archs}
 
@@ -11,28 +11,29 @@
 
 WORKDIR /go/src/fortio.org
 COPY . fortio
-# Check we still build with go 1.8 (and macos does not break)
-RUN make -C fortio official-build BUILD_DIR=/build 
OFFICIAL_BIN=../fortio_go_latest.mac GOOS=darwin GO_BIN=/usr/local/go/bin/go
-# Windows release, for now assumes running from fortio directory (static 
resources in .)
-RUN make -C fortio official-build BUILD_DIR=/build LIB_DIR=. 
OFFICIAL_BIN=/tmp/fortio.exe GOOS=windows
+# Check macos does not break
+RUN make -C fortio official-build BUILD_DIR=/build 
OFFICIAL_DIR=/tmp/fortio_mac GOOS=darwin GO_BIN=/usr/local/go/bin/go
+# Windows release
+RUN make -C fortio official-build BUILD_DIR=/build 
OFFICIAL_DIR=/tmp/fortio_win GOOS=windows
+RUN mv /tmp/fortio_win/fortio.exe /tmp/fortio.exe
 # Linux per-architecture binaries building
 RUN sh -c \
     'set -ex; for arch in ${archs}; do \
-       make -C fortio official-build-version BUILD_DIR=/build GOARCH=${arch} 
OFFICIAL_BIN=/tmp/fortio_${arch}; \
+       make -C fortio official-build BUILD_DIR=/build GOARCH=${arch} 
OFFICIAL_DIR=/tmp/fortio_${arch}; \
     done'
 
-RUN cd fortio && /tmp/fortio_$(go env GOARCH) version -s > /tmp/version
+RUN cd fortio && /tmp/fortio_$(go env GOARCH)/fortio version -s > /tmp/version
 
 WORKDIR /stage
 
 # Make per-architecture .tgz files
 RUN sh -c \
     'set -ex; for arch in ${archs}; do \
-        cp /tmp/fortio_${arch} usr/bin/fortio; \
+        cp /tmp/fortio_${arch}/fortio usr/bin/fortio; \
         # Make sure the list here is both minimal and complete \
         # we could take all of * but that adds system directories to the tar \
         tar cvf - usr/share/man/man1/fortio.1 usr/bin/fortio | gzip --best > 
/tgz/fortio-linux_${arch}-$(cat /tmp/version).tgz; \
-        rm -rf usr/bin/fortio; \
+        rm -f usr/bin/fortio; \
     done'
 
 WORKDIR /tmp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/release/README.md 
new/fortio-1.30.0/release/README.md
--- old/fortio-1.28.0/release/README.md 2022-04-26 02:16:27.000000000 +0200
+++ new/fortio-1.30.0/release/README.md 2022-05-14 01:39:50.000000000 +0200
@@ -1,24 +1,8 @@
 # How to make a fortio release
 
-- Make sure `version/version.go`'s `major`/`minor`/`patch` is newer than the 
most recent [release](https://github.com/fortio/fortio/releases)
+- All the builds and docker, except the build image updates, are now fully 
automated through github actions based on tags
 
-- Update debian/changelog to match said upcoming release
-
-- Make a release there and document the changes since the previous release
-
-- Make sure to use the same git tag format (e.g "v0.7.1" - note that there is 
`v` prefix in the tag, like many projects but unlike the rest of istio). Docker 
and internal version/tag is "0.7.1", the `v` is only for git tags.
-
-- Make sure your git status is clean, and the tag is present (git pull) before 
the next step or it will get marked dirty/pre
-
-- Create the binary tgz, deb and rpm packages: `make release` (from/in the 
toplevel directory)
-
-- Upload the release/fortio-\*.tgz, .orig.tar.gz, .deb and .rpm to GitHub
-
-- Push the dist to Debian/Ubuntu
-
-- The docker official builds are done automatically based on tag, check 
[fortio's cloud docker build 
page](https://cloud.docker.com/app/fortio/repository/docker/fortio/fortio/builds)
-
-- Increment the `patch` and commit that right away so the first point is true 
next time and so master/latest docker images have the correct next-pre version.
+- Make sure to use the same git tag format (e.g "v0.7.1" - note that there is 
`v` prefix in the tag, like many projects). Docker and internal version/tag is 
"0.7.1", the `v` is only for git tags.
 
 - Once the release is deemed good/stable: move the git tag `latest_release` to 
the same as the release.
 
@@ -39,9 +23,9 @@
   docker push fortio/fortio:latest_release
   ```
 
-- To update the command line flags in the ../README.md; go install the right 
version of fortio so it is in your path and run updateFlags.sh
+- To update the command line flags in the ../README.md; run 
`release/updateFlags.sh`
 
-- Update the homebrew tap
+- Update the homebrew tap `brew bump-formula-pr --tag v1.2.3 fortio`
 
 ## How to change the build image
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/stats/stats_test.go 
new/fortio-1.30.0/stats/stats_test.go
--- old/fortio-1.28.0/stats/stats_test.go       2022-04-26 02:16:27.000000000 
+0200
+++ new/fortio-1.30.0/stats/stats_test.go       2022-05-14 01:39:50.000000000 
+0200
@@ -726,7 +726,6 @@
                input float64 // input
                start float64 // start
                end   float64 // end
-
        }{
                {input: 11, start: 10, end: 11},
                {input: 171, start: 160, end: 180},
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/ui/restHandler.go 
new/fortio-1.30.0/ui/restHandler.go
--- old/fortio-1.28.0/ui/restHandler.go 2022-04-26 02:16:27.000000000 +0200
+++ new/fortio-1.30.0/ui/restHandler.go 2022-05-14 01:39:50.000000000 +0200
@@ -236,7 +236,8 @@
 
 // Run executes the run (can be called async or not, writer is nil for async 
mode).
 func Run(w http.ResponseWriter, r *http.Request, jd map[string]interface{},
-       runner, url string, ro periodic.RunnerOptions, httpopts 
*fhttp.HTTPOptions) {
+       runner, url string, ro periodic.RunnerOptions, httpopts 
*fhttp.HTTPOptions,
+) {
        //      go func() {
        var res periodic.HasRunnerResult
        var err error
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/ui/uihandler.go 
new/fortio-1.30.0/ui/uihandler.go
--- old/fortio-1.28.0/ui/uihandler.go   2022-04-26 02:16:27.000000000 +0200
+++ new/fortio-1.30.0/ui/uihandler.go   2022-05-14 01:39:50.000000000 +0200
@@ -998,7 +998,7 @@
        fmt.Printf(uiMsg + "\n")
        uiPath = "/"
        dataDir = datadir
-       logoPath = version.Short() + "/static/img/logo.svg"
+       logoPath = version.Short() + 
"/static/img/fortio-logo-gradient-no-bg.svg"
        chartJSPath = version.Short() + "/static/js/Chart.min.js"
        fs := http.FileServer(http.FS(staticFS))
        prefix := uiPath + version.Short()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fortio-1.28.0/version/version.go 
new/fortio-1.30.0/version/version.go
--- old/fortio-1.28.0/version/version.go        2022-04-26 02:16:27.000000000 
+0200
+++ new/fortio-1.30.0/version/version.go        2022-05-14 01:39:50.000000000 
+0200
@@ -15,21 +15,18 @@
 // Package version for fortio holds version information and build information.
 package version // import "fortio.org/fortio/version"
 import (
+       "fmt"
        "runtime"
+       "runtime/debug"
 
        "fortio.org/fortio/log"
 )
 
-const (
-       debug = false // turn on to debug init()
-)
-
 var (
-       // The following are set by Dockerfile during link time.
-       buildInfo = "unknown"
-       version   = "dev"
-       // computed in init().
-       longVersion = ""
+       // The following are (re)computed in init().
+       version     = "dev"
+       longVersion = "unknown long"
+       fullVersion = "unknown full"
 )
 
 // Short returns the 3 digit short version string Major.Minor.Patch[-pre]
@@ -42,18 +39,32 @@
        return version
 }
 
-// Long returns the full version and build information.
+// Long returns the long version and build information.
 // Format is "X.Y.X[-pre] YYYY-MM-DD HH:MM SHA[-dirty]" date and time is
 // the build date (UTC), sha is the git sha of the source tree.
 func Long() string {
        return longVersion
 }
 
+// Full returns the Long version + all the run time BuildInfo, ie
+// all the dependent modules and version and hash as well.
+func Full() string {
+       return fullVersion
+}
+
 // Carefully manually tested all the combinations in pair with Dockerfile.
 
 func init() { // nolint:gochecknoinits //we do need an init for this
-       if debug {
-               log.SetLogLevel(log.Debug)
+       binfo, ok := debug.ReadBuildInfo()
+       if !ok {
+               log.Errf("fortio: unexpected but no build info available")
+               return
+       }
+       v := binfo.Main.Version
+       // '(devel)' messes up the release-tests paths
+       if v != "(devel)" {
+               version = v[1:] // skip leading v
        }
-       longVersion = version + " " + buildInfo + " " + runtime.Version()
+       longVersion = version + " " + binfo.Main.Sum + " " + binfo.GoVersion + 
" " + runtime.GOARCH + " " + runtime.GOOS
+       fullVersion = fmt.Sprintf("%s\n%v", longVersion, binfo.String())
 }

++++++ vendor.tar.gz ++++++
++++ 15587 lines of diff (skipped)

Reply via email to