docker_test.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package main
  2. import (
  3. "context"
  4. "testing"
  5. F "github.com/sagernet/sing/common/format"
  6. "github.com/docker/docker/api/types"
  7. "github.com/docker/docker/api/types/container"
  8. "github.com/docker/docker/client"
  9. "github.com/docker/go-connections/nat"
  10. "github.com/stretchr/testify/require"
  11. )
  12. type DockerOptions struct {
  13. Image string
  14. EntryPoint string
  15. Ports []uint16
  16. Cmd []string
  17. Env []string
  18. Bind []string
  19. }
  20. func startDockerContainer(t *testing.T, options DockerOptions) {
  21. dockerClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
  22. require.NoError(t, err)
  23. defer dockerClient.Close()
  24. var containerOptions container.Config
  25. containerOptions.Image = options.Image
  26. containerOptions.Entrypoint = []string{options.EntryPoint}
  27. containerOptions.Cmd = options.Cmd
  28. containerOptions.Env = options.Env
  29. containerOptions.ExposedPorts = make(nat.PortSet)
  30. var hostOptions container.HostConfig
  31. if !isDarwin {
  32. hostOptions.NetworkMode = "host"
  33. }
  34. hostOptions.PortBindings = make(nat.PortMap)
  35. for _, port := range options.Ports {
  36. containerOptions.ExposedPorts[nat.Port(F.ToString(port, "/tcp"))] = struct{}{}
  37. containerOptions.ExposedPorts[nat.Port(F.ToString(port, "/udp"))] = struct{}{}
  38. hostOptions.PortBindings[nat.Port(F.ToString(port, "/tcp"))] = []nat.PortBinding{
  39. {HostPort: F.ToString(port), HostIP: "0.0.0.0"},
  40. }
  41. hostOptions.PortBindings[nat.Port(F.ToString(port, "/udp"))] = []nat.PortBinding{
  42. {HostPort: F.ToString(port), HostIP: "0.0.0.0"},
  43. }
  44. }
  45. dockerContainer, err := dockerClient.ContainerCreate(context.Background(), &containerOptions, &hostOptions, nil, nil, "")
  46. require.NoError(t, err)
  47. t.Cleanup(func() {
  48. cleanContainer(dockerContainer.ID)
  49. })
  50. require.NoError(t, dockerClient.ContainerStart(context.Background(), dockerContainer.ID, types.ContainerStartOptions{}))
  51. /*attach, err := dockerClient.ContainerAttach(context.Background(), dockerContainer.ID, types.ContainerAttachOptions{
  52. Logs: true, Stream: true, Stdout: true, Stderr: true,
  53. })
  54. require.NoError(t, err)
  55. go func() {
  56. attach.Reader.WriteTo(os.Stderr)
  57. }()*/
  58. }
  59. func cleanContainer(id string) error {
  60. dockerClient, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
  61. if err != nil {
  62. return err
  63. }
  64. defer dockerClient.Close()
  65. return dockerClient.ContainerRemove(context.Background(), id, types.ContainerRemoveOptions{Force: true})
  66. }