1 package com.atlassian.sal.core.upgrade;
2
3 import com.atlassian.plugin.Plugin;
4 import com.atlassian.plugin.PluginAccessor;
5 import com.atlassian.plugin.event.PluginEventManager;
6 import com.atlassian.sal.api.message.Message;
7 import com.atlassian.sal.api.pluginsettings.PluginSettings;
8 import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory;
9 import com.atlassian.sal.api.transaction.TransactionCallback;
10 import com.atlassian.sal.api.transaction.TransactionTemplate;
11 import com.atlassian.sal.api.upgrade.PluginUpgradeTask;
12 import com.atlassian.sal.core.message.DefaultMessage;
13
14 import org.hamcrest.Matchers;
15 import org.junit.After;
16 import org.junit.Before;
17 import org.junit.Test;
18 import org.junit.runner.RunWith;
19 import org.mockito.Mock;
20 import org.mockito.runners.MockitoJUnitRunner;
21
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.List;
25
26 import static com.atlassian.sal.core.upgrade.PluginUpgrader.BUILD;
27 import static java.util.Collections.singletonList;
28 import static org.hamcrest.Matchers.empty;
29 import static org.hamcrest.Matchers.is;
30 import static org.hamcrest.Matchers.not;
31 import static org.junit.Assert.assertThat;
32 import static org.mockito.Matchers.anyString;
33 import static org.mockito.Mockito.never;
34 import static org.mockito.Mockito.verify;
35 import static org.mockito.Mockito.when;
36
37 @RunWith (MockitoJUnitRunner.class)
38 public class DefaultPluginUpgradeManagerTest
39 {
40 @Mock private Plugin plugin;
41 @Mock private Plugin secondPlugin;
42 @Mock private PluginUpgradeTask pluginUpgradeTask;
43 @Mock private PluginUpgradeTask secondPluginUpgradeTask;
44 @Mock private PluginUpgradeTask thirdPluginUpgradeTask;
45 @Mock private PluginAccessor pluginAccessor;
46 @Mock private PluginSettingsFactory pluginSettingsFactory;
47 @Mock private PluginEventManager pluginEventManager;
48 @Mock private PluginSettings pluginSettings;
49
50 private static final String PLUGIN_KEY = "com.atlassian.plugin.test.upgrade-test";
51 private static final String SECOND_PLUGIN_KEY = "com.atlassian.plugin2.test.upgrade-test";
52
53 private DefaultPluginUpgradeManager pluginUpgradeManager;
54 private CountingTransactionTemplate transactionTemplate;
55
56 @Before
57 public void setUp() throws Exception
58 {
59 transactionTemplate = new CountingTransactionTemplate();
60
61 when(plugin.getKey()).thenReturn(PLUGIN_KEY);
62 when(secondPlugin.getKey()).thenReturn(SECOND_PLUGIN_KEY);
63
64 when(pluginAccessor.getPlugin(PLUGIN_KEY)).thenReturn(plugin);
65 when(pluginAccessor.getPlugin(SECOND_PLUGIN_KEY)).thenReturn(secondPlugin);
66
67 when(pluginUpgradeTask.getPluginKey()).thenReturn(PLUGIN_KEY);
68 when(pluginUpgradeTask.getBuildNumber()).thenReturn(1);
69 when(pluginUpgradeTask.doUpgrade()).thenReturn(Collections.<Message>emptyList());
70
71 when(secondPluginUpgradeTask.getPluginKey()).thenReturn(PLUGIN_KEY);
72 when(secondPluginUpgradeTask.getBuildNumber()).thenReturn(2);
73 when(secondPluginUpgradeTask.doUpgrade()).thenReturn(Collections.<Message>emptyList());
74
75 when(thirdPluginUpgradeTask.getPluginKey()).thenReturn(SECOND_PLUGIN_KEY);
76 when(thirdPluginUpgradeTask.getBuildNumber()).thenReturn(1);
77 when(thirdPluginUpgradeTask.doUpgrade()).thenReturn(Collections.<Message>emptyList());
78
79 when(pluginSettingsFactory.createGlobalSettings()).thenReturn(pluginSettings);
80 }
81
82 @After
83 public void tearDown()
84 {
85 transactionTemplate.resetTransactionCount();
86 }
87
88 @Test
89 public void testUpgradeInternalIsSuccessful() throws Exception
90 {
91 pluginUpgradeManager = new DefaultPluginUpgradeManager(singletonList(pluginUpgradeTask), transactionTemplate, pluginAccessor, pluginSettingsFactory, pluginEventManager);
92
93 when(pluginSettings.get(plugin.getKey() + BUILD)).thenReturn(Integer.toString(0));
94
95 List<Message> messages = pluginUpgradeManager.upgradeInternal(plugin);
96
97
98 verify(pluginSettings).put(PLUGIN_KEY + BUILD, "1");
99
100 assertThat(messages, empty());
101 }
102
103 @Test
104 public void testUpgradeInternalFailsIfUpgradeFails() throws Exception
105 {
106 pluginUpgradeManager = new DefaultPluginUpgradeManager(singletonList(pluginUpgradeTask), transactionTemplate, pluginAccessor, pluginSettingsFactory, pluginEventManager);
107
108 when(pluginUpgradeTask.doUpgrade()).thenReturn(Collections.<Message>singletonList(new DefaultMessage("failed.upgrade")));
109
110 List<Message> messages = pluginUpgradeManager.upgradeInternal(plugin);
111
112
113 verify(pluginSettings, never()).put(anyString(), anyString());
114
115 assertThat(messages, not(empty()));
116 }
117
118 @Test
119 public void testThatOnlyOneTransactionTemplateIsExecutedPerPluginUpgrade() throws Exception
120 {
121 pluginUpgradeManager = new DefaultPluginUpgradeManager(Arrays.asList(pluginUpgradeTask, secondPluginUpgradeTask), transactionTemplate, pluginAccessor, pluginSettingsFactory, pluginEventManager);
122
123 List<Message> messages = pluginUpgradeManager.upgradeInternal(plugin);
124
125 assertThat(messages, empty());
126 assertThat(transactionTemplate.getTransactionCount(), is(1));
127
128 verify(pluginSettings).put(PLUGIN_KEY + BUILD, "2");
129 }
130
131 @Test
132 public void testThatOnlyOneTransactionTemplateIsExecutedPerPluginUpgradeWithMultiplePlugins() throws Exception
133 {
134 pluginUpgradeManager = new DefaultPluginUpgradeManager(Arrays.asList(pluginUpgradeTask, secondPluginUpgradeTask, thirdPluginUpgradeTask), transactionTemplate, pluginAccessor, pluginSettingsFactory, pluginEventManager);
135
136 List<Message> messages = pluginUpgradeManager.upgradeInternal();
137
138 verify(pluginSettings).put(PLUGIN_KEY + BUILD, "2");
139 verify(pluginSettings).put(SECOND_PLUGIN_KEY + BUILD, "1");
140
141 assertThat(messages, empty());
142 assertThat(transactionTemplate.getTransactionCount(), is(2));
143 }
144
145 private static class CountingTransactionTemplate implements TransactionTemplate
146 {
147 private int transactionCount = 0;
148
149 @Override
150 public <T> T execute(final TransactionCallback<T> action)
151 {
152 transactionCount++;
153 return action.doInTransaction();
154 }
155
156 void resetTransactionCount()
157 {
158 transactionCount = 0;
159 }
160
161 int getTransactionCount()
162 {
163 return transactionCount;
164 }
165 }
166 }