1   package com.atlassian.util.concurrent.atomic;
2   
3   import static com.google.common.base.Suppliers.ofInstance;
4   import static org.junit.Assert.assertEquals;
5   
6   import org.junit.Test;
7   
8   import com.google.common.base.Function;
9   import com.google.common.base.Supplier;
10  
11  public class AtomicReferenceTest {
12      @Test
13      public void getAndSetIfNormal() {
14          final String from = "from";
15          final String to = "to";
16          final AtomicReference<String> ref = new AtomicReference<String>(from);
17          assertEquals(to, ref.getOrSetAndGetIf(from, ofInstance(to)));
18      }
19  
20      @Test
21      public void getAndSetIfNormalValue() {
22          final String from = "from";
23          final String to = "to";
24          final AtomicReference<String> ref = new AtomicReference<String>(from);
25          assertEquals(to, ref.getOrSetAndGetIf(from, to));
26      }
27  
28      @Test
29      public void getAndSetIfNull() {
30          final String to = "to";
31          final AtomicReference<String> ref = new AtomicReference<String>();
32          assertEquals(to, Atomics.getAndSetIfNull(ref, ofInstance(to)));
33      }
34  
35      @Test
36      public void getAndSetContended() {
37          final String from = "from";
38          final String to = "to";
39          final String different = "different";
40          final AtomicReference<String> ref = new AtomicReference<String>(from);
41          assertEquals(different, ref.getOrSetAndGetIf(from, new Supplier<String>() {
42              public String get() {
43                  // being called, set the reference so the CAS fails
44                  ref.set(different);
45                  return to;
46              }
47          }));
48      }
49  
50      @Test
51      public void getAndSetReturnsOldValueIfChanged() {
52          final String old = "old";
53          final String from = "from";
54          final String to = "to";
55          final AtomicReference<String> ref = new AtomicReference<String>(old);
56          assertEquals(old, ref.getOrSetAndGetIf(from, ofInstance(to)));
57      }
58  
59      @Test
60      public void getAndSetSameValue() {
61          final String from = "from";
62          final String to = from;
63          final AtomicReference<String> ref = new AtomicReference<String>(from);
64          assertEquals(to, ref.getOrSetAndGetIf(from, ofInstance(to)));
65      }
66  
67      @Test
68      public void getAndSetSameValueDifferent() {
69          final String from = "from";
70          final String to = from;
71          final String different = "blah";
72          final AtomicReference<String> ref = new AtomicReference<String>(different);
73          assertEquals(different, ref.getOrSetAndGetIf(from, ofInstance(to)));
74      }
75  
76      @Test
77      public void updateNormal() {
78          final String from = "from";
79          final String to = "to";
80          final AtomicReference<String> ref = new AtomicReference<String>(from);
81          final Function<String, String> newValueFactory = new Function<String, String>() {
82              public String apply(final String input) {
83                  return to;
84              }
85          };
86          assertEquals(to, ref.update(newValueFactory));
87      }
88  
89      @Test
90      public void updateContended() {
91          final Integer from = 0;
92          final Integer to = 10;
93          final AtomicReference<Integer> ref = new AtomicReference<Integer>(from);
94          assertEquals(to, ref.update(new Function<Integer, Integer>() {
95              int x = from;
96  
97              public Integer apply(final Integer input) {
98                  if (x < to) {
99                      ref.set(++x);
100                 }
101                 return x;
102             }
103         }));
104     }
105 }