def test_recovery_archive(tmpdir): # Recover from the "archive" state correctly. shutil.copytree(resources_test_dir("install_recovery_archive"), str(tmpdir.join("install")), symlinks=True) install = Install(str(tmpdir.join("install")), resources_test_dir("systemd"), True, False, True) action, _ = install.recover_swap_active() assert action # TODO(cmaloney): expect_fs expect_fs( str(tmpdir.join("install")), { ".gitignore": None, "active": ["mesos"], "active.buildinfo.full.json": None, "active.old": ["mesos"], "bin": ["mesos", "mesos-dir"], "dcos.target.wants": [".gitignore"], "environment": None, "environment.export": None, "environment.old": None, "etc": [".gitignore"], "include": [".gitignore"], "lib": ["libmesos.so"] })
def test_check_target_list(): output = check_output([ 'pkgpanda', 'check', '--list', '--root', resources_test_dir("opt/mesosphere"), '--repository', resources_test_dir("opt/mesosphere/packages") ], stderr=STDOUT) assert output.decode() == list_output
def test_check_target_list(): output = check_output([ 'pkgpanda', 'check', '--list', '--root', resources_test_dir("opt/mesosphere"), '--repository', resources_test_dir("opt/mesosphere/packages")], stderr=STDOUT) assert output.decode() == list_output
def test_check_target_run(): cmd = Popen([ 'pkgpanda', 'check', '--root', resources_test_dir('opt/mesosphere'), '--repository', resources_test_dir('opt/mesosphere/packages')], stdout=PIPE, stderr=PIPE) stdout, stderr = cmd.communicate() assert stdout.decode() == run_output_stdout assert stderr.decode() == run_output_stderr
def test_remove(tmpdir): repo_dir = str(tmpdir.join("repo")) copytree(resources_test_dir("packages"), repo_dir) assert run([ "pkgpanda", "remove", "mesos--0.22.0", "--repository={}".format(repo_dir), "--root={}".format(resources_test_dir("install_empty"))]) assert run(["pkgpanda", "list", "--repository={}".format(repo_dir)]) == list_remove_output
def test_check_target_run(): cmd = Popen([ 'pkgpanda', 'check', '--root', resources_test_dir('opt/mesosphere'), '--repository', resources_test_dir('opt/mesosphere/packages') ], stdout=PIPE, stderr=PIPE) stdout, stderr = cmd.communicate() assert stdout.decode() == run_output_stdout assert stderr.decode() == run_output_stderr
def test_remove(tmpdir): repo_dir = str(tmpdir.join("repo")) copytree(resources_test_dir("packages"), repo_dir) assert run([ "pkgpanda", "remove", "mesos--0.22.0", "--repository={}".format(repo_dir), "--root={}".format(resources_test_dir("install_empty")) ]) assert run(["pkgpanda", "list", "--repository={}".format(repo_dir)]) == list_remove_output
def test_fetch_package(tmpdir): _set_test_config(app) client = app.test_client() app.config['DCOS_REPO_DIR'] = str(tmpdir) # Successful package fetch. assert_json_response(client.get('/repository/'), 200, []) assert_response( client.post( '/repository/mesos--0.22.0', content_type='application/json', data=json.dumps({ 'repository_url': 'file://{}/{}/'.format(os.getcwd(), resources_test_dir('remote_repo')) }), ), 204, b'', ) assert_json_response(client.get('/repository/'), 200, ['mesos--0.22.0']) # No repository URL provided. assert_error( client.post( '/repository/mesos--0.23.0', content_type='application/json', data=json.dumps({}), ), 400, ) # Invalid package ID. assert_error( client.post( '/repository/invalid---package', content_type='application/json', data=json.dumps({ 'repository_url': 'file://{}/'.format(resources_test_dir('remote_repo')) }), ), 400, )
def test_recovery_move_new(tmpdir): # From the "move_new" state correctly. shutil.copytree(resources_test_dir("install_recovery_move"), str(tmpdir.join("install")), symlinks=True) install = Install(str(tmpdir.join("install")), resources_test_dir("systemd"), True, False, True) action, _ = install.recover_swap_active() assert action # TODO(cmaloney): expect_fs expect_fs( str(tmpdir.join("install")), { ".gitignore": None, "active": ["mesos"], "active.buildinfo.full.json": None, "bin": ["mesos", "mesos-dir"], "dcos.target.wants": [".gitignore"], "environment": None, "environment.export": None, "etc": [".gitignore"], "include": [".gitignore"], "lib": ["libmesos.so"] })
def test_add(tmpdir): assert run([ "pkgpanda", "add", resources_test_dir('remote_repo/packages/mesos/mesos--0.22.0.tar.xz'), "--repository={0}".format(tmpdir), ]) == "" # Ensure that the package at least somewhat extracted correctly. expect_fs("{0}".format(tmpdir), { "mesos--0.22.0": ["lib", "bin_master", "bin_slave", "pkginfo.json", "bin"] })
def test_add(tmpdir): assert run([ "pkgpanda", "add", resources_test_dir('remote_repo/packages/mesos/mesos--0.22.0.tar.xz'), "--repository={0}".format(tmpdir), ]) == "" # Ensure that the package at least somewhat extracted correctly. expect_fs( "{0}".format(tmpdir), { "mesos--0.22.0": ["lib", "bin_master", "bin_slave", "pkginfo.json", "bin"] })
def test_fetch(tmpdir): # NOTE: tmpdir is explicitly empty because we want to be sure a fetch. # succeeds when there isn't anything yet. # Start a simpleHTTPServer to serve the packages # fetch a couple packages assert run([ "pkgpanda", "fetch", "mesos--0.22.0", "--repository={0}".format(tmpdir), "--repository-url=file://{}/".format(resources_test_dir('remote_repo')) ]) == fetch_output # Ensure that the package at least somewhat extracted correctly. expect_fs("{0}".format(tmpdir), { "mesos--0.22.0": ["lib", "bin_master", "bin_slave", "pkginfo.json", "bin"] })
def test_activate_packages(tmpdir): _set_test_config(app) install_dir = str(tmpdir.join('install')) copytree(resources_test_dir('install'), install_dir, symlinks=True) app.config['DCOS_ROOT'] = install_dir app.config['DCOS_ROOTED_SYSTEMD'] = True client = app.test_client() # Upgrade from mesos--0.22.0 to mesos--0.23.0. old_packages = [ 'mesos--0.22.0', 'mesos-config--ffddcfb53168d42f92e4771c6f8a8a9a818fd6b8', ] new_packages = [ 'mesos--0.23.0', 'mesos-config--ffddcfb53168d42f92e4771c6f8a8a9a818fd6b8', ] assert_json_response(client.get('/active/'), 200, old_packages) assert_response( client.put( '/active/', content_type='application/json', data=json.dumps(new_packages), ), 204, b'', ) assert_json_response(client.get('/active/'), 200, new_packages) # mesos--0.23.0 expects to have a state directory. assert os.path.isdir(app.config['DCOS_STATE_DIR_ROOT'] + '/mesos') # Attempt to activate nonexistent packages. nonexistent_packages = [ 'nonexistent-package--fakeversion1', 'nonexistent-package--fakeversion2', ] assert_error( client.put( '/active/', content_type='application/json', data=json.dumps(['mesos--0.23.0'] + nonexistent_packages), ), 409, missing_packages=sorted(nonexistent_packages), )
def test_remove_package(tmpdir): _set_test_config(app) repo_dir = str(tmpdir.join('repo')) copytree(resources_test_dir('packages'), repo_dir) app.config['DCOS_REPO_DIR'] = repo_dir client = app.test_client() # Successful deletion. package_to_delete = 'mesos--0.23.0' assert_json_response( client.get('/repository/'), 200, package_to_delete, body_cmp=lambda response_body, package: package in response_body, ) assert_response(client.delete('/repository/' + package_to_delete), 204, b'') assert_json_response( client.get('/repository/'), 200, package_to_delete, body_cmp=lambda response_body, package: package not in response_body, ) # Attempted deletion of active package. package_to_delete = 'mesos--0.22.0' assert_json_response( client.get('/active/'), 200, package_to_delete, body_cmp=lambda response_body, package: package in response_body, ) assert_error(client.delete('/repository/' + package_to_delete), 409) assert_json_response( client.get('/active/'), 200, package_to_delete, body_cmp=lambda response_body, package: package in response_body, ) # Attempted deletion of nonexistent package. assert_error(client.delete('/repository/nonexistent-package--fakeversion'), 404) assert_error(client.delete('/repository/invalid---package'), 404)
def test_systemd_unit_files(tmpdir): repo_path = tmp_repository(tmpdir) tmpdir.join("root", "bootstrap").write("", ensure=True) check_call([ "pkgpanda", "setup", "--root={0}/root".format(tmpdir), "--rooted-systemd", "--repository={}".format(repo_path), "--config-dir={}".format(resources_test_dir("etc-active")), "--no-systemd" ]) unit_file = 'dcos-mesos-master.service' base_path = '{}/root/{}'.format(tmpdir, unit_file) wants_path = '{}/root/dcos.target.wants/{}'.format(tmpdir, unit_file) # The unit file is copied to the base dir and symlinked from dcos.target.wants. assert os.path.islink(wants_path) assert os.path.isfile(base_path) and not os.path.islink(base_path) assert os.path.realpath(wants_path) == base_path
def test_fetch(tmpdir): # NOTE: tmpdir is explicitly empty because we want to be sure a fetch. # succeeds when there isn't anything yet. # Start a simpleHTTPServer to serve the packages # fetch a couple packages assert run([ "pkgpanda", "fetch", "mesos--0.22.0", "--repository={0}".format(tmpdir), "--repository-url=file://{}/".format(resources_test_dir('remote_repo')) ]) == fetch_output # Ensure that the package at least somewhat extracted correctly. expect_fs( "{0}".format(tmpdir), { "mesos--0.22.0": ["lib", "bin_master", "bin_slave", "pkginfo.json", "bin"] })
def test_systemd_unit_files(tmpdir): repo_path = tmp_repository(tmpdir) tmpdir.join("root", "bootstrap").write("", ensure=True) check_call(["pkgpanda", "setup", "--root={0}/root".format(tmpdir), "--rooted-systemd", "--repository={}".format(repo_path), "--config-dir={}".format(resources_test_dir("etc-active")), "--no-systemd" ]) unit_file = 'dcos-mesos-master.service' base_path = '{}/root/{}'.format(tmpdir, unit_file) wants_path = '{}/root/dcos.target.wants/{}'.format(tmpdir, unit_file) # The unit file is copied to the base dir and symlinked from dcos.target.wants. assert os.path.islink(wants_path) assert os.path.isfile(base_path) and not os.path.islink(base_path) assert os.path.realpath(wants_path) == base_path
def test_list(): assert run([ "pkgpanda", "list", "--repository={}".format(resources_test_dir("packages")) ]) == list_output
def repository(): return Repository(resources_test_dir("packages"))
def install(): return Install(resources_test_dir("install"), resources_test_dir("systemd"), True, False, True)
def test_active(): assert run(["pkgpanda", "active", "--root={}".format(resources_test_dir("install"))]) == active_output
def test_list(): assert run(["pkgpanda", "list", "--repository={}".format(resources_test_dir("packages"))]) == list_output
def tmp_repository(temp_dir, repo_dir=resources_test_dir("packages")): repo_path = temp_dir.join("repository") copytree(repo_dir, str(repo_path)) return repo_path
def test_activate(tmpdir): repo_path = tmp_repository(tmpdir) state_dir_root = tmpdir.join("package_state") tmpdir.join("root", "bootstrap").write("", ensure=True) # TODO(cmaloney): Depending on setup here is less than ideal, but meh. check_call(["pkgpanda", "setup", "--root={0}/root".format(tmpdir), "--rooted-systemd", "--repository={}".format(repo_path), "--config-dir={}".format(resources_test_dir("etc-active")), "--no-systemd" ]) assert run(["pkgpanda", "activate", "mesos--0.22.0", "mesos-config--ffddcfb53168d42f92e4771c6f8a8a9a818fd6b8", "--root={0}/root".format(tmpdir), "--rooted-systemd", "--repository={}".format(repo_path), "--config-dir=../resources/etc-active", "--no-systemd"]) == "" # Check introspection to active is working right. active = set(check_output([ "pkgpanda", "active", "--root={0}/root".format(tmpdir), "--rooted-systemd", "--repository={}".format(repo_path), "--config-dir=../resources/etc-active"]).decode().split()) assert active == {"mesos--0.22.0", "mesos-config--ffddcfb53168d42f92e4771c6f8a8a9a818fd6b8"} # Swap out one package assert run(["pkgpanda", "swap", "mesos-config--justmesos", "--root={0}/root".format(tmpdir), "--rooted-systemd", "--repository={}".format(repo_path), "--config-dir=../resources/etc-active", "--no-systemd"]) == "" # Check introspection to active is working right. active = set(check_output([ "pkgpanda", "active", "--root={0}/root".format(tmpdir), "--rooted-systemd", "--repository={}".format(repo_path), "--config-dir=../resources/etc-active"]).decode().split()) assert active == {"mesos--0.22.0", "mesos-config--justmesos"} assert run(["pkgpanda", "activate", "mesos--0.22.0", "--root={0}/root".format(tmpdir), "--rooted-systemd", "--repository={}".format(repo_path), "--config-dir=../resources/etc-active", "--no-systemd"]) == "" # Check introspection to active is working right. active = set(check_output([ "pkgpanda", "active", "--root={0}/root".format(tmpdir), "--rooted-systemd", "--repository={}".format(repo_path), "--config-dir=../resources/etc-active"]).decode().split()) assert active == {"mesos--0.22.0"} # Check that mesos--0.23.0 gets its state directory created. assert not os.path.isdir(str(state_dir_root) + '/mesos') assert run(["pkgpanda", "activate", "mesos--0.23.0", "--root={0}/root".format(tmpdir), "--rooted-systemd", "--repository={}".format(repo_path), "--config-dir=../resources/etc-active", "--no-systemd", "--state-dir-root={}".format(state_dir_root)]) == "" assert os.path.isdir(str(state_dir_root) + '/mesos')
def test_active(): assert run([ "pkgpanda", "active", "--root={}".format(resources_test_dir("install")) ]) == active_output
def _set_test_config(app): app.config['TESTING'] = True app.config['DCOS_ROOT'] = resources_test_dir('install') app.config['DCOS_REPO_DIR'] = resources_test_dir('packages')
def test_setup(tmpdir): repo_path = tmp_repository(tmpdir) tmpdir.join("root", "bootstrap").write("", ensure=True) check_call(["pkgpanda", "setup", "--root={0}/root".format(tmpdir), "--rooted-systemd", "--repository={}".format(repo_path), "--config-dir={}".format(resources_test_dir("etc-active")), "--no-systemd" ]) expect_fs("{0}".format(tmpdir), ["repository", "root"]) # TODO(cmaloney): Validate things got placed correctly. expect_fs( "{0}/root".format(tmpdir), { "active": ["dcos-provider-abcdef-test", "mesos", "mesos-config"], "active.buildinfo.full.json": None, "bin": [ "mesos", "mesos-dir", "mesos-master", "mesos-slave"], "lib": ["libmesos.so"], "etc": ["dcos-service-configuration.json", "foobar", "some.json"], "include": [], "dcos.target.wants": ["dcos-mesos-master.service"], "dcos.target": None, "environment": None, "environment.export": None, "dcos-mesos-master.service": None # rooted_systemd }) expected_dcos_service_configuration = { "sysctl": { "dcos-mesos-master": { "kernel.watchdog_thresh": "11", "net.netfilter.nf_conntrack_udp_timeout": "30" }, "dcos-mesos-slave": { "kperf.debug_level": "1" } } } assert expected_dcos_service_configuration == load_json( "{tmpdir}/root/etc/dcos-service-configuration.json".format(tmpdir=tmpdir)) assert load_json('{0}/root/etc/some.json'.format(tmpdir)) == { 'cluster-specific-stuff': 'magic', 'foo': 'bar', 'baz': 'qux', } # Introspection should work right active = set(check_output([ "pkgpanda", "active", "--root={0}/root".format(tmpdir), "--rooted-systemd", "--repository={}".format(repo_path), "--config-dir={}".format(resources_test_dir("etc-active"))]).decode().split()) assert active == { "dcos-provider-abcdef-test--setup", "mesos--0.22.0", "mesos-config--ffddcfb53168d42f92e4771c6f8a8a9a818fd6b8", } tmpdir.join("root", "bootstrap").write("", ensure=True) # If we setup the same directory again we should get .old files. check_call(["pkgpanda", "setup", "--root={0}/root".format(tmpdir), "--rooted-systemd", "--repository={}".format(repo_path), "--config-dir={}".format(resources_test_dir("etc-active")), "--no-systemd" ]) # TODO(cmaloney): Validate things got placed correctly. expect_fs( "{0}/root".format(tmpdir), { "active": ["dcos-provider-abcdef-test", "mesos", "mesos-config"], "active.buildinfo.full.json.old": None, "active.buildinfo.full.json": None, "bin": [ "mesos", "mesos-dir", "mesos-master", "mesos-slave"], "lib": ["libmesos.so"], "etc": ["dcos-service-configuration.json", "foobar", "some.json"], "include": [], "dcos.target": None, "dcos.target.wants": ["dcos-mesos-master.service"], "environment": None, "environment.export": None, "active.old": ["dcos-provider-abcdef-test", "mesos", "mesos-config"], "bin.old": [ "mesos", "mesos-dir", "mesos-master", "mesos-slave"], "lib.old": ["libmesos.so"], "etc.old": ["dcos-service-configuration.json", "foobar", "some.json"], "include.old": [], "dcos.target.wants.old": ["dcos-mesos-master.service"], "environment.old": None, "environment.export.old": None, "dcos-mesos-master.service": None # rooted systemd }) # Should only pickup the packages once / one active set. active = set(check_output([ "pkgpanda", "active", "--root={0}/root".format(tmpdir), "--rooted-systemd", "--repository={}".format(repo_path), "--config-dir={}".format(resources_test_dir("etc-active"))]).decode().split()) assert active == { "dcos-provider-abcdef-test--setup", "mesos--0.22.0", "mesos-config--ffddcfb53168d42f92e4771c6f8a8a9a818fd6b8", } # Touch some .new files so we can be sure that deactivate cleans those up as well. tmpdir.mkdir("root/bin.new") tmpdir.mkdir("root/lib.new") tmpdir.mkdir("root/etc.new") tmpdir.mkdir("root/foo.new") tmpdir.mkdir("root/baz") tmpdir.mkdir("root/foobar.old") tmpdir.mkdir("root/packages") # Uninstall / deactivate everything, check_call(["pkgpanda", "uninstall", "--root={0}/root".format(tmpdir), "--rooted-systemd", "--repository={}".format(repo_path), "--config-dir={}".format(resources_test_dir("etc-active")), "--no-systemd" ]) expect_fs("{0}".format(tmpdir), {"repository": None})
def _set_test_config(app): app.config['TESTING'] = True app.config['DCOS_ROOT'] = resources_test_dir('install') app.config['DCOS_STATE_DIR_ROOT'] = resources_test_dir( 'install/package_state') app.config['DCOS_REPO_DIR'] = resources_test_dir('packages')