github.com/ystia/yorc/v4@v4.3.0/plugin/infra_usage_collector_test.go (about) 1 // Copyright 2018 Bull S.A.S. Atos Technologies - Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois, France. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package plugin 16 17 import ( 18 "context" 19 "errors" 20 "testing" 21 "time" 22 23 "github.com/hashicorp/go-plugin" 24 "github.com/stretchr/testify/assert" 25 "github.com/stretchr/testify/require" 26 27 "github.com/ystia/yorc/v4/config" 28 "github.com/ystia/yorc/v4/events" 29 "github.com/ystia/yorc/v4/prov" 30 ) 31 32 type mockInfraUsageCollector struct { 33 getUsageInfoCalled bool 34 ctx context.Context 35 conf config.Configuration 36 taskID string 37 infraName string 38 locationName string 39 params map[string]string 40 contextCancelled bool 41 lof events.LogOptionalFields 42 } 43 44 func (m *mockInfraUsageCollector) GetUsageInfo(ctx context.Context, conf config.Configuration, taskID, infraName, locationName string, 45 params map[string]string) (map[string]interface{}, error) { 46 m.getUsageInfoCalled = true 47 m.ctx = ctx 48 m.conf = conf 49 m.taskID = taskID 50 m.infraName = infraName 51 m.locationName = locationName 52 m.params = params 53 m.lof, _ = events.FromContext(ctx) 54 55 go func() { 56 <-m.ctx.Done() 57 m.contextCancelled = true 58 }() 59 if m.taskID == "TestCancel" { 60 <-m.ctx.Done() 61 } 62 if m.taskID == "TestFailure" { 63 return nil, NewRPCError(errors.New("a failure occurred during plugin infra usage collector")) 64 } 65 res := make(map[string]interface{}) 66 res["keyOne"] = "valueOne" 67 res["keyTwo"] = "valueTwo" 68 res["keyThree"] = "valueThree" 69 return res, nil 70 } 71 72 func setupInfraUsageCollectorTestEnv(t *testing.T) (*mockInfraUsageCollector, *plugin.RPCClient, 73 prov.InfraUsageCollector, events.LogOptionalFields, context.Context) { 74 75 t.Parallel() 76 mock := new(mockInfraUsageCollector) 77 client, _ := plugin.TestPluginRPCConn( 78 t, 79 map[string]plugin.Plugin{ 80 InfraUsageCollectorPluginName: &InfraUsageCollectorPlugin{F: func() prov.InfraUsageCollector { 81 return mock 82 }}, 83 }, 84 nil) 85 86 raw, err := client.Dispense(InfraUsageCollectorPluginName) 87 require.Nil(t, err) 88 89 plugin := raw.(prov.InfraUsageCollector) 90 91 lof := events.LogOptionalFields{ 92 events.WorkFlowID: "testWF", 93 events.InterfaceName: "delegate", 94 events.OperationName: "myTest", 95 } 96 ctx := events.NewContext(context.Background(), lof) 97 98 return mock, client, plugin, lof, ctx 99 100 } 101 func TestInfraUsageCollectorGetUsageInfo(t *testing.T) { 102 mock, client, plugin, lof, ctx := setupInfraUsageCollectorTestEnv(t) 103 defer client.Close() 104 params := map[string]string{"param1": "value1"} 105 info, err := plugin.GetUsageInfo( 106 ctx, 107 config.Configuration{Consul: config.Consul{Address: "test", Datacenter: "testdc"}}, 108 "TestTaskID", "myInfra", "myLocation", params) 109 require.Nil(t, err) 110 require.True(t, mock.getUsageInfoCalled) 111 require.Equal(t, "test", mock.conf.Consul.Address) 112 require.Equal(t, "testdc", mock.conf.Consul.Datacenter) 113 require.Equal(t, "TestTaskID", mock.taskID) 114 require.Equal(t, "myInfra", mock.infraName) 115 require.Equal(t, "myLocation", mock.locationName) 116 require.Equal(t, params, mock.params) 117 require.Equal(t, 3, len(info)) 118 assert.Equal(t, lof, mock.lof) 119 120 val, exist := info["keyOne"] 121 require.True(t, exist) 122 require.Equal(t, "valueOne", val) 123 124 val, exist = info["keyTwo"] 125 require.True(t, exist) 126 require.Equal(t, "valueTwo", val) 127 128 val, exist = info["keyThree"] 129 require.True(t, exist) 130 require.Equal(t, "valueThree", val) 131 } 132 133 func TestInfraUsageCollectorGetUsageInfoWithFailure(t *testing.T) { 134 _, client, plugin, _, ctx := setupInfraUsageCollectorTestEnv(t) 135 defer client.Close() 136 _, err := plugin.GetUsageInfo( 137 ctx, 138 config.Configuration{Consul: config.Consul{Address: "test", Datacenter: "testdc"}}, 139 "TestFailure", "myInfra", "myLocation", map[string]string{}) 140 require.Error(t, err, "An error was expected during executing plugin infra usage collector") 141 require.EqualError(t, err, "a failure occurred during plugin infra usage collector") 142 } 143 144 func TestInfraUsageCollectorGetUsageInfoWithCancel(t *testing.T) { 145 mock, client, plugin, _, ctx := setupInfraUsageCollectorTestEnv(t) 146 defer client.Close() 147 ctx, cancelF := context.WithCancel(ctx) 148 go func() { 149 _, err := plugin.GetUsageInfo( 150 ctx, 151 config.Configuration{Consul: config.Consul{Address: "test", Datacenter: "testdc"}}, 152 "TestCancel", "myInfra", "myLocation", map[string]string{}) 153 require.Nil(t, err) 154 }() 155 cancelF() 156 // Wait for cancellation signal to be dispatched 157 time.Sleep(50 * time.Millisecond) 158 require.True(t, mock.contextCancelled, "Context should be cancelled") 159 } 160 161 func TestGetSupportedInfra(t *testing.T) { 162 t.Parallel() 163 mock := new(mockInfraUsageCollector) 164 client, _ := plugin.TestPluginRPCConn( 165 t, 166 map[string]plugin.Plugin{ 167 InfraUsageCollectorPluginName: &InfraUsageCollectorPlugin{ 168 F: func() prov.InfraUsageCollector { 169 return mock 170 }, 171 SupportedInfras: []string{"myInfra"}, 172 }, 173 }, 174 nil) 175 defer client.Close() 176 177 raw, err := client.Dispense(InfraUsageCollectorPluginName) 178 require.Nil(t, err) 179 180 plugin := raw.(InfraUsageCollector) 181 182 infras, err := plugin.GetSupportedInfras() 183 require.Nil(t, err) 184 require.Equal(t, 1, len(infras)) 185 require.Equal(t, "myInfra", infras[0]) 186 }