def setUp(self): super(LocalRepositoryTest, self).setUp() # bundle sample charms CharmDirectory(self.sample_dir1).make_archive( os.path.join(self.bundled_repo_path, "series", "old.charm")) CharmDirectory(self.sample_dir2).make_archive( os.path.join(self.bundled_repo_path, "series", "new.charm")) # define repository objects self.repository1 = LocalCharmRepository(self.unbundled_repo_path) self.repository2 = LocalCharmRepository(self.bundled_repo_path)
def add_charm(self, metadata, revision, repository_dir=None, bundle=False): if repository_dir is None: repository_dir = self.makeDir() series_dir = os.path.join(repository_dir, "series") os.mkdir(series_dir) charm_dir = self.makeDir() with open(os.path.join(charm_dir, "metadata.yaml"), "w") as f: f.write(dump(metadata)) with open(os.path.join(charm_dir, "revision"), "w") as f: f.write(str(revision)) if bundle: CharmDirectory(charm_dir).make_archive( os.path.join(series_dir, "%s.charm" % metadata["name"])) else: os.rename(charm_dir, os.path.join(series_dir, metadata["name"])) return LocalCharmRepository(repository_dir)
class LocalRepositoryTest(RepositoryTestBase): def setUp(self): super(LocalRepositoryTest, self).setUp() # bundle sample charms CharmDirectory(self.sample_dir1).make_archive( os.path.join(self.bundled_repo_path, "series", "old.charm")) CharmDirectory(self.sample_dir2).make_archive( os.path.join(self.bundled_repo_path, "series", "new.charm")) # define repository objects self.repository1 = LocalCharmRepository(self.unbundled_repo_path) self.repository2 = LocalCharmRepository(self.bundled_repo_path) self.output = self.capture_logging("juju.charm") def assert_there(self, name, repo, revision, latest_revision=None): url = self.charm_url(name) charm = yield repo.find(url) self.assertEquals(charm.get_revision(), revision) latest = yield repo.latest(url) self.assertEquals(latest, latest_revision or revision) @inlineCallbacks def assert_not_there(self, name, repo, revision=None): url = self.charm_url(name) msg = "Charm 'local:series/%s' not found in repository %s" % ( name, repo.path) err = yield self.assertFailure(repo.find(url), CharmNotFound) self.assertEquals(str(err), msg) if revision is None: err = yield self.assertFailure(repo.latest(url), CharmNotFound) self.assertEquals(str(err), msg) def charm_url(self, name): return CharmURL.parse("local:series/" + name) def test_no_path(self): err = self.assertRaises(RepositoryNotFound, LocalCharmRepository, None) self.assertEquals(str(err), "No repository specified") def test_bad_path(self): path = os.path.join(self.makeDir(), "blah") err = self.assertRaises(RepositoryNotFound, LocalCharmRepository, path) self.assertEquals(str(err), "No repository found at %r" % path) with open(path, "w"): pass err = self.assertRaises(RepositoryNotFound, LocalCharmRepository, path) self.assertEquals(str(err), "No repository found at %r" % path) def test_find_inappropriate_url(self): url = CharmURL.parse("cs:foo/bar") err = self.assertRaises(AssertionError, self.repository1.find, url) self.assertEquals(str(err), "schema mismatch") def test_completely_missing(self): return self.assert_not_there("zebra", self.repository1) def test_unknown_files_ignored(self): self.makeFile( "Foobar", path=os.path.join(self.repository1.path, "series", "zebra")) return self.assert_not_there("zebra", self.repository1) @inlineCallbacks def test_random_error_logged(self): get_charm = self.mocker.replace(provider.get_charm_from_path) get_charm(ANY) self.mocker.throw(SyntaxError("magic")) self.mocker.count(0, 3) self.mocker.replay() yield self.assertFailure( self.repository1.find(self.charm_url("zebra")), CharmNotFound) self.assertIn( "Unexpected error while processing", self.output.getvalue()) self.assertIn( "SyntaxError('magic',)", self.output.getvalue()) def test_unknown_directories_ignored(self): self.makeDir( path=os.path.join(self.repository1.path, "series", "zebra")) return self.assert_not_there("zebra", self.repository1) @inlineCallbacks def test_broken_charm_metadata_ignored(self): charm_path = self.makeDir( path=os.path.join(self.repository1.path, "series", "zebra")) fh = open(os.path.join(charm_path, "metadata.yaml"), "w+") fh.write("""\ description: helo name: hi requires: {interface: zebra revision: 0 summary: hola""") fh.close() yield self.assertFailure( self.repository1.find(self.charm_url("zebra")), CharmNotFound) output = self.output.getvalue() self.assertIn( "Charm 'zebra' has a YAML error", output) self.assertIn( "%s/series/zebra/metadata.yaml" % self.repository1.path, output) @inlineCallbacks def test_broken_charm_config_ignored(self): """YAML Errors propogate to the log, but the search continues.""" fh = open( os.path.join( self.repository1.path, "series", "mysql", "config.yaml"), "w+") fh.write("""\ description: helo name: hi requires: {interface: zebra revision: 0 summary: hola""") fh.close() yield self.repository1.find(self.charm_url("sample")) output = self.output.getvalue() self.assertIn( "Charm 'mysql' has a YAML error", output) self.assertIn( "%s/series/mysql/config.yaml" % self.repository1.path, output) @inlineCallbacks def test_invalid_charm_config_ignored(self): fh = open( os.path.join( self.repository1.path, "series", "mysql", "config.yaml"), "w+") fh.write("foobar: {}") fh.close() stream = self.capture_logging("juju.charm") yield self.assertFailure( self.repository1.find(self.charm_url("mysql")), CharmNotFound) output = stream.getvalue() self.assertIn( "Charm 'mysql' has an error", output) self.assertIn( "%s/series/mysql/config.yaml" % self.repository1.path, output) def test_repo_type(self): self.assertEqual(self.repository1.type, "local") @inlineCallbacks def test_success_unbundled(self): yield self.assert_there("sample", self.repository1, 2) yield self.assert_there("sample-1", self.repository1, 1, 2) yield self.assert_there("sample-2", self.repository1, 2) yield self.assert_not_there("sample-3", self.repository1, 2) @inlineCallbacks def test_success_bundled(self): yield self.assert_there("sample", self.repository2, 2) yield self.assert_there("sample-1", self.repository2, 1, 2) yield self.assert_there("sample-2", self.repository2, 2) yield self.assert_not_there("sample-3", self.repository2, 2) @inlineCallbacks def test_no_revision_gets_latest(self): yield self.assert_there("sample", self.repository1, 2) yield self.assert_there("sample-1", self.repository1, 1, 2) yield self.assert_there("sample-2", self.repository1, 2) yield self.assert_not_there("sample-3", self.repository1, 2) revision_path = os.path.join( self.repository1.path, "series/old/revision") with open(revision_path, "w") as f: f.write("3") yield self.assert_there("sample", self.repository1, 3) yield self.assert_not_there("sample-1", self.repository1, 3) yield self.assert_there("sample-2", self.repository1, 2, 3) yield self.assert_there("sample-3", self.repository1, 3)
class LocalRepositoryTest(RepositoryTestBase): def setUp(self): super(LocalRepositoryTest, self).setUp() # bundle sample charms CharmDirectory(self.sample_dir1).make_archive( os.path.join(self.bundled_repo_path, "series", "old.charm")) CharmDirectory(self.sample_dir2).make_archive( os.path.join(self.bundled_repo_path, "series", "new.charm")) # define repository objects self.repository1 = LocalCharmRepository(self.unbundled_repo_path) self.repository2 = LocalCharmRepository(self.bundled_repo_path) def charm_url(self, name): return CharmURL.parse("local:series/" + name) def test_no_path(self): err = self.assertRaises(RepositoryNotFound, LocalCharmRepository, None) self.assertEquals(str(err), "No repository specified") def test_bad_path(self): path = os.path.join(self.makeDir(), "blah") err = self.assertRaises(RepositoryNotFound, LocalCharmRepository, path) self.assertEquals(str(err), "No repository found at %r" % path) with open(path, "w"): pass err = self.assertRaises(RepositoryNotFound, LocalCharmRepository, path) self.assertEquals(str(err), "No repository found at %r" % path) @inlineCallbacks def assert_not_there(self, name, repo, revision=None): url = self.charm_url(name) msg = "Charm 'local:series/%s' not found in repository %s" % ( name, repo.path) err = yield self.assertFailure(repo.find(url), CharmNotFound) self.assertEquals(str(err), msg) if revision is None: err = yield self.assertFailure(repo.latest(url), CharmNotFound) self.assertEquals(str(err), msg) def test_find_inappropriate_url(self): url = CharmURL.parse("cs:foo/bar") err = self.assertRaises(AssertionError, self.repository1.find, url) self.assertEquals(str(err), "schema mismatch") def test_completely_missing(self): return self.assert_not_there("zebra", self.repository1) def test_unkown_files_ignored(self): self.makeFile("Foobar", path=os.path.join(self.repository1.path, "series", "zebra")) return self.assert_not_there("zebra", self.repository1) def test_unknown_directories_ignored(self): self.makeDir( path=os.path.join(self.repository1.path, "series", "zebra")) return self.assert_not_there("zebra", self.repository1) @inlineCallbacks def test_broken_charm_metadata_ignored(self): charm_path = self.makeDir( path=os.path.join(self.repository1.path, "series", "zebra")) fh = open(os.path.join(charm_path, "metadata.yaml"), "w+") fh.write("""\ description: helo name: hi requires: {interface: zebra revision: 0 summary: hola""") fh.close() stream = self.capture_logging("juju.charm") yield self.assertFailure( self.repository1.find(self.charm_url("zebra")), CharmNotFound) output = stream.getvalue() self.assertIn("Charm 'zebra' has a YAML error", output) self.assertIn("%s/series/zebra/metadata.yaml" % self.repository1.path, output) @inlineCallbacks def test_broken_charm_config_ignored(self): """YAML Errors propogate to the log, but the search continues.""" fh = open( os.path.join(self.repository1.path, "series", "mysql", "config.yaml"), "w+") fh.write("""\ description: helo name: hi requires: {interface: zebra revision: 0 summary: hola""") fh.close() stream = self.capture_logging("juju.charm") yield self.repository1.find(self.charm_url("sample")) output = stream.getvalue() self.assertIn("Charm 'mysql' has a YAML error", output) self.assertIn("%s/series/mysql/config.yaml" % self.repository1.path, output) @inlineCallbacks def test_invalid_charm_config_ignored(self): fh = open( os.path.join(self.repository1.path, "series", "mysql", "config.yaml"), "w+") fh.write("foobar: {}") fh.close() stream = self.capture_logging("juju.charm") yield self.assertFailure( self.repository1.find(self.charm_url("mysql")), CharmNotFound) output = stream.getvalue() self.assertIn("Charm 'mysql' has an error", output) self.assertIn("%s/series/mysql/config.yaml" % self.repository1.path, output) def assert_there(self, name, repo, revision, latest_revision=None): url = self.charm_url(name) charm = yield repo.find(url) self.assertEquals(charm.get_revision(), revision) latest = yield repo.latest(url) self.assertEquals(latest, latest_revision or revision) @inlineCallbacks def test_success_unbundled(self): yield self.assert_there("sample", self.repository1, 2) yield self.assert_there("sample-1", self.repository1, 1, 2) yield self.assert_there("sample-2", self.repository1, 2) yield self.assert_not_there("sample-3", self.repository1, 2) @inlineCallbacks def test_success_bundled(self): yield self.assert_there("sample", self.repository2, 2) yield self.assert_there("sample-1", self.repository2, 1, 2) yield self.assert_there("sample-2", self.repository2, 2) yield self.assert_not_there("sample-3", self.repository2, 2) @inlineCallbacks def test_no_revision_gets_latest(self): yield self.assert_there("sample", self.repository1, 2) yield self.assert_there("sample-1", self.repository1, 1, 2) yield self.assert_there("sample-2", self.repository1, 2) yield self.assert_not_there("sample-3", self.repository1, 2) revision_path = os.path.join(self.repository1.path, "series/old/revision") with open(revision_path, "w") as f: f.write("3") yield self.assert_there("sample", self.repository1, 3) yield self.assert_not_there("sample-1", self.repository1, 3) yield self.assert_there("sample-2", self.repository1, 2, 3) yield self.assert_there("sample-3", self.repository1, 3)