|
51 | 51 | import org.apache.beam.sdk.state.TimerSpecs; |
52 | 52 | import org.apache.beam.sdk.state.ValueState; |
53 | 53 | import org.apache.beam.sdk.state.WatermarkHoldState; |
| 54 | +import org.apache.beam.sdk.testing.ExpectedLogs; |
54 | 55 | import org.apache.beam.sdk.testing.SerializableMatchers; |
55 | 56 | import org.apache.beam.sdk.transforms.DoFn; |
56 | 57 | import org.apache.beam.sdk.transforms.Sum; |
@@ -137,6 +138,8 @@ public void process(@FireTimestamp Instant ts) {} |
137 | 138 |
|
138 | 139 | @Rule public ExpectedException thrown = ExpectedException.none(); |
139 | 140 |
|
| 141 | + @Rule public ExpectedLogs expectedLogs = ExpectedLogs.none(DoFnSignatures.class); |
| 142 | + |
140 | 143 | @Test |
141 | 144 | public void testBasicDoFnProcessContext() throws Exception { |
142 | 145 | DoFnSignature sig = |
@@ -1810,4 +1813,118 @@ public void onMyTimer() {} |
1810 | 1813 | @Override |
1811 | 1814 | public void processWithTimer(ProcessContext context, Timer timer) {} |
1812 | 1815 | } |
| 1816 | + |
| 1817 | + // Test DoFns for ValueState collection warning tests |
| 1818 | + private static class DoFnWithMapValueState extends DoFn<String, String> { |
| 1819 | + @StateId("mapState") |
| 1820 | + private final StateSpec<ValueState<java.util.Map<String, String>>> mapState = |
| 1821 | + StateSpecs.value(); |
| 1822 | + |
| 1823 | + @ProcessElement |
| 1824 | + public void process() {} |
| 1825 | + } |
| 1826 | + |
| 1827 | + private static class DoFnWithListValueState extends DoFn<String, String> { |
| 1828 | + @StateId("listState") |
| 1829 | + private final StateSpec<ValueState<java.util.List<String>>> listState = StateSpecs.value(); |
| 1830 | + |
| 1831 | + @ProcessElement |
| 1832 | + public void process() {} |
| 1833 | + } |
| 1834 | + |
| 1835 | + private static class DoFnWithSetValueState extends DoFn<String, String> { |
| 1836 | + @StateId("setState") |
| 1837 | + private final StateSpec<ValueState<java.util.Set<String>>> setState = StateSpecs.value(); |
| 1838 | + |
| 1839 | + @ProcessElement |
| 1840 | + public void process() {} |
| 1841 | + } |
| 1842 | + |
| 1843 | + private static class DoFnWithSimpleValueState extends DoFn<String, String> { |
| 1844 | + @StateId("simpleState") |
| 1845 | + private final StateSpec<ValueState<String>> simpleState = StateSpecs.value(); |
| 1846 | + |
| 1847 | + @ProcessElement |
| 1848 | + public void process() {} |
| 1849 | + } |
| 1850 | + |
| 1851 | + private static class DoFnWithParameterizedSetValueState<T> extends DoFn<String, String> { |
| 1852 | + @StateId("parameterizedSetState") |
| 1853 | + private final StateSpec<ValueState<java.util.Set<T>>> parameterizedSetState = |
| 1854 | + StateSpecs.value(); |
| 1855 | + |
| 1856 | + @ProcessElement |
| 1857 | + public void process() {} |
| 1858 | + } |
| 1859 | + |
| 1860 | + private static class DoFnWithParameterizedListValueState<T> extends DoFn<String, String> { |
| 1861 | + @StateId("parameterizedListState") |
| 1862 | + private final StateSpec<ValueState<java.util.List<T>>> parameterizedListState = |
| 1863 | + StateSpecs.value(); |
| 1864 | + |
| 1865 | + @ProcessElement |
| 1866 | + public void process() {} |
| 1867 | + } |
| 1868 | + |
| 1869 | + private static class DoFnWithTypeVariableValueState<T> extends DoFn<String, String> { |
| 1870 | + @StateId("typeVariableState") |
| 1871 | + private final StateSpec<ValueState<T>> typeVariableState = StateSpecs.value(); |
| 1872 | + |
| 1873 | + @ProcessElement |
| 1874 | + public void process() {} |
| 1875 | + } |
| 1876 | + |
| 1877 | + @Test |
| 1878 | + public void testValueStateWithMapLogsWarning() { |
| 1879 | + // This test verifies that the signature can be parsed for DoFns with collection ValueState. |
| 1880 | + // The warning is logged but doesn't prevent the signature from being created. |
| 1881 | + DoFnSignature signature = DoFnSignatures.getSignature(DoFnWithMapValueState.class); |
| 1882 | + assertThat(signature.stateDeclarations().get("mapState"), notNullValue()); |
| 1883 | + } |
| 1884 | + |
| 1885 | + @Test |
| 1886 | + public void testValueStateWithListLogsWarning() { |
| 1887 | + DoFnSignature signature = DoFnSignatures.getSignature(DoFnWithListValueState.class); |
| 1888 | + assertThat(signature.stateDeclarations().get("listState"), notNullValue()); |
| 1889 | + } |
| 1890 | + |
| 1891 | + @Test |
| 1892 | + public void testValueStateWithSetLogsWarning() { |
| 1893 | + DoFnSignature signature = DoFnSignatures.getSignature(DoFnWithSetValueState.class); |
| 1894 | + assertThat(signature.stateDeclarations().get("setState"), notNullValue()); |
| 1895 | + } |
| 1896 | + |
| 1897 | + @Test |
| 1898 | + public void testValueStateWithSimpleTypeNoWarning() { |
| 1899 | + // Simple types should not trigger any warning |
| 1900 | + DoFnSignature signature = DoFnSignatures.getSignature(DoFnWithSimpleValueState.class); |
| 1901 | + assertThat(signature.stateDeclarations().get("simpleState"), notNullValue()); |
| 1902 | + expectedLogs.verifyNotLogged("with collection type"); |
| 1903 | + } |
| 1904 | + |
| 1905 | + @Test |
| 1906 | + public void testValueStateWithParameterizedSetLogsWarning() { |
| 1907 | + // A parameterized collection such as ValueState<Set<T>> still has a known raw collection type |
| 1908 | + // (Set) even though the element type is a type variable, so it should still recommend SetState. |
| 1909 | + DoFnSignature signature = DoFnSignatures.getSignature(DoFnWithParameterizedSetValueState.class); |
| 1910 | + assertThat(signature.stateDeclarations().get("parameterizedSetState"), notNullValue()); |
| 1911 | + expectedLogs.verifyWarn("SetState"); |
| 1912 | + } |
| 1913 | + |
| 1914 | + @Test |
| 1915 | + public void testValueStateWithParameterizedListLogsWarning() { |
| 1916 | + DoFnSignature signature = |
| 1917 | + DoFnSignatures.getSignature(DoFnWithParameterizedListValueState.class); |
| 1918 | + assertThat(signature.stateDeclarations().get("parameterizedListState"), notNullValue()); |
| 1919 | + expectedLogs.verifyWarn("BagState or OrderedListState"); |
| 1920 | + } |
| 1921 | + |
| 1922 | + @Test |
| 1923 | + public void testValueStateWithBareTypeVariableNoWarning() { |
| 1924 | + // A bare type variable payload (ValueState<T>) has no raw collection type to inspect and must |
| 1925 | + // not produce a collection recommendation. |
| 1926 | + DoFnSignature signature = DoFnSignatures.getSignature(DoFnWithTypeVariableValueState.class); |
| 1927 | + assertThat(signature.stateDeclarations().get("typeVariableState"), notNullValue()); |
| 1928 | + expectedLogs.verifyNotLogged("with collection type"); |
| 1929 | + } |
1813 | 1930 | } |
0 commit comments