github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/worker/uniter/runner/export_test.go (about)

     1  // Copyright 2012-2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package runner
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/names"
     9  	"github.com/juju/utils/proxy"
    10  	"gopkg.in/juju/charm.v5"
    11  
    12  	"github.com/juju/juju/api/uniter"
    13  	"github.com/juju/juju/apiserver/params"
    14  	"github.com/juju/juju/worker/leadership"
    15  	"github.com/juju/juju/worker/uniter/runner/jujuc"
    16  )
    17  
    18  var (
    19  	MergeWindowsEnvironment = mergeWindowsEnvironment
    20  	SearchHook              = searchHook
    21  	HookCommand             = hookCommand
    22  	LookPath                = lookPath
    23  	ValidatePortRange       = validatePortRange
    24  	TryOpenPorts            = tryOpenPorts
    25  	TryClosePorts           = tryClosePorts
    26  	LockTimeout             = lockTimeout
    27  )
    28  
    29  func RunnerPaths(rnr Runner) Paths {
    30  	return rnr.(*runner).paths
    31  }
    32  
    33  type LeadershipContextFunc func(LeadershipSettingsAccessor, leadership.Tracker) LeadershipContext
    34  
    35  func PatchNewLeadershipContext(f LeadershipContextFunc) func() {
    36  	var old LeadershipContextFunc
    37  	old, newLeadershipContext = newLeadershipContext, f
    38  	return func() { newLeadershipContext = old }
    39  }
    40  
    41  func UpdateCachedSettings(f0 Factory, relId int, unitName string, settings params.Settings) {
    42  	f := f0.(*factory)
    43  	members := f.relationCaches[relId].members
    44  	if members[unitName] == nil {
    45  		members[unitName] = params.Settings{}
    46  	}
    47  	for key, value := range settings {
    48  		members[unitName][key] = value
    49  	}
    50  }
    51  
    52  func CachedSettings(f0 Factory, relId int, unitName string) (params.Settings, bool) {
    53  	f := f0.(*factory)
    54  	settings, found := f.relationCaches[relId].members[unitName]
    55  	return settings, found
    56  }
    57  
    58  // PatchMeterStatus changes the meter status of the context.
    59  func (ctx *HookContext) PatchMeterStatus(code, info string) func() {
    60  	oldMeterStatus := ctx.meterStatus
    61  	ctx.meterStatus = &meterStatus{
    62  		code: code,
    63  		info: info,
    64  	}
    65  	return func() {
    66  		ctx.meterStatus = oldMeterStatus
    67  	}
    68  }
    69  
    70  func ContextEnvInfo(ctx Context) (name, uuid string) {
    71  	hctx := ctx.(*HookContext)
    72  	return hctx.envName, hctx.uuid
    73  }
    74  
    75  func ContextMachineTag(ctx Context) names.MachineTag {
    76  	hctx := ctx.(*HookContext)
    77  	return hctx.assignedMachineTag
    78  }
    79  
    80  func GetStubActionContext(in map[string]interface{}) *HookContext {
    81  	return &HookContext{
    82  		actionData: &ActionData{
    83  			ResultsMap: in,
    84  		},
    85  	}
    86  }
    87  
    88  func PatchCachedStatus(ctx Context, status, info string, data map[string]interface{}) func() {
    89  	hctx := ctx.(*HookContext)
    90  	oldStatus := hctx.status
    91  	hctx.status = &jujuc.StatusInfo{
    92  		Status: status,
    93  		Info:   info,
    94  		Data:   data,
    95  	}
    96  	return func() {
    97  		hctx.status = oldStatus
    98  	}
    99  }
   100  
   101  // PatchMetricsReader patches the metrics reader used by the context with a new
   102  // object.
   103  func PatchMetricsReader(ctx Context, reader MetricsReader) func() {
   104  	hctx := ctx.(*HookContext)
   105  	oldReader := hctx.metricsReader
   106  	hctx.metricsReader = reader
   107  	return func() {
   108  		hctx.metricsReader = oldReader
   109  	}
   110  }
   111  
   112  func NewHookContext(
   113  	unit *uniter.Unit,
   114  	state *uniter.State,
   115  	id,
   116  	uuid,
   117  	envName string,
   118  	relationId int,
   119  	remoteUnitName string,
   120  	relations map[int]*ContextRelation,
   121  	apiAddrs []string,
   122  	serviceOwner names.UserTag,
   123  	proxySettings proxy.Settings,
   124  	canAddMetrics bool,
   125  	metrics *charm.Metrics,
   126  	actionData *ActionData,
   127  	assignedMachineTag names.MachineTag,
   128  	paths Paths,
   129  ) (*HookContext, error) {
   130  	ctx := &HookContext{
   131  		unit:               unit,
   132  		state:              state,
   133  		id:                 id,
   134  		uuid:               uuid,
   135  		envName:            envName,
   136  		unitName:           unit.Name(),
   137  		relationId:         relationId,
   138  		remoteUnitName:     remoteUnitName,
   139  		relations:          relations,
   140  		apiAddrs:           apiAddrs,
   141  		serviceOwner:       serviceOwner,
   142  		proxySettings:      proxySettings,
   143  		metricsRecorder:    nil,
   144  		definedMetrics:     metrics,
   145  		metricsSender:      unit,
   146  		actionData:         actionData,
   147  		pendingPorts:       make(map[PortRange]PortRangeInfo),
   148  		assignedMachineTag: assignedMachineTag,
   149  	}
   150  	if canAddMetrics {
   151  		charmURL, err := unit.CharmURL()
   152  		if err != nil {
   153  			return nil, err
   154  		}
   155  		ctx.metricsRecorder, err = NewJSONMetricsRecorder(paths.GetMetricsSpoolDir(), charmURL.String())
   156  		if err != nil {
   157  			return nil, err
   158  		}
   159  		ctx.metricsReader, err = NewJSONMetricsReader(paths.GetMetricsSpoolDir())
   160  		if err != nil {
   161  			return nil, err
   162  		}
   163  	}
   164  	// Get and cache the addresses.
   165  	var err error
   166  	ctx.publicAddress, err = unit.PublicAddress()
   167  	if err != nil && !params.IsCodeNoAddressSet(err) {
   168  		return nil, err
   169  	}
   170  	ctx.privateAddress, err = unit.PrivateAddress()
   171  	if err != nil && !params.IsCodeNoAddressSet(err) {
   172  		return nil, err
   173  	}
   174  	ctx.availabilityzone, err = unit.AvailabilityZone()
   175  	if err != nil {
   176  		return nil, err
   177  	}
   178  	ctx.machinePorts, err = state.AllMachinePorts(ctx.assignedMachineTag)
   179  	if err != nil {
   180  		return nil, errors.Trace(err)
   181  	}
   182  
   183  	statusCode, statusInfo, err := unit.MeterStatus()
   184  	if err != nil {
   185  		return nil, errors.Annotate(err, "could not retrieve meter status for unit")
   186  	}
   187  	ctx.meterStatus = &meterStatus{
   188  		code: statusCode,
   189  		info: statusInfo,
   190  	}
   191  	return ctx, nil
   192  }
   193  
   194  // NewEnvironmentHookContext exists purely to set the fields used in rs.
   195  // The returned value is not otherwise valid.
   196  func NewEnvironmentHookContext(
   197  	id, envUUID, envName, unitName, meterCode, meterInfo, availZone string,
   198  	apiAddresses []string, proxySettings proxy.Settings,
   199  	machineTag names.MachineTag,
   200  ) *HookContext {
   201  	return &HookContext{
   202  		id:            id,
   203  		unitName:      unitName,
   204  		uuid:          envUUID,
   205  		envName:       envName,
   206  		apiAddrs:      apiAddresses,
   207  		proxySettings: proxySettings,
   208  		meterStatus: &meterStatus{
   209  			code: meterCode,
   210  			info: meterInfo,
   211  		},
   212  		relationId:         -1,
   213  		assignedMachineTag: machineTag,
   214  		availabilityzone:   availZone,
   215  	}
   216  }
   217  
   218  // SetEnvironmentHookContextRelation exists purely to set the fields used in hookVars.
   219  // It makes no assumptions about the validity of context.
   220  func SetEnvironmentHookContextRelation(
   221  	context *HookContext,
   222  	relationId int, endpointName, remoteUnitName string,
   223  ) {
   224  	context.relationId = relationId
   225  	context.remoteUnitName = remoteUnitName
   226  	context.relations = map[int]*ContextRelation{
   227  		relationId: {
   228  			endpointName: endpointName,
   229  			relationId:   relationId,
   230  		},
   231  	}
   232  }
   233  
   234  func (ctx *HookContext) StorageAddConstraints() map[string][]params.StorageConstraints {
   235  	return ctx.storageAddConstraints
   236  }
   237  
   238  // PatchMetricsSender patches the metricsSender used by the context to use the provided function.
   239  func PatchMetricsSender(ctx Context, send func(batches []params.MetricBatch) (map[string]error, error)) func() {
   240  	hctx := ctx.(*HookContext)
   241  	oldSender := hctx.metricsSender
   242  	hctx.metricsSender = &mockMetricsSender{send: send}
   243  	return func() {
   244  		hctx.metricsSender = oldSender
   245  	}
   246  }
   247  
   248  type mockMetricsSender struct {
   249  	send func(batches []params.MetricBatch) (map[string]error, error)
   250  }
   251  
   252  func (m mockMetricsSender) AddMetricBatches(batches []params.MetricBatch) (map[string]error, error) {
   253  	return m.send(batches)
   254  }