github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/uniter/charm/charm_test.go (about)

     1  // Copyright 2012-2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package charm_test
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"path/filepath"
    10  
    11  	jc "github.com/juju/testing/checkers"
    12  	"github.com/juju/utils/set"
    13  	gc "gopkg.in/check.v1"
    14  	corecharm "gopkg.in/juju/charm.v6-unstable"
    15  
    16  	"github.com/juju/juju/testcharms"
    17  	"github.com/juju/juju/worker/uniter/charm"
    18  )
    19  
    20  // bundleReader is a charm.BundleReader that lets us mock out the bundles we
    21  // deploy to test the Deployers.
    22  type bundleReader struct {
    23  	bundles     map[string]charm.Bundle
    24  	stopWaiting <-chan struct{}
    25  }
    26  
    27  // EnableWaitForAbort allows us to test that a Deployer.Stage call passes its abort
    28  // chan down to its BundleReader's Read method. If you call EnableWaitForAbort, the
    29  // next call to Read will block until either the abort chan is closed (in which case
    30  // it will return an error) or the stopWaiting chan is closed (in which case it
    31  // will return the bundle).
    32  func (br *bundleReader) EnableWaitForAbort() (stopWaiting chan struct{}) {
    33  	stopWaiting = make(chan struct{})
    34  	br.stopWaiting = stopWaiting
    35  	return stopWaiting
    36  }
    37  
    38  // Read implements the BundleReader interface.
    39  func (br *bundleReader) Read(info charm.BundleInfo, abort <-chan struct{}) (charm.Bundle, error) {
    40  	bundle, ok := br.bundles[info.URL().String()]
    41  	if !ok {
    42  		return nil, fmt.Errorf("no such charm!")
    43  	}
    44  	if br.stopWaiting != nil {
    45  		// EnableWaitForAbort is a one-time wait; make sure we clear it.
    46  		defer func() { br.stopWaiting = nil }()
    47  		select {
    48  		case <-abort:
    49  			return nil, fmt.Errorf("charm read aborted")
    50  		case <-br.stopWaiting:
    51  			// We can stop waiting for the abort chan and return the bundle.
    52  		}
    53  	}
    54  	return bundle, nil
    55  }
    56  
    57  func (br *bundleReader) AddCustomBundle(c *gc.C, url *corecharm.URL, customize func(path string)) charm.BundleInfo {
    58  	base := c.MkDir()
    59  	dirpath := testcharms.Repo.ClonedDirPath(base, "dummy")
    60  	if customize != nil {
    61  		customize(dirpath)
    62  	}
    63  	dir, err := corecharm.ReadCharmDir(dirpath)
    64  	c.Assert(err, jc.ErrorIsNil)
    65  	err = dir.SetDiskRevision(url.Revision)
    66  	c.Assert(err, jc.ErrorIsNil)
    67  	bunpath := filepath.Join(base, "bundle")
    68  	file, err := os.Create(bunpath)
    69  	c.Assert(err, jc.ErrorIsNil)
    70  	defer file.Close()
    71  	err = dir.ArchiveTo(file)
    72  	c.Assert(err, jc.ErrorIsNil)
    73  	bundle, err := corecharm.ReadCharmArchive(bunpath)
    74  	c.Assert(err, jc.ErrorIsNil)
    75  	return br.AddBundle(c, url, bundle)
    76  }
    77  
    78  func (br *bundleReader) AddBundle(c *gc.C, url *corecharm.URL, bundle charm.Bundle) charm.BundleInfo {
    79  	if br.bundles == nil {
    80  		br.bundles = map[string]charm.Bundle{}
    81  	}
    82  	br.bundles[url.String()] = bundle
    83  	return &bundleInfo{nil, url}
    84  }
    85  
    86  type bundleInfo struct {
    87  	charm.BundleInfo
    88  	url *corecharm.URL
    89  }
    90  
    91  func (info *bundleInfo) URL() *corecharm.URL {
    92  	return info.url
    93  }
    94  
    95  type mockBundle struct {
    96  	paths  set.Strings
    97  	expand func(dir string) error
    98  }
    99  
   100  func (b mockBundle) Manifest() (set.Strings, error) {
   101  	// TODO(dfc) this looks like set.Strings().Duplicate()
   102  	return set.NewStrings(b.paths.Values()...), nil
   103  }
   104  
   105  func (b mockBundle) ExpandTo(dir string) error {
   106  	if b.expand != nil {
   107  		return b.expand(dir)
   108  	}
   109  	return nil
   110  }
   111  
   112  func charmURL(revision int) *corecharm.URL {
   113  	baseURL := corecharm.MustParseURL("cs:s/c")
   114  	return baseURL.WithRevision(revision)
   115  }