github.com/apache/beam/sdks/v2@v2.48.2/go/test/integration/expansions_test.go (about) 1 // Licensed to the Apache Software Foundation (ASF) under one or more 2 // contributor license agreements. See the NOTICE file distributed with 3 // this work for additional information regarding copyright ownership. 4 // The ASF licenses this file to You under the Apache License, Version 2.0 5 // (the "License"); you may not use this file except in compliance with 6 // the License. You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package integration 17 18 import ( 19 "fmt" 20 "testing" 21 "time" 22 23 _ "github.com/apache/beam/sdks/v2/go/pkg/beam/runners/dataflow" 24 _ "github.com/apache/beam/sdks/v2/go/pkg/beam/runners/flink" 25 _ "github.com/apache/beam/sdks/v2/go/pkg/beam/runners/samza" 26 _ "github.com/apache/beam/sdks/v2/go/pkg/beam/runners/spark" 27 "github.com/apache/beam/sdks/v2/go/test/integration/internal/jars" 28 "github.com/google/go-cmp/cmp" 29 "github.com/google/go-cmp/cmp/cmpopts" 30 ) 31 32 type testProcess struct { 33 killed bool 34 jar string 35 } 36 37 func (p *testProcess) Kill() error { 38 p.killed = true 39 return nil 40 } 41 42 func failRun(_ time.Duration, _ string, _ ...string) (jars.Process, error) { 43 return nil, fmt.Errorf("unexpectedly running a jar, failing") 44 } 45 46 func succeedRun(_ time.Duration, jar string, _ ...string) (jars.Process, error) { 47 return &testProcess{jar: jar}, nil 48 } 49 50 // TestExpansionServices_GetAddr_Addresses tests calling GetAddr on provided addresses. 51 func TestExpansionServices_GetAddr_Addresses(t *testing.T) { 52 addrsMap := map[string]string{ 53 "label1": "testAddr1", 54 "label2": "testAddr2", 55 "label3": "testAddr3", 56 } 57 jarsMap := map[string]string{ 58 "label2": "jarFilepath2", 59 } 60 es := &ExpansionServices{ 61 addrs: addrsMap, 62 jars: jarsMap, 63 procs: make([]jars.Process, 0), 64 run: failRun, 65 waitTime: 0, 66 } 67 68 // Ensure we get the same map we put in, and that addresses take priority over jars if 69 // both are given for the same label. 70 for label, wantAddr := range addrsMap { 71 gotAddr, err := es.GetAddr(label) 72 if err != nil { 73 t.Errorf("unexpected error when getting address for \"%v\": %v", label, err) 74 continue 75 } 76 if gotAddr != wantAddr { 77 t.Errorf("incorrect address for \"%v\", want %v, got %v", label, wantAddr, gotAddr) 78 } 79 } 80 // Check that nonexistent labels fail. 81 if _, err := es.GetAddr("nonexistent_label"); err == nil { 82 t.Errorf("did not receive error when calling GetAddr with nonexistent label") 83 } 84 } 85 86 // TestExpansionServices_GetAddr_Jars tests calling GetAddr on provided jars. 87 func TestExpansionServices_GetAddr_Jars(t *testing.T) { 88 addrsMap := map[string]string{} 89 jarsMap := map[string]string{ 90 "label1": "jarFilepath1", 91 "label2": "jarFilepath2", 92 "label3": "jarFilepath3", 93 } 94 es := &ExpansionServices{ 95 addrs: addrsMap, 96 jars: jarsMap, 97 procs: make([]jars.Process, 0), 98 run: succeedRun, 99 waitTime: 0, 100 } 101 102 // Call GetAddr on each jar twice, checking that the addresses remain consistent. 103 gotMap := make(map[string]string) 104 for label := range jarsMap { 105 gotAddr, err := es.GetAddr(label) 106 if err != nil { 107 t.Errorf("unexpected error when getting address for \"%v\": %v", label, err) 108 continue 109 } 110 gotMap[label] = gotAddr 111 } 112 for label, gotAddr := range gotMap { 113 secondAddr, err := es.GetAddr(label) 114 if err != nil { 115 t.Errorf("unexpected error when getting address for \"%v\": %v", label, err) 116 continue 117 } 118 if secondAddr != gotAddr { 119 t.Errorf("getAddr returned different address when called twice for \"%v\", "+ 120 "attempt 1: %v, attempt 2: %v", label, gotAddr, secondAddr) 121 } 122 } 123 // Check that all jars were run. 124 gotJars := make([]string, 0) 125 for _, proc := range es.procs { 126 testProc := proc.(*testProcess) 127 gotJars = append(gotJars, testProc.jar) 128 } 129 wantJars := make([]string, 0) 130 for _, jar := range jarsMap { 131 wantJars = append(wantJars, jar) 132 } 133 lessFunc := func(a, b string) bool { return a < b } 134 if diff := cmp.Diff(wantJars, gotJars, cmpopts.SortSlices(lessFunc)); diff != "" { 135 t.Errorf("processes in ExpansionServices does not match jars that should be running: diff(-want,+got):\n%v", diff) 136 } 137 } 138 139 // TestExpansionServices_Shutdown tests that a shutdown correctly kills all jars started by an 140 // ExpansionServices. 141 func TestExpansionServices_Shutdown(t *testing.T) { 142 addrsMap := map[string]string{} 143 jarsMap := map[string]string{ 144 "label1": "jarFilepath1", 145 "label2": "jarFilepath2", 146 "label3": "jarFilepath3", 147 } 148 es := &ExpansionServices{ 149 addrs: addrsMap, 150 jars: jarsMap, 151 procs: make([]jars.Process, 0), 152 run: succeedRun, 153 waitTime: 0, 154 } 155 // Call getAddr on each label to run jars. 156 for label := range addrsMap { 157 _, err := es.GetAddr(label) 158 if err != nil { 159 t.Errorf("unexpected error when getting address for \"%v\": %v", label, err) 160 continue 161 } 162 } 163 164 // Shutdown and confirm that jars are killed and addresses can no longer be retrieved. 165 procs := es.procs 166 es.Shutdown() 167 for _, proc := range procs { 168 testProc := proc.(*testProcess) 169 if !testProc.killed { 170 t.Errorf("process for jar %v was not killed on Shutdown()", testProc.jar) 171 } 172 } 173 for label := range addrsMap { 174 _, err := es.GetAddr(label) 175 if err == nil { 176 t.Errorf("calling GetAddr after Shutdown did not return an error for \"%v\"", label) 177 } 178 } 179 }