Skip to content

Commit b6f5d31

Browse files
committed
adding a bunch of tests
1 parent 640faa4 commit b6f5d31

File tree

16 files changed

+716
-36
lines changed

16 files changed

+716
-36
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ install:
1717
- python setup.py sdist
1818
- python setup.py install
1919
- pylint --version
20-
- git clone https://github.com/singularityware/singularity.git && cd singularity && ./autogen.sh && ./configure --prefix=/usr/local && make && sudo make install
20+
- git clone -b development https://github.com/singularityware/singularity.git && cd singularity && ./autogen.sh && ./configure --prefix=/usr/local && make && sudo make install
2121

2222
script:
2323
- python -m unittest discover -s $TRAVIS_BUILD_DIR/singularity/tests/ -p '[t|T]est*.py'

singularity/analysis/classify.py

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import os
3434
import re
3535
import requests
36+
from singularity.cli import Singularity
3637
from singularity.logman import bot
3738
from singularity.analysis.compare import (
3839
compare_packages,
@@ -199,34 +200,7 @@ def get_tags(container=None,image_package=None,sudopw=None,search_folders=None,d
199200
# COUNTING ########################################################################
200201
###################################################################################
201202

202-
203-
def get_files(container,S=None,tmpdir=None):
204-
'''get_files will return a list of files inside a container, sorted by name
205-
:param container: the container to use, either shub:// or docker:// or actual
206-
'''
207-
files = None
208-
if tmpdir == None:
209-
tmpdir = tempfile.mkdtemp()
210-
tmpfile = "%s/files.txt" %tmpdir
211-
container_name = remove_uri(container)
212-
command = ' ls -LR >> %s 2>/dev/null' %(tmpfile)
213-
if S==None:
214-
S = Singularity(sudo=None)
215-
result = S.execute(container,command)
216-
if os.path.exists(tmpfile):
217-
os.system("sed -i '/^$/d' %s" %(tmpfile))
218-
os.system('sort %s -or %s' %(tmpfile,tmpfile))
219-
files = read_file(tmpfile)
220-
if len(files) > 0:
221-
files = [x for x in files if x.startswith('.')]
222-
files = [x.split(container_name)[1:] for x in files]
223-
files = [x for x in files if len(x) > 0]
224-
files = [x[0] for x in files]
225-
shutil.rmtree(tmpdir)
226-
return files
227-
228203

229-
230204
def file_counts(container=None,patterns=None,image_package=None,sudopw=None,diff=None):
231205
'''file counts will return a list of files that match one or more regular expressions.
232206
if no patterns is defined, a default of readme is used. All patterns and files are made

singularity/analysis/compare.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,28 @@
44
compare.py: part of singularity package
55
functions to compare packages and images
66
7+
The MIT License (MIT)
8+
9+
Copyright (c) 2016-2017 Vanessa Sochat
10+
11+
Permission is hereby granted, free of charge, to any person obtaining a copy
12+
of this software and associated documentation files (the "Software"), to deal
13+
in the Software without restriction, including without limitation the rights
14+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15+
copies of the Software, and to permit persons to whom the Software is
16+
furnished to do so, subject to the following conditions:
17+
18+
The above copyright notice and this permission notice shall be included in all
19+
copies or substantial portions of the Software.
20+
21+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27+
SOFTWARE.
28+
729
'''
830

931
from glob import glob
@@ -86,6 +108,12 @@ def compare_singularity_images(image_paths1,image_paths2=None):
86108
image_paths2 = image_paths1
87109
repeat = True
88110

111+
if not isinstance(image_paths1,list):
112+
image_paths1 = [image_paths1]
113+
114+
if not isinstance(image_paths2,list):
115+
image_paths2 = [image_paths2]
116+
89117
dfs = pandas.DataFrame(index=image_paths1,columns=image_paths2)
90118

91119
comparisons_done = []

singularity/analysis/utils.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,28 @@
44
analysis/utils.py: part of singularity package
55
utilities for working with analysis / data
66
7+
The MIT License (MIT)
8+
9+
Copyright (c) 2016-2017 Vanessa Sochat
10+
11+
Permission is hereby granted, free of charge, to any person obtaining a copy
12+
of this software and associated documentation files (the "Software"), to deal
13+
in the Software without restriction, including without limitation the rights
14+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15+
copies of the Software, and to permit persons to whom the Software is
16+
furnished to do so, subject to the following conditions:
17+
18+
The above copyright notice and this permission notice shall be included in all
19+
copies or substantial portions of the Software.
20+
21+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27+
SOFTWARE.
28+
729
'''
830

931
from glob import glob
@@ -38,7 +60,7 @@ def get_packages(family=None):
3860
package_folders = glob("%s/*" %(package_base))
3961
package_families = [os.path.basename(x) for x in package_folders]
4062
if family == None:
41-
family = "os"
63+
family = "docker-os"
4264
family = family.lower()
4365
if family in package_families:
4466
package_folder = "%s/%s" %(package_base,family)

singularity/build/utils.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,28 @@
33
'''
44
build/utils.py: general building util functions
55
6+
The MIT License (MIT)
7+
8+
Copyright (c) 2016-2017 Vanessa Sochat
9+
10+
Permission is hereby granted, free of charge, to any person obtaining a copy
11+
of this software and associated documentation files (the "Software"), to deal
12+
in the Software without restriction, including without limitation the rights
13+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14+
copies of the Software, and to permit persons to whom the Software is
15+
furnished to do so, subject to the following conditions:
16+
17+
The above copyright notice and this permission notice shall be included in all
18+
copies or substantial portions of the Software.
19+
20+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26+
SOFTWARE.
27+
628
'''
729

830
import os

singularity/cli.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -201,23 +201,38 @@ def importcmd(self,image_path,input_source):
201201
return image_path
202202

203203

204-
def pull(self,image_path,pull_folder=None):
204+
def pull(self,image_path,pull_folder=None,name_by=None):
205205
'''pull will pull a singularity hub image
206206
:param image_path: full path to image
207+
:param name_by: can be one of commit or hash, default is by image name
207208
'''
209+
if name_by is None:
210+
name_by = "name"
211+
name_by = name_by.lower()
212+
208213
if pull_folder is not None:
209-
os.environ['SINGULARITY_PULL_FOLDER'] = pull_folder
214+
os.environ['SINGULARITY_PULLFOLDER'] = pull_folder
210215

211216
if not image_path.startswith('shub://'):
212217
bot.logger.error("pull is only valid for the shub://uri, %s is invalid.",image_name)
213218
sys.exit(1)
214219

215220
if self.debug == True:
216-
cmd = ['singularity','--debug','pull',image_path]
221+
cmd = ['singularity','--debug','pull']
217222
else:
218-
cmd = ['singularity','pull',image_path]
223+
cmd = ['singularity','pull']
224+
225+
if name_by in ['name','commit','hash']:
226+
bot.logger.debug("user specified naming pulled image by %s",name_by)
227+
name_by = "--%s" %name_by
228+
cmd.append(name_by)
229+
230+
cmd.append(image_path)
231+
219232
output = self.run_command(cmd)
220233
self.println(output)
234+
if isinstance(output,bytes):
235+
output = output.decode('utf-8')
221236
return output.split("Container is at:")[-1].strip('\n').strip()
222237

223238

@@ -239,7 +254,7 @@ def run(self,image_path,args=None,writable=False,contain=False):
239254

240255
if args is not None:
241256
if not isinstance(args,list):
242-
args = command.split(' ')
257+
args = args.split(' ')
243258
cmd = cmd + args
244259

245260
result = self.run_command(cmd,sudo=sudo)

singularity/reproduce.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ def get_content_hashes(image_path,level=None,regexp=None,include_files=None,tag_
435435
file_filter = level_filter
436436

437437
elif level is None:
438-
file_filter = get_level("RECIPE",version=version,
438+
file_filter = get_level("REPLICATE",version=version,
439439
skip_files=skip_files,
440440
include_files=include_files)
441441

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#!/usr/bin/python
2+
3+
'''
4+
Test analysis classification functions
5+
6+
The MIT License (MIT)
7+
8+
Copyright (c) 2016-2017 Vanessa Sochat
9+
10+
Permission is hereby granted, free of charge, to any person obtaining a copy
11+
of this software and associated documentation files (the "Software"), to deal
12+
in the Software without restriction, including without limitation the rights
13+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14+
copies of the Software, and to permit persons to whom the Software is
15+
furnished to do so, subject to the following conditions:
16+
17+
The above copyright notice and this permission notice shall be included in all
18+
copies or substantial portions of the Software.
19+
20+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26+
SOFTWARE.
27+
28+
'''
29+
30+
31+
from numpy.testing import (
32+
assert_array_equal,
33+
assert_almost_equal,
34+
assert_equal
35+
)
36+
37+
from singularity.cli import get_image
38+
import unittest
39+
import tempfile
40+
import shutil
41+
import json
42+
import os
43+
44+
class TestAnalysisClassify(unittest.TestCase):
45+
46+
def setUp(self):
47+
self.tmpdir = tempfile.mkdtemp()
48+
self.container = get_image('docker://ubuntu:16.04')
49+
self.comparator = get_image('docker://ubuntu:12.04')
50+
51+
def tearDown(self):
52+
shutil.rmtree(self.tmpdir)
53+
54+
55+
def test_get_diff(self):
56+
print("Testing singularity.analysis.classify.get_diff")
57+
from singularity.analysis.classify import get_diff
58+
diff = get_diff(self.container)
59+
for key in ['.singularity.d', 'lists', 'actions', 'user', 'env']:
60+
self.assertTrue(key in diff)
61+
62+
63+
def test_estimate_os(self):
64+
print("Testing singularity.analysis.classify.estimate_os")
65+
from singularity.analysis.classify import estimate_os
66+
estimated_os = estimate_os(self.container)
67+
self.assertEqual(estimated_os,'ubuntu:16.10')
68+
69+
70+
def test_get_tags(self):
71+
print("Testing singularity.analysis.classify.get_tags")
72+
from singularity.analysis.classify import get_tags
73+
tags = get_tags(self.container)
74+
75+
print("Case 1: Testing that empty OS (with no additions) returns no relevant tags")
76+
self.assertEqual(estimated_os,'ubuntu:16.10')
77+
self.assertTrue(len(tags)==0)
78+
79+
80+
def test_file_counts(self):
81+
print("Testing singularity.analysis.classify.file_counts")
82+
from singularity.analysis.classify import file_counts
83+
counts = file_counts(self.container)
84+
85+
86+
def test_extension_counts(self):
87+
print("Testing singularity.analysis.classify.extension_counts")
88+
from singularity.analysis.classify import extension_counts
89+
counts = extension_counts(self.container)
90+
self.assertTrue(len(counts)>0)
91+
92+
93+
94+
if __name__ == '__main__':
95+
unittest.main()

0 commit comments

Comments
 (0)