github.com/uber-go/tally/v4@v4.1.17/m3/reporter_integration_test.go (about) 1 // Copyright (c) 2021 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package m3 22 23 import ( 24 "fmt" 25 "io/ioutil" 26 "os" 27 "os/exec" 28 "path" 29 "path/filepath" 30 "sync" 31 "testing" 32 33 "github.com/stretchr/testify/require" 34 ) 35 36 var mainFileFmt = ` 37 package main 38 39 import ( 40 "time" 41 42 tally "github.com/uber-go/tally/v4" 43 "github.com/uber-go/tally/v4/m3" 44 ) 45 46 func main() { 47 r, err := m3.NewReporter(m3.Options{ 48 HostPorts: []string{"%s"}, 49 Service: "test-service", 50 Env: "test", 51 }) 52 if err != nil { 53 panic(err) 54 } 55 56 scope, closer := tally.NewRootScope(tally.ScopeOptions{ 57 CachedReporter: r, 58 OmitCardinalityMetrics: true, 59 }, 5 * time.Second) 60 defer closer.Close() 61 62 scope.Counter("my-counter").Inc(42) 63 scope.Gauge("my-gauge").Update(123) 64 scope.Timer("my-timer").Record(456 * time.Millisecond) 65 } 66 ` 67 68 // TestIntegrationProcessFlushOnExit tests whether data is correctly flushed 69 // when the scope is closed for shortly lived programs 70 func TestIntegrationProcessFlushOnExit(t *testing.T) { 71 for i := 0; i < 5; i++ { 72 testProcessFlushOnExit(t, i) 73 } 74 } 75 76 func testProcessFlushOnExit(t *testing.T, i int) { 77 dir, err := os.MkdirTemp(".", "foo") 78 require.NoError(t, err) 79 defer os.RemoveAll(dir) 80 81 dir, err = filepath.Abs(dir) 82 require.NoError(t, err) 83 84 var wg sync.WaitGroup 85 server := newFakeM3Server(t, &wg, true, Compact) 86 go server.Serve() 87 defer server.Close() 88 89 mainFile := path.Join(dir, "main.go") 90 mainFileContents := fmt.Sprintf(mainFileFmt, server.Addr) 91 92 fileErr := ioutil.WriteFile(mainFile, []byte(mainFileContents), 0o666) 93 require.NoError(t, fileErr) 94 95 binary := path.Join(dir, "m3testemit") 96 97 // build 98 cmd := exec.Command("go", "build", "-o", binary, mainFile) 99 cmd.Dir = dir 100 output, err := cmd.CombinedOutput() 101 require.NoError(t, err, fmt.Sprintf("output:\n\n%s", output)) 102 103 // run, do not sleep at end of the main program as per 104 // main program source code 105 wg.Add(1) 106 require.NoError(t, exec.Command(binary).Run()) 107 108 // Wait for fake M3 server to receive the batch 109 wg.Wait() 110 111 require.Equal(t, 1, len(server.Service.getBatches())) 112 require.NotNil(t, server.Service.getBatches()[0]) 113 // 3 metrics are emitted by mainFileFmt plus various other internal metrics. 114 require.Equal(t, internalMetrics+3, len(server.Service.getBatches()[0].GetMetrics())) 115 metrics := server.Service.getBatches()[0].GetMetrics() 116 fmt.Printf("Test %d emitted:\n%v\n", i, metrics) 117 }