diff --git a/.github/workflows/on-push.yaml b/.github/workflows/on-push.yaml new file mode 100644 index 0000000..799c469 --- /dev/null +++ b/.github/workflows/on-push.yaml @@ -0,0 +1,14 @@ +name: tests + +on: + push: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: test + run: | + ./scripts/docker-run-all-tests.sh diff --git a/.gitignore b/.gitignore index 2c8b7b4..5dfa331 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ .idea/ .idea/workspace.xml +.vim +.vscode + run-amqp.iml + +netskope* diff --git a/Dockerfile b/Dockerfile index b2a03a1..a2d7a6a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,15 @@ #syntax=docker/dockerfile:1.10.0 ARG GOLANG_VERSION=1.23.1 -ARG GOLANG_LINT_VERSION=v1.61.0 FROM golang:${GOLANG_VERSION} ENV CGO_ENABLED=0 -RUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin ${GOLANG_LINT_VERSION} - WORKDIR /go/src/github.com/mergermarket/run-amqp -ADD . /go/src/github.com/mergermarket/run-amqp +COPY *netskope-CA.pem /etc/ssl/certs +COPY go.mod go.sum ./ +RUN go mod download + +COPY . ./ +RUN go mod tidy CMD ./build-app.sh diff --git a/Dockerfile.lint b/Dockerfile.lint new file mode 100644 index 0000000..8010d07 --- /dev/null +++ b/Dockerfile.lint @@ -0,0 +1,8 @@ +FROM golangci/golangci-lint:v1.61 + +ENV CGO_ENABLED=0 +WORKDIR /app + +COPY *netskope-CA.pem /etc/ssl/certs + +COPY . ./ diff --git a/README.md b/README.md index 67d3271..5a9ad87 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,7 @@ Prerequisites: Run all tests: - docker compose run runamqp - -Run specific test: - - docker compose run runamqp go test -run=TestRequeue_DLQ_Message_After_Retries + ./scripts/docker-run-all-tests.sh ## Test Harness Application diff --git a/build-app.sh b/build-app.sh index 98253ee..fb23bbb 100755 --- a/build-app.sh +++ b/build-app.sh @@ -4,7 +4,5 @@ set -o errexit set -o nounset set -o pipefail -golangci-lint run --timeout=10m - go fmt $(go list ./... | grep -v /vendor/) go test $(go list ./... | grep -v acceptance-tests ) --cover -timeout 25s \ No newline at end of file diff --git a/compose.yaml b/compose.yaml index 879b162..b5fb924 100644 --- a/compose.yaml +++ b/compose.yaml @@ -27,3 +27,10 @@ services: interval: 30s timeout: 30s retries: 3 + + lint: + build: + context: . + dockerfile: ./Dockerfile.lint + command: | + golangci-lint run ./... --timeout=10m -v diff --git a/config.go b/config.go index 01f806a..c5771ae 100644 --- a/config.go +++ b/config.go @@ -51,59 +51,85 @@ type ConsumerConfig struct { exchange exchange queue queue } +type NewPublisherConfig struct { + URL string + exchangeName string + exchangeType ExchangeType + confirmable bool + logger logger +} // NewPublisherConfig returns a PublisherConfig derived from the consumer config. This config can be used to create a Publisher to Publish to this consumer func (c ConsumerConfig) NewPublisherConfig() PublisherConfig { - return NewPublisherConfig(c.URL, c.exchange.Name, c.exchange.Type, false, c.Logger) + nc := NewPublisherConfig{ + URL: c.URL, + exchangeName: c.exchange.Name, + exchangeType: c.exchange.Type, + confirmable: false, + logger: c.Logger, + } + return nc.Config() } // NewPublisherConfig config for establishing a RabbitMq Publisher -func NewPublisherConfig(URL string, exchangeName string, exchangeType ExchangeType, confirmable bool, logger logger) PublisherConfig { +func (p *NewPublisherConfig) Config() PublisherConfig { return PublisherConfig{ - confirmable: confirmable, + confirmable: p.confirmable, connectionConfig: connectionConfig{ - URL: URL, - Logger: logger, + URL: p.URL, + Logger: p.logger, }, exchange: exchange{ - Name: exchangeName, - Type: exchangeType, + Name: p.exchangeName, + Type: p.exchangeType, }, } } +type NewConsumerConfig struct { + URL string + exchangeName string + exchangeType ExchangeType + patterns []string + logger logger + requeueTTL int16 + requeueLimit int + serviceName string + prefetch int +} + // NewConsumerConfig config for establishing a RabbitMq consumer -func NewConsumerConfig(URL string, exchangeName string, exchangeType ExchangeType, patterns []string, logger logger, requeueTTL int16, requeueLimit int, serviceName string, prefetch int) ConsumerConfig { +func (p *NewConsumerConfig) Config() ConsumerConfig { - if len(patterns) == 0 { - logger.Info("Executive decision made! You did not supply a pattern so we have added a default of '#'") - patterns = append(patterns, "#") //testme + if len(p.patterns) == 0 { + p.logger.Info("Executive decision made! You did not supply a pattern so we have added a default of '#'") + p.patterns = append(p.patterns, "#") //testme } - queueName := fmt.Sprintf("%s-for-%s", exchangeName, serviceName) + queueName := fmt.Sprintf("%s-for-%s", p.exchangeName, p.serviceName) return ConsumerConfig{ connectionConfig: connectionConfig{ - URL: URL, - Logger: logger, + URL: p.URL, + Logger: p.logger, }, exchange: exchange{ - Name: exchangeName, - RetryNow: fmt.Sprintf("%s-for-%s-retry-now", exchangeName, serviceName), - RetryLater: fmt.Sprintf("%s-for-%s-retry-%dms-later", exchangeName, serviceName, requeueTTL), - DLE: fmt.Sprintf("%s-for-%s-dle", exchangeName, serviceName), - Type: exchangeType, + Name: p.exchangeName, + RetryNow: fmt.Sprintf("%s-for-%s-retry-now", p.exchangeName, p.serviceName), + RetryLater: fmt.Sprintf("%s-for-%s-retry-%dms-later", p.exchangeName, p.serviceName, p.requeueTTL), + DLE: fmt.Sprintf("%s-for-%s-dle", p.exchangeName, p.serviceName), + Type: p.exchangeType, }, queue: queue{ Name: queueName, DLQ: queueName + "-dlq", - RetryLater: fmt.Sprintf("%s-retry-%dms-later", queueName, requeueTTL), - RequeueTTL: requeueTTL, - RetryLimit: requeueLimit, - Patterns: patterns, + RetryLater: fmt.Sprintf("%s-retry-%dms-later", queueName, p.requeueTTL), + RequeueTTL: p.requeueTTL, + RetryLimit: p.requeueLimit, + Patterns: p.patterns, MaxPriority: 10, - PrefetchCount: prefetch, + PrefetchCount: p.prefetch, }, } } diff --git a/config_test.go b/config_test.go index 432f293..ca4a88e 100644 --- a/config_test.go +++ b/config_test.go @@ -1,8 +1,9 @@ package runamqp import ( - "github.com/mergermarket/run-amqp/helpers" "testing" + + "github.com/mergermarket/run-amqp/helpers" ) const defaultPrefetch = 10 @@ -11,17 +12,18 @@ func TestItDerivesConsumerExchanges(t *testing.T) { logger := helpers.NewTestLogger(t) - consumerConfig := NewConsumerConfig( - testRabbitURI, - "producer-stuff", - Fanout, - noPatterns, - logger, - 200, - testRequeueLimit, - "service", - defaultPrefetch, - ) + c := NewConsumerConfig{ + URL: testRabbitURI, + exchangeName: "producer-stuff", + exchangeType: Fanout, + patterns: noPatterns, + logger: logger, + requeueTTL: 200, + requeueLimit: testRequeueLimit, + serviceName: "service", + prefetch: defaultPrefetch, + } + consumerConfig := c.Config() expectedQueueName := "producer-stuff-for-service" @@ -66,17 +68,18 @@ func TestItDerivesConsumerExchanges(t *testing.T) { func TestItSetsPatternToHashWhenNoneSupplied(t *testing.T) { logger := helpers.NewTestLogger(t) - consumerConfig := NewConsumerConfig( - testRabbitURI, - "exchange", - Fanout, - noPatterns, - logger, - 200, - testRequeueLimit, - "service", - defaultPrefetch, - ) + c := NewConsumerConfig{ + URL: testRabbitURI, + exchangeName: "exchange", + exchangeType: Fanout, + patterns: noPatterns, + logger: logger, + requeueTTL: 200, + requeueLimit: testRequeueLimit, + serviceName: "service", + prefetch: defaultPrefetch, + } + consumerConfig := c.Config() if len(consumerConfig.queue.Patterns) != 1 { t.Fatal("When there are no patterns supplied it should've put one in") @@ -90,17 +93,18 @@ func TestItSetsPatternToHashWhenNoneSupplied(t *testing.T) { func TestItSetsPatternsOnQueue(t *testing.T) { logger := helpers.NewTestLogger(t) pattern := "pretty.pattern" - consumerConfig := NewConsumerConfig( - testRabbitURI, - "exchange", - Fanout, - []string{pattern}, - logger, - 200, - testRequeueLimit, - "service", - defaultPrefetch, - ) + c := NewConsumerConfig{ + URL: testRabbitURI, + exchangeName: "exchange", + exchangeType: Fanout, + patterns: []string{pattern}, + logger: logger, + requeueTTL: 200, + requeueLimit: testRequeueLimit, + serviceName: "service", + prefetch: defaultPrefetch, + } + consumerConfig := c.Config() if len(consumerConfig.queue.Patterns) != 1 { t.Fatal("There should be one pattern set") diff --git a/consumer_test.go b/consumer_test.go index b5526af..49b8c2f 100644 --- a/consumer_test.go +++ b/consumer_test.go @@ -2,10 +2,11 @@ package runamqp import ( "fmt" - "github.com/mergermarket/run-amqp/helpers" "math/rand" "testing" "time" + + "github.com/mergermarket/run-amqp/helpers" ) var ( @@ -466,17 +467,19 @@ func newTestConsumerConfig(t *testing.T, config consumerConfigOptions) ConsumerC config.ServiceName = serviceName } - return NewConsumerConfig( - "amqp://guest:guest@rabbitmq:5672/", - config.ExchangeName, - config.ExchangeType, - config.Patterns, - logger, - config.RequeueTTL, - config.Retries, - config.ServiceName, - defaultPrefetch, - ) + c := + NewConsumerConfig{ + URL: "amqp://guest:guest@rabbitmq:5672/", + exchangeName: config.ExchangeName, + exchangeType: config.ExchangeType, + patterns: config.Patterns, + logger: logger, + requeueTTL: config.RequeueTTL, + requeueLimit: config.Retries, + serviceName: config.ServiceName, + prefetch: defaultPrefetch, + } + return c.Config() } var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") diff --git a/example_consumer_test.go b/example_consumer_test.go index 18af7ea..8ec08b7 100644 --- a/example_consumer_test.go +++ b/example_consumer_test.go @@ -28,18 +28,19 @@ func (e *ExampleHandler) Name() string { func ExampleConsumer() { + c := NewConsumerConfig{ + URL: testRabbitURI, + exchangeName: "test-example-exchange", + exchangeType: Fanout, + patterns: noPatterns, + logger: &SimpleLogger{io.Discard}, + requeueTTL: testRequeueTTL, + requeueLimit: testRequeueLimit, + serviceName: serviceName, + prefetch: defaultPrefetch, + } // Create a consumer config - config := NewConsumerConfig( - testRabbitURI, - "test-example-exchange", - Fanout, - noPatterns, - &SimpleLogger{io.Discard}, - testRequeueTTL, - testRequeueLimit, - serviceName, - defaultPrefetch, - ) + config := c.Config() // Create a consumer, which holds the references to the channel of Messages consumer := NewConsumer(config) @@ -59,7 +60,14 @@ func ExampleConsumer() { consumer.Process(handler, numberOfWorkers) // We can now publish to the same exchange for fun - publisherConfig := NewPublisherConfig(config.URL, config.exchange.Name, config.exchange.Type, false, config.Logger) + pc := NewPublisherConfig{ + URL: config.URL, + exchangeName: config.exchange.Name, + exchangeType: config.exchange.Type, + confirmable: false, + logger: config.Logger, + } + publisherConfig := pc.Config() publisher, err := NewPublisher(publisherConfig) // Let's check the Publisher is ready too diff --git a/netskope-CA.pem b/netskope-CA.pem new file mode 100644 index 0000000..aaceae5 --- /dev/null +++ b/netskope-CA.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIQOXHiHVfxaadBzMxrQ149wDANBgkqhkiG9w0BAQsFADBQ +MRMwEQYKCZImiZPyLGQBGRYDbmV0MRgwFgYKCZImiZPyLGQBGRYISU9OZ3JvdXAx +HzAdBgNVBAMTFklPTmdyb3VwLXVrd2Rjci1kYzEtQ0EwHhcNMTkwNjA4MTgzNTM0 +WhcNMjkwNjA4MTg0NTM0WjBQMRMwEQYKCZImiZPyLGQBGRYDbmV0MRgwFgYKCZIm +iZPyLGQBGRYISU9OZ3JvdXAxHzAdBgNVBAMTFklPTmdyb3VwLXVrd2Rjci1kYzEt +Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCoB+H+daHI09SGyMb7 +cu021aW2IQShpYEUrbw9sG9n0KqdXdtPDa4s2458eE3OEGCDyMnV/ms2EAxySj7X +VHq5kFAGF1YKhn1j3hKHvAkf3cb3o+xr3PDwpOA6huSnNmXvhRE1WcV0WWqZAiXN +BDRanqmhlqxNbh2xsI+qgWMYQvgZf09D1W8O27TzPl8WFAU67t3XazAl41cuvPJe +nHvie7vYnVMim5v01YpEPSIg9TgMSFvuTKpEXX8LDkme2TspXjptiJlWp3FvjmjZ +28l2pT88HA82xyzzRaACabnhiAnAs8pWro6wYTezUrUt9JkO3cNtMrLeWgWLJ63N +Fa4fAgMBAAGjUTBPMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBSw/cEQB31dXtK5omN9ieVdnVyAPzAQBgkrBgEEAYI3FQEEAwIBADANBgkq +hkiG9w0BAQsFAAOCAQEAG03otbkAI12laUPr0lgy7yLfDBfuIVaXSAvsC1WHBbAo +0VKFuP/6eQVcgerdW0G0Sg+alr2ZhJ6/3GQneiYnVX6veRAIDV0I8VuOHC852iAy +E3qqCfbypRFQkPbaLFAfpmGdCKShW5WW55Lfirnre8QdcT4M4FGP+jpY2ZEOFIDi +MODQcdoAALqKJbulFaBVyUMnsNuy1KnfLfJZU4lJ44bUrgGOU4fBGkkrzoJ9s9zP +JJNzr1cPxwy1+C92rHx7IEPCeUk9CSNZYo+r2X446byC+BDIw+Q60iacvkCVgaOe +1dKF4G9Q5hrav3/owAwodIl5wuZyndP9+VwQyGRSVg== +-----END CERTIFICATE----- diff --git a/publisher_test.go b/publisher_test.go index 53f43e9..5c3a60b 100644 --- a/publisher_test.go +++ b/publisher_test.go @@ -1,15 +1,23 @@ package runamqp import ( - "github.com/mergermarket/run-amqp/helpers" "testing" + + "github.com/mergermarket/run-amqp/helpers" ) func TestNakedPublisher(t *testing.T) { t.Parallel() expectedExchangeName := "chris-rulz" + randomString(5) - config := NewPublisherConfig(testRabbitURI, expectedExchangeName, Fanout, true, helpers.NewTestLogger(t)) + c := NewPublisherConfig{ + URL: testRabbitURI, + exchangeName: expectedExchangeName, + exchangeType: Fanout, + confirmable: true, + logger: helpers.NewTestLogger(t), + } + config := c.Config() publisher, err := NewPublisher(config) @@ -28,7 +36,14 @@ func TestNotReadyPublisherErrorsOnPublish(t *testing.T) { t.Parallel() expectedExchangeName := "chris-rulz" + randomString(5) - config := NewPublisherConfig(testRabbitURI, expectedExchangeName, Fanout, true, helpers.NewTestLogger(t)) + c := NewPublisherConfig{ + URL: testRabbitURI, + exchangeName: expectedExchangeName, + exchangeType: Fanout, + confirmable: true, + logger: helpers.NewTestLogger(t), + } + config := c.Config() publisher, err := NewPublisher(config) diff --git a/sample/Dockerfile b/sample/Dockerfile index 807b165..152aa82 100644 --- a/sample/Dockerfile +++ b/sample/Dockerfile @@ -6,5 +6,11 @@ FROM golang:${GOLANG_VERSION} AS build ENV CGO_ENABLED=0 WORKDIR /go/src/github.com/mergermarket/run-amqp -ADD . . +COPY *netskope-CA.pem /etc/ssl/certs +COPY go.mod go.sum ./ +RUN go mod download + +COPY . ./ +RUN go mod tidy + CMD go run sample/app.go diff --git a/scripts/docker-run-all-tests.sh b/scripts/docker-run-all-tests.sh new file mode 100755 index 0000000..b164701 --- /dev/null +++ b/scripts/docker-run-all-tests.sh @@ -0,0 +1,5 @@ +#!/bin/bash -e + +./scripts/docker-run-lint.sh +./scripts/docker-run-tests.sh + diff --git a/scripts/docker-run-lint.sh b/scripts/docker-run-lint.sh new file mode 100755 index 0000000..e595f0c --- /dev/null +++ b/scripts/docker-run-lint.sh @@ -0,0 +1,3 @@ +#!/bin/bash -e + +docker compose run --remove-orphans --build --rm lint diff --git a/scripts/docker-run-tests.sh b/scripts/docker-run-tests.sh new file mode 100755 index 0000000..56aeda6 --- /dev/null +++ b/scripts/docker-run-tests.sh @@ -0,0 +1,5 @@ +#!/bin/bash -e + +docker compose build test --no-cache +docker compose run test +