Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple macro benchmark #2304

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[allowlist]
description = "Project allowlist"

paths = [
'''benchmark\/internal\/registry\/fake_quay.key$''',
]
15 changes: 15 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,21 @@ feature_%: ## Run acceptance tests for a single feature file, e.g. make feature_
scenario_%: build ## Run acceptance tests for a single scenario, e.g. make scenario_inline_policy
@cd acceptance && go test -test.run 'TestFeatures/$*'

benchmark/%/data.tar.gz:
@cd benchmark/$*
@./prepare_data.sh

.PHONY: benchmark_%
benchmark_%: benchmark/%/data.tar.gz
@cd benchmark/$*
@go run .

.PHONY: benchmark_data
benchmark_data: benchmark/simple/data.tar.gz ## Prepare data for benchmark

.PHONY: benchmark
benchmark: benchmark_simple ## Run benchmarks

.PHONY: ci
ci: test lint-fix acceptance ## Run the usual required CI tasks

Expand Down
12 changes: 12 additions & 0 deletions benchmark/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Benchmarks of ec CLI

Benchmarks within this directory use the [golang
benchmarking](golang.org/x/benchmarks/) package and output in the [standard
benchmark
format](https://go.googlesource.com/proposal/+/master/design/14313-benchmark-format.md).

Each benchmark is built as a standalone executable with no external dependency
other than any data that is contained within it. Benchmarks are run from within
the directory they're defined in, simply by running `go run .`, additional
arguments can be passed in, for example `-benchnum 10` to run the benchmark 10
times.
20 changes: 20 additions & 0 deletions benchmark/internal/registry/fake_quay.cer
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDOjCCAiKgAwIBAgIUOc/vG5o8pNnIBCIYsrYJ01jkmfEwDQYJKoZIhvcNAQEL
BQAwFzEVMBMGA1UEAwwMYmVuY2htYXJrLmVjMB4XDTI0MTIwOTE1MzIyMVoXDTM0
MTIwNzE1MzIyMVowFzEVMBMGA1UEAwwMYmVuY2htYXJrLmVjMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnVIvUGHA2XFScaRcN8vxNiuDShN4SNuCWcdC
cbzvCbA7yu4v2LJBqsbDIs5zWcr9kb15vg0Cg3dCHztnsJCmFIwp6lKc3l60eD4+
Qke2YnD3cUB/P4A7jMUC2kEjjlqdnoLw6IIwt7D6JZeaZhDpPfGyf3llxoVdT5+J
dfBtn6U4WnYqqTg7vccoe0RTXkotLAUMyshd00QaGKIOZ5HdzDBXHUVszTU+Vidf
9xyxndDVlxnE70zWv/jeZLhgnkxMRzoi0q2hq25TeugQ+yrGKVD4UBB6CaGWgAIN
Sw0iTFmYd+0uBVpTYF8KLO2jc/bNqFGJn2t/+P88XqfHTCZVfwIDAQABo34wfDA5
BgNVHREEMjAwggdxdWF5LmlvghpyZWdpc3RyeS5hY2Nlc3MucmVkaGF0LmNvbYIJ
bG9jYWxob3N0MAsGA1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNV
HQ4EFgQUP3lNVxeEEpMjoKQ2wPk6hhLsXOwwDQYJKoZIhvcNAQELBQADggEBAFKp
MpYwkR5vb73JsRATYr6H/A5bRAjVg+NoMklOJ5lu5PtwomD0rlD8OIJeXuT57Bsy
PAukG7gXlHk0zJ3cExxsys+jscsGKi2+gKEWvOYj06Z5xug7GPZyoA9r6MOKclZJ
VXCxpQfkl5pGDQiIhtpvuADt8oBogx4mwDhP16WBz/5BkKIpsLn7jGZOUYaSrjG3
OLf5AArhHzs0rRRcaCjbybuah8nQMMqG7Q6bz7jF4szCeIL7ndWro2U5kgVVMrXS
5zbEklvW5OXFO/UREiY+5YBAu6gCr0APFLAQi5qfAhKpbQkjZ28unuB/3aQlT0kR
wHo3oDNZDNaIwBoP/54=
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions benchmark/internal/registry/fake_quay.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCdUi9QYcDZcVJx
pFw3y/E2K4NKE3hI24JZx0JxvO8JsDvK7i/YskGqxsMiznNZyv2RvXm+DQKDd0If
O2ewkKYUjCnqUpzeXrR4Pj5CR7ZicPdxQH8/gDuMxQLaQSOOWp2egvDogjC3sPol
l5pmEOk98bJ/eWXGhV1Pn4l18G2fpThadiqpODu9xyh7RFNeSi0sBQzKyF3TRBoY
og5nkd3MMFcdRWzNNT5WJ1/3HLGd0NWXGcTvTNa/+N5kuGCeTExHOiLSraGrblN6
6BD7KsYpUPhQEHoJoZaAAg1LDSJMWZh37S4FWlNgXwos7aNz9s2oUYmfa3/4/zxe
p8dMJlV/AgMBAAECggEASM1Xh+M002tVs7FT255NKbxJLWaFK3IpiFJltSyxkdI0
WVyQV79mFBmXA+x2BP+jCGaeiAyNNTljKADdox/NO4UBgKZqYZ2B9oMXXKTDChss
5wPp3wEAjcw93bJ3OdFFT61YvsBAu0DzAaJ+mO0Kgtfuun77Ujs1SzuQ6Tsx/8ZD
STr8q7DcMAd6afHFFk5NZDqyFPgzmEMUWRFy7BH/vLLEgdRi7I7UbTYhjpP7uyjF
/0HLSjBQJr58554CyL11OcVOwqktKZYKMVsCNWg6l4uhYxg0ChyJgO+PuUhPqh1i
eIybcaDUVQ0LG/gBYzDlnw8yNXPO4+HX+MdIXafBAQKBgQDZx6m2rsI3L4M0ow89
T6L8jMrFF6bUp2PBVPOYvobk4de3x7ma4WwK212l869A2u536+8BlBaiZN0yRSmI
XXX0oL8JfqTO7d5efa9zHdkEN+t7iwVFWsYe74jjVR/oOyW7ZJ07gP/kZudbm8uk
DnGzEGsjTYo7K6dEcEiXXmZiDwKBgQC47j8iR7v6a0E7EzEcM6FIpAV8tlpj0wUt
pXKHPRdMQaOi39YyNWCGGake7bRCGz2ni1zqSVqVIcm6yvzlS/o3lLMTUYlUxtqt
0cGrTJXkyhwkyoAJg0vwU43BJkbUNsX0y5revv/T4TaVTYK4dv2RTv8Jbdp6sT7i
B6I7tFmFkQKBgQDQShe24rRchbPOrzoPINC5DYuOMA3fC+3r5e1KJMftt1dTrdGG
IZ3tUFvkMgpnVD2KMvyYHOP9E80/nEiZ5RHBE9FDKn5Eb9sjssAQsPZ0A2vU8GTt
LWGaCu14yFzJB3ESJqv/UmTsNcOHqZ1+XlY+tjBSRoI0D49edKnpJF913wKBgQCn
WSHUuamIIYr0FJf6d1ZaT+OPSc1eTFWBSxjq/QOaREP6XiiNYvQoJgx/KohW0iPm
/Bxm/15zWhIdcReNwEV8CppKvxxRlWnKpehmRXXXhnYVbRKUiTYtEs9SnHq4C6Dz
t1Q8ggcsC7/DOFM07qjj1+K++6QcJ01KabIL6VahoQKBgGNCgw4+0291OA8nwjXl
HNu9WBzJVHsAL9RDvrL6c4wcUWmhJTUcKN/TnndYN5SdvrOzZ2RjysS8KZoLnHgI
c41uBNLvGtE9RPuzFe7U3zt9t80d4gcjy92tBru6xszPIgmKsUe8Hrl2EWbJvCET
/BbfoyzzqH3f+vYm25GFSIy5
-----END PRIVATE KEY-----
169 changes: 169 additions & 0 deletions benchmark/internal/registry/registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
// Copyright The Enterprise Contract Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//type Closer func()
// SPDX-License-Identifier: Apache-2.0

package registry

import (
"context"
"crypto/tls"
"crypto/x509"
_ "embed"
"fmt"
"log"
"net"
"net/http"
"net/http/httptest"
"net/url"
"os"
"path"
"time"

"github.com/docker/docker/api/types/container"
"github.com/smarty/cproxy/v2"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/modules/registry"
"github.com/testcontainers/testcontainers-go/wait"

"github.com/enterprise-contract/ec-cli/benchmark/internal/suite"
)

//go:embed fake_quay.cer
var certificate []byte

//go:embed fake_quay.key
var key []byte

type registryCloser struct {
tempDir string
container *registry.RegistryContainer
proxy *httptest.Server
}

func (r *registryCloser) Close() {
if r == nil {
return
}

Check warning on line 58 in benchmark/internal/registry/registry.go

View check run for this annotation

Codecov / codecov/patch

benchmark/internal/registry/registry.go#L55-L58

Added lines #L55 - L58 were not covered by tests

if r.tempDir != "" {
_ = os.RemoveAll(r.tempDir)
}

Check warning on line 62 in benchmark/internal/registry/registry.go

View check run for this annotation

Codecov / codecov/patch

benchmark/internal/registry/registry.go#L60-L62

Added lines #L60 - L62 were not covered by tests

if r.container != nil {
_ = r.container.Terminate(context.Background())
}

Check warning on line 66 in benchmark/internal/registry/registry.go

View check run for this annotation

Codecov / codecov/patch

benchmark/internal/registry/registry.go#L64-L66

Added lines #L64 - L66 were not covered by tests

if r.proxy != nil {
r.proxy.Close()
}

Check warning on line 70 in benchmark/internal/registry/registry.go

View check run for this annotation

Codecov / codecov/patch

benchmark/internal/registry/registry.go#L68-L70

Added lines #L68 - L70 were not covered by tests
}

type registryProxy struct {
registry string
}

func (f *registryProxy) IsAuthorized(_ http.ResponseWriter, req *http.Request) bool {
req.RequestURI = fmt.Sprintf("https://%s/", f.registry)
req.URL, _ = url.Parse(req.RequestURI)
req.Host = f.registry

return true

Check warning on line 82 in benchmark/internal/registry/registry.go

View check run for this annotation

Codecov / codecov/patch

benchmark/internal/registry/registry.go#L77-L82

Added lines #L77 - L82 were not covered by tests
}

func Launch(data string) (suite.Closer, error) {
ctx := context.Background()

env := testcontainers.WithEnv(map[string]string{
"REGISTRY_HTTP_TLS_CERTIFICATE": "/tls/fake_quay.cer",
"REGISTRY_HTTP_TLS_KEY": "/tls/fake_quay.key",
})

dir, err := os.MkdirTemp("", "ec-benchmark-tls-*")
if err != nil {
return nil, err
}
closer := &registryCloser{dir, nil, nil}

if err := os.Setenv("https_proxy", "http://localhost:3128"); err != nil {
return nil, err
}

Check warning on line 101 in benchmark/internal/registry/registry.go

View check run for this annotation

Codecov / codecov/patch

benchmark/internal/registry/registry.go#L85-L101

Added lines #L85 - L101 were not covered by tests

if err := os.Chmod(dir, 0755); err != nil {
return closer.Close, err
}

Check warning on line 105 in benchmark/internal/registry/registry.go

View check run for this annotation

Codecov / codecov/patch

benchmark/internal/registry/registry.go#L103-L105

Added lines #L103 - L105 were not covered by tests

certPath := path.Join(dir, "fake_quay.cer")
if err := os.WriteFile(certPath, certificate, 0600); err != nil {
return closer.Close, err
}

Check warning on line 110 in benchmark/internal/registry/registry.go

View check run for this annotation

Codecov / codecov/patch

benchmark/internal/registry/registry.go#L107-L110

Added lines #L107 - L110 were not covered by tests

if err := os.Setenv("SSL_CERT_FILE", certPath); err != nil {
return closer.Close, err
}

Check warning on line 114 in benchmark/internal/registry/registry.go

View check run for this annotation

Codecov / codecov/patch

benchmark/internal/registry/registry.go#L112-L114

Added lines #L112 - L114 were not covered by tests

if err := os.WriteFile(path.Join(dir, "fake_quay.key"), key, 0600); err != nil {
return closer.Close, err
}

Check warning on line 118 in benchmark/internal/registry/registry.go

View check run for this annotation

Codecov / codecov/patch

benchmark/internal/registry/registry.go#L116-L118

Added lines #L116 - L118 were not covered by tests

rp := registryProxy{}
proxy := cproxy.New(cproxy.Options.Filter(&rp), cproxy.Options.Logger(log.Default()))
proxyServer := httptest.NewUnstartedServer(proxy)
proxyServer.Listener, err = net.Listen("tcp", "127.0.0.1:3128")
if err != nil {
return closer.Close, err
}
proxyServer.Config.ErrorLog = log.Default()
proxyServer.Start()
closer.proxy = proxyServer

tlsMount := testcontainers.WithHostConfigModifier(func(hostConfig *container.HostConfig) {
hostConfig.Binds = append(hostConfig.Binds, fmt.Sprintf("%s:/tls:ro,Z", dir))
})

Check warning on line 133 in benchmark/internal/registry/registry.go

View check run for this annotation

Codecov / codecov/patch

benchmark/internal/registry/registry.go#L120-L133

Added lines #L120 - L133 were not covered by tests

roots := x509.NewCertPool()
roots.AppendCertsFromPEM(certificate)
waitStrategy := testcontainers.WithWaitStrategy(wait.ForHTTP("/").
WithPort("5000/tcp").
WithTLS(true, &tls.Config{
RootCAs: roots,
MinVersion: tls.VersionTLS13,
}).
WithStartupTimeout(10 * time.Second))

opts := []testcontainers.ContainerCustomizer{
registry.WithData(data),
env,
tlsMount,
waitStrategy,
}

if false {
opts = append(opts,
testcontainers.WithConfigModifier(func(config *container.Config) {
config.AttachStdout = true
}),

Check warning on line 156 in benchmark/internal/registry/registry.go

View check run for this annotation

Codecov / codecov/patch

benchmark/internal/registry/registry.go#L135-L156

Added lines #L135 - L156 were not covered by tests
testcontainers.WithLogger(log.Default()))
}

r, err := registry.Run(ctx, "registry:2.8.3", opts...)
if err != nil {
return closer.Close, err
}
closer.container = r

rp.registry = r.RegistryName

return closer.Close, nil

Check warning on line 168 in benchmark/internal/registry/registry.go

View check run for this annotation

Codecov / codecov/patch

benchmark/internal/registry/registry.go#L160-L168

Added lines #L160 - L168 were not covered by tests
}
19 changes: 19 additions & 0 deletions benchmark/internal/suite/closer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright The Enterprise Contract Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

package suite

type Closer func()
32 changes: 32 additions & 0 deletions benchmark/internal/suite/suite.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright The Enterprise Contract Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

package suite

import (
"io"

"github.com/enterprise-contract/ec-cli/cmd"
"github.com/enterprise-contract/ec-cli/cmd/root"
)

func Execute(args []string) error {
c := root.NewRootCmd()
cmd.AddCommandsTo(c)
c.SetArgs(args)
c.SetOutput(io.Discard)
return c.Execute()
}
Loading
Loading