2016-06-15 19:07:42 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
#
|
|
|
|
# Copyright 2016 Google Inc.
|
|
|
|
#
|
|
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
|
|
# found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
|
|
"""Tests for asset_utils."""
|
|
|
|
|
|
|
|
|
|
|
|
import asset_utils
|
|
|
|
import os
|
|
|
|
import shutil
|
|
|
|
import subprocess
|
|
|
|
import sys
|
|
|
|
import tempfile
|
|
|
|
import unittest
|
|
|
|
import uuid
|
|
|
|
|
|
|
|
|
|
|
|
FILE_DIR = os.path.dirname(os.path.abspath(__file__))
|
2016-06-28 11:41:49 +00:00
|
|
|
INFRA_BOTS_DIR = os.path.realpath(os.path.join(FILE_DIR, os.pardir))
|
2016-06-15 19:07:42 +00:00
|
|
|
sys.path.insert(0, INFRA_BOTS_DIR)
|
|
|
|
import test_utils
|
|
|
|
import utils
|
|
|
|
|
|
|
|
|
2016-06-28 11:41:49 +00:00
|
|
|
CIPD_DEV_SERVICE_URL = 'https://chrome-infra-packages-dev.appspot.com'
|
2016-06-15 19:07:42 +00:00
|
|
|
GS_BUCKET = 'skia-infra-testdata'
|
|
|
|
|
|
|
|
|
|
|
|
def _fake_prompt(result):
|
|
|
|
"""Make a function that pretends to prompt for input and returns a result."""
|
|
|
|
return lambda s: result
|
|
|
|
|
|
|
|
|
|
|
|
def _write_stuff(target_dir):
|
|
|
|
"""Write some files and directories into target_dir."""
|
|
|
|
fw = test_utils.FileWriter(target_dir)
|
|
|
|
fw.mkdir('mydir')
|
|
|
|
fw.mkdir('anotherdir', 0666)
|
|
|
|
fw.mkdir('dir3', 0600)
|
|
|
|
fw.mkdir('subdir')
|
|
|
|
fw.write('a.txt', 0777)
|
|
|
|
fw.write('b.txt', 0751)
|
|
|
|
fw.write('c.txt', 0640)
|
|
|
|
fw.write(os.path.join('subdir', 'd.txt'), 0640)
|
|
|
|
|
|
|
|
|
2016-06-28 11:41:49 +00:00
|
|
|
class _LocalStore(object):
|
|
|
|
"""Local store used for testing."""
|
|
|
|
def __init__(self):
|
|
|
|
self.dir = tempfile.mkdtemp()
|
|
|
|
|
|
|
|
def get_available_versions(self, name):
|
|
|
|
target = os.path.join(self.dir, name)
|
|
|
|
if not os.path.isdir(target):
|
|
|
|
return []
|
|
|
|
contents = os.listdir(os.path.join(self.dir, name))
|
|
|
|
return sorted([int(d) for d in contents])
|
|
|
|
|
2019-01-25 17:05:59 +00:00
|
|
|
def upload(self, name, version, target_dir, extra_tags=None):
|
2016-06-28 11:41:49 +00:00
|
|
|
shutil.copytree(target_dir, os.path.join(self.dir, name, str(version)))
|
|
|
|
|
|
|
|
def download(self, name, version, target_dir):
|
|
|
|
shutil.copytree(os.path.join(self.dir, name, str(version)), target_dir)
|
|
|
|
|
|
|
|
def delete_contents(self, name):
|
|
|
|
try:
|
|
|
|
shutil.rmtree(self.dir)
|
|
|
|
except OSError:
|
|
|
|
if os.path.exists(self.dir):
|
|
|
|
raise
|
|
|
|
|
|
|
|
|
|
|
|
class StoreTest(unittest.TestCase):
|
|
|
|
"""Superclass used for testing one of the stores."""
|
|
|
|
def setUp(self):
|
|
|
|
self.asset_name = str(uuid.uuid4())
|
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def _test_upload_download(self, store):
|
|
|
|
with utils.tmp_dir():
|
|
|
|
# Create input files and directories.
|
|
|
|
input_dir = os.path.join(os.getcwd(), 'input')
|
|
|
|
_write_stuff(input_dir)
|
|
|
|
|
|
|
|
# Upload a version, download it again.
|
|
|
|
store.upload(self.asset_name, 0, input_dir)
|
|
|
|
output_dir = os.path.join(os.getcwd(), 'output')
|
|
|
|
store.download(self.asset_name, 0, output_dir)
|
|
|
|
|
|
|
|
# Compare.
|
|
|
|
test_utils.compare_trees(self, input_dir, output_dir)
|
|
|
|
|
|
|
|
def _test_versions(self, store):
|
|
|
|
with utils.tmp_dir():
|
|
|
|
# Create input files and directories.
|
|
|
|
input_dir = os.path.join(os.getcwd(), 'input')
|
|
|
|
_write_stuff(input_dir)
|
|
|
|
self.assertEqual(store.get_available_versions(self.asset_name), [])
|
|
|
|
store.upload(self.asset_name, 0, input_dir)
|
|
|
|
self.assertEqual(store.get_available_versions(self.asset_name), [0])
|
|
|
|
store.upload(self.asset_name, 1, input_dir)
|
|
|
|
self.assertEqual(store.get_available_versions(self.asset_name), [0, 1])
|
|
|
|
store.delete_contents(self.asset_name)
|
|
|
|
self.assertEqual(store.get_available_versions(self.asset_name), [])
|
|
|
|
|
|
|
|
|
|
|
|
class LocalStoreTest(StoreTest):
|
|
|
|
"""Test the local store."""
|
|
|
|
def setUp(self):
|
|
|
|
super(LocalStoreTest, self).setUp()
|
|
|
|
self._store = _LocalStore()
|
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
self._store.delete_contents(self.asset_name)
|
|
|
|
super(LocalStoreTest, self).tearDown()
|
|
|
|
|
|
|
|
def test_upload_download(self):
|
|
|
|
self._test_upload_download(self._store)
|
|
|
|
|
|
|
|
def test_versions(self):
|
|
|
|
self._test_versions(self._store)
|
|
|
|
|
|
|
|
|
2016-10-14 13:32:09 +00:00
|
|
|
# This test is disabled due to permissions issues with CIPD.
|
|
|
|
#class CIPDStoreTest(StoreTest):
|
|
|
|
# """Test the CIPD store."""
|
|
|
|
# def setUp(self):
|
|
|
|
# super(CIPDStoreTest, self).setUp()
|
|
|
|
# self._store = asset_utils.CIPDStore(cipd_url=CIPD_DEV_SERVICE_URL)
|
|
|
|
#
|
|
|
|
# def tearDown(self):
|
|
|
|
# self._store.delete_contents(self.asset_name)
|
|
|
|
# super(CIPDStoreTest, self).tearDown()
|
|
|
|
#
|
|
|
|
# def test_upload_download(self):
|
|
|
|
# self._test_upload_download(self._store)
|
|
|
|
#
|
|
|
|
# def test_versions(self):
|
|
|
|
# self._test_versions(self._store)
|
2016-06-28 11:41:49 +00:00
|
|
|
|
|
|
|
|
2016-12-12 15:38:45 +00:00
|
|
|
# This test is disabled because the interactions with GS can be flaky.
|
|
|
|
#class GSStoreTest(StoreTest):
|
|
|
|
# """Test the GS store."""
|
|
|
|
# def setUp(self):
|
|
|
|
# super(GSStoreTest, self).setUp()
|
|
|
|
# self._store = asset_utils.GSStore(gsutil=None, bucket=GS_BUCKET)
|
|
|
|
#
|
|
|
|
# def tearDown(self):
|
|
|
|
# self._store.delete_contents(self.asset_name)
|
|
|
|
# super(GSStoreTest, self).tearDown()
|
|
|
|
#
|
|
|
|
# def test_upload_download(self):
|
|
|
|
# self._test_upload_download(self._store)
|
|
|
|
#
|
|
|
|
# def test_versions(self):
|
|
|
|
# self._test_versions(self._store)
|
2016-06-28 11:41:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
class AssetTest(unittest.TestCase):
|
|
|
|
"""Test Asset operations using a local store."""
|
2016-06-15 19:07:42 +00:00
|
|
|
def setUp(self):
|
|
|
|
self.asset_name = str(uuid.uuid4())
|
|
|
|
self.old_prompt = asset_utils._prompt
|
|
|
|
asset_utils._prompt = _fake_prompt('y')
|
2016-06-28 11:41:49 +00:00
|
|
|
self._store = _LocalStore()
|
|
|
|
self.a = asset_utils.Asset.add(self.asset_name, self._store)
|
2016-06-15 19:07:42 +00:00
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
if self.a:
|
2016-06-28 11:41:49 +00:00
|
|
|
self.a.remove(remove_in_store=True)
|
2016-06-15 19:07:42 +00:00
|
|
|
asset_utils._prompt = self.old_prompt
|
|
|
|
|
|
|
|
gs_path = 'gs://%s/assets/%s' % (GS_BUCKET, self.asset_name)
|
2019-06-24 18:53:47 +00:00
|
|
|
gsutil = asset_utils.GSStore()._gsutil
|
2016-06-15 19:07:42 +00:00
|
|
|
attempt_delete = True
|
|
|
|
try:
|
2019-06-24 18:53:47 +00:00
|
|
|
subprocess.check_call(gsutil + ['ls', gs_path])
|
2016-06-15 19:07:42 +00:00
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
attempt_delete = False
|
|
|
|
if attempt_delete:
|
2019-06-24 18:53:47 +00:00
|
|
|
subprocess.check_call(gsutil + ['rm', '-rf', gs_path])
|
2016-06-15 19:07:42 +00:00
|
|
|
|
|
|
|
def test_add_remove(self):
|
|
|
|
# Ensure that we can't create an asset twice.
|
|
|
|
with self.assertRaises(Exception):
|
2016-06-28 11:41:49 +00:00
|
|
|
asset_utils.Asset.add(self.asset_name, self._store)
|
2016-06-15 19:07:42 +00:00
|
|
|
|
|
|
|
# Ensure that the asset dir exists.
|
|
|
|
asset_dir = os.path.join(FILE_DIR, self.asset_name)
|
|
|
|
self.assertTrue(os.path.isdir(asset_dir))
|
|
|
|
|
|
|
|
# Remove the asset, ensure that it's gone.
|
|
|
|
self.a.remove()
|
|
|
|
self.a = None
|
|
|
|
self.assertFalse(os.path.exists(asset_dir))
|
|
|
|
|
|
|
|
def test_upload_download(self):
|
|
|
|
with utils.tmp_dir():
|
|
|
|
# Create input files and directories.
|
|
|
|
input_dir = os.path.join(os.getcwd(), 'input')
|
|
|
|
_write_stuff(input_dir)
|
|
|
|
|
|
|
|
# Upload a version, download it again.
|
|
|
|
self.a.upload_new_version(input_dir)
|
|
|
|
output_dir = os.path.join(os.getcwd(), 'output')
|
|
|
|
self.a.download_current_version(output_dir)
|
|
|
|
|
|
|
|
# Compare.
|
|
|
|
test_utils.compare_trees(self, input_dir, output_dir)
|
|
|
|
|
|
|
|
def test_versions(self):
|
|
|
|
with utils.tmp_dir():
|
|
|
|
# Create input files and directories.
|
|
|
|
input_dir = os.path.join(os.getcwd(), 'input')
|
|
|
|
_write_stuff(input_dir)
|
|
|
|
|
|
|
|
self.assertEqual(self.a.get_current_version(), -1)
|
|
|
|
self.assertEqual(self.a.get_available_versions(), [])
|
|
|
|
self.assertEqual(self.a.get_next_version(), 0)
|
|
|
|
|
|
|
|
self.a.upload_new_version(input_dir)
|
|
|
|
|
|
|
|
self.assertEqual(self.a.get_current_version(), 0)
|
|
|
|
self.assertEqual(self.a.get_available_versions(), [0])
|
|
|
|
self.assertEqual(self.a.get_next_version(), 1)
|
|
|
|
|
|
|
|
self.a.upload_new_version(input_dir)
|
|
|
|
|
|
|
|
self.assertEqual(self.a.get_current_version(), 1)
|
|
|
|
self.assertEqual(self.a.get_available_versions(), [0, 1])
|
|
|
|
self.assertEqual(self.a.get_next_version(), 2)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
unittest.main()
|