github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/container/kvm/mock/mock-kvm.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package mock
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/juju/juju/container/kvm"
    10  )
    11  
    12  // This file provides a mock implementation of the kvm interfaces
    13  // ContainerFactory and Container.
    14  
    15  type Action int
    16  
    17  const (
    18  	// A container has been started.
    19  	Started Action = iota
    20  	// A container has been stopped.
    21  	Stopped
    22  )
    23  
    24  func (action Action) String() string {
    25  	switch action {
    26  	case Started:
    27  		return "Started"
    28  	case Stopped:
    29  		return "Stopped"
    30  	}
    31  	return "unknown"
    32  }
    33  
    34  type Event struct {
    35  	Action     Action
    36  	InstanceId string
    37  }
    38  
    39  type ContainerFactory interface {
    40  	kvm.ContainerFactory
    41  
    42  	AddListener(chan<- Event)
    43  	RemoveListener(chan<- Event)
    44  	HasListener(chan<- Event) bool
    45  }
    46  
    47  type mockFactory struct {
    48  	instances map[string]kvm.Container
    49  	listeners []chan<- Event
    50  }
    51  
    52  func MockFactory() ContainerFactory {
    53  	return &mockFactory{
    54  		instances: make(map[string]kvm.Container),
    55  	}
    56  }
    57  
    58  type mockContainer struct {
    59  	factory *mockFactory
    60  	name    string
    61  	started bool
    62  }
    63  
    64  // Name returns the name of the container.
    65  func (mock *mockContainer) Name() string {
    66  	return mock.name
    67  }
    68  
    69  func (mock *mockContainer) Start(params kvm.StartParams) error {
    70  	if mock.started {
    71  		return fmt.Errorf("container is already running")
    72  	}
    73  	mock.started = true
    74  	mock.factory.notify(Started, mock.name)
    75  	return nil
    76  }
    77  
    78  // Stop terminates the running container.
    79  func (mock *mockContainer) Stop() error {
    80  	if !mock.started {
    81  		return fmt.Errorf("container is not running")
    82  	}
    83  	mock.started = false
    84  	mock.factory.notify(Stopped, mock.name)
    85  	return nil
    86  }
    87  
    88  func (mock *mockContainer) IsRunning() bool {
    89  	return mock.started
    90  }
    91  
    92  // String returns information about the container.
    93  func (mock *mockContainer) String() string {
    94  	return fmt.Sprintf("<MockContainer %q>", mock.name)
    95  }
    96  
    97  func (mock *mockFactory) String() string {
    98  	return fmt.Sprintf("<Mock KVM Factory>")
    99  }
   100  
   101  func (mock *mockFactory) New(name string) kvm.Container {
   102  	container, ok := mock.instances[name]
   103  	if ok {
   104  		return container
   105  	}
   106  	container = &mockContainer{
   107  		factory: mock,
   108  		name:    name,
   109  	}
   110  	mock.instances[name] = container
   111  	return container
   112  }
   113  
   114  func (mock *mockFactory) List() (result []kvm.Container, err error) {
   115  	for _, container := range mock.instances {
   116  		result = append(result, container)
   117  	}
   118  	return
   119  }
   120  
   121  func (mock *mockFactory) notify(action Action, instanceId string) {
   122  	event := Event{action, instanceId}
   123  	for _, c := range mock.listeners {
   124  		c <- event
   125  	}
   126  }
   127  
   128  func (mock *mockFactory) AddListener(listener chan<- Event) {
   129  	mock.listeners = append(mock.listeners, listener)
   130  }
   131  
   132  func (mock *mockFactory) RemoveListener(listener chan<- Event) {
   133  	pos := 0
   134  	for i, c := range mock.listeners {
   135  		if c == listener {
   136  			pos = i
   137  		}
   138  	}
   139  	mock.listeners = append(mock.listeners[:pos], mock.listeners[pos+1:]...)
   140  }
   141  
   142  func (mock *mockFactory) HasListener(listener chan<- Event) bool {
   143  	for _, c := range mock.listeners {
   144  		if c == listener {
   145  			return true
   146  		}
   147  	}
   148  	return false
   149  }