github.com/rita33cool1/iot-system-gateway@v0.0.0-20200911033302-e65bde238cc5/docker-engine/plugin/executor/containerd/containerd_test.go (about)

     1  package containerd
     2  
     3  import (
     4  	"context"
     5  	"io/ioutil"
     6  	"os"
     7  	"sync"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/docker/docker/libcontainerd"
    12  	"github.com/gotestyourself/gotestyourself/assert"
    13  	specs "github.com/opencontainers/runtime-spec/specs-go"
    14  	"github.com/pkg/errors"
    15  )
    16  
    17  func TestLifeCycle(t *testing.T) {
    18  	t.Parallel()
    19  
    20  	mock := newMockClient()
    21  	exec, cleanup := setupTest(t, mock, mock)
    22  	defer cleanup()
    23  
    24  	id := "test-create"
    25  	mock.simulateStartError(true, id)
    26  	err := exec.Create(id, specs.Spec{}, nil, nil)
    27  	assert.Assert(t, err != nil)
    28  	mock.simulateStartError(false, id)
    29  
    30  	err = exec.Create(id, specs.Spec{}, nil, nil)
    31  	assert.Assert(t, err)
    32  	running, _ := exec.IsRunning(id)
    33  	assert.Assert(t, running)
    34  
    35  	// create with the same ID
    36  	err = exec.Create(id, specs.Spec{}, nil, nil)
    37  	assert.Assert(t, err != nil)
    38  
    39  	mock.HandleExitEvent(id) // simulate a plugin that exits
    40  
    41  	err = exec.Create(id, specs.Spec{}, nil, nil)
    42  	assert.Assert(t, err)
    43  }
    44  
    45  func setupTest(t *testing.T, client Client, eh ExitHandler) (*Executor, func()) {
    46  	rootDir, err := ioutil.TempDir("", "test-daemon")
    47  	assert.Assert(t, err)
    48  	assert.Assert(t, client != nil)
    49  	assert.Assert(t, eh != nil)
    50  
    51  	return &Executor{
    52  			rootDir:     rootDir,
    53  			client:      client,
    54  			exitHandler: eh,
    55  		}, func() {
    56  			assert.Assert(t, os.RemoveAll(rootDir))
    57  		}
    58  }
    59  
    60  type mockClient struct {
    61  	mu           sync.Mutex
    62  	containers   map[string]bool
    63  	errorOnStart map[string]bool
    64  }
    65  
    66  func newMockClient() *mockClient {
    67  	return &mockClient{
    68  		containers:   make(map[string]bool),
    69  		errorOnStart: make(map[string]bool),
    70  	}
    71  }
    72  
    73  func (c *mockClient) Create(ctx context.Context, id string, _ *specs.Spec, _ interface{}) error {
    74  	c.mu.Lock()
    75  	defer c.mu.Unlock()
    76  
    77  	if _, ok := c.containers[id]; ok {
    78  		return errors.New("exists")
    79  	}
    80  
    81  	c.containers[id] = false
    82  	return nil
    83  }
    84  
    85  func (c *mockClient) Restore(ctx context.Context, id string, attachStdio libcontainerd.StdioCallback) (alive bool, pid int, err error) {
    86  	return false, 0, nil
    87  }
    88  
    89  func (c *mockClient) Status(ctx context.Context, id string) (libcontainerd.Status, error) {
    90  	c.mu.Lock()
    91  	defer c.mu.Unlock()
    92  
    93  	running, ok := c.containers[id]
    94  	if !ok {
    95  		return libcontainerd.StatusUnknown, errors.New("not found")
    96  	}
    97  	if running {
    98  		return libcontainerd.StatusRunning, nil
    99  	}
   100  	return libcontainerd.StatusStopped, nil
   101  }
   102  
   103  func (c *mockClient) Delete(ctx context.Context, id string) error {
   104  	c.mu.Lock()
   105  	defer c.mu.Unlock()
   106  	delete(c.containers, id)
   107  	return nil
   108  }
   109  
   110  func (c *mockClient) DeleteTask(ctx context.Context, id string) (uint32, time.Time, error) {
   111  	return 0, time.Time{}, nil
   112  }
   113  
   114  func (c *mockClient) Start(ctx context.Context, id, checkpointDir string, withStdin bool, attachStdio libcontainerd.StdioCallback) (pid int, err error) {
   115  	c.mu.Lock()
   116  	defer c.mu.Unlock()
   117  
   118  	if _, ok := c.containers[id]; !ok {
   119  		return 0, errors.New("not found")
   120  	}
   121  
   122  	if c.errorOnStart[id] {
   123  		return 0, errors.New("some startup error")
   124  	}
   125  	c.containers[id] = true
   126  	return 1, nil
   127  }
   128  
   129  func (c *mockClient) SignalProcess(ctx context.Context, containerID, processID string, signal int) error {
   130  	return nil
   131  }
   132  
   133  func (c *mockClient) simulateStartError(sim bool, id string) {
   134  	c.mu.Lock()
   135  	defer c.mu.Unlock()
   136  	if sim {
   137  		c.errorOnStart[id] = sim
   138  		return
   139  	}
   140  	delete(c.errorOnStart, id)
   141  }
   142  
   143  func (c *mockClient) HandleExitEvent(id string) error {
   144  	c.mu.Lock()
   145  	defer c.mu.Unlock()
   146  	delete(c.containers, id)
   147  	return nil
   148  }