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  }