github.com/mutagen-io/mutagen@v0.18.0-rc1/pkg/integration/integration_test.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "os" 6 "testing" 7 8 "google.golang.org/grpc" 9 10 "github.com/mutagen-io/mutagen/cmd" 11 "github.com/mutagen-io/mutagen/pkg/agent" 12 "github.com/mutagen-io/mutagen/pkg/daemon" 13 "github.com/mutagen-io/mutagen/pkg/forwarding" 14 "github.com/mutagen-io/mutagen/pkg/grpcutil" 15 "github.com/mutagen-io/mutagen/pkg/ipc" 16 daemonsvc "github.com/mutagen-io/mutagen/pkg/service/daemon" 17 forwardingsvc "github.com/mutagen-io/mutagen/pkg/service/forwarding" 18 promptingsvc "github.com/mutagen-io/mutagen/pkg/service/prompting" 19 synchronizationsvc "github.com/mutagen-io/mutagen/pkg/service/synchronization" 20 "github.com/mutagen-io/mutagen/pkg/synchronization" 21 22 // Explicitly import packages that need to register protocol handlers. 23 _ "github.com/mutagen-io/mutagen/pkg/forwarding/protocols/docker" 24 _ "github.com/mutagen-io/mutagen/pkg/forwarding/protocols/local" 25 _ "github.com/mutagen-io/mutagen/pkg/forwarding/protocols/ssh" 26 _ "github.com/mutagen-io/mutagen/pkg/integration/protocols/netpipe" 27 _ "github.com/mutagen-io/mutagen/pkg/synchronization/protocols/docker" 28 _ "github.com/mutagen-io/mutagen/pkg/synchronization/protocols/local" 29 _ "github.com/mutagen-io/mutagen/pkg/synchronization/protocols/ssh" 30 ) 31 32 // forwardingManager is the forwarding session manager for the integration 33 // testing daemon. It is exposed for integration tests that operate at the API 34 // level (as opposed to the gRPC or command line level). 35 var forwardingManager *forwarding.Manager 36 37 // synchronizationManager is the synchronization session manager for the 38 // integration testing daemon. It is exposed for integration tests that operate 39 // at the API level (as opposed to the gRPC or command line level). 40 var synchronizationManager *synchronization.Manager 41 42 // TestMain is the entry point for integration tests. It replaces the default 43 // test entry point so that it can copy the mutagen executable to a well-known 44 // path, set up the agent bundle to work during testing, set up a functionally 45 // complete daemon instance for testing, and tear down all of the aforementioned 46 // infrastructure after running tests. 47 func TestMain(m *testing.M) { 48 // Override the expected agent bundle location. 49 agent.ExpectedBundleLocation = agent.BundleLocationBuildDirectory 50 51 // Acquire the daemon lock and defer its release. 52 lock, err := daemon.AcquireLock() 53 if err != nil { 54 cmd.Fatal(fmt.Errorf("unable to acquire daemon lock: %w", err)) 55 } 56 defer lock.Release() 57 58 // Create a forwarding session manager and defer its shutdown. 59 forwardingManager, err = forwarding.NewManager(nil) 60 if err != nil { 61 cmd.Fatal(fmt.Errorf("unable to create forwarding session manager: %w", err)) 62 } 63 defer forwardingManager.Shutdown() 64 65 // Create a session manager and defer its shutdown. 66 synchronizationManager, err = synchronization.NewManager(nil) 67 if err != nil { 68 cmd.Fatal(fmt.Errorf("unable to create synchronization session manager: %w", err)) 69 } 70 defer synchronizationManager.Shutdown() 71 72 // Create the gRPC server and defer its termination. We use a hard stop 73 // rather than a graceful stop so that it doesn't hang on open requests. 74 server := grpc.NewServer( 75 grpc.MaxSendMsgSize(grpcutil.MaximumMessageSize), 76 grpc.MaxRecvMsgSize(grpcutil.MaximumMessageSize), 77 ) 78 defer server.Stop() 79 80 // Create and register the daemon service and defer its shutdown. 81 daemonServer := daemonsvc.NewServer() 82 daemonsvc.RegisterDaemonServer(server, daemonServer) 83 defer daemonServer.Shutdown() 84 85 // Create and register the prompt service. 86 promptingsvc.RegisterPromptingServer(server, promptingsvc.NewServer()) 87 88 // Create and register the forwarding server. 89 forwardingServer := forwardingsvc.NewServer(forwardingManager) 90 forwardingsvc.RegisterForwardingServer(server, forwardingServer) 91 92 // Create and register the session service. 93 synchronizationServer := synchronizationsvc.NewServer(synchronizationManager) 94 synchronizationsvc.RegisterSynchronizationServer(server, synchronizationServer) 95 96 // Compute the path to the daemon IPC endpoint. 97 endpoint, err := daemon.EndpointPath() 98 if err != nil { 99 cmd.Fatal(fmt.Errorf("unable to compute endpoint path: %w", err)) 100 } 101 102 // Create the daemon listener and defer its closure. Since we hold the 103 // daemon lock, we preemptively remove any existing socket since it (should) 104 // be stale. 105 os.Remove(endpoint) 106 listener, err := ipc.NewListener(endpoint) 107 if err != nil { 108 cmd.Fatal(fmt.Errorf("unable to create daemon listener: %w", err)) 109 } 110 defer listener.Close() 111 112 // Serve incoming connections in a separate Goroutine. We don't monitor for 113 // errors since there's nothing that we can do about them and because 114 // they'll likely show up in the test output anyway. 115 go server.Serve(listener) 116 117 // Run tests. 118 m.Run() 119 }