Repository: moby/moby
File: daemon/logger/fluentd/fluentd_test.go (Go)

Code before:
				// Unable to process the connection. This can happen if the connection is closed.
				select {
				case <-ctx.Done():
					// If the context is canceled, there's nothing for us to do here.
					return
				default:
					t.Logf("Unable to accept connection: %v", err)
					continue
				}
			}

			// Handle an incoming connection. We're essentially blackholing this by not reading from
			// or writing to the connection.
			go func(ctx context.Context, conn net.Conn) {
				defer conn.Close()
				// Simulate unresponsive server: do nothing with the connection
				<-ctx.Done()
			}(ctx, conn)
		}
	}(ctx, &connectedWG)

	f, err := New(logger.Info{
		ContainerName: "/test-container",
		ContainerID:   "container-abcdefghijklmnopqrstuvwxyz01234567890",
		Config: map[string]string{
			"fluentd-address": "unix://" + socketFile,
			"tag":             "{{.Name}}/{{.FullID}}",
			// Disabling async behavior with limited retries and buffer size lets
			// us test this in a more preditable manner for failures. Otherwise,
			// write errors could be silently consumed. The "fluentd-write-timeout"
			// flag should be equally effective regardless of async being enabled/disabled.
			"fluentd-async":         "false",
			"fluentd-max-retries":   "1",
			"fluentd-retry-wait":    "10ms",
			"fluentd-buffer-limit":  "1",
			"fluentd-write-timeout": "1ms",
		},
	})
	assert.NilError(t, err)
	defer f.Close()

	// Ensure that the server is ready to accept connections since we have disabled async mode
	// in fluentd options.
	connectedWG.Wait()

	// Attempt writing 1MiB worth of log data (all 0's) repeatedly. We should see a failure
	// after the 1st or the 2nd attempt depending on when the connection's write buffer gets
	// filled up.
	// If we don't set a write timeout on the connection, this will hang forever. But, because
	// we have a write timeout, we expect the `Log` method to return an error.
	data := make([]byte, 1024*1024)

Review comment (suggestion):
Micro-nit; can remove the defer, to make my IDE ever-so-slightly less noisy about "unhandled error" 😂 

```go
go func(ctx context.Context, conn net.Conn) {
	// Simulate unresponsive server: do nothing with the connection
	<-ctx.Done()
	_ = conn.Close()
}(ctx, conn)
```


Code after:

	// Start accepting connections.
	go func(ctx context.Context, wg *sync.WaitGroup) {
		wg.Done()

		for {
			conn, err := l.Accept()
			if err != nil {
				// Unable to process the connection. This can happen if the connection is closed.
				select {
				case <-ctx.Done():
					// If the context is canceled, there's nothing for us to do here.
					return
				default:
					t.Logf("Unable to accept connection: %v", err)
					continue
				}
			}

			// Handle an incoming connection. We're essentially blackholing this by not reading from
			// or writing to the connection.
			go func(ctx context.Context, conn net.Conn) {
				// Simulate unresponsive server: do nothing with the connection
				<-ctx.Done()
				_ = conn.Close()
			}(ctx, conn)
		}
	}(ctx, &connectedWG)

	f, err := New(logger.Info{
		ContainerName: "/test-container",
		ContainerID:   "container-abcdefghijklmnopqrstuvwxyz01234567890",
		Config: map[string]string{
			"fluentd-address": "unix://" + socketFile,
			"tag":             "{{.Name}}/{{.FullID}}",
			// Disabling async behavior with limited retries and buffer size lets
			// us test this in a more preditable manner for failures. Otherwise,
			// write errors could be silently consumed. The "fluentd-write-timeout"
			// flag should be equally effective regardless of async being enabled/disabled.
			"fluentd-async":         "false",
			"fluentd-max-retries":   "1",
			"fluentd-retry-wait":    "10ms",
			"fluentd-buffer-limit":  "1",
			"fluentd-write-timeout": "1ms",
		},
	})
	assert.NilError(t, err)
	defer f.Close()

	// Ensure that the server is ready to accept connections since we have disabled async mode
	// in fluentd options.