diff --git a/pwd/instance.go b/pwd/instance.go index 5f3ed81..25ac1d0 100644 --- a/pwd/instance.go +++ b/pwd/instance.go @@ -192,6 +192,9 @@ func (p *pwd) checkHostnameExists(session *Session, hostname string) bool { } func (p *pwd) InstanceNew(session *Session, conf InstanceConfig) (*Instance, error) { + session.rw.Lock() + defer session.rw.Unlock() + if conf.ImageName == "" { conf.ImageName = config.GetDindImageName() } diff --git a/pwd/instance_test.go b/pwd/instance_test.go index b2e0320..10ffcad 100644 --- a/pwd/instance_test.go +++ b/pwd/instance_test.go @@ -2,6 +2,7 @@ package pwd import ( "fmt" + "sync" "testing" "time" @@ -86,6 +87,48 @@ func TestInstanceNew(t *testing.T) { assert.Equal(t, expectedContainerOpts, containerOpts) } +func TestInstanceNew_Concurrency(t *testing.T) { + i := 0 + dock := &mockDocker{} + dock.createContainer = func(opts docker.CreateContainerOpts) (string, error) { + time.Sleep(time.Second) + i++ + return fmt.Sprintf("10.0.0.%d", i), nil + } + + tasks := &mockTasks{} + broadcast := &mockBroadcast{} + storage := &mockStorage{} + + p := NewPWD(dock, tasks, broadcast, storage) + + session, err := p.SessionNew(time.Hour, "", "") + + assert.Nil(t, err) + + var instance1 *Instance + var instance2 *Instance + + wg := sync.WaitGroup{} + wg.Add(2) + + go func() { + defer wg.Done() + instance, err := p.InstanceNew(session, InstanceConfig{}) + assert.Nil(t, err) + instance1 = instance + }() + go func() { + defer wg.Done() + instance, err := p.InstanceNew(session, InstanceConfig{}) + assert.Nil(t, err) + instance2 = instance + }() + wg.Wait() + + assert.Subset(t, []string{"node1", "node2"}, []string{instance1.Hostname, instance2.Hostname}) +} + func TestInstanceNew_WithNotAllowedImage(t *testing.T) { containerOpts := docker.CreateContainerOpts{} dock := &mockDocker{}