1 | package geniusweb.profilesserver;
|
---|
2 |
|
---|
3 | import static org.junit.Assert.assertEquals;
|
---|
4 | import static org.junit.Assert.assertNotNull;
|
---|
5 | import static org.junit.Assert.assertNull;
|
---|
6 | import static org.junit.Assert.assertTrue;
|
---|
7 |
|
---|
8 | import java.io.BufferedWriter;
|
---|
9 | import java.io.File;
|
---|
10 | import java.io.FileNotFoundException;
|
---|
11 | import java.io.FileWriter;
|
---|
12 | import java.io.IOException;
|
---|
13 | import java.net.URISyntaxException;
|
---|
14 | import java.nio.file.Files;
|
---|
15 | import java.nio.file.Path;
|
---|
16 | import java.nio.file.Paths;
|
---|
17 | import java.util.Collections;
|
---|
18 | import java.util.LinkedList;
|
---|
19 | import java.util.List;
|
---|
20 | import java.util.logging.Level;
|
---|
21 |
|
---|
22 | import org.junit.Before;
|
---|
23 | import org.junit.Test;
|
---|
24 |
|
---|
25 | import com.fasterxml.jackson.databind.ObjectMapper;
|
---|
26 |
|
---|
27 | import geniusweb.profile.Profile;
|
---|
28 | import geniusweb.profile.utilityspace.LinearAdditiveUtilitySpace;
|
---|
29 | import geniusweb.profilesserver.events.ChangeEvent;
|
---|
30 | import geniusweb.profilesserver.events.DomainChangeEvent;
|
---|
31 | import geniusweb.profilesserver.events.ProfileChangeEvent;
|
---|
32 | import tudelft.utilities.files.FileInfo;
|
---|
33 | import tudelft.utilities.files.FileWatcher;
|
---|
34 | import tudelft.utilities.immutablelist.Tuple;
|
---|
35 | import tudelft.utilities.listener.Listenable;
|
---|
36 | import tudelft.utilities.listener.Listener;
|
---|
37 | import tudelft.utilities.logging.Reporter;
|
---|
38 |
|
---|
39 | /**
|
---|
40 | * Most tests are using a (copy of ) a real filesystem repository. This is
|
---|
41 | * because the AutoUpdatingProfilesFactory accesses the real filesystem that we
|
---|
42 | * can't properly mock.
|
---|
43 | *
|
---|
44 | */
|
---|
45 | public class AutoUpdatingProfilesFactoryTest {
|
---|
46 |
|
---|
47 | private static final String JOBS = "jobs";
|
---|
48 | private static final String JOB1 = "jobs/jobs1";
|
---|
49 | private final Path REPO_DIRECTORY = Paths
|
---|
50 | .get("src/main/webapp/domainsrepo/");
|
---|
51 | private List<String> warnings;
|
---|
52 | private Path copyrepodir;
|
---|
53 | private AutoUpdatingProfilesRepository factory;
|
---|
54 | private final long HIGHRATE = 500; // fast so that we can test quickly.
|
---|
55 | private final List<ChangeEvent> changes = new LinkedList<>();
|
---|
56 |
|
---|
57 | @Before
|
---|
58 | public void before() throws IOException, URISyntaxException {
|
---|
59 | final Path dir = Files.createTempDirectory("profilestest");
|
---|
60 | copyrepodir = Paths.get(dir.toString(), "repo");
|
---|
61 | copyFolder(REPO_DIRECTORY, copyrepodir);
|
---|
62 |
|
---|
63 | System.out.println("copy placed in " + copyrepodir);
|
---|
64 | Reporter logger = new Reporter() {
|
---|
65 |
|
---|
66 | @Override
|
---|
67 | public void log(Level level, String string, Throwable e) {
|
---|
68 | if (level.intValue() >= Level.WARNING.intValue()) {
|
---|
69 | warnings.add(string);
|
---|
70 | }
|
---|
71 | }
|
---|
72 |
|
---|
73 | @Override
|
---|
74 | public void log(Level level, String string) {
|
---|
75 | if (level.intValue() >= Level.WARNING.intValue()) {
|
---|
76 | warnings.add(string);
|
---|
77 | }
|
---|
78 | }
|
---|
79 |
|
---|
80 | };
|
---|
81 |
|
---|
82 | factory = new AutoUpdatingProfilesRepository(logger) {
|
---|
83 |
|
---|
84 | @Override
|
---|
85 | protected Path getRootDir() {
|
---|
86 | return copyrepodir;
|
---|
87 | }
|
---|
88 |
|
---|
89 | @Override
|
---|
90 | protected Listenable<Tuple<FileInfo, FileInfo>> getFileWatcher(
|
---|
91 | File file) {
|
---|
92 | return new FileWatcher(file, HIGHRATE - 100, 2);
|
---|
93 | }
|
---|
94 |
|
---|
95 | };
|
---|
96 |
|
---|
97 | factory.addListener(new Listener<ChangeEvent>() {
|
---|
98 |
|
---|
99 | @Override
|
---|
100 | public void notifyChange(ChangeEvent evt) {
|
---|
101 | changes.add(evt);
|
---|
102 | }
|
---|
103 | });
|
---|
104 |
|
---|
105 | warnings = new LinkedList<>();
|
---|
106 |
|
---|
107 | }
|
---|
108 |
|
---|
109 | /**
|
---|
110 | * test loading the repo
|
---|
111 | */
|
---|
112 | @Test
|
---|
113 | public void loadRepoTest() throws InterruptedException {
|
---|
114 | assertEquals(Collections.EMPTY_LIST, warnings);
|
---|
115 | assertNotNull(factory.getDomain(JOBS));
|
---|
116 | assertNotNull(factory.getProfile(JOB1));
|
---|
117 |
|
---|
118 | }
|
---|
119 |
|
---|
120 | @Test
|
---|
121 | public void getDomainsTest() {
|
---|
122 | assertTrue(factory.getDomains().size() > 2);
|
---|
123 | assertTrue(factory.getDomains().contains(JOBS));
|
---|
124 | assertTrue(factory.getDomains().contains(JOBS));
|
---|
125 | assertTrue(factory.getDomains().contains("7issues"));
|
---|
126 |
|
---|
127 | }
|
---|
128 |
|
---|
129 | @Test
|
---|
130 | public void removeProfileTest() throws InterruptedException {
|
---|
131 |
|
---|
132 | copyrepodir.resolve("jobs/jobs1.json").toFile().delete();
|
---|
133 | Thread.sleep(HIGHRATE);
|
---|
134 |
|
---|
135 | assertEquals(1, changes.size());
|
---|
136 | assertTrue(changes.get(0) instanceof ProfileChangeEvent);
|
---|
137 | assertEquals(Collections.EMPTY_LIST, warnings);
|
---|
138 | assertNotNull(factory.getDomain(JOBS));
|
---|
139 | assertNull(factory.getProfile(JOB1));
|
---|
140 | }
|
---|
141 |
|
---|
142 | @Test
|
---|
143 | public void removeDomainTest() throws InterruptedException {
|
---|
144 |
|
---|
145 | copyrepodir.resolve("jobs/jobs.json").toFile().delete();
|
---|
146 | Thread.sleep(HIGHRATE);
|
---|
147 |
|
---|
148 | assertEquals(4, changes.size());
|
---|
149 | assertTrue(changes.get(0) instanceof ProfileChangeEvent);
|
---|
150 | assertTrue(changes.get(1) instanceof ProfileChangeEvent);
|
---|
151 | assertTrue(changes.get(2) instanceof ProfileChangeEvent);
|
---|
152 | assertTrue(changes.get(3) instanceof DomainChangeEvent);
|
---|
153 | assertEquals(1, warnings.size()); // jobs domain file missing
|
---|
154 | assertNull(factory.getDomain(JOBS));
|
---|
155 | assertNull(factory.getProfile(JOB1));
|
---|
156 |
|
---|
157 | }
|
---|
158 |
|
---|
159 | @Test
|
---|
160 | public void renameDomainTest() throws InterruptedException {
|
---|
161 |
|
---|
162 | assertTrue(copyrepodir.resolve(JOBS).toFile()
|
---|
163 | .renameTo(copyrepodir.resolve("otherjobs").toFile()));
|
---|
164 | Thread.sleep(HIGHRATE);
|
---|
165 |
|
---|
166 | assertEquals(4, changes.size());
|
---|
167 | assertTrue(changes.get(0) instanceof ProfileChangeEvent);
|
---|
168 | assertTrue(changes.get(1) instanceof ProfileChangeEvent);
|
---|
169 | assertTrue(changes.get(2) instanceof ProfileChangeEvent);
|
---|
170 | assertTrue(changes.get(3) instanceof DomainChangeEvent);
|
---|
171 | assertEquals(1, warnings.size()); // wrong domain file, wrong profile
|
---|
172 | assertNull(factory.getDomain(JOBS));
|
---|
173 | assertNull(factory.getProfile(JOB1));
|
---|
174 | assertNull(factory.getDomain("otherjobs"));
|
---|
175 | }
|
---|
176 |
|
---|
177 | @Test
|
---|
178 | public void addProfileTest() throws InterruptedException, IOException {
|
---|
179 | LinearAdditiveUtilitySpace profile = (LinearAdditiveUtilitySpace) factory
|
---|
180 | .getProfile(JOB1);
|
---|
181 | Profile newprofile = new LinearAdditiveUtilitySpace(profile.getDomain(),
|
---|
182 | "jobs9", profile.getUtilities(), profile.getWeights(),
|
---|
183 | profile.getReservationBid());
|
---|
184 |
|
---|
185 | ObjectMapper jackson = new ObjectMapper();
|
---|
186 | BufferedWriter writer = new BufferedWriter(new FileWriter(
|
---|
187 | copyrepodir.resolve("jobs/jobs9.json").toFile()));
|
---|
188 | writer.write(jackson.writeValueAsString(newprofile));
|
---|
189 | writer.close();
|
---|
190 |
|
---|
191 | Thread.sleep(HIGHRATE);
|
---|
192 |
|
---|
193 | assertEquals(1, changes.size());
|
---|
194 | assertTrue(changes.get(0) instanceof ProfileChangeEvent);
|
---|
195 | assertTrue(warnings.isEmpty());
|
---|
196 | assertNotNull(factory.getProfile("jobs/jobs2"));
|
---|
197 | }
|
---|
198 |
|
---|
199 | /**
|
---|
200 | * We add domain as jobs8 but it has internally the name jobs9.
|
---|
201 | */
|
---|
202 | @Test
|
---|
203 | public void addWrongProfileTest() throws InterruptedException, IOException {
|
---|
204 | LinearAdditiveUtilitySpace profile = (LinearAdditiveUtilitySpace) factory
|
---|
205 | .getProfile(JOB1);
|
---|
206 | Profile newprofile = new LinearAdditiveUtilitySpace(profile.getDomain(),
|
---|
207 | "jobs9", profile.getUtilities(), profile.getWeights(),
|
---|
208 | profile.getReservationBid());
|
---|
209 |
|
---|
210 | ObjectMapper jackson = new ObjectMapper();
|
---|
211 | BufferedWriter writer = new BufferedWriter(new FileWriter(
|
---|
212 | copyrepodir.resolve("jobs/jobs8.json").toFile()));
|
---|
213 | writer.write(jackson.writeValueAsString(newprofile));
|
---|
214 | writer.close();
|
---|
215 |
|
---|
216 | Thread.sleep(HIGHRATE);
|
---|
217 |
|
---|
218 | // the bad profile should be completely ignored but we should get
|
---|
219 | // warnings.
|
---|
220 | assertEquals(0, changes.size());
|
---|
221 | assertEquals(1, warnings.size());
|
---|
222 | }
|
---|
223 |
|
---|
224 | @Test
|
---|
225 | public void saveProfileTest() throws IOException {
|
---|
226 | assertEquals(0, changes.size());
|
---|
227 | LinearAdditiveUtilitySpace profile = (LinearAdditiveUtilitySpace) factory
|
---|
228 | .getProfile(JOB1);
|
---|
229 | Profile newprofile = new LinearAdditiveUtilitySpace(profile.getDomain(),
|
---|
230 | "jobsA", profile.getUtilities(), profile.getWeights(),
|
---|
231 | profile.getReservationBid());
|
---|
232 | factory.putProfile(newprofile);
|
---|
233 | // check response immediately
|
---|
234 | assertEquals(1, changes.size());
|
---|
235 | assertTrue(changes.get(0) instanceof ProfileChangeEvent);
|
---|
236 | // check file was written
|
---|
237 | assertTrue(copyrepodir.resolve("jobs/jobsA.json").toFile().exists());
|
---|
238 | }
|
---|
239 |
|
---|
240 | /**
|
---|
241 | * We remove jobs domain.
|
---|
242 | */
|
---|
243 | @Test
|
---|
244 | public void removeRootdirTest() throws InterruptedException, IOException {
|
---|
245 | assertNotNull(factory.getDomain(JOBS));
|
---|
246 |
|
---|
247 | delete(copyrepodir.resolve(JOBS).toFile());
|
---|
248 | Thread.sleep(HIGHRATE);
|
---|
249 |
|
---|
250 | assertNull(factory.getDomain(JOBS));
|
---|
251 | assertNull(factory.getProfile(JOB1));
|
---|
252 |
|
---|
253 | assertEquals(4, changes.size());
|
---|
254 | assertTrue(changes.get(0) instanceof ProfileChangeEvent);
|
---|
255 | assertTrue(changes.get(1) instanceof ProfileChangeEvent);
|
---|
256 | assertTrue(changes.get(2) instanceof ProfileChangeEvent);
|
---|
257 | assertTrue(changes.get(3) instanceof DomainChangeEvent);
|
---|
258 | assertEquals(0, warnings.size());
|
---|
259 | }
|
---|
260 |
|
---|
261 | @Test
|
---|
262 | public void testEnvVariable() throws IOException {
|
---|
263 | Path dir = Files.createTempDirectory("tempdir");
|
---|
264 | // This test does not work because we can not set the env variable.
|
---|
265 | // new EnvironmentVariables().set("PROFILES_ROOTDIR", "1");
|
---|
266 | System.setProperty("PROFILES_ROOTDIR", "1");// dir.toAbsolutePath().toString());
|
---|
267 | System.out.println(System.getenv("PROFILES_ROOTDIR"));
|
---|
268 | }
|
---|
269 |
|
---|
270 | /**
|
---|
271 | * Copy files and all sub-files.
|
---|
272 | *
|
---|
273 | * @param source
|
---|
274 | * @param dest
|
---|
275 | */
|
---|
276 | private void copy(Path source, Path dest) {
|
---|
277 | try {
|
---|
278 | Files.copy(source, dest);
|
---|
279 | } catch (IOException e) {
|
---|
280 | e.printStackTrace();
|
---|
281 | }
|
---|
282 | }
|
---|
283 |
|
---|
284 | private void copyFolder(Path src, Path dest) throws IOException {
|
---|
285 | Files.walk(src).forEach(
|
---|
286 | source -> copy(source, dest.resolve(src.relativize(source))));
|
---|
287 | }
|
---|
288 |
|
---|
289 | /**
|
---|
290 | * recursively delete file and all subfiles.
|
---|
291 | *
|
---|
292 | * @param f the file to be deleted. can be directory.
|
---|
293 | * @throws IOException if file can't be deleted. This halts the delete
|
---|
294 | * procedure immediately.
|
---|
295 | */
|
---|
296 | private void delete(File f) throws IOException {
|
---|
297 | if (f.isDirectory()) {
|
---|
298 | for (File c : f.listFiles())
|
---|
299 | delete(c);
|
---|
300 | }
|
---|
301 | if (!f.delete())
|
---|
302 | throw new FileNotFoundException("Failed to delete file: " + f);
|
---|
303 | }
|
---|
304 | }
|
---|