github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/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  	stdtesting "testing"
    11  
    12  	corecharm "github.com/juju/charm"
    13  	charmtesting "github.com/juju/charm/testing"
    14  	"github.com/juju/utils/set"
    15  	gc "launchpad.net/gocheck"
    16  
    17  	coretesting "github.com/juju/juju/testing"
    18  	"github.com/juju/juju/worker/uniter/charm"
    19  )
    20  
    21  func TestPackage(t *stdtesting.T) {
    22  	// TODO(fwereade) 2014-03-21 not-worth-a-bug-number
    23  	// rewrite BundlesDir tests to use the mocks below and not require an API
    24  	// server and associated gubbins.
    25  	coretesting.MgoTestPackage(t)
    26  }
    27  
    28  // bundleReader is a charm.BundleReader that lets us mock out the bundles we
    29  // deploy to test the Deployers.
    30  type bundleReader struct {
    31  	bundles     map[string]charm.Bundle
    32  	stopWaiting <-chan struct{}
    33  }
    34  
    35  // EnableWaitForAbort allows us to test that a Deployer.Stage call passes its abort
    36  // chan down to its BundleReader's Read method. If you call EnableWaitForAbort, the
    37  // next call to Read will block until either the abort chan is closed (in which case
    38  // it will return an error) or the stopWaiting chan is closed (in which case it
    39  // will return the bundle).
    40  func (br *bundleReader) EnableWaitForAbort() (stopWaiting chan struct{}) {
    41  	stopWaiting = make(chan struct{})
    42  	br.stopWaiting = stopWaiting
    43  	return stopWaiting
    44  }
    45  
    46  // Read implements the BundleReader interface.
    47  func (br *bundleReader) Read(info charm.BundleInfo, abort <-chan struct{}) (charm.Bundle, error) {
    48  	bundle, ok := br.bundles[info.URL().String()]
    49  	if !ok {
    50  		return nil, fmt.Errorf("no such charm!")
    51  	}
    52  	if br.stopWaiting != nil {
    53  		// EnableWaitForAbort is a one-time wait; make sure we clear it.
    54  		defer func() { br.stopWaiting = nil }()
    55  		select {
    56  		case <-abort:
    57  			return nil, fmt.Errorf("charm read aborted")
    58  		case <-br.stopWaiting:
    59  			// We can stop waiting for the abort chan and return the bundle.
    60  		}
    61  	}
    62  	return bundle, nil
    63  }
    64  
    65  func (br *bundleReader) AddCustomBundle(c *gc.C, url *corecharm.URL, customize func(path string)) charm.BundleInfo {
    66  	base := c.MkDir()
    67  	dirpath := charmtesting.Charms.ClonedDirPath(base, "dummy")
    68  	if customize != nil {
    69  		customize(dirpath)
    70  	}
    71  	dir, err := corecharm.ReadDir(dirpath)
    72  	c.Assert(err, gc.IsNil)
    73  	err = dir.SetDiskRevision(url.Revision)
    74  	c.Assert(err, gc.IsNil)
    75  	bunpath := filepath.Join(base, "bundle")
    76  	file, err := os.Create(bunpath)
    77  	c.Assert(err, gc.IsNil)
    78  	defer file.Close()
    79  	err = dir.BundleTo(file)
    80  	c.Assert(err, gc.IsNil)
    81  	bundle, err := corecharm.ReadBundle(bunpath)
    82  	c.Assert(err, gc.IsNil)
    83  	return br.AddBundle(c, url, bundle)
    84  }
    85  
    86  func (br *bundleReader) AddBundle(c *gc.C, url *corecharm.URL, bundle charm.Bundle) charm.BundleInfo {
    87  	if br.bundles == nil {
    88  		br.bundles = map[string]charm.Bundle{}
    89  	}
    90  	br.bundles[url.String()] = bundle
    91  	return &bundleInfo{nil, url}
    92  }
    93  
    94  type bundleInfo struct {
    95  	charm.BundleInfo
    96  	url *corecharm.URL
    97  }
    98  
    99  func (info *bundleInfo) URL() *corecharm.URL {
   100  	return info.url
   101  }
   102  
   103  type mockBundle struct {
   104  	paths  set.Strings
   105  	expand func(dir string) error
   106  }
   107  
   108  func (b mockBundle) Manifest() (set.Strings, error) {
   109  	return set.NewStrings(b.paths.Values()...), nil
   110  }
   111  
   112  func (b mockBundle) ExpandTo(dir string) error {
   113  	if b.expand != nil {
   114  		return b.expand(dir)
   115  	}
   116  	return nil
   117  }
   118  
   119  func charmURL(revision int) *corecharm.URL {
   120  	baseURL := corecharm.MustParseURL("cs:s/c")
   121  	return baseURL.WithRevision(revision)
   122  }