1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.beans;
18
19 import java.io.ByteArrayOutputStream;
20 import java.io.IOException;
21 import java.util.Collections;
22 import java.util.HashSet;
23 import java.util.Iterator;
24 import java.util.Properties;
25 import java.util.Set;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.junit.Test;
30
31 import static org.junit.Assert.*;
32
33
34
35
36
37
38
39 public final class ConcurrentBeanWrapperTests {
40
41 private final Log logger = LogFactory.getLog(getClass());
42
43 private Set<TestRun> set = Collections.synchronizedSet(new HashSet<TestRun>());
44
45 private Throwable ex = null;
46
47 @Test
48 public void testSingleThread() {
49 for (int i = 0; i < 100; i++) {
50 performSet();
51 }
52 }
53
54 @Test
55 public void testConcurrent() {
56 for (int i = 0; i < 10; i++) {
57 TestRun run = new TestRun(this);
58 set.add(run);
59 Thread t = new Thread(run);
60 t.setDaemon(true);
61 t.start();
62 }
63 logger.info("Thread creation over, " + set.size() + " still active.");
64 synchronized (this) {
65 while (!set.isEmpty() && ex == null) {
66 try {
67 wait();
68 }
69 catch (InterruptedException e) {
70 logger.info(e.toString());
71 }
72 logger.info(set.size() + " threads still active.");
73 }
74 }
75 if (ex != null) {
76 fail(ex.getMessage());
77 }
78 }
79
80 private static void performSet() {
81 TestBean bean = new TestBean();
82
83 Properties p = (Properties) System.getProperties().clone();
84
85 assertTrue("The System properties must not be empty", p.size() != 0);
86
87 for (Iterator<?> i = p.entrySet().iterator(); i.hasNext();) {
88 i.next();
89 if (Math.random() > 0.9) {
90 i.remove();
91 }
92 }
93
94 ByteArrayOutputStream buffer = new ByteArrayOutputStream();
95 try {
96 p.store(buffer, null);
97 }
98 catch (IOException e) {
99
100
101 }
102 String value = new String(buffer.toByteArray());
103
104 BeanWrapperImpl wrapper = new BeanWrapperImpl(bean);
105 wrapper.setPropertyValue("properties", value);
106 assertEquals(p, bean.getProperties());
107 }
108
109
110 private static class TestRun implements Runnable {
111
112 private ConcurrentBeanWrapperTests test;
113
114 public TestRun(ConcurrentBeanWrapperTests test) {
115 this.test = test;
116 }
117
118 @Override
119 public void run() {
120 try {
121 for (int i = 0; i < 100; i++) {
122 performSet();
123 }
124 }
125 catch (Throwable e) {
126 test.ex = e;
127 }
128 finally {
129 synchronized (test) {
130 test.set.remove(this);
131 test.notifyAll();
132 }
133 }
134 }
135 }
136
137
138 @SuppressWarnings("unused")
139 private static class TestBean {
140
141 private Properties properties;
142
143 public Properties getProperties() {
144 return properties;
145 }
146
147 public void setProperties(Properties properties) {
148 this.properties = properties;
149 }
150 }
151
152 }